src/main/java/cc/mrbird/febs/mall/service/impl/AdminMallMemberServiceImpl.java | ●●●●● patch | view | raw | blame | history | |
src/main/java/cc/mrbird/febs/pay/model/SinglePayDto.java | ●●●●● patch | view | raw | blame | history | |
src/main/java/cc/mrbird/febs/pay/service/impl/UnipayServiceImpl.java | ●●●●● patch | view | raw | blame | history | |
src/main/java/cc/mrbird/febs/pay/util/Md5_Sign.java | ●●●●● patch | view | raw | blame | history | |
src/test/java/cc/mrbird/febs/ProfitTest.java | ●●●●● patch | view | raw | blame | history |
src/main/java/cc/mrbird/febs/mall/service/impl/AdminMallMemberServiceImpl.java
@@ -16,6 +16,8 @@ import cc.mrbird.febs.mall.service.IApiMallMemberWalletService; import cc.mrbird.febs.mall.service.IMallMoneyFlowService; import cc.mrbird.febs.mall.vo.*; import cc.mrbird.febs.pay.model.SinglePayDto; import cc.mrbird.febs.pay.service.UnipayService; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; @@ -64,6 +66,8 @@ private final MallShopApplyMapper mallShopApplyMapper; private final IMallMoneyFlowService mallMoneyFlowService; private final UnipayService unipayService; private final MallMemberBankMapper mallMemberBankMapper; @Override public IPage<MallMember> getMallMemberList(MallMember mallMember, QueryRequest request) { @@ -152,6 +156,28 @@ if(1 != mallMemberWithdraw.getStatus()){ return new FebsResponse().fail().message("当前状态不是提现中"); } Long wtihdrawTypeId = mallMemberWithdraw.getWtihdrawTypeId(); MallMemberBank mallMemberBank = mallMemberBankMapper.selectById(wtihdrawTypeId); /** * 调用汇聚代付 */ SinglePayDto singlePayDto = new SinglePayDto(); singlePayDto.setMerchantOrderNo(mallMemberWithdraw.getWithdrawNo()); singlePayDto.setReceiverAccountNoEncBankNo(mallMemberBank.getBankNo()); singlePayDto.setReceiverAccountNoEncName(mallMemberBank.getName()); singlePayDto.setReceiverAccountType("201"); BigDecimal paidAmount = mallMemberWithdraw.getAmount().subtract(mallMemberWithdraw.getAmountFee()).setScale(2, BigDecimal.ROUND_DOWN); singlePayDto.setPaidAmount(paidAmount); singlePayDto.setCurrency("201"); singlePayDto.setIsChecked("202"); singlePayDto.setPaidDesc("用户提现"); singlePayDto.setPaidUse("202"); String singlePayRep = unipayService.singlePay(singlePayDto); if(!mallMemberWithdraw.getWithdrawNo().equals(singlePayRep)){ return new FebsResponse().fail().message("提现失败,请联系技术人员"); } mallMemberWithdraw.setStatus(2); mallMemberWithdrawMapper.updateById(mallMemberWithdraw); @@ -175,7 +201,6 @@ if(1 != mallMemberWithdraw.getStatus()){ return new FebsResponse().fail().message("当前状态不是提现中"); } mallMemberWithdraw.setStatus(3); mallMemberWithdrawMapper.updateById(mallMemberWithdraw); src/main/java/cc/mrbird/febs/pay/model/SinglePayDto.java
@@ -3,7 +3,39 @@ import io.swagger.annotations.ApiModel; import lombok.Data; import java.math.BigDecimal; @Data @ApiModel(value = "SinglePayDto", description = "汇聚支付代付接收参数类") public class SinglePayDto { //商户订单号(全局唯一,由数字或字母组成,长度 //须控制在 12 到 25 之间,可包含边界 //值) private String merchantOrderNo; //收款账户号(收款人银行卡卡号) private String receiverAccountNoEncBankNo; // 收款人(收款人银行卡持卡人名称) private String receiverAccountNoEncName; // 账户类型(对私账户:201 //对公账户:204) private String receiverAccountType; // 收款账户联行号,对公账户必须填写此字段 // private String receiverBankChannelNo; // 交易金额,单位:元,精确到分,保留两位小数 private BigDecimal paidAmount; // 人民币币种填写:201 private String currency; // 是否复核:复核:201,不复核:202 (见注释 //一)是否审核→填写为 201 时,需到商户后台进行审核,审核通过汇聚才会进行打款,审核不通过,则订 //单状态为订单已取消(没有异步);填写为 202 时,不需要到商户后台进行审核,订单提交汇聚成功则开 //始打款。 private String isChecked; //(代付说明填写此次单笔代付的代付说明(长度 //为 30 个字符以内) private String paidDesc; //代付用途 如其他 209 private String paidUse; //代付用途 如其他 209 // private String callbackUrl; } src/main/java/cc/mrbird/febs/pay/service/impl/UnipayServiceImpl.java
@@ -6,6 +6,7 @@ import cc.mrbird.febs.pay.service.UnipayService; import cc.mrbird.febs.pay.util.*; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSON; @@ -44,6 +45,7 @@ "MXm0GwJAZd4Bk8ZYJopIOUyRLibRQIFnI78Q7HAuAUW7QtSX4yh5bMcu+Nt8zIkNAuvBC8Ju7hAmmo1V7n" + "cNgAAtydXYWQJALLOFCjCkRgeRVL8YE8bVi4U16b8ltAN1DlbWEzui6VFy2vIga3IryesNVAOOdornyAwf" + "1huqB2lYfuQwtrIBKg=="; public static final String MD5KEY = "2e95f6a3e11e47fa8a4386d6aefe1735"; public static final String notifyUrl = "http://47.111.90.145:8800/api/unipay/unipayCallBack"; public static final String agreementPayNotifyUrl = "http://47.111.90.145:8800/api/unipay/agreeMentPayCallBack"; public static final String p1MerchantNo = "888118000001971";/** 商户编号 */ @@ -233,8 +235,134 @@ } @Override @Transactional public String singlePay(SinglePayDto singlePayDto) { return null; String singlePay = null; String key = MD5KEY; Map<String, Object> map = new HashMap<>(); map.put("userNo", p1MerchantNo);// 商户编号 map.put("productCode", "BANK_PAY_DAILY_ORDER");//产品类型 map.put("requestTime", DateUtil.now()); // 交易请求时间 map.put("merchantOrderNo", singlePayDto.getMerchantOrderNo());//商户订单号 map.put("receiverAccountNoEnc", singlePayDto.getReceiverAccountNoEncBankNo()); // 收款账户号 map.put("receiverNameEnc", singlePayDto.getReceiverAccountNoEncName()); // 收款人 map.put("receiverAccountType", singlePayDto.getReceiverAccountType());//账户类型 map.put("paidAmount", singlePayDto.getPaidAmount()); //交易金额 map.put("currency", singlePayDto.getCurrency());//币种 map.put("isChecked", singlePayDto.getIsChecked());//是否复核 map.put("paidDesc", singlePayDto.getPaidDesc());//代付说明 map.put("paidUse", singlePayDto.getPaidUse());//代付用途 // map.put("callbackUrl", singlePayDto.getCallbackUrl());//商户通知地址 String reqSign = getRequestSign(map); // 签名 String hmac = Md5_Sign.SignByMD5(reqSign, key); map.put("hmac", hmac);/** 签名数据 */ // Map转json字符串 String reqBodyJson = JSON.toJSONString(map); System.out.println("reqBodyJson:" + reqBodyJson); String httpResponseJson = null; try { httpResponseJson = HttpClientUtil .sendHttpPost("https://www.joinpay.com/payment/pay/singlePay",reqBodyJson); } catch (Exception e) { e.printStackTrace(); } System.out.println(httpResponseJson); if(StrUtil.isNotBlank(httpResponseJson)){ try { singlePay = doResponseInfo(httpResponseJson, key); } catch (Exception e) { e.printStackTrace(); } return singlePay; }else{ return "fail"; } } /** * 对单笔代付响应信息的处理 * * @param httpResponseJson 响应信息json字符串 * @param key 商户秘钥 * @throws Exception 异常实体类 */ @SuppressWarnings("unchecked") private static String doResponseInfo(String httpResponseJson, String key) throws Exception { // 响应信息map集合 Map<String, Object> httpResponseMap = (Map<String, Object>) JSONObject.parse(httpResponseJson); // 业务数据map集合 Map<String, Object> dataMap = (Map<String, Object>) httpResponseMap.get("data"); dataMap.put("statusCode", httpResponseMap.get("statusCode")); dataMap.put("message", httpResponseMap.get("message")); // 请求签名串 String reqSign = getRequestSign(httpResponseMap); // 响应签名串 String respSign = getResponseSign(dataMap); // 请求数据的加密签名 String reqHmac = Md5_Sign.SignByMD5(respSign, key); // 请求数据的加密签名 String respHmac = (String) dataMap.get("hmac"); System.out.println("reqHmac:" + reqHmac); System.out.println("respSign:" + respHmac); reqHmac=reqHmac.toUpperCase(); respHmac=respHmac.toUpperCase(); boolean isMatch = reqHmac.equals(respHmac); if (isMatch) { if("2001".equals(httpResponseMap.get("statusCode").toString()) && ObjectUtil.isEmpty(dataMap.get("errorCode"))){ System.out.println("验签成功"); return dataMap.get("merchantOrderNo").toString(); } } return "fail"; } /** * 获取响应数据签名串信息 * 必须按新代付接口文档应答参数信息顺序来进行字符串的拼接,详情请参考新代付接口文档的应答报文 * * @param params 响应数据参数 * @return 返回响应签名串 */ public static String getResponseSign(Map<String, Object> params) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append(params.get("statusCode")).append(params.get("message")).append(params.get("errorCode")) .append(params.get("errorDesc")).append(params.get("userNo")).append(params.get("merchantOrderNo")); return stringBuilder.toString(); } /** * 获取请求数据签名串信息 * 必须按新代付接口文档请求参数信息顺序来进行字符串的拼接,详情请参考新代付接口文档请求报文 * * @param params 请求数据参数 * @return 返回请求签名串 */ public static String getRequestSign(Map<String, Object> params) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append(params.get("userNo")) .append(params.get("productCode")) .append(params.get("requestTime")) .append(params.get("merchantOrderNo")) .append(params.get("receiverAccountNoEnc")) .append(params.get("receiverNameEnc")) .append(params.get("receiverAccountType")) .append(params.get("paidAmount")) .append(params.get("currency")) .append(params.get("isChecked")) .append(params.get("paidDesc")) .append(params.get("paidUse")); System.out.println("reqSign:" + stringBuilder.toString()); return stringBuilder.toString(); } public static void main(String[] args) { src/main/java/cc/mrbird/febs/pay/util/Md5_Sign.java
New file @@ -0,0 +1,27 @@ package cc.mrbird.febs.pay.util; import org.apache.commons.codec.digest.DigestUtils; /** * 类MD5_Sign:MD5签名和验签 * * @author Lori 2018年6月04日 下午16:10:04 */ public class Md5_Sign { /** * MD5签名 * * @param requestSign 请求签名串 * @param merchantKey 商户秘钥 */ public static String SignByMD5(String requestSign, String merchantKey) { String reqHmac = ""; try { reqHmac = DigestUtils.md5Hex(requestSign + merchantKey).toUpperCase(); } catch (Exception e) {} return reqHmac; } } src/test/java/cc/mrbird/febs/ProfitTest.java
@@ -1,6 +1,7 @@ package cc.mrbird.febs; import cc.mrbird.febs.common.entity.FebsResponse; import cc.mrbird.febs.common.utils.MallUtils; import cc.mrbird.febs.mall.entity.MallOrderItem; import cc.mrbird.febs.mall.mapper.MallOrderInfoMapper; import cc.mrbird.febs.mall.mapper.MallOrderItemMapper; @@ -8,10 +9,7 @@ import cc.mrbird.febs.mall.service.IAgentService; import cc.mrbird.febs.mall.service.IMallAchieveService; import cc.mrbird.febs.mall.service.IMemberProfitService; import cc.mrbird.febs.pay.model.AgreeMentPaySmsDto; import cc.mrbird.febs.pay.model.AgreementPayDto; import cc.mrbird.febs.pay.model.AgreementSignDto; import cc.mrbird.febs.pay.model.UnipayDto; import cc.mrbird.febs.pay.model.*; import cc.mrbird.febs.pay.service.UnipayService; import cc.mrbird.febs.rabbit.consumer.AgentConsumer; import cn.hutool.core.date.DateUtil; @@ -181,4 +179,26 @@ agreementPayDto.setBankNo("6222031901002389639"); unipayService.agreementPay(agreementPayDto); } @Test public void singlePay(){ /** * 调用汇聚代付 */ String orderNo = MallUtils.getOrderNum("W"); SinglePayDto singlePayDto = new SinglePayDto(); singlePayDto.setMerchantOrderNo(orderNo); singlePayDto.setReceiverAccountNoEncBankNo("6222031901002389639"); singlePayDto.setReceiverAccountNoEncName("肖永"); singlePayDto.setReceiverAccountType("201"); BigDecimal paidAmount = new BigDecimal(1.00); singlePayDto.setPaidAmount(paidAmount); singlePayDto.setCurrency("201"); singlePayDto.setIsChecked("202"); singlePayDto.setPaidDesc("用户提现"); singlePayDto.setPaidUse("202"); String singlePayRep = unipayService.singlePay(singlePayDto); System.out.println(singlePayRep); } }