| @@ -0,0 +1,2 @@ | |||||
| ALTER TABLE `mallink`.`wx_pay_account` | |||||
| ADD COLUMN `pay_version` smallint(1) COMMENT '支付版本' AFTER `open_pay`; | |||||
| @@ -169,7 +169,7 @@ public class TtPayController extends BaseController { | |||||
| logger.error("未找到订单"+orderId); | logger.error("未找到订单"+orderId); | ||||
| resultMap.put("err_tips","未找到订单"); | resultMap.put("err_tips","未找到订单"); | ||||
| }else{ | }else{ | ||||
| PayQueryAdapterResult queryResult = payServiceFactory.getPayAdapterService(wxpayOrder.getPayVendor()).queryPayStatus(wxpayOrder, appinfo, payAccount); | |||||
| PayQueryAdapterResult queryResult = payServiceFactory.getPayAdapterService(wxpayOrder.getPayVendor(),payAccount.getPayVersion()).queryPayStatus(wxpayOrder, appinfo, payAccount); | |||||
| if (EnumPayStatus.PAY_STATUS_SUCCESS.getCode() == queryResult.getCode()) { | if (EnumPayStatus.PAY_STATUS_SUCCESS.getCode() == queryResult.getCode()) { | ||||
| WxComposeOrder composeOrder = orderFactory.getOrderAdapterService(wxpayOrder.getComposeOrder()).getComposeOrder(wxpayOrder.getOrderId(), wxpayOrder.getTenantId()); | WxComposeOrder composeOrder = orderFactory.getOrderAdapterService(wxpayOrder.getComposeOrder()).getComposeOrder(wxpayOrder.getOrderId(), wxpayOrder.getTenantId()); | ||||
| wxPayOrderService.handleSuccessOrder(wxpayOrder, composeOrder, queryResult, true,false); | wxPayOrderService.handleSuccessOrder(wxpayOrder, composeOrder, queryResult, true,false); | ||||
| @@ -124,7 +124,7 @@ public class CashOutSchedule { | |||||
| if (null == payAccount) { | if (null == payAccount) { | ||||
| return; | return; | ||||
| } | } | ||||
| CashOutAdapterResult result = payServiceFactory.getCashOutAdapterService(payWay.getCode()).queryCashOut(appInfo, payAccount, cashout); | |||||
| CashOutAdapterResult result = payServiceFactory.getCashOutAdapterService(payWay.getCode(),payAccount.getPayVersion()).queryCashOut(appInfo, payAccount, cashout); | |||||
| cashout.setUpdateDate(new Date()); | cashout.setUpdateDate(new Date()); | ||||
| if (result.isSuccess()) { | if (result.isSuccess()) { | ||||
| cashout.setStatus(EnumCashOutStatus.SUCCESS.getCode()); | cashout.setStatus(EnumCashOutStatus.SUCCESS.getCode()); | ||||
| @@ -316,7 +316,7 @@ public class OrderExpiringSchedule { | |||||
| } | } | ||||
| //Map<String, String> retMap = WxPayOrderServiceHelper.wxOrderPayStatusMap(wxpayOrder, order, appInfo, payAccount); | //Map<String, String> retMap = WxPayOrderServiceHelper.wxOrderPayStatusMap(wxpayOrder, order, appInfo, payAccount); | ||||
| //int status = WxPayOrderServiceHelper.getPayStatusFromMap(retMap, wxpayOrder.getPayOrderNo()); | //int status = WxPayOrderServiceHelper.getPayStatusFromMap(retMap, wxpayOrder.getPayOrderNo()); | ||||
| PayQueryAdapterResult payResult = payServiceFactory.getPayAdapterService(wxpayOrder.getPayVendor()).queryPayStatus(wxpayOrder, appInfo, payAccount); | |||||
| PayQueryAdapterResult payResult = payServiceFactory.getPayAdapterService(wxpayOrder.getPayVendor(),payAccount.getPayVersion()).queryPayStatus(wxpayOrder, appInfo, payAccount); | |||||
| //如果是支付成功,并且需要重试成功流程, | //如果是支付成功,并且需要重试成功流程, | ||||
| if (EnumPayStatus.PAY_STATUS_SUCCESS.getCode().intValue() == payResult.getCode()) { | if (EnumPayStatus.PAY_STATUS_SUCCESS.getCode().intValue() == payResult.getCode()) { | ||||
| if (autoReHandle) { | if (autoReHandle) { | ||||
| @@ -45,8 +45,10 @@ public class WxPayAccount extends TenantEntity { | |||||
| private Integer type; | private Integer type; | ||||
| @io.swagger.annotations.ApiModelProperty(value="EnumPayMchType 0:总分1:直连",name="mchType") | @io.swagger.annotations.ApiModelProperty(value="EnumPayMchType 0:总分1:直连",name="mchType") | ||||
| private Integer mchType; | private Integer mchType; | ||||
| @io.swagger.annotations.ApiModelProperty(value="抖音用 ",name="openPay") | |||||
| @io.swagger.annotations.ApiModelProperty(value="开通的支付方式。抖音用 ",name="openPay") | |||||
| private String openPay; | private String openPay; | ||||
| @io.swagger.annotations.ApiModelProperty(value="支付版本 EnumPayVersion",name="payVersion") | |||||
| private Integer payVersion; | |||||
| @io.swagger.annotations.ApiModelProperty(value="是否开启分账(0:未开启分账1:开启分账)",name="type") | @io.swagger.annotations.ApiModelProperty(value="是否开启分账(0:未开启分账1:开启分账)",name="type") | ||||
| private Integer share; | private Integer share; | ||||
| @io.swagger.annotations.ApiModelProperty(value="手续费(万分之几,默认60)",name="rate") | @io.swagger.annotations.ApiModelProperty(value="手续费(万分之几,默认60)",name="rate") | ||||
| @@ -0,0 +1,37 @@ | |||||
| package com.iformall.enums; | |||||
| /** | |||||
| * Created by Stormeye on 2018/08/09. | |||||
| */ | |||||
| public enum EnumPayVersion { | |||||
| WX_PAY_V2(1, "微信支付2.0,老版本"), | |||||
| WX_PAY_V3(2, "微信支付3.0,对接电商收付通"), | |||||
| DY_PAY_V2(3,"抖音支付2.0,对接商品库") | |||||
| ; | |||||
| public static EnumPayVersion getEnum(Integer code) { | |||||
| for (EnumPayVersion value : values()) { | |||||
| if (value.getCode().equals(code)) { | |||||
| return value; | |||||
| } | |||||
| } | |||||
| return null; | |||||
| } | |||||
| private Integer code; | |||||
| private String name; | |||||
| EnumPayVersion(Integer code, String name) { | |||||
| this.code = code; | |||||
| this.name = name; | |||||
| } | |||||
| public Integer getCode() { | |||||
| return code; | |||||
| } | |||||
| public String getName() { | |||||
| return name; | |||||
| } | |||||
| } | |||||
| @@ -204,8 +204,8 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||||
| PayQueryAdapterResult queryResult = null; | PayQueryAdapterResult queryResult = null; | ||||
| int wxpaystatus = 0; | int wxpaystatus = 0; | ||||
| try { | try { | ||||
| queryResult = payServiceFactory.getPayAdapterService(oldRecord.getPayVendor()).queryPayStatus(oldRecord, appInfo, payAccount); | |||||
| wxpaystatus = payServiceFactory.getPayAdapterService(oldRecord.getPayVendor()).queryPayStatus(queryResult, oldRecord.getPayOrderNo()); | |||||
| queryResult = payServiceFactory.getPayAdapterService(oldRecord.getPayVendor(),payAccount.getPayVersion()).queryPayStatus(oldRecord, appInfo, payAccount); | |||||
| wxpaystatus = payServiceFactory.getPayAdapterService(oldRecord.getPayVendor(),payAccount.getPayVersion()).queryPayStatus(queryResult, oldRecord.getPayOrderNo()); | |||||
| } catch (Exception e) { | } catch (Exception e) { | ||||
| logger.error("pay order service handleWxOrderQuery error: " ,e); | logger.error("pay order service handleWxOrderQuery error: " ,e); | ||||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR); | throw new MallinkException(ErrorCode.PAY_ORDER_ERROR); | ||||
| @@ -433,7 +433,7 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||||
| record.setShare(isShare.getCode()); | record.setShare(isShare.getCode()); | ||||
| record.setComposeOrder(composeOrder.getComposeOrderType()); | record.setComposeOrder(composeOrder.getComposeOrderType()); | ||||
| // if (isShare == EnumPayShare.YES) { | // if (isShare == EnumPayShare.YES) { | ||||
| PayShareAdapterService payShareServie = payServiceFactory.getPayShareAdapterService(payWay.getCode()); | |||||
| PayShareAdapterService payShareServie = payServiceFactory.getPayShareAdapterService(payWay.getCode(),payAccount.getPayVersion()); | |||||
| // PayShareCalculateAmount recordShareAmount = payShareServie.calculateAmount(record.getPayAmount(), payAccount); | // PayShareCalculateAmount recordShareAmount = payShareServie.calculateAmount(record.getPayAmount(), payAccount); | ||||
| // // 分账金额 | // // 分账金额 | ||||
| @@ -481,7 +481,7 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||||
| } | } | ||||
| } | } | ||||
| PayAdapterService payAdapterService = payServiceFactory.getPayAdapterService(payWay.getCode()); | |||||
| PayAdapterService payAdapterService = payServiceFactory.getPayAdapterService(payWay.getCode(),payAccount.getPayVersion()); | |||||
| if(!isCreatePay){ | if(!isCreatePay){ | ||||
| PayAdapterResult payResult = payAdapterService.noCreatePay(record,composeOrder,childOrders); | PayAdapterResult payResult = payAdapterService.noCreatePay(record,composeOrder,childOrders); | ||||
| @@ -613,7 +613,7 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||||
| logger.debug("wxPayRecord md5 before:"+record.toString()); | logger.debug("wxPayRecord md5 before:"+record.toString()); | ||||
| String beforemd5 = HashUtil.md5(record.toString()); | String beforemd5 = HashUtil.md5(record.toString()); | ||||
| PayAdapterResult payResult = payServiceFactory.getPayAdapterService(payWay.getCode()).pay(payAccount, record,composeOrder,"付款码支付",isShare,appInfo, currentDate, params); | |||||
| PayAdapterResult payResult = payServiceFactory.getPayAdapterService(payWay.getCode(),payAccount.getPayVersion()).pay(payAccount, record,composeOrder,"付款码支付",isShare,appInfo, currentDate, params); | |||||
| String aftermd5 = HashUtil.md5(record.toString()); | String aftermd5 = HashUtil.md5(record.toString()); | ||||
| if (beforemd5.equals(aftermd5)) { | if (beforemd5.equals(aftermd5)) { | ||||
| logger.error("支付方式["+payWay.getCode()+"]支付接口【pay】过程中 WxPayOrder 未做更新.record:"+record.toString()); | logger.error("支付方式["+payWay.getCode()+"]支付接口【pay】过程中 WxPayOrder 未做更新.record:"+record.toString()); | ||||
| @@ -675,10 +675,10 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||||
| } | } | ||||
| WxAppinfo appInfo = wxAppinfoService.getCAppInfo(record,payWay.getPlat()); | WxAppinfo appInfo = wxAppinfoService.getCAppInfo(record,payWay.getPlat()); | ||||
| PayAdapterService payService = payServiceFactory.getPayAdapterService(payWay.getCode()); | |||||
| WxPayAccount payAccount = wxPayAccountMapper.selectById(appInfo.getPayId()); | WxPayAccount payAccount = wxPayAccountMapper.selectById(appInfo.getPayId()); | ||||
| PayAdapterService payService = payServiceFactory.getPayAdapterService(payWay.getCode(),payAccount.getPayVersion()); | |||||
| PayQueryAdapterResult apiResult = payService.queryPayStatus(record, appInfo, payAccount); | PayQueryAdapterResult apiResult = payService.queryPayStatus(record, appInfo, payAccount); | ||||
| int status = payServiceFactory.getPayAdapterService(payWay.getCode()).queryPayStatus(apiResult, record.getPayOrderNo()); | |||||
| int status = payServiceFactory.getPayAdapterService(payWay.getCode(),payAccount.getPayVersion()).queryPayStatus(apiResult, record.getPayOrderNo()); | |||||
| boolean isSuccess = true; | boolean isSuccess = true; | ||||
| String msg = ""; | String msg = ""; | ||||
| if (status == EnumPayStatus.PAY_STATUS_REFUND.getCode().intValue()) { | if (status == EnumPayStatus.PAY_STATUS_REFUND.getCode().intValue()) { | ||||
| @@ -747,7 +747,7 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||||
| public ResultData payOrderClose(WxAppinfo appInfo, WxPayOrder record) { | public ResultData payOrderClose(WxAppinfo appInfo, WxPayOrder record) { | ||||
| WxPayAccount payAccount = wxPayAccountMapper.selectById(appInfo.getPayId()); | WxPayAccount payAccount = wxPayAccountMapper.selectById(appInfo.getPayId()); | ||||
| try { | try { | ||||
| PayAdapterResult result = payServiceFactory.getPayAdapterService(record.getPayVendor()).payOrderClose(appInfo, record, payAccount); | |||||
| PayAdapterResult result = payServiceFactory.getPayAdapterService(record.getPayVendor(),payAccount.getPayVersion()).payOrderClose(appInfo, record, payAccount); | |||||
| if (result.isSuccess()) { | if (result.isSuccess()) { | ||||
| record.setPayOrderStatus(EnumPayStatus.PAY_STATUS_CANCEL.getCode()); | record.setPayOrderStatus(EnumPayStatus.PAY_STATUS_CANCEL.getCode()); | ||||
| }else { | }else { | ||||
| @@ -784,7 +784,7 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||||
| WxAppinfo appInfo = wxAppinfoService.getCAppInfo(record,EnumPayWay.getEnum(record.getPayVendor()).getPlat()); | WxAppinfo appInfo = wxAppinfoService.getCAppInfo(record,EnumPayWay.getEnum(record.getPayVendor()).getPlat()); | ||||
| WxPayAccount payAccount = wxPayAccountMapper.selectById(appInfo.getPayId()); | WxPayAccount payAccount = wxPayAccountMapper.selectById(appInfo.getPayId()); | ||||
| try { | try { | ||||
| PayAdapterResult result = payServiceFactory.getPayAdapterService(record.getPayVendor()).payOrderReverse(appInfo, record, payAccount); | |||||
| PayAdapterResult result = payServiceFactory.getPayAdapterService(record.getPayVendor(),payAccount.getPayVersion()).payOrderReverse(appInfo, record, payAccount); | |||||
| if (result.isSuccess()) { | if (result.isSuccess()) { | ||||
| record.setPayOrderStatus(EnumPayStatus.PAY_STATUS_REVERSE.getCode()); | record.setPayOrderStatus(EnumPayStatus.PAY_STATUS_REVERSE.getCode()); | ||||
| record.setUpdateTime(new Date()); | record.setUpdateTime(new Date()); | ||||
| @@ -1059,7 +1059,7 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||||
| WxPayOrder payOrder = new WxPayOrder(); | WxPayOrder payOrder = new WxPayOrder(); | ||||
| payOrder.setPayOrderNo(id.toString()); | payOrder.setPayOrderNo(id.toString()); | ||||
| try { | try { | ||||
| return payServiceFactory.getPayAdapterService(EnumPayWay.PAY_WAY_TT.getCode()).queryPayStatus(payOrder, appInfo, payAccount); | |||||
| return payServiceFactory.getPayAdapterService(EnumPayWay.PAY_WAY_TT.getCode(),payAccount.getPayVersion()).queryPayStatus(payOrder, appInfo, payAccount); | |||||
| } catch (Exception e) { | } catch (Exception e) { | ||||
| return new PayQueryAdapterResult(ErrorCode.SYS_SERVER_ERROR.getCode(), e.getMessage(),null,null,null,null); | return new PayQueryAdapterResult(ErrorCode.SYS_SERVER_ERROR.getCode(), e.getMessage(),null,null,null,null); | ||||
| } | } | ||||
| @@ -1350,7 +1350,7 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||||
| // 回调未返回,主动检查支付订单状态 | // 回调未返回,主动检查支付订单状态 | ||||
| try { | try { | ||||
| WxPayAccount payAccount = wxPayAccountMapper.selectById(appInfo.getPayId()); | WxPayAccount payAccount = wxPayAccountMapper.selectById(appInfo.getPayId()); | ||||
| int payStatus = payServiceFactory.getPayAdapterService(record.getPayVendor()).queryPayStatusCode(record, appInfo, payAccount); | |||||
| int payStatus = payServiceFactory.getPayAdapterService(record.getPayVendor(),payAccount.getPayVersion()).queryPayStatusCode(record, appInfo, payAccount); | |||||
| if (payStatus!=EnumPayStatus.PAY_STATUS_SUCCESS.getCode().intValue() && payStatus!=EnumPayStatus.PAY_STATUS_WAIT.getCode().intValue()) { | if (payStatus!=EnumPayStatus.PAY_STATUS_SUCCESS.getCode().intValue() && payStatus!=EnumPayStatus.PAY_STATUS_WAIT.getCode().intValue()) { | ||||
| // 支付订单未成功,返回异常 | // 支付订单未成功,返回异常 | ||||
| record.setPayOrderStatus(EnumPayStatus.PAY_STATUS_FAIL.getCode()); | record.setPayOrderStatus(EnumPayStatus.PAY_STATUS_FAIL.getCode()); | ||||
| @@ -204,7 +204,7 @@ public class WxProfitSharingOrderServiceImpl implements WxProfitSharingOrderServ | |||||
| } | } | ||||
| PayShareResult shareResult = payServiceFactory.getPayShareAdapterService(dto.getPayWay()).haveReciversShare(appInfo, payAccount, frecord, | |||||
| PayShareResult shareResult = payServiceFactory.getPayShareAdapterService(dto.getPayWay(),payAccount.getPayVersion()).haveReciversShare(appInfo, payAccount, frecord, | |||||
| sharingOrder.getTransactionId(), JSONArray.parseArray(JSON.toJSONString(receivers)), EnumProfitSharingOrderType.getEnum(sharingOrder.getType())); | sharingOrder.getTransactionId(), JSONArray.parseArray(JSON.toJSONString(receivers)), EnumProfitSharingOrderType.getEnum(sharingOrder.getType())); | ||||
| WxProfitSharingOrder updSharingOrder = new WxProfitSharingOrder(); | WxProfitSharingOrder updSharingOrder = new WxProfitSharingOrder(); | ||||
| updSharingOrder.updateTenantInfo(sharingOrder); | updSharingOrder.updateTenantInfo(sharingOrder); | ||||
| @@ -237,7 +237,7 @@ public class WxProfitSharingOrderServiceImpl implements WxProfitSharingOrderServ | |||||
| WxAppinfo appInfo = dto.getAppinfo(); | WxAppinfo appInfo = dto.getAppinfo(); | ||||
| WxPayAccount payAccount = wxPayAccountMapper.selectById(appInfo.getPayId()); | WxPayAccount payAccount = wxPayAccountMapper.selectById(appInfo.getPayId()); | ||||
| PayShareResult shareResult = payServiceFactory.getPayShareAdapterService(dto.getPayWay()).noReciverShare(appInfo,payAccount,sharingOrder,sharingOrder.getTransactionId(),sharingOrder.getPayAmount()); | |||||
| PayShareResult shareResult = payServiceFactory.getPayShareAdapterService(dto.getPayWay(),payAccount.getPayVersion()).noReciverShare(appInfo,payAccount,sharingOrder,sharingOrder.getTransactionId(),sharingOrder.getPayAmount()); | |||||
| WxProfitSharingOrder updSharingOrder = new WxProfitSharingOrder(); | WxProfitSharingOrder updSharingOrder = new WxProfitSharingOrder(); | ||||
| updSharingOrder.updateTenantInfo(sharingOrder); | updSharingOrder.updateTenantInfo(sharingOrder); | ||||
| @@ -346,7 +346,7 @@ public class WxProfitSharingOrderServiceImpl implements WxProfitSharingOrderServ | |||||
| if (record == null) | if (record == null) | ||||
| return new ResultData(ErrorCode.ORDER_IS_NOT_FIND); | return new ResultData(ErrorCode.ORDER_IS_NOT_FIND); | ||||
| PayShareQueryResult shareResult = payServiceFactory.getPayShareAdapterService(dto.getPayWay()).shareQuery(appInfo, payAccount, record); | |||||
| PayShareQueryResult shareResult = payServiceFactory.getPayShareAdapterService(dto.getPayWay(),payAccount.getPayVersion()).shareQuery(appInfo, payAccount, record); | |||||
| if (!shareResult.isSuccess()) { | if (!shareResult.isSuccess()) { | ||||
| throw new MallinkException(shareResult.getCode(),shareResult.getMsg()); | throw new MallinkException(shareResult.getCode(),shareResult.getMsg()); | ||||
| } | } | ||||
| @@ -447,11 +447,9 @@ public class WxProfitSharingOrderServiceImpl implements WxProfitSharingOrderServ | |||||
| return new ResultData(ErrorCode.SYS_PARAMETER_ERROR); | return new ResultData(ErrorCode.SYS_PARAMETER_ERROR); | ||||
| } | } | ||||
| PayShareAdapterService payShareAdapterService = payServiceFactory.getPayShareAdapterService(payWay); | |||||
| WxAppinfo appInfo = getAppinfo(sharingOrderDto.getTenantId(),payWay); | WxAppinfo appInfo = getAppinfo(sharingOrderDto.getTenantId(),payWay); | ||||
| WxPayAccount payAccount = wxPayAccountMapper.selectById(appInfo.getPayId()); | WxPayAccount payAccount = wxPayAccountMapper.selectById(appInfo.getPayId()); | ||||
| PayShareAdapterService payShareAdapterService = payServiceFactory.getPayShareAdapterService(payWay,payAccount.getPayVersion()); | |||||
| //分账检查是否已创建分账订单 | //分账检查是否已创建分账订单 | ||||
| WxProfitSharingOrder record = new WxProfitSharingOrder(); | WxProfitSharingOrder record = new WxProfitSharingOrder(); | ||||
| @@ -667,7 +665,7 @@ public class WxProfitSharingOrderServiceImpl implements WxProfitSharingOrderServ | |||||
| WxProfitSharingReceiver psReceiverQ = new WxProfitSharingReceiver(); | WxProfitSharingReceiver psReceiverQ = new WxProfitSharingReceiver(); | ||||
| psReceiverQ.updateTenantInfo(payAccount); | psReceiverQ.updateTenantInfo(payAccount); | ||||
| psReceiverQ.setMerchantId(sharingOrder.getMerchantId()); | psReceiverQ.setMerchantId(sharingOrder.getMerchantId()); | ||||
| psReceiverQ.setSharingType(payServiceFactory.getPayShareAdapterService(dto.getPayWay()).getProfitSharingType()); | |||||
| psReceiverQ.setSharingType(payServiceFactory.getPayShareAdapterService(dto.getPayWay(),payAccount.getPayVersion()).getProfitSharingType()); | |||||
| psReceiverQ.setStatus(EnumProfitSharingReceiverStatus.PROFIT_SHARING_RECEIVER_STATUS_VALID.getCode()); | psReceiverQ.setStatus(EnumProfitSharingReceiverStatus.PROFIT_SHARING_RECEIVER_STATUS_VALID.getCode()); | ||||
| List<WxProfitSharingReceiver> psReceiverList = wxProfitSharingReceiverMapper.findList(psReceiverQ); | List<WxProfitSharingReceiver> psReceiverList = wxProfitSharingReceiverMapper.findList(psReceiverQ); | ||||
| if (null == psReceiverList || psReceiverList.size() !=1 ) { | if (null == psReceiverList || psReceiverList.size() !=1 ) { | ||||
| @@ -677,7 +675,7 @@ public class WxProfitSharingOrderServiceImpl implements WxProfitSharingOrderServ | |||||
| JSONArray realReceivers = new JSONArray(); | JSONArray realReceivers = new JSONArray(); | ||||
| psReceiverList.stream().forEach(receiver->{ | psReceiverList.stream().forEach(receiver->{ | ||||
| JSONObject jo = new JSONObject(); | JSONObject jo = new JSONObject(); | ||||
| jo.put("type",payServiceFactory.getPayShareAdapterService(dto.getPayWay()).getShareAccount(receiver.getReceiverType()).getMessage()); | |||||
| jo.put("type",payServiceFactory.getPayShareAdapterService(dto.getPayWay(),payAccount.getPayVersion()).getShareAccount(receiver.getReceiverType()).getMessage()); | |||||
| jo.put("account",receiver.getReceiverAccount()); | jo.put("account",receiver.getReceiverAccount()); | ||||
| jo.put("amount", amount); | jo.put("amount", amount); | ||||
| //jo.put("description",receiver.getReceiverComments()); //改为存ID, | //jo.put("description",receiver.getReceiverComments()); //改为存ID, | ||||
| @@ -157,7 +157,7 @@ public class WxProfitSharingReceiverServiceImpl implements WxProfitSharingReceiv | |||||
| //receiver.setTrueName(receiverParam.getTrueName()); | //receiver.setTrueName(receiverParam.getTrueName()); | ||||
| //添加分账账户 | //添加分账账户 | ||||
| ShareAccountResult createResult = payServiceFactory.getPayShareAdapterService(payWay.getCode()).createShareAccount(appInfo, payAccount, receiver); | |||||
| ShareAccountResult createResult = payServiceFactory.getPayShareAdapterService(payWay.getCode(),payAccount.getPayVersion()).createShareAccount(appInfo, payAccount, receiver); | |||||
| if (!createResult.isSuccess()) { | if (!createResult.isSuccess()) { | ||||
| return new ResultData(createResult.getCode(), createResult.getMsg()); | return new ResultData(createResult.getCode(), createResult.getMsg()); | ||||
| } | } | ||||
| @@ -395,7 +395,7 @@ public class WxProfitSharingReceiverServiceImpl implements WxProfitSharingReceiv | |||||
| ))) { | ))) { | ||||
| //还有别的商户使用这个账号,不从微信服务器申请删除 | //还有别的商户使用这个账号,不从微信服务器申请删除 | ||||
| } else { | } else { | ||||
| ShareAccountResult shareResult = payServiceFactory.getPayShareAdapterService(receiver.getPlat()).deleteShareAccount(appInfo, payAccount, receiver); | |||||
| ShareAccountResult shareResult = payServiceFactory.getPayShareAdapterService(receiver.getPlat(),payAccount.getPayVersion()).deleteShareAccount(appInfo, payAccount, receiver); | |||||
| if (!shareResult.isSuccess()) { | if (!shareResult.isSuccess()) { | ||||
| return new ResultData(shareResult.getCode(), shareResult.getMsg()); | return new ResultData(shareResult.getCode(), shareResult.getMsg()); | ||||
| } | } | ||||
| @@ -229,7 +229,7 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { | |||||
| throw new MallinkException(ErrorCode.PAY_ORDER_QUERY_ERROR.getCode(), "payAccount为空[payId:"+appInfo.getPayId()+"]"); | throw new MallinkException(ErrorCode.PAY_ORDER_QUERY_ERROR.getCode(), "payAccount为空[payId:"+appInfo.getPayId()+"]"); | ||||
| } | } | ||||
| try { | try { | ||||
| PayQueryAdapterResult queryResult = payServiceFactory.getPayAdapterService(payOrder.getPayVendor()).queryPayStatus(payOrder, appInfo, payAccount); | |||||
| PayQueryAdapterResult queryResult = payServiceFactory.getPayAdapterService(payOrder.getPayVendor(),payAccount.getPayVersion()).queryPayStatus(payOrder, appInfo, payAccount); | |||||
| if(EnumPayStatus.PAY_STATUS_SUCCESS.getCode() != queryResult.getCode()){ | if(EnumPayStatus.PAY_STATUS_SUCCESS.getCode() != queryResult.getCode()){ | ||||
| return new ResultData(ErrorCode.PAY_ORDER_ERROR.getCode(),"该订单查询支付状态为未支付成功,无法退款。"); | return new ResultData(ErrorCode.PAY_ORDER_ERROR.getCode(),"该订单查询支付状态为未支付成功,无法退款。"); | ||||
| } | } | ||||
| @@ -350,7 +350,7 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { | |||||
| throw new MallinkException(ErrorCode.DB_FAIL); | throw new MallinkException(ErrorCode.DB_FAIL); | ||||
| } | } | ||||
| RefundAdapterResult refundResult = payServiceFactory.getRefundPayAdapterService(payOrder.getPayVendor()).refund(payAccount, appInfo, record, payOrder, payType); | |||||
| RefundAdapterResult refundResult = payServiceFactory.getRefundPayAdapterService(payOrder.getPayVendor(),payAccount.getPayVersion()).refund(payAccount, appInfo, record, payOrder, payType); | |||||
| if (refundResult.isSuccess()) { | if (refundResult.isSuccess()) { | ||||
| record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_SUCCESS.getCode()); | record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_SUCCESS.getCode()); | ||||
| wxRefundOrderMapper.updateById(record); | wxRefundOrderMapper.updateById(record); | ||||
| @@ -554,7 +554,7 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { | |||||
| if (null == payAccount) { | if (null == payAccount) { | ||||
| throw new MallinkException(ErrorCode.PAY_ORDER_QUERY_ERROR.getCode(), "payAccount为空[payId:"+appInfo.getPayId()+"]"); | throw new MallinkException(ErrorCode.PAY_ORDER_QUERY_ERROR.getCode(), "payAccount为空[payId:"+appInfo.getPayId()+"]"); | ||||
| } | } | ||||
| RefundAdapterResult refundResult = payServiceFactory.getRefundPayAdapterService(payOrder.getPayVendor()).refund(payAccount, appInfo, record, payOrder, payType); | |||||
| RefundAdapterResult refundResult = payServiceFactory.getRefundPayAdapterService(payOrder.getPayVendor(),payAccount.getPayVersion()).refund(payAccount, appInfo, record, payOrder, payType); | |||||
| if (refundResult.isSuccess()) { | if (refundResult.isSuccess()) { | ||||
| record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_SUCCESS.getCode()); | record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_SUCCESS.getCode()); | ||||
| wxRefundOrderMapper.updateById(record); | wxRefundOrderMapper.updateById(record); | ||||
| @@ -573,7 +573,7 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { | |||||
| @Override | @Override | ||||
| public ResultData queryRefundOrder(WxAppinfo appInfo, WxRefundOrder record) { | public ResultData queryRefundOrder(WxAppinfo appInfo, WxRefundOrder record) { | ||||
| WxPayAccount payAccount = wxPayAccountMapper.selectById(appInfo.getPayId()); | WxPayAccount payAccount = wxPayAccountMapper.selectById(appInfo.getPayId()); | ||||
| RefundAdapterResult result = payServiceFactory.getRefundPayAdapterService(record.getRefundVendor()).queryRefund(appInfo, payAccount, record); | |||||
| RefundAdapterResult result = payServiceFactory.getRefundPayAdapterService(record.getRefundVendor(),payAccount.getPayVersion()).queryRefund(appInfo, payAccount, record); | |||||
| if (result.isSuccess()) { | if (result.isSuccess()) { | ||||
| return new ResultData(Result.SUCCESS, "退款", result.getData()); | return new ResultData(Result.SUCCESS, "退款", result.getData()); | ||||
| }else { | }else { | ||||
| @@ -776,7 +776,7 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { | |||||
| logger.error("退款订单已存在, 无法再提交退款申请"); | logger.error("退款订单已存在, 无法再提交退款申请"); | ||||
| throw new MallinkException(ErrorCode.REFUND_ORDER_EXIST.getCode(), "退款订单已存在, 无法再提交退款申请"); | throw new MallinkException(ErrorCode.REFUND_ORDER_EXIST.getCode(), "退款订单已存在, 无法再提交退款申请"); | ||||
| } | } | ||||
| RefundAdapterResult refundResult = payServiceFactory.getRefundPayAdapterService(payOrder.getPayVendor()).refund(payAccount, appInfo, record, payOrder, null); | |||||
| RefundAdapterResult refundResult = payServiceFactory.getRefundPayAdapterService(payOrder.getPayVendor(),payAccount.getPayVersion()).refund(payAccount, appInfo, record, payOrder, null); | |||||
| if (refundResult.isSuccess()) { | if (refundResult.isSuccess()) { | ||||
| record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_SUCCESS.getCode()); | record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_SUCCESS.getCode()); | ||||
| wxRefundOrderMapper.updateById(record); | wxRefundOrderMapper.updateById(record); | ||||
| @@ -1022,7 +1022,7 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService { | |||||
| @Override | @Override | ||||
| @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) | @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) | ||||
| public ResultData syncRefundOrder(WxAppinfo appinfo, WxPayAccount payAccount, WxRefundOrder order) { | public ResultData syncRefundOrder(WxAppinfo appinfo, WxPayAccount payAccount, WxRefundOrder order) { | ||||
| RefundAdapterResult refundAdapterResult = payServiceFactory.getRefundPayAdapterService(order.getRefundVendor()).queryRefund(appinfo, payAccount, order); | |||||
| RefundAdapterResult refundAdapterResult = payServiceFactory.getRefundPayAdapterService(order.getRefundVendor(),payAccount.getPayVersion()).queryRefund(appinfo, payAccount, order); | |||||
| if(EnumRefundStatus.REFUND_REQ_SUCCESS.getCode().equals(refundAdapterResult.getCode())){//退款中 退款申请成功 | if(EnumRefundStatus.REFUND_REQ_SUCCESS.getCode().equals(refundAdapterResult.getCode())){//退款中 退款申请成功 | ||||
| if(EnumRefundStatus.REFUND_WAIT.getCode().equals(order.getRefundOrderStatus())){ | if(EnumRefundStatus.REFUND_WAIT.getCode().equals(order.getRefundOrderStatus())){ | ||||
| @@ -2,28 +2,34 @@ package com.iformall.service.pay; | |||||
| import java.util.Map; | import java.util.Map; | ||||
| import java.util.concurrent.ConcurrentHashMap; | import java.util.concurrent.ConcurrentHashMap; | ||||
| import com.iformall.enums.EnumAppPlat; | import com.iformall.enums.EnumAppPlat; | ||||
| import com.iformall.enums.EnumPayVersion; | |||||
| import com.iformall.service.pay.service.pay.douyin.miniApp.TtMiniAppPayAdapterService; | import com.iformall.service.pay.service.pay.douyin.miniApp.TtMiniAppPayAdapterService; | ||||
| import com.iformall.service.pay.service.refund.douyin.TtRefundAdapterService; | import com.iformall.service.pay.service.refund.douyin.TtRefundAdapterService; | ||||
| import com.iformall.service.pay.service.refund.wx.v2.WxRefundAdapterService; | |||||
| import com.iformall.service.pay.service.refund.wx.v3.WxRefundV3AdapterService; | |||||
| import com.iformall.service.pay.service.share.douyin.TtPayShareService; | import com.iformall.service.pay.service.share.douyin.TtPayShareService; | ||||
| import com.iformall.service.pay.service.share.wx.v2.WxPayShareService; | |||||
| import com.iformall.service.pay.service.share.wx.v3.WxPayShareV3Service; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||
| import com.iformall.common.ErrorCode; | import com.iformall.common.ErrorCode; | ||||
| import com.iformall.enums.EnumPayWay; | import com.iformall.enums.EnumPayWay; | ||||
| import com.iformall.exception.MallinkException; | import com.iformall.exception.MallinkException; | ||||
| import com.iformall.service.pay.service.cashout.CashOutAdapterService; | import com.iformall.service.pay.service.cashout.CashOutAdapterService; | ||||
| import com.iformall.service.pay.service.cashout.wx.WxCashOutAdapterService; | |||||
| import com.iformall.service.pay.service.cashout.wx.v2.WxCashOutAdapterService; | |||||
| import com.iformall.service.pay.service.cashout.wx.v3.WxCashOutV3AdapterService; | |||||
| import com.iformall.service.pay.service.pay.CDrivingPayService; | import com.iformall.service.pay.service.pay.CDrivingPayService; | ||||
| import com.iformall.service.pay.service.pay.CPassivePayService; | import com.iformall.service.pay.service.pay.CPassivePayService; | ||||
| import com.iformall.service.pay.service.pay.PayAdapterService; | import com.iformall.service.pay.service.pay.PayAdapterService; | ||||
| import com.iformall.service.pay.service.pay.wx.h5.WxH5PayService; | |||||
| import com.iformall.service.pay.service.pay.wx.miniApp.appPay.WxMiniAppPayAdapterService; | |||||
| import com.iformall.service.pay.service.pay.wx.miniApp.maPay.WxMiniMaPayAdapterService; | |||||
| import com.iformall.service.pay.service.pay.wx.v2.h5.WxH5PayService; | |||||
| import com.iformall.service.pay.service.pay.wx.v2.miniApp.appPay.WxMiniAppPayAdapterService; | |||||
| import com.iformall.service.pay.service.pay.wx.v2.miniApp.maPay.WxMiniMaPayAdapterService; | |||||
| import com.iformall.service.pay.service.pay.wx.v3.h5.WxH5PayV3Service; | |||||
| import com.iformall.service.pay.service.pay.wx.v3.miniApp.appPay.WxMiniAppPayV3AdapterService; | |||||
| import com.iformall.service.pay.service.pay.wx.v3.miniApp.maPay.WxMiniMaPayV3AdapterService; | |||||
| import com.iformall.service.pay.service.refund.RefundPayAdapterService; | import com.iformall.service.pay.service.refund.RefundPayAdapterService; | ||||
| import com.iformall.service.pay.service.refund.wx.WxRefundAdapterService; | |||||
| import com.iformall.service.pay.service.share.PayShareAdapterService; | import com.iformall.service.pay.service.share.PayShareAdapterService; | ||||
| import com.iformall.service.pay.service.share.wx.WxPayShareService; | |||||
| /** | /** | ||||
| * 支付方式工厂 | * 支付方式工厂 | ||||
| @@ -32,119 +38,154 @@ import com.iformall.service.pay.service.share.wx.WxPayShareService; | |||||
| @Service | @Service | ||||
| public class PayServiceFactory { | public class PayServiceFactory { | ||||
| private Map<Integer,PayAdapterService> serviceMap = null; | |||||
| private Map<Integer,PayAdapterService> qrcodeMap = null; | |||||
| private Map<Integer,PayShareAdapterService> shareMap = null; | |||||
| private Map<Integer,RefundPayAdapterService> refundMap = null; | |||||
| private Map<Integer,CashOutAdapterService> cashoutMap = null; | |||||
| private Map<String,PayAdapterService> serviceMap = null; | |||||
| private Map<String,PayAdapterService> qrcodeMap = null; | |||||
| private Map<String,PayShareAdapterService> shareMap = null; | |||||
| private Map<String,RefundPayAdapterService> refundMap = null; | |||||
| private Map<String,CashOutAdapterService> cashoutMap = null; | |||||
| @Autowired | @Autowired | ||||
| WxMiniAppPayAdapterService wxMiniAppPayService; | WxMiniAppPayAdapterService wxMiniAppPayService; | ||||
| @Autowired | |||||
| WxMiniAppPayV3AdapterService wxMiniAppPayV3AdapterService; | |||||
| @Autowired | @Autowired | ||||
| WxMiniMaPayAdapterService wxMiniAppMaPayService; | WxMiniMaPayAdapterService wxMiniAppMaPayService; | ||||
| @Autowired | |||||
| WxMiniMaPayV3AdapterService wxMiniMaPayV3AdapterService; | |||||
| @Autowired | @Autowired | ||||
| WxH5PayService wxH5PayService; | WxH5PayService wxH5PayService; | ||||
| @Autowired | |||||
| WxH5PayV3Service wxH5PayV3Service; | |||||
| @Autowired | @Autowired | ||||
| TtMiniAppPayAdapterService ttMiniAppPayService; | TtMiniAppPayAdapterService ttMiniAppPayService; | ||||
| @Autowired | @Autowired | ||||
| WxPayShareService wxShareService; | WxPayShareService wxShareService; | ||||
| @Autowired | |||||
| WxPayShareV3Service wxPayShareV3Service; | |||||
| @Autowired | @Autowired | ||||
| TtPayShareService ttShareService; | TtPayShareService ttShareService; | ||||
| @Autowired | @Autowired | ||||
| WxRefundAdapterService wxRefundService; | WxRefundAdapterService wxRefundService; | ||||
| @Autowired | |||||
| WxRefundV3AdapterService wxRefundV3AdapterService; | |||||
| @Autowired | @Autowired | ||||
| TtRefundAdapterService ttRefundService; | TtRefundAdapterService ttRefundService; | ||||
| @Autowired | @Autowired | ||||
| WxCashOutAdapterService wxCashOutService; | WxCashOutAdapterService wxCashOutService; | ||||
| @Autowired | |||||
| WxCashOutV3AdapterService wxCashOutV3AdapterService; | |||||
| private Map<Integer,PayAdapterService> getServiceMap() { | |||||
| private Map<String,PayAdapterService> getServiceMap() { | |||||
| if (null == serviceMap) { | if (null == serviceMap) { | ||||
| serviceMap = new ConcurrentHashMap<Integer,PayAdapterService>(); | |||||
| serviceMap.put(EnumPayWay.PAY_WAY_WECHAT.getCode(), wxMiniAppPayService); | |||||
| serviceMap.put(EnumPayWay.PAY_WAY_WECHAT_MA.getCode(), wxMiniAppMaPayService); | |||||
| serviceMap.put(EnumPayWay.PAY_WAY_WECHAT_WAP.getCode(), wxH5PayService); | |||||
| serviceMap.put(EnumPayWay.PAY_WAY_TT.getCode(),ttMiniAppPayService); | |||||
| serviceMap = new ConcurrentHashMap<String,PayAdapterService>(); | |||||
| serviceMap.put(EnumPayWay.PAY_WAY_WECHAT.getCode()+"_"+EnumPayVersion.WX_PAY_V2.getCode(), wxMiniAppPayService); | |||||
| serviceMap.put(EnumPayWay.PAY_WAY_WECHAT.getCode()+"_"+EnumPayVersion.WX_PAY_V3.getCode(), wxMiniAppPayV3AdapterService); | |||||
| serviceMap.put(EnumPayWay.PAY_WAY_WECHAT_MA.getCode()+"_"+EnumPayVersion.WX_PAY_V2.getCode(), wxMiniAppMaPayService); | |||||
| serviceMap.put(EnumPayWay.PAY_WAY_WECHAT_MA.getCode()+"_"+EnumPayVersion.WX_PAY_V3.getCode(), wxMiniMaPayV3AdapterService); | |||||
| serviceMap.put(EnumPayWay.PAY_WAY_WECHAT_WAP.getCode()+"_"+EnumPayVersion.WX_PAY_V2.getCode(), wxH5PayService); | |||||
| serviceMap.put(EnumPayWay.PAY_WAY_WECHAT_WAP.getCode()+"_"+EnumPayVersion.WX_PAY_V3.getCode(), wxH5PayV3Service); | |||||
| serviceMap.put(EnumPayWay.PAY_WAY_TT.getCode()+"_"+EnumPayVersion.DY_PAY_V2.getCode(),ttMiniAppPayService); | |||||
| } | } | ||||
| return serviceMap; | return serviceMap; | ||||
| } | } | ||||
| private Map<Integer,PayAdapterService> getQrcodeMap() { | |||||
| private Map<String,PayAdapterService> getQrcodeMap() { | |||||
| if (null == qrcodeMap) { | if (null == qrcodeMap) { | ||||
| qrcodeMap = new ConcurrentHashMap<Integer,PayAdapterService>(); | |||||
| qrcodeMap.put(EnumAppPlat.WX.getCode(), wxMiniAppPayService); | |||||
| qrcodeMap.put(EnumAppPlat.TOUTIAO.getCode(),ttMiniAppPayService); | |||||
| qrcodeMap = new ConcurrentHashMap<String,PayAdapterService>(); | |||||
| qrcodeMap.put(EnumAppPlat.WX.getCode()+"_"+EnumPayVersion.WX_PAY_V2.getCode(), wxMiniAppPayService); | |||||
| qrcodeMap.put(EnumAppPlat.WX.getCode()+"_"+EnumPayVersion.WX_PAY_V3.getCode(), wxMiniAppPayService); | |||||
| qrcodeMap.put(EnumAppPlat.TOUTIAO.getCode()+"_"+EnumPayVersion.DY_PAY_V2.getCode(),ttMiniAppPayService); | |||||
| } | } | ||||
| return qrcodeMap; | return qrcodeMap; | ||||
| } | } | ||||
| private Map<Integer,PayShareAdapterService> getShareMap(){ | |||||
| private Map<String,PayShareAdapterService> getShareMap(){ | |||||
| if (null == shareMap ) { | if (null == shareMap ) { | ||||
| shareMap = new ConcurrentHashMap<Integer, PayShareAdapterService>(); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_WECHAT.getCode(), wxShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_WECHAT_MA.getCode(), wxShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_TT.getCode(), ttShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_POS_NEU.getCode(), wxShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_MERCHANT.getCode(), wxShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_VERRIFY.getCode(), wxShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_B_MA.getCode(), wxShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_CAR_STOP.getCode(), wxShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_SYSTEM_SEND.getCode(), wxShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_INJECT_SEND.getCode(), ttShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_BATCH_SEND.getCode(), wxShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_TRADE.getCode(), wxShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_PASSWD.getCode(), wxShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_CREDIT.getCode(), wxShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_GIFTLIST.getCode(), wxShareService); | |||||
| shareMap = new ConcurrentHashMap<String, PayShareAdapterService>(); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_WECHAT.getCode()+"_"+EnumPayVersion.WX_PAY_V2.getCode(), wxShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_WECHAT_MA.getCode()+"_"+EnumPayVersion.WX_PAY_V2.getCode(), wxShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_TT.getCode()+"_"+EnumPayVersion.DY_PAY_V2.getCode(), ttShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_POS_NEU.getCode()+"_"+EnumPayVersion.WX_PAY_V2.getCode(), wxShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_MERCHANT.getCode()+"_"+EnumPayVersion.WX_PAY_V2.getCode(), wxShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_VERRIFY.getCode()+"_"+EnumPayVersion.WX_PAY_V2.getCode(), wxShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_B_MA.getCode()+"_"+EnumPayVersion.WX_PAY_V2.getCode(), wxShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_CAR_STOP.getCode()+"_"+EnumPayVersion.WX_PAY_V2.getCode(), wxShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_SYSTEM_SEND.getCode()+"_"+EnumPayVersion.WX_PAY_V2.getCode(), wxShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_INJECT_SEND.getCode()+"_"+EnumPayVersion.DY_PAY_V2.getCode(), ttShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_BATCH_SEND.getCode()+"_"+EnumPayVersion.WX_PAY_V2.getCode(), wxShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_TRADE.getCode()+"_"+EnumPayVersion.WX_PAY_V2.getCode(), wxShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_PASSWD.getCode()+"_"+EnumPayVersion.WX_PAY_V2.getCode(), wxShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_CREDIT.getCode()+"_"+EnumPayVersion.WX_PAY_V2.getCode(), wxShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_GIFTLIST.getCode()+"_"+EnumPayVersion.WX_PAY_V2.getCode(), wxShareService); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_WECHAT.getCode()+"_"+EnumPayVersion.WX_PAY_V3.getCode(), wxPayShareV3Service); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_WECHAT_MA.getCode()+"_"+EnumPayVersion.WX_PAY_V3.getCode(), wxPayShareV3Service); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_POS_NEU.getCode()+"_"+EnumPayVersion.WX_PAY_V3.getCode(), wxPayShareV3Service); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_MERCHANT.getCode()+"_"+EnumPayVersion.WX_PAY_V3.getCode(), wxPayShareV3Service); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_VERRIFY.getCode()+"_"+EnumPayVersion.WX_PAY_V3.getCode(), wxPayShareV3Service); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_B_MA.getCode()+"_"+EnumPayVersion.WX_PAY_V3.getCode(), wxPayShareV3Service); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_CAR_STOP.getCode()+"_"+EnumPayVersion.WX_PAY_V3.getCode(), wxPayShareV3Service); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_SYSTEM_SEND.getCode()+"_"+EnumPayVersion.WX_PAY_V3.getCode(), wxPayShareV3Service); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_BATCH_SEND.getCode()+"_"+EnumPayVersion.WX_PAY_V3.getCode(), wxPayShareV3Service); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_TRADE.getCode()+"_"+EnumPayVersion.WX_PAY_V3.getCode(), wxPayShareV3Service); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_PASSWD.getCode()+"_"+EnumPayVersion.WX_PAY_V3.getCode(), wxPayShareV3Service); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_CREDIT.getCode()+"_"+EnumPayVersion.WX_PAY_V3.getCode(), wxPayShareV3Service); | |||||
| shareMap.put(EnumPayWay.PAY_WAY_NOT_UNPAY_GIFTLIST.getCode()+"_"+EnumPayVersion.WX_PAY_V3.getCode(), wxPayShareV3Service); | |||||
| } | } | ||||
| return shareMap; | return shareMap; | ||||
| } | } | ||||
| private Map<Integer,RefundPayAdapterService> getRefundMap(){ | |||||
| private Map<String,RefundPayAdapterService> getRefundMap(){ | |||||
| if (null == refundMap ) { | if (null == refundMap ) { | ||||
| refundMap = new ConcurrentHashMap<Integer, RefundPayAdapterService>(); | |||||
| refundMap.put(EnumPayWay.PAY_WAY_WECHAT.getCode(), wxRefundService); | |||||
| refundMap.put(EnumPayWay.PAY_WAY_WECHAT_MA.getCode(), wxRefundService); | |||||
| refundMap.put(EnumPayWay.PAY_WAY_TT.getCode(), ttRefundService); | |||||
| refundMap = new ConcurrentHashMap<String, RefundPayAdapterService>(); | |||||
| refundMap.put(EnumPayWay.PAY_WAY_WECHAT.getCode()+"_"+EnumPayVersion.WX_PAY_V2.getCode(), wxRefundService); | |||||
| refundMap.put(EnumPayWay.PAY_WAY_WECHAT_MA.getCode()+"_"+EnumPayVersion.WX_PAY_V2.getCode(), wxRefundService); | |||||
| refundMap.put(EnumPayWay.PAY_WAY_WECHAT.getCode()+"_"+EnumPayVersion.WX_PAY_V3.getCode(), wxRefundV3AdapterService); | |||||
| refundMap.put(EnumPayWay.PAY_WAY_WECHAT_MA.getCode()+"_"+EnumPayVersion.WX_PAY_V3.getCode(), wxRefundV3AdapterService); | |||||
| refundMap.put(EnumPayWay.PAY_WAY_TT.getCode()+"_"+EnumPayVersion.DY_PAY_V2.getCode(), ttRefundService); | |||||
| } | } | ||||
| return refundMap; | return refundMap; | ||||
| } | } | ||||
| private Map<Integer,CashOutAdapterService> getCashOutMap() { | |||||
| private Map<String,CashOutAdapterService> getCashOutMap() { | |||||
| if (null == cashoutMap ) { | if (null == cashoutMap ) { | ||||
| cashoutMap = new ConcurrentHashMap<Integer, CashOutAdapterService>(); | |||||
| cashoutMap.put(EnumPayWay.PAY_WAY_WECHAT.getCode(), wxCashOutService); | |||||
| cashoutMap.put(EnumPayWay.PAY_WAY_WECHAT_MA.getCode(), wxCashOutService); | |||||
| cashoutMap = new ConcurrentHashMap<String, CashOutAdapterService>(); | |||||
| cashoutMap.put(EnumPayWay.PAY_WAY_WECHAT.getCode()+"_"+EnumPayVersion.WX_PAY_V2.getCode(), wxCashOutService); | |||||
| cashoutMap.put(EnumPayWay.PAY_WAY_WECHAT_MA.getCode()+"_"+EnumPayVersion.WX_PAY_V2.getCode(), wxCashOutService); | |||||
| cashoutMap.put(EnumPayWay.PAY_WAY_WECHAT.getCode()+"_"+EnumPayVersion.WX_PAY_V3.getCode(), wxCashOutV3AdapterService); | |||||
| cashoutMap.put(EnumPayWay.PAY_WAY_WECHAT_MA.getCode()+"_"+EnumPayVersion.WX_PAY_V3.getCode(), wxCashOutV3AdapterService); | |||||
| } | } | ||||
| return cashoutMap; | return cashoutMap; | ||||
| } | } | ||||
| public PayAdapterService getPayAdapterService(Integer type) throws MallinkException{ | |||||
| PayAdapterService service = getServiceMap().get(type); | |||||
| public PayAdapterService getPayAdapterService(Integer type,Integer payVersion) throws MallinkException{ | |||||
| PayAdapterService service = getServiceMap().get(type+"_"+payVersion); | |||||
| if (null == service) { | if (null == service) { | ||||
| throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payWay["+type+"] 支付service未找到"); | throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payWay["+type+"] 支付service未找到"); | ||||
| } | } | ||||
| return service; | return service; | ||||
| } | } | ||||
| public PayAdapterService getQrcodeService(Integer type) throws MallinkException{ | |||||
| PayAdapterService service = getQrcodeMap().get(type); | |||||
| public PayAdapterService getQrcodeService(Integer type,Integer payVersion) throws MallinkException{ | |||||
| PayAdapterService service = getQrcodeMap().get(type+"_"+payVersion); | |||||
| if (null == service) { | if (null == service) { | ||||
| throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payWay["+type+"] 支付service未找到"); | throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payWay["+type+"] 支付service未找到"); | ||||
| } | } | ||||
| return service; | return service; | ||||
| } | } | ||||
| public CDrivingPayService getCDrivingPayService(Integer type) throws MallinkException{ | |||||
| PayAdapterService service = getServiceMap().get(type); | |||||
| public CDrivingPayService getCDrivingPayService(Integer type,Integer payVersion) throws MallinkException{ | |||||
| PayAdapterService service = getServiceMap().get(type+"_"+payVersion); | |||||
| if (null == service) { | if (null == service) { | ||||
| throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payWay["+type+"] 支付service未找到"); | throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payWay["+type+"] 支付service未找到"); | ||||
| } | } | ||||
| @@ -155,8 +196,8 @@ public class PayServiceFactory { | |||||
| } | } | ||||
| } | } | ||||
| public CPassivePayService getCPassivePayService(Integer type) throws MallinkException{ | |||||
| PayAdapterService service = getServiceMap().get(type); | |||||
| public CPassivePayService getCPassivePayService(Integer type,Integer payVersion) throws MallinkException{ | |||||
| PayAdapterService service = getServiceMap().get(type+"_"+payVersion); | |||||
| if (null == service) { | if (null == service) { | ||||
| throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payWay["+type+"] 支付service未找到"); | throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payWay["+type+"] 支付service未找到"); | ||||
| } | } | ||||
| @@ -167,24 +208,24 @@ public class PayServiceFactory { | |||||
| } | } | ||||
| } | } | ||||
| public PayShareAdapterService getPayShareAdapterService(Integer type) throws MallinkException{ | |||||
| PayShareAdapterService shareService = getShareMap().get(type); | |||||
| public PayShareAdapterService getPayShareAdapterService(Integer type,Integer payVersion) throws MallinkException{ | |||||
| PayShareAdapterService shareService = getShareMap().get(type+"_"+payVersion); | |||||
| if (null == shareService) { | if (null == shareService) { | ||||
| throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payWay["+type+"] 分账service未找到"); | throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payWay["+type+"] 分账service未找到"); | ||||
| } | } | ||||
| return shareService; | return shareService; | ||||
| } | } | ||||
| public RefundPayAdapterService getRefundPayAdapterService(Integer type) throws MallinkException{ | |||||
| RefundPayAdapterService refundService = getRefundMap().get(type); | |||||
| public RefundPayAdapterService getRefundPayAdapterService(Integer type,Integer payVersion) throws MallinkException{ | |||||
| RefundPayAdapterService refundService = getRefundMap().get(type+"_"+payVersion); | |||||
| if (null == refundService) { | if (null == refundService) { | ||||
| throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payWay["+type+"] 退款service未找到"); | throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payWay["+type+"] 退款service未找到"); | ||||
| } | } | ||||
| return refundService; | return refundService; | ||||
| } | } | ||||
| public CashOutAdapterService getCashOutAdapterService(Integer type)throws MallinkException { | |||||
| CashOutAdapterService cashOutService = getCashOutMap().get(type); | |||||
| public CashOutAdapterService getCashOutAdapterService(Integer type,Integer payVersion)throws MallinkException { | |||||
| CashOutAdapterService cashOutService = getCashOutMap().get(type+"_"+payVersion); | |||||
| if (null == cashOutService) { | if (null == cashOutService) { | ||||
| throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payWay["+type+"] 零钱service未找到"); | throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payWay["+type+"] 零钱service未找到"); | ||||
| } | } | ||||
| @@ -1,4 +1,4 @@ | |||||
| package com.iformall.service.pay.service.cashout.wx; | |||||
| package com.iformall.service.pay.service.cashout.wx.v2; | |||||
| import java.io.UnsupportedEncodingException; | import java.io.UnsupportedEncodingException; | ||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||
| @@ -0,0 +1,500 @@ | |||||
| package com.iformall.service.pay.service.cashout.wx.v3; | |||||
| import java.io.UnsupportedEncodingException; | |||||
| import java.util.ArrayList; | |||||
| import java.util.List; | |||||
| import java.util.Map; | |||||
| import java.util.SortedMap; | |||||
| import java.util.TreeMap; | |||||
| import org.apache.commons.lang3.StringUtils; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.stereotype.Service; | |||||
| import com.alibaba.fastjson.JSON; | |||||
| import com.alibaba.fastjson.JSONObject; | |||||
| import com.github.binarywang.wxpay.service.WxPayService; | |||||
| import com.iformall.common.ErrorCode; | |||||
| import com.iformall.common.Result; | |||||
| import com.iformall.common.ResultData; | |||||
| import com.iformall.domain.po.WxAppinfo; | |||||
| import com.iformall.domain.po.WxCashOut; | |||||
| import com.iformall.domain.po.WxPayAccount; | |||||
| import com.iformall.domain.po.WxPayOrder; | |||||
| import com.iformall.domain.po.WxRefundOrder; | |||||
| import com.iformall.domain.po.base.TenantEntity; | |||||
| import com.iformall.enums.EnumAppPlat; | |||||
| import com.iformall.enums.EnumCashOutStatus; | |||||
| import com.iformall.enums.EnumPayMode; | |||||
| import com.iformall.enums.EnumPayType; | |||||
| import com.iformall.enums.EnumPayWay; | |||||
| import com.iformall.enums.EnumRefundStatus; | |||||
| import com.iformall.exception.MallinkException; | |||||
| import com.iformall.mapper.WxAppinfoMapper; | |||||
| import com.iformall.mapper.WxPayAccountMapper; | |||||
| import com.iformall.mapper.WxPayOrderMapper; | |||||
| import com.iformall.mapper.WxRefundOrderMapper; | |||||
| import com.iformall.pay.WxCashOutP; | |||||
| import com.iformall.pay.WxCashOutPV3; | |||||
| import com.iformall.pay.WxCashOutPV3Item; | |||||
| import com.iformall.pay.WxCashOutQueryP; | |||||
| import com.iformall.pay.WxPay; | |||||
| import com.iformall.pay.WxPayment; | |||||
| import com.iformall.pay.WxRefundOrderP; | |||||
| import com.iformall.pay.WxRefundOrderSP; | |||||
| import com.iformall.service.WxAppinfoService; | |||||
| import com.iformall.service.pay.service.cashout.CashOutAdapterService; | |||||
| import com.iformall.service.pay.service.cashout.entity.CashOutAdapterResult; | |||||
| import com.iformall.service.pay.service.refund.RefundPayAdapterService; | |||||
| import com.iformall.service.pay.service.refund.entity.RefundAdapterResult; | |||||
| import com.iformall.service.pay.service.refund.entity.RefundNotifyAdapterResult; | |||||
| import com.iformall.utils.BeanUtils; | |||||
| import com.iformall.utils.CipherUtil; | |||||
| import com.iformall.utils.DateUtils; | |||||
| import com.iformall.utils.MaUtil; | |||||
| import com.iformall.utils.Utility; | |||||
| import com.iformall.utils.XmlUtil; | |||||
| import lombok.extern.slf4j.Slf4j; | |||||
| @Slf4j | |||||
| @Service | |||||
| public class WxCashOutV3AdapterService implements CashOutAdapterService{ | |||||
| @Autowired | |||||
| WxAppinfoService wxAppinfoService; | |||||
| @Autowired | |||||
| MaUtil maUtil; | |||||
| JSONObject errorRefundReqMap = JSON.parseObject("{\n" + | |||||
| " \"NO_AUTH\": {\n" + | |||||
| " \"detail\": \"没有该接口权限\",\n" + | |||||
| " \"reason\": \"1. 用户账号被冻结,无法付款;2. 产品权限没有开通或者被风控冻结;3. 此IP地址不允许调用接口,如有需要请登录微信支付商户平台更改配置\",\n" + | |||||
| " \"resolution\": \"请根据具体的错误返回描述做对应处理,如返回描述不够明确,请参考此处的错误原因做排查。\"\n" + | |||||
| " },\n" + | |||||
| " \"AMOUNT_LIMIT\": {\n" + | |||||
| " \"detail\": \"金额超限\",\n" + | |||||
| " \"reason\": \"1. 被微信风控拦截,最低单笔付款限额调整为5元。2. 低于最低单笔付款限额或者高于最高单笔付款限额\",\n" + | |||||
| " \"resolution\": \"目前最低付款金额为1元,最高10万元,请确认是否付款金额超限。\"\n" + | |||||
| " },\n" + | |||||
| " \"PARAM_ERROR\": {\n" + | |||||
| " \"detail\": \"参数错误\",\n" + | |||||
| " \"reason\": \"1. 请求参数校验错误 2. 字符中包含非utf8字符 3. 商户号和appid没有绑定关系\\t\",\n" + | |||||
| " \"resolution\": \"请参照原因检查您的请求参数是否正确\"\n" + | |||||
| " },\n" + | |||||
| " \"OPENID_ERROR\": {\n" + | |||||
| " \"detail\": \"Openid错误\",\n" + | |||||
| " \"reason\": \"Openid格式错误或者不属于商家公众账号\",\n" + | |||||
| " \"resolution\": \"Openid与appid是有一一映射关系的,请确保正确使用。\"\n" + | |||||
| " },\n" + | |||||
| " \"SEND_FAILED\": {\n" + | |||||
| " \"detail\": \"付款错误\",\n" + | |||||
| " \"reason\": \"付款错误,请查单确认付款结果\",\n" + | |||||
| " \"resolution\": \"请查单确认付款结果,以查单结果为准。\"\n" + | |||||
| " },\n" + | |||||
| " \"NOTENOUGH\": {\n" + | |||||
| " \"detail\": \"余额不足\",\n" + | |||||
| " \"reason\": \"您的付款帐号余额不足或资金未到账\\t\",\n" + | |||||
| " \"resolution\": \"如果要继续付款必须使用原商户订单号重试\"\n" + | |||||
| " },\n" + | |||||
| " \"SYSTEMERROR\": {\n" + | |||||
| " \"detail\": \"系统繁忙,请稍后再试\",\n" + | |||||
| " \"reason\": \"微信内部接口调用发生错误\",\n" + | |||||
| " \"resolution\": \"请先调用查询接口,查看此次付款结果,如结果为不明确状态(如订单号不存在),请务必使用原商户订单号进行重试。\"\n" + | |||||
| " },\n" + | |||||
| " \"NAME_MISMATCH\": {\n" + | |||||
| " \"detail\": \"姓名校验出错\",\n" + | |||||
| " \"reason\": \"收款人身份校验不通过\",\n" + | |||||
| " \"resolution\": \"如果要继续付款必须使用原商户订单号重试\"\n" + | |||||
| " },\n" + | |||||
| " \"SIGN_ERROR\": {\n" + | |||||
| " \"detail\": \"签名错误\",\n" + | |||||
| " \"reason\": \"校验签名错误\",\n" + | |||||
| " \"resolution\": \"请检查您的请求参数和签名密钥KEY是否正确,如果要继续付款必须使用原商户订单号重试\"\n" + | |||||
| " },\n" + | |||||
| " \"XML_ERROR\": {\n" + | |||||
| " \"detail\": \"Post内容出错\",\n" + | |||||
| " \"reason\": \"Post请求数据不是合法的xml格式内容\",\n" + | |||||
| " \"resolution\": \"格式问题,请检查请求格式是否正确。\"\n" + | |||||
| " },\n" + | |||||
| " \"FATAL_ERROR\": {\n" + | |||||
| " \"detail\": \"两次请求参数不一致\",\n" + | |||||
| " \"reason\": \"两次请求商户单号一样,但是参数不一致\",\n" + | |||||
| " \"resolution\": \"重入必须保证所有参数值都不变\"\n" + | |||||
| " },\n" + | |||||
| " \"FREQ_LIMIT\": {\n" + | |||||
| " \"detail\": \"超过频率限制,请稍后再试\",\n" + | |||||
| " \"reason\": \"接口请求频率超时接口限制\",\n" + | |||||
| " \"resolution\": \"调用接口过于频繁,请稍后再试,如果要继续付款必须使用原商户订单号重试\"\n" + | |||||
| " },\n" + | |||||
| " \"MONEY_LIMIT\": {\n" + | |||||
| " \"detail\": \"已经达到今日付款总额上限/已达到付款给此用户额度上限\",\n" + | |||||
| " \"reason\": \"请关注接口的付款限额条件\",\n" + | |||||
| " \"resolution\": \"付款额度已经超限,请参考接口使用条件,如果要继续付款必须使用原商户订单号重试\"\n" + | |||||
| " },\n" + | |||||
| " \"CA_ERROR\": {\n" + | |||||
| " \"detail\": \"商户API证书校验出错\",\n" + | |||||
| " \"reason\": \"请求没带商户API证书或者带上了错误的商户API证书\",\n" + | |||||
| " \"resolution\": \"您使用的调用证书有误,请确认是否使用了正确的证书,可以前往商户平台重新下载,证书需与商户号对应,如果要继续付款必须使用原商户订单号重试\"\n" + | |||||
| " },\n" + | |||||
| " \"V2_ACCOUNT_SIMPLE_BAN\": {\n" + | |||||
| " \"detail\": \"无法给未实名用户付款\",\n" + | |||||
| " \"reason\": \"用户微信支付账户未实名,无法付款\",\n" + | |||||
| " \"resolution\": \"不支持给未实名用户付款,如果要继续付款必须使用原商户订单号重试\"\n" + | |||||
| " },\n" + | |||||
| " \"PARAM_IS_NOT_UTF8\": {\n" + | |||||
| " \"detail\": \"请求参数中包含非utf8编码字符\",\n" + | |||||
| " \"reason\": \"接口规范要求所有请求参数都必须为utf8编码\",\n" + | |||||
| " \"resolution\": \"微信接口使用编码是UTF-8,请确认,如果要继续付款必须使用原商户订单号重试\"\n" + | |||||
| " },\n" + | |||||
| " \"SENDNUM_LIMIT\": {\n" + | |||||
| " \"detail\": \"该用户今日付款次数超过限制,如有需要请进入【微信支付商户平台-产品中心-企业付款到零钱-产品设置】进行修改\",\n" + | |||||
| " \"reason\": \"该用户今日付款次数超过限制,如有需要请进入【微信支付商户平台-产品中心-企业付款到零钱-产品设置】进行修改\",\n" + | |||||
| " \"resolution\": \"向用户付款的次数超限了,请参考接口使用条件,如果要继续付款必须使用原商户订单号重试\"\n" + | |||||
| " },\n" + | |||||
| " \"RECV_ACCOUNT_NOT_ALLOWED\": {\n" + | |||||
| " \"detail\": \"收款账户不在收款账户列表\",\n" + | |||||
| " \"reason\": \"收款账户不在收款账户列表\",\n" + | |||||
| " \"resolution\": \"请登陆商户平台,查看产品中心企业付款到零钱的产品配置\"\n" + | |||||
| " },\n" + | |||||
| " \"PAY_CHANNEL_NOT_ALLOWED\": {\n" + | |||||
| " \"detail\": \"本商户号未配置API发起能力\",\n" + | |||||
| " \"reason\": \"本商户号未配置API发起能力\",\n" + | |||||
| " \"resolution\": \"请登陆商户平台,查看产品中心企业付款到零钱的产品配置\"\n" + | |||||
| " }\n" + | |||||
| "}"); | |||||
| JSONObject errorQueryReqMap = JSON.parseObject("{\n" + | |||||
| " \"CA_ERROR\": {\n" + | |||||
| " \"detail\": \"请求未携带证书,或请求携带的证书出错\",\n" + | |||||
| " \"reason\": \"请求未携带证书,或请求携带的证书出错\",\n" + | |||||
| " \"resolution\": \"到商户平台下载证书,请求带上证书后重试。\"\n" + | |||||
| " },\n" + | |||||
| " \"SIGN_ERROR\": {\n" + | |||||
| " \"detail\": \"商户签名错误\",\n" + | |||||
| " \"reason\": \"商户签名错误\",\n" + | |||||
| " \"resolution\": \"按文档要求重新生成签名后再重试。\"\n" + | |||||
| " },\n" + | |||||
| " \"FREQ_LIMIT\": {\n" + | |||||
| " \"detail\": \"受频率限制\",\n" + | |||||
| " \"reason\": \"受频率限制\\t\",\n" + | |||||
| " \"resolution\": \"请对请求做频率控制\"\n" + | |||||
| " },\n" + | |||||
| " \"XML_ERROR\": {\n" + | |||||
| " \"detail\": \"请求的xml格式错误,或者post的数据为空\",\n" + | |||||
| " \"reason\": \"请求的xml格式错误,或者post的数据为空\",\n" + | |||||
| " \"resolution\": \"检查请求串,确认无误后重试。\"\n" + | |||||
| " },\n" + | |||||
| " \"PARAM_ERROR\": {\n" + | |||||
| " \"detail\": \"参数错误\",\n" + | |||||
| " \"reason\": \"参数错误\",\n" + | |||||
| " \"resolution\": \"请查看err_code_des,修改设置错误的参数。\"\n" + | |||||
| " },\n" + | |||||
| " \"SYSTEMERROR\": {\n" + | |||||
| " \"detail\": \"系统繁忙,请再试\",\n" + | |||||
| " \"reason\": \"系统繁忙,请再试\\t\",\n" + | |||||
| " \"resolution\": \"系统繁忙\"\n" + | |||||
| " },\n" + | |||||
| " \"NOT_FOUND\": {\n" + | |||||
| " \"detail\": \"1、指定单号数据不存在 2、指定单号数据不存在,单据查询超过有效期\",\n" + | |||||
| " \"reason\": \"1、指定单号数据不存在 2、指定单号数据不存在,单据查询超过有效期\",\n" + | |||||
| " \"resolution\": \"1、查询单号对应的数据不存在,请使用正确的商户订单号查询2、如需查询超过有效期的单据,请登录到商户平台进行查询。\"\n" + | |||||
| " }\n" + | |||||
| "}"); | |||||
| @Override | |||||
| public CashOutAdapterResult cashOut(WxAppinfo appInfo, WxPayAccount payAccount, WxCashOut cashOut) { | |||||
| if (StringUtils.isBlank(payAccount.getMerchantCertPath())) { | |||||
| return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户证书为空。请联系管理员配置。", null); | |||||
| } | |||||
| if (StringUtils.isBlank(payAccount.getMerchantKeyPath())) { | |||||
| return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户密钥为空。请联系管理员配置。", null); | |||||
| } | |||||
| if (StringUtils.isBlank(payAccount.getMerchantApiv3Key())) { | |||||
| return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户密钥ApiV3为空。请联系管理员配置。", null); | |||||
| } | |||||
| WxPayService payService = maUtil.getWxPayServiceBySelfModel(appInfo,payAccount); | |||||
| if (null == payService) { | |||||
| return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。当前小程序未查询到payService。", null); | |||||
| } | |||||
| String response = null; | |||||
| try { | |||||
| response = WxPay.merchantTranferChange(payService,generateWxCashOutPV3(payAccount, appInfo, cashOut)); | |||||
| } catch (Exception e) { | |||||
| log.error("零钱支付异常: " + e.getMessage(),e); | |||||
| return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "微信零钱支付接口调用异常:"+e.getMessage(), null); | |||||
| } | |||||
| log.info("微信零钱支付:, response: " + response.toString()); | |||||
| return generateResult(response,cashOut); | |||||
| // if (payAccount.getType() == EnumPayMode.MCH.getCode()) { | |||||
| // 普通商户模式 | |||||
| // } | |||||
| } | |||||
| private WxCashOutPV3 generateWxCashOutPV3(WxPayAccount payAccount,WxAppinfo appInfo,WxCashOut cashOut) { | |||||
| WxCashOutPV3 wxCashOutPv3 = new WxCashOutPV3(); | |||||
| wxCashOutPv3.setAppid(appInfo.getAppId()); | |||||
| wxCashOutPv3.setOut_batch_no(String.valueOf(cashOut.getId())); | |||||
| StringBuffer bn = new StringBuffer(cashOut.getMerchantName()).append("提现"); | |||||
| try { | |||||
| wxCashOutPv3.setBatch_name(new String(bn.toString().getBytes("ISO-8859-1"), "UTF-8")); | |||||
| } catch (UnsupportedEncodingException e) { | |||||
| wxCashOutPv3.setBatch_name("tixian"); | |||||
| } | |||||
| wxCashOutPv3.setBatch_remark("From FM WxMiniApp"); | |||||
| wxCashOutPv3.setTotal_amount(cashOut.getTotalFee()); | |||||
| wxCashOutPv3.setTotal_num(1); | |||||
| List<WxCashOutPV3Item> itemList = new ArrayList<WxCashOutPV3Item>(); | |||||
| WxCashOutPV3Item item = new WxCashOutPV3Item(); | |||||
| item.setOut_detail_no(Utility.generate32UUID()); | |||||
| item.setOpenid(cashOut.getReciveOpenId()); | |||||
| item.setTransfer_amount(cashOut.getTotalFee()); | |||||
| item.setTransfer_remark("From FM WxMiniApp Tranfer."); | |||||
| item.setUser_name(cashOut.getRealName()); | |||||
| itemList.add(item); | |||||
| wxCashOutPv3.setTransfer_detail_list(itemList); | |||||
| return wxCashOutPv3; | |||||
| } | |||||
| private CashOutAdapterResult generateResult(String response,WxCashOut cashOut) { | |||||
| JSONObject result = JSON.parseObject(response); | |||||
| String batchId = result.getString("batch_id"); | |||||
| if (!StringUtils.isBlank(batchId)) { | |||||
| cashOut.setWxPayNo(batchId); | |||||
| String payTime = result.getString("create_time"); | |||||
| cashOut.setWxPayTime(payTime); | |||||
| return new CashOutAdapterResult(true,EnumCashOutStatus.SUCCESS.getCode(),"微信零钱支付申请成功",result); | |||||
| }else { | |||||
| //log.error("微信零钱支付申请失败: " + response); | |||||
| return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "微信零钱支付申请失败:微信接口未返回值", result); | |||||
| } | |||||
| } | |||||
| @Override | |||||
| public CashOutAdapterResult queryCashOut(WxAppinfo appInfo, WxPayAccount payAccount, WxCashOut cashOut) { | |||||
| if (StringUtils.isBlank(payAccount.getMerchantCertPath())) { | |||||
| return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户证书为空。请联系管理员配置。", null); | |||||
| } | |||||
| if (StringUtils.isBlank(payAccount.getMerchantKeyPath())) { | |||||
| return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户密钥为空。请联系管理员配置。", null); | |||||
| } | |||||
| if (StringUtils.isBlank(payAccount.getMerchantApiv3Key())) { | |||||
| return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户密钥ApiV3为空。请联系管理员配置。", null); | |||||
| } | |||||
| WxPayService payService = maUtil.getWxPayServiceBySelfModel(appInfo,payAccount); | |||||
| if (null == payService) { | |||||
| return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。当前小程序未查询到payService。", null); | |||||
| } | |||||
| String response = null; | |||||
| try { | |||||
| response = WxPay.merchantTransferInfo(String.valueOf(cashOut.getId()), payService); | |||||
| } catch (Exception e) { | |||||
| log.error("零钱支付查询异常: " + e.getMessage(),e); | |||||
| throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "微信零钱支付查询接口异常:"+e.getMessage()); | |||||
| } | |||||
| log.info("微信零钱支付查询:"+ response.toString()); | |||||
| return getReusltFromQuery(response,cashOut); | |||||
| } | |||||
| private CashOutAdapterResult getReusltFromQuery(String response,WxCashOut cashOut) throws MallinkException{ | |||||
| JSONObject result = JSON.parseObject(response); | |||||
| JSONObject transferBatch = result.getJSONObject("transfer_batch"); | |||||
| if (null != transferBatch) { | |||||
| /** | |||||
| * WAIT_PAY:待付款,商户员工确认付款阶段 | |||||
| * ACCEPTED:已受理。批次已受理成功,若发起批量转账的30分钟后,转账批次单仍处于该状态,可能原因是商户账户余额不足等 | |||||
| * PROCESSING:转账中。已开始处理批次内的转账明细单 | |||||
| * FINISHED:已完成。批次内的所有转账明细单都已处理完成 | |||||
| * CLOSED:已关闭。可查询具体的批次关闭原因确认 | |||||
| */ | |||||
| String batchStatus = transferBatch.getString("batch_status"); | |||||
| if ("WAIT_PAY".equals(batchStatus)) { | |||||
| throw new MallinkException(EnumCashOutStatus.FAIL.getCode(), "待商户付款:"); | |||||
| }else if ("ACCEPTED".equals(batchStatus)) { | |||||
| throw new MallinkException(EnumCashOutStatus.FAIL.getCode(), "已受理,待转账:"); | |||||
| }else if ("PROCESSING".equals(batchStatus)) { | |||||
| throw new MallinkException(EnumCashOutStatus.FAIL.getCode(), "待转账中"); | |||||
| }else if ("CLOSED".equals(batchStatus)) { | |||||
| /** | |||||
| * MERCHANT_REVOCATION:商户主动撤销 OVERDUE_CLOSE:系统超时关闭 | |||||
| */ | |||||
| String close_reason = transferBatch.getString("close_reason"); | |||||
| if ("MERCHANT_REVOCATION".equals(close_reason)) { | |||||
| close_reason = "商户主动撤销"; | |||||
| }else if ("OVERDUE_CLOSE".equals(close_reason)) { | |||||
| close_reason = "系统超时关闭"; | |||||
| } | |||||
| return new CashOutAdapterResult(false,EnumCashOutStatus.FAIL.getCode(),"转账已关闭:"+close_reason,result); | |||||
| }else if ("FINISHED".equals(batchStatus)) { | |||||
| String detailId = transferBatch.getString("out_batch_no"); | |||||
| cashOut.setWxPayNo(detailId); | |||||
| String wxPayTime = transferBatch.getString("create_time"); | |||||
| cashOut.setWxPayTime(wxPayTime); | |||||
| return new CashOutAdapterResult(true,EnumCashOutStatus.SUCCESS.getCode(),"转账已完成",result); | |||||
| }else { | |||||
| log.error("微信零钱支付查询失败,微信返回未知状态: " + response); | |||||
| throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "微信零钱支付查询失败, 微信返回未知状态:"+batchStatus); | |||||
| } | |||||
| }else { | |||||
| log.error("微信零钱支付查询失败,微信未返回值: " + response); | |||||
| throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "微信零钱支付查询失败,微信未返回值:"); | |||||
| } | |||||
| } | |||||
| // /** | |||||
| // * https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2 | |||||
| // * | |||||
| // * 在wx_pay_account里面要设置merchant_cert_path,登陆特约商户的商户后台,账号中心-API安全。 | |||||
| // */ | |||||
| // @Deprecated | |||||
| // @Override | |||||
| // public CashOutAdapterResult cashOut(WxAppinfo appInfo, WxPayAccount payAccount, WxCashOut cashOut) { | |||||
| // if (StringUtils.isBlank(payAccount.getMerchantCertPath())) { | |||||
| // return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户证书为空。请联系管理员配置。", null); | |||||
| // } | |||||
| // if (StringUtils.isBlank(payAccount.getMerchantApiKey())) { | |||||
| // return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户密钥为空。请联系管理员配置。", null); | |||||
| // } | |||||
| // WxCashOutP wxCashOutP = generateWxCashOutP(payAccount, appInfo, cashOut); | |||||
| // Map signMap = null; | |||||
| // try { | |||||
| // signMap = BeanUtils.toStringMap(wxCashOutP); | |||||
| // } catch (Exception e) { | |||||
| // log.error("零钱支付命令生辰: " + e.getMessage(),e); | |||||
| // return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付签名异常", null); | |||||
| // } | |||||
| // | |||||
| // String signAgent = WxPayment.createSign(signMap, payAccount.getMerchantApiKey()); | |||||
| // signMap.put("sign", signAgent); | |||||
| // String response = null; | |||||
| // try { | |||||
| // response = WxPay.merchantTranferChange(signMap, payAccount.getMerchantCertPath(), payAccount.getSubMchId()); | |||||
| // } catch (Exception e) { | |||||
| // log.error("零钱支付异常: " + e.getMessage(),e); | |||||
| // return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "微信零钱支付接口调用异常", null); | |||||
| // } | |||||
| // log.info("微信零钱支付:" + wxCashOutP.toString() +", response: " + response.toString()); | |||||
| // return getReusltFromp(response,cashOut); | |||||
| // | |||||
| //// if (payAccount.getType() == EnumPayMode.MCH.getCode()) { | |||||
| // // 普通商户模式 | |||||
| //// } | |||||
| // } | |||||
| // | |||||
| // private WxCashOutP generateWxCashOutP(WxPayAccount payAccount,WxAppinfo appInfo,WxCashOut cashOut) { | |||||
| // String noncestr = Utility.generate32UUID(); | |||||
| // WxCashOutP wxCashOutP = new WxCashOutP(); | |||||
| // wxCashOutP.setMch_appid(appInfo.getAppId()); | |||||
| // wxCashOutP.setMchid(payAccount.getSubMchId()); | |||||
| // wxCashOutP.setNonce_str(noncestr); | |||||
| // wxCashOutP.setAmount(cashOut.getTotalFee()); | |||||
| // wxCashOutP.setCheck_name("NO_CHECK"); | |||||
| // wxCashOutP.setDesc("客户结算"); | |||||
| // wxCashOutP.setOpenid(cashOut.getReciveOpenId()); | |||||
| // wxCashOutP.setPartner_trade_no(String.valueOf(cashOut.getId())); | |||||
| // return wxCashOutP; | |||||
| // } | |||||
| // | |||||
| // private CashOutAdapterResult getReusltFromp(String response,WxCashOut cashOut) throws MallinkException{ | |||||
| // Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||||
| // String result_no = returnMap.get("result_code"); | |||||
| // if ("SUCCESS".equals(result_no)) { | |||||
| // log.info("微信零钱支付申请成功: " + returnMap.toString()); | |||||
| // String wxPayNo = returnMap.get("payment_no"); | |||||
| // String payTime = returnMap.get("payment_time"); | |||||
| // cashOut.setWxPayNo(wxPayNo); | |||||
| // cashOut.setWxPayTime(payTime); | |||||
| // return new CashOutAdapterResult(true,EnumCashOutStatus.SUCCESS.getCode(),"微信零钱支付申请成功",returnMap); | |||||
| // } else { | |||||
| // log.error("微信零钱支付申请失败: " + response); | |||||
| // String errMsg = ""; | |||||
| // JSONObject errObj = errorRefundReqMap.getJSONObject(result_no); | |||||
| // if (errObj != null) { | |||||
| // errMsg = errObj.toJSONString(); | |||||
| // } else { | |||||
| // errMsg = returnMap.get("err_code_des"); | |||||
| // } | |||||
| // return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), errMsg, returnMap); | |||||
| // } | |||||
| // } | |||||
| // | |||||
| // @Override | |||||
| // public CashOutAdapterResult queryCashOut(WxAppinfo appInfo, WxPayAccount payAccount, WxCashOut cashOut) { | |||||
| // if (StringUtils.isBlank(payAccount.getMerchantCertPath())) { | |||||
| // return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户证书为空。请联系管理员配置。", null); | |||||
| // } | |||||
| // WxCashOutQueryP wxCashOutP = generateQueryWxCashOutP(payAccount, appInfo, cashOut); | |||||
| // Map signMap = null; | |||||
| // try { | |||||
| // signMap = BeanUtils.toStringMap(wxCashOutP); | |||||
| // } catch (Exception e) { | |||||
| // log.error("零钱支付命令生辰: " + e.getMessage(),e); | |||||
| // throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "零钱支付签名异常"); | |||||
| // } | |||||
| // | |||||
| // String signAgent = WxPayment.createSign(signMap, payAccount.getMerchantApiKey()); | |||||
| // signMap.put("sign", signAgent); | |||||
| // String response = null; | |||||
| // try { | |||||
| // response = WxPay.getTransferInfo(signMap, payAccount.getMerchantCertPath(), payAccount.getSubMchId()); | |||||
| // } catch (Exception e) { | |||||
| // log.error("零钱支付查询异常: " + e.getMessage(),e); | |||||
| // throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "微信零钱支付查询接口异常"); | |||||
| // } | |||||
| // log.info("微信零钱支付查询:" + wxCashOutP.toString() + ", response: " + response.toString()); | |||||
| // return getReusltFromQueryp(response,cashOut); | |||||
| // } | |||||
| // | |||||
| // private WxCashOutQueryP generateQueryWxCashOutP(WxPayAccount payAccount,WxAppinfo appInfo,WxCashOut cashOut) { | |||||
| // String noncestr = Utility.generate32UUID(); | |||||
| // WxCashOutQueryP wxCashOutQueryP = new WxCashOutQueryP(); | |||||
| // wxCashOutQueryP.setAppid(appInfo.getAppId()); | |||||
| // wxCashOutQueryP.setMch_id(payAccount.getSubMchId()); | |||||
| // wxCashOutQueryP.setNonce_str(noncestr); | |||||
| // wxCashOutQueryP.setPartner_trade_no(String.valueOf(cashOut.getId())); | |||||
| // return wxCashOutQueryP; | |||||
| // } | |||||
| // | |||||
| // private CashOutAdapterResult getReusltFromQueryp(String response,WxCashOut cashOut) throws MallinkException{ | |||||
| // Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||||
| // String result_no = returnMap.get("result_code"); | |||||
| // if ("SUCCESS".equals(result_no)) { | |||||
| // String realStatus = returnMap.get("status"); | |||||
| // if ("SUCCESS".equals(realStatus) || "PROCESSING".equals(realStatus)) { | |||||
| // String detailId = returnMap.get("detail_id"); | |||||
| // cashOut.setWxPayNo(detailId); | |||||
| // String wxPayTime = returnMap.get("transfer_time"); | |||||
| // cashOut.setWxPayTime(wxPayTime); | |||||
| // return new CashOutAdapterResult(true,EnumCashOutStatus.SUCCESS.getCode(),"微信零钱支付查询成功",returnMap); | |||||
| // }else if("FAILED".equals(realStatus)) { | |||||
| // String msg = returnMap.get("reason"); | |||||
| // return new CashOutAdapterResult(false,EnumCashOutStatus.FAIL.getCode(),msg,returnMap); | |||||
| // }else { | |||||
| // log.error("微信零钱支付查询失败,微信返回未知状态: " + response); | |||||
| // throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "微信零钱支付查询失败, 微信返回未知状态:"+realStatus); | |||||
| // } | |||||
| // } else { | |||||
| // log.error("微信零钱支付查询失败: " + response); | |||||
| // String errMsg = returnMap.get("err_code_des"); | |||||
| // String errCode = returnMap.get("err_code"); | |||||
| // if ("NOT_FOUND".equals(errCode)) { | |||||
| // return new CashOutAdapterResult(false,EnumCashOutStatus.FAIL.getCode(),errMsg,returnMap); | |||||
| // } | |||||
| //// JSONObject errObj = errorQueryReqMap.getJSONObject(result_no); | |||||
| //// if (errObj != null) { | |||||
| //// errMsg = errObj.toJSONString(); | |||||
| //// } else { | |||||
| //// errMsg = returnMap.get("err_code_des"); | |||||
| //// } | |||||
| // throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "微信零钱支付查询失败:"+errMsg); | |||||
| // } | |||||
| // } | |||||
| } | |||||
| @@ -1,4 +1,4 @@ | |||||
| package com.iformall.service.pay.service.pay.wx; | |||||
| package com.iformall.service.pay.service.pay.wx.v2; | |||||
| import java.io.File; | import java.io.File; | ||||
| import java.util.Date; | import java.util.Date; | ||||
| @@ -1,4 +1,4 @@ | |||||
| package com.iformall.service.pay.service.pay.wx.h5; | |||||
| package com.iformall.service.pay.service.pay.wx.v2.h5; | |||||
| import java.io.File; | import java.io.File; | ||||
| import java.util.Date; | import java.util.Date; | ||||
| @@ -16,7 +16,7 @@ import com.iformall.service.pay.entity.PayExtraParam; | |||||
| import com.iformall.service.pay.service.pay.CDrivingPayService; | import com.iformall.service.pay.service.pay.CDrivingPayService; | ||||
| import com.iformall.service.pay.service.pay.entity.PayAdapterResult; | import com.iformall.service.pay.service.pay.entity.PayAdapterResult; | ||||
| import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult; | import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult; | ||||
| import com.iformall.service.pay.service.pay.wx.BaseWxPayAdapterService; | |||||
| import com.iformall.service.pay.service.pay.wx.v2.BaseWxPayAdapterService; | |||||
| @Service | @Service | ||||
| public class WxH5PayService extends BaseWxPayAdapterService implements CDrivingPayService{ | public class WxH5PayService extends BaseWxPayAdapterService implements CDrivingPayService{ | ||||
| @@ -1,4 +1,4 @@ | |||||
| package com.iformall.service.pay.service.pay.wx.miniApp.appPay; | |||||
| package com.iformall.service.pay.service.pay.wx.v2.miniApp.appPay; | |||||
| import java.io.File; | import java.io.File; | ||||
| import java.util.Date; | import java.util.Date; | ||||
| @@ -28,7 +28,7 @@ import com.iformall.service.pay.entity.PayExtraParam; | |||||
| import com.iformall.service.pay.service.pay.CDrivingPayService; | import com.iformall.service.pay.service.pay.CDrivingPayService; | ||||
| import com.iformall.service.pay.service.pay.entity.PayAdapterResult; | import com.iformall.service.pay.service.pay.entity.PayAdapterResult; | ||||
| import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult; | import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult; | ||||
| import com.iformall.service.pay.service.pay.wx.BaseWxPayAdapterService; | |||||
| import com.iformall.service.pay.service.pay.wx.v2.BaseWxPayAdapterService; | |||||
| import com.iformall.utils.BeanUtils; | import com.iformall.utils.BeanUtils; | ||||
| import com.iformall.utils.MapUtil; | import com.iformall.utils.MapUtil; | ||||
| import com.iformall.utils.Utility; | import com.iformall.utils.Utility; | ||||
| @@ -1,4 +1,4 @@ | |||||
| package com.iformall.service.pay.service.pay.wx.miniApp.maPay; | |||||
| package com.iformall.service.pay.service.pay.wx.v2.miniApp.maPay; | |||||
| import java.io.File; | import java.io.File; | ||||
| import java.util.Date; | import java.util.Date; | ||||
| @@ -31,7 +31,7 @@ import com.iformall.service.pay.service.pay.CPassivePayService; | |||||
| import com.iformall.service.pay.service.pay.entity.CreateUser; | import com.iformall.service.pay.service.pay.entity.CreateUser; | ||||
| import com.iformall.service.pay.service.pay.entity.PayAdapterResult; | import com.iformall.service.pay.service.pay.entity.PayAdapterResult; | ||||
| import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult; | import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult; | ||||
| import com.iformall.service.pay.service.pay.wx.BaseWxPayAdapterService; | |||||
| import com.iformall.service.pay.service.pay.wx.v2.BaseWxPayAdapterService; | |||||
| import com.iformall.utils.BeanUtils; | import com.iformall.utils.BeanUtils; | ||||
| import com.iformall.utils.Utility; | import com.iformall.utils.Utility; | ||||
| import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
| @@ -0,0 +1,81 @@ | |||||
| package com.iformall.service.pay.service.pay.wx.v3.h5; | |||||
| import java.io.File; | |||||
| import java.util.Date; | |||||
| import java.util.List; | |||||
| import java.util.Map; | |||||
| import com.iformall.common.ErrorCode; | |||||
| import com.iformall.domain.po.*; | |||||
| import com.iformall.exception.MallinkException; | |||||
| import org.springframework.stereotype.Service; | |||||
| import com.iformall.enums.EnumPayShare; | |||||
| import com.iformall.service.order.entity.WxComposeOrder; | |||||
| import com.iformall.service.pay.entity.PayExtraParam; | |||||
| import com.iformall.service.pay.service.pay.CDrivingPayService; | |||||
| import com.iformall.service.pay.service.pay.entity.PayAdapterResult; | |||||
| import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult; | |||||
| import com.iformall.service.pay.service.pay.wx.v2.BaseWxPayAdapterService; | |||||
| @Service | |||||
| public class WxH5PayV3Service implements CDrivingPayService{ | |||||
| @Override | |||||
| public PayAdapterResult pay(WxPayAccount payAccount, WxPayOrder record,WxComposeOrder composeOrder,String productName, EnumPayShare isShare, | |||||
| WxAppinfo appInfo, Date currentDate, PayExtraParam params) throws Exception { | |||||
| // TODO Auto-generated method stub | |||||
| return null; | |||||
| } | |||||
| @Override | |||||
| public PayQueryAdapterResult queryPayStatus(WxPayOrder oldRecord, WxAppinfo appInfo, | |||||
| WxPayAccount payAccount) throws Exception { | |||||
| //return super.queryPayStatus(oldRecord, appInfo, payAccount); | |||||
| return null; | |||||
| } | |||||
| @Override | |||||
| public int queryPayStatus(PayQueryAdapterResult statusObject, String orderOutNo) throws Exception { | |||||
| //return super.queryPayStatus(statusObject, orderOutNo); | |||||
| return 0; | |||||
| } | |||||
| @Override | |||||
| public int queryPayStatusCode(WxPayOrder oldRecord, WxAppinfo appInfo, WxPayAccount payAccount) | |||||
| throws Exception { | |||||
| //return super.queryPayStatusCode(oldRecord, appInfo, payAccount); | |||||
| return 0; | |||||
| } | |||||
| @Override | |||||
| public PayAdapterResult payOrderClose(WxAppinfo appInfo, WxPayOrder record, WxPayAccount payAccount) | |||||
| throws Exception { | |||||
| // TODO Auto-generated method stub | |||||
| return null; | |||||
| } | |||||
| @Override | |||||
| public PayAdapterResult payOrderReverse(WxAppinfo appInfo, WxPayOrder record, WxPayAccount payAccount) | |||||
| throws Exception { | |||||
| // TODO Auto-generated method stub | |||||
| return null; | |||||
| } | |||||
| @Override | |||||
| public PayAdapterResult payOrderPush(String openId,WxAppinfo appInfo, WxBatchOrder batchOrder,WxPayOrder payOrder) throws Exception { | |||||
| return null; | |||||
| } | |||||
| @Override | |||||
| public File getQrcode(WxAppinfo appinfo,String pageUrl,int type,String sceneParam) throws Exception{ | |||||
| // TODO Auto-generated method stub | |||||
| return null; | |||||
| } | |||||
| @Override | |||||
| public PayAdapterResult noCreatePay(WxPayOrder record, WxComposeOrder composeOrder, List<WxOrder> childOrders) { | |||||
| throw new MallinkException(ErrorCode.SYS_PARAMETER_ERROR); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,291 @@ | |||||
| package com.iformall.service.pay.service.pay.wx.v3.miniApp.appPay; | |||||
| import java.io.File; | |||||
| import java.util.Date; | |||||
| import java.util.List; | |||||
| import java.util.Map; | |||||
| import com.iformall.domain.po.*; | |||||
| import org.apache.commons.lang3.StringUtils; | |||||
| import org.springframework.stereotype.Service; | |||||
| import com.alibaba.fastjson.JSON; | |||||
| import com.alibaba.fastjson.JSONObject; | |||||
| import com.iformall.common.ErrorCode; | |||||
| import com.iformall.common.Result; | |||||
| import com.iformall.common.ResultData; | |||||
| import com.iformall.enums.EnumOrderStatus; | |||||
| import com.iformall.enums.EnumPayMode; | |||||
| import com.iformall.enums.EnumPayShare; | |||||
| import com.iformall.enums.EnumPayStatus; | |||||
| import com.iformall.exception.MallinkException; | |||||
| import com.iformall.pay.WxPay; | |||||
| import com.iformall.pay.WxPayOrderP; | |||||
| import com.iformall.pay.WxPayOrderSP; | |||||
| import com.iformall.pay.WxPayment; | |||||
| import com.iformall.service.order.entity.WxComposeOrder; | |||||
| import com.iformall.service.pay.entity.PayExtraParam; | |||||
| import com.iformall.service.pay.service.pay.CDrivingPayService; | |||||
| import com.iformall.service.pay.service.pay.entity.PayAdapterResult; | |||||
| import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult; | |||||
| import com.iformall.service.pay.service.pay.wx.v2.BaseWxPayAdapterService; | |||||
| import com.iformall.utils.BeanUtils; | |||||
| import com.iformall.utils.MapUtil; | |||||
| import com.iformall.utils.Utility; | |||||
| import lombok.extern.slf4j.Slf4j; | |||||
| @Slf4j | |||||
| @Service | |||||
| public class WxMiniAppPayV3AdapterService implements CDrivingPayService{ | |||||
| JSONObject errorMap = JSON.parseObject("{" + | |||||
| "\"NOAUTH\":{\"detail\":\"商户无此接口权限\",\"reason\":\"商户未开通此接口权限\",\"resolution\":\"请商户前往申请此接口权限\"}," + | |||||
| "\"NOTENOUGH\":{\"detail\":\"余额不足\",\"reason\":\"用户帐号余额不足\",\"resolution\":\"用户帐号余额不足,请用户充值或更换支付卡后再支付\"}," + | |||||
| "\"ORDERPAID\":{\"detail\":\"商户订单已支付\",\"reason\":\"商户订单已支付,无需重复操作\",\"resolution\":\"商户订单已支付,无需更多操作\"}," + | |||||
| "\"ORDERCLOSED\":{\"detail\":\"订单已关闭\",\"reason\":\"当前订单已关闭,无法支付\",\"resolution\":\"当前订单已关闭,请重新下单\"}," + | |||||
| "\"SYSTEMERROR\":{\"detail\":\"系统错误\t\",\"reason\":\"系统超时\",\"resolution\":\"系统异常,请用相同参数重新调用\"}," + | |||||
| "\"APPID_NOT_EXIST\":{\"detail\":\"APPID不存在\",\"reason\":\"参数中缺少APPID\",\"resolution\":\"请检查APPID是否正确\"}," + | |||||
| "\"MCHID_NOT_EXIST\":{\"detail\":\"MCHID不存在\",\"reason\":\"参数中缺少MCHID\",\"resolution\":\"请检查MCHID是否正确\"}," + | |||||
| "\"APPID_MCHID_NOT_MATCH\":{\"detail\":\"appid和mch_id不匹配\",\"reason\":\"appid和mch_id不匹配\",\"resolution\":\"请确认appid和mch_id是否匹配\"}," + | |||||
| "\"LACK_PARAMS\":{\"detail\":\"缺少参数\t\",\"reason\":\"缺少必要的请求参数\",\"resolution\":\"请检查参数是否齐全\"}," + | |||||
| "\"OUT_TRADE_NO_USED\":{\"detail\":\"商户订单号重复\",\"reason\":\"同一笔交易不能多次提交\",\"resolution\":\"请核实商户订单号是否重复提交\"}," + | |||||
| "\"SIGNERROR\":{\"detail\":\"签名错误\",\"reason\":\"参数签名结果不正确\",\"resolution\":\"请检查签名参数和方法是否都符合签名算法要求\"}," + | |||||
| "\"XML_FORMAT_ERROR\":{\"detail\":\"XML格式错误\t\",\"reason\":\"XML格式错误\",\"resolution\":\"请检查XML参数格式是否正确\"}," + | |||||
| "\"REQUIRE_POST_METHOD\":{\"detail\":\"请使用post方法\",\"reason\":\"未使用post传递参数\",\"resolution\":\"请检查请求参数是否通过post方法提交\"}," + | |||||
| "\"POST_DATA_EMPTY\":{\"detail\":\"post数据为空\",\"reason\":\"post数据不能为空\",\"resolution\":\"请检查post数据是否为空\"}," + | |||||
| "\"NOT_UTF8\":{\"detail\":\"编码格式错误\",\"reason\":\"未使用指定编码格式\",\"resolution\":\"请使用UTF-8编码格式\"}}"); | |||||
| private WxPayOrderP generateWxPayOrderP(WxPayAccount payAccount,WxComposeOrder composeOrder,String productName, WxPayOrder record,String openId,String appId,Date currentDate) throws Exception { | |||||
| // 统一下单 普通商户模式 | |||||
| String noncestr = Utility.generate32UUID(); | |||||
| WxPayOrderP wxPayOrderP = new WxPayOrderP(); | |||||
| wxPayOrderP.setOpenid(openId); | |||||
| wxPayOrderP.setAppid(appId); | |||||
| wxPayOrderP.setMch_id(payAccount.getMchId()); | |||||
| wxPayOrderP.setNonce_str(noncestr); | |||||
| wxPayOrderP.setBody(productName); | |||||
| wxPayOrderP.setOut_trade_no(record.getPayOrderNo()); | |||||
| wxPayOrderP.setTotal_fee(composeOrder.getPayment()); | |||||
| wxPayOrderP.setSpbill_create_ip(record.getIp()); // 终端IP | |||||
| wxPayOrderP.setGoods_tag(productName); | |||||
| wxPayOrderP.setNotify_url(payAccount.getPayNotifyUrl()); | |||||
| wxPayOrderP.setTrade_type(WxPay.TradeType.JSAPI.name()); // 终端类型 | |||||
| wxPayOrderP.setProduct_id(String.valueOf(composeOrder.getMainOrderId())); // 订单ID | |||||
| wxPayOrderP.setTime_start(Utility.getDataFormatStringYYYYMMDDHHmmss(currentDate)); | |||||
| Date futureDate = new Date(); | |||||
| futureDate.setTime(currentDate.getTime() + 15 * 60 * 1000); | |||||
| wxPayOrderP.setTime_expire(Utility.getDataFormatStringYYYYMMDDHHmmss(futureDate)); // 15分钟后结束 | |||||
| Map<String, String> payOrderMap = BeanUtils.toStringMap(wxPayOrderP); | |||||
| wxPayOrderP.setSign(WxPayment.createSign(payOrderMap, payAccount.getApiKey())); | |||||
| return wxPayOrderP; | |||||
| } | |||||
| private PayAdapterResult getOrderPResult(Map<String, String> returnMap,WxPayOrder record,WxPayAccount payAccount,String noncestr) { | |||||
| PayAdapterResult par = new PayAdapterResult(); | |||||
| returnMap.put("payOrderId", String.valueOf(record.getId())); | |||||
| String result_code = returnMap.get("result_code"); | |||||
| if ("SUCCESS".equals(result_code)) { | |||||
| par.setSuccess(true); | |||||
| par.setMsg("success."); | |||||
| par.setData(returnMap); | |||||
| String prepay_id = returnMap.get("prepay_id"); | |||||
| // update payOrder with prepay_id | |||||
| record.setPrepayId(prepay_id); | |||||
| record.setUpdateTime(new Date()); | |||||
| record.setPayOrderStatus(EnumPayStatus.PAY_STATUS_SUCCESS.getCode()); | |||||
| String timestamp = String.valueOf(Utility.getCurrentTimeStamp()); | |||||
| Map<String, String> sighMap = MapUtil.getOrderMap(); | |||||
| sighMap.put("appId", returnMap.get("appid")); | |||||
| sighMap.put("timeStamp", timestamp); | |||||
| sighMap.put("nonceStr", noncestr); | |||||
| sighMap.put("package", "prepay_id=" + prepay_id); | |||||
| sighMap.put("signType", "MD5"); | |||||
| String signAgent = WxPayment.createSign(sighMap, payAccount.getApiKey()); | |||||
| returnMap.put("timeStamp", timestamp); | |||||
| returnMap.put("nonceStr", noncestr); | |||||
| returnMap.put("package", "prepay_id=" + prepay_id); | |||||
| returnMap.put("paySign", signAgent); | |||||
| log.info("back to UI: " + returnMap.toString()); | |||||
| } else { | |||||
| String errMsg = ""; | |||||
| JSONObject errObj = errorMap.getJSONObject(result_code); | |||||
| if (errObj != null) { | |||||
| errMsg = errObj.toJSONString(); | |||||
| record.setFailReason(errMsg); | |||||
| } else { | |||||
| errMsg = returnMap.get("return_msg"); | |||||
| record.setFailReason(errMsg); | |||||
| } | |||||
| record.setUpdateTime(new Date()); | |||||
| par.setSuccess(false); | |||||
| par.setMsg(errMsg); | |||||
| par.setData(returnMap); | |||||
| } | |||||
| return par; | |||||
| } | |||||
| private WxPayOrderSP generateWxPayOrderSP(WxPayAccount payAccount, WxComposeOrder composeOrder,String productName,WxPayOrder record,WxAppinfo appInfo,String openId,String appId,Date currentDate,EnumPayShare isShare) throws Exception { | |||||
| String noncestr = Utility.generate32UUID(); | |||||
| WxPayOrderSP wxPayOrderSP = new WxPayOrderSP(); | |||||
| wxPayOrderSP.setSub_openid(openId); | |||||
| wxPayOrderSP.setAppid(appInfo.getParentAppId()); | |||||
| wxPayOrderSP.setMch_id(payAccount.getMchId()); | |||||
| wxPayOrderSP.setSub_appid(appId); | |||||
| wxPayOrderSP.setSub_mch_id(payAccount.getSubMchId()); | |||||
| wxPayOrderSP.setNonce_str(noncestr); | |||||
| wxPayOrderSP.setBody(productName); | |||||
| wxPayOrderSP.setOut_trade_no(record.getPayOrderNo()); | |||||
| wxPayOrderSP.setTotal_fee(composeOrder.getPayment().toString()); | |||||
| wxPayOrderSP.setSpbill_create_ip(record.getIp()); // 终端IP | |||||
| wxPayOrderSP.setGoods_tag(productName); // 券ID | |||||
| wxPayOrderSP.setNotify_url(payAccount.getPayNotifyUrl()); | |||||
| wxPayOrderSP.setTrade_type(WxPay.TradeType.JSAPI.name()); // 终端类型 | |||||
| wxPayOrderSP.setProduct_id(String.valueOf(composeOrder.getMainOrderId())); // | |||||
| wxPayOrderSP.setTime_start(Utility.getDataFormatStringYYYYMMDDHHmmss(currentDate)); | |||||
| Date futureDate = new Date(); | |||||
| futureDate.setTime(currentDate.getTime() + 15 * 60 * 1000); | |||||
| wxPayOrderSP.setTime_expire(Utility.getDataFormatStringYYYYMMDDHHmmss(futureDate)); // 15分钟后结束 | |||||
| wxPayOrderSP.setSign_type("HMAC-SHA256"); | |||||
| wxPayOrderSP.setProfit_sharing(null); | |||||
| if (isShare == EnumPayShare.YES) { | |||||
| wxPayOrderSP.setProfit_sharing("Y"); | |||||
| } | |||||
| Map<String, String> payOrderMap = BeanUtils.toStringMap(wxPayOrderSP); | |||||
| wxPayOrderSP.setSign(WxPayment.createSignHMAC(payOrderMap, payAccount.getApiKey())); | |||||
| return wxPayOrderSP; | |||||
| } | |||||
| private PayAdapterResult getOrderSPResult(Map<String, String> returnMap,WxPayOrder record,WxPayAccount payAccount,WxAppinfo appInfo,String noncestr) { | |||||
| PayAdapterResult par = new PayAdapterResult(); | |||||
| returnMap.put("payOrderId", String.valueOf(record.getId())); | |||||
| String result_code = returnMap.get("result_code"); | |||||
| if ("SUCCESS".equals(result_code)) { | |||||
| par.setSuccess(true); | |||||
| par.setMsg("success."); | |||||
| par.setData(returnMap); | |||||
| String prepay_id = returnMap.get("prepay_id"); | |||||
| // update payOrder with prepay_id | |||||
| record.setPrepayId(prepay_id); | |||||
| record.setUpdateTime(new Date()); | |||||
| String timestamp = String.valueOf(Utility.getCurrentTimeStamp()); | |||||
| Map<String, String> sighMap = MapUtil.getOrderMap(); | |||||
| sighMap.put("appId", appInfo.getAppId()); | |||||
| sighMap.put("timeStamp", timestamp); | |||||
| sighMap.put("nonceStr", noncestr); | |||||
| sighMap.put("package", "prepay_id=" + prepay_id); | |||||
| sighMap.put("signType", "HMAC-SHA256"); | |||||
| String signAgent = WxPayment.createSignHMAC(sighMap, payAccount.getApiKey()); | |||||
| returnMap.put("timeStamp", timestamp); | |||||
| returnMap.put("nonceStr", noncestr); | |||||
| returnMap.put("package", "prepay_id=" + prepay_id); | |||||
| returnMap.put("paySign", signAgent); | |||||
| returnMap.put("signType", "HMAC-SHA256"); | |||||
| log.info("back to UI: " + returnMap.toString()); | |||||
| } else { | |||||
| String errMsg = ""; | |||||
| JSONObject errObj = errorMap.getJSONObject(result_code); | |||||
| if (errObj != null) { | |||||
| errMsg = errObj.toJSONString(); | |||||
| record.setFailReason(errMsg); | |||||
| } else { | |||||
| errMsg = returnMap.get("return_msg"); | |||||
| record.setFailReason(errMsg); | |||||
| } | |||||
| record.setUpdateTime(new Date()); | |||||
| par.setSuccess(false); | |||||
| par.setMsg(errMsg); | |||||
| par.setData(returnMap); | |||||
| } | |||||
| return par; | |||||
| } | |||||
| /** | |||||
| * https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_8_2.shtml | |||||
| */ | |||||
| @Override | |||||
| public PayAdapterResult pay(WxPayAccount payAccount, WxPayOrder record,WxComposeOrder composeOrder,String productName,EnumPayShare isShare,WxAppinfo appInfo,Date currentDate, PayExtraParam params) throws Exception { | |||||
| if (null == params ) { | |||||
| throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"openId为空"); | |||||
| } | |||||
| String openId = (String) params.getValue("openId"); | |||||
| if (StringUtils.isBlank(openId) ) { | |||||
| throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"openId为空"); | |||||
| } | |||||
| //普通商户模式 | |||||
| if (payAccount.getType() == EnumPayMode.MCH.getCode()) { | |||||
| WxPayOrderP wxPayOrderP = generateWxPayOrderP(payAccount,composeOrder,productName,record,openId,appInfo.getAppId(),currentDate); | |||||
| String response = WxPay.pushOrder(BeanUtils.toStringMap(wxPayOrderP)); | |||||
| log.info("pay order, wechat pushOrder, " + wxPayOrderP.toString() + ", response: " + response.toString()); | |||||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||||
| return getOrderPResult(returnMap,record,payAccount,wxPayOrderP.getNonce_str()); | |||||
| } else { | |||||
| // 统一下单 // 服务商模式 | |||||
| WxPayOrderSP wxPayOrderSP = generateWxPayOrderSP(payAccount,composeOrder,productName,record,appInfo,openId,appInfo.getAppId(),currentDate,isShare); | |||||
| String response = WxPay.pushOrder(BeanUtils.toStringMap(wxPayOrderSP)); | |||||
| log.info("pay order, wechat pushOrder, " + wxPayOrderSP.toString() + ", response: " + response.toString()); | |||||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||||
| return getOrderSPResult(returnMap,record,payAccount,appInfo,wxPayOrderSP.getNonce_str()); | |||||
| } | |||||
| } | |||||
| @Override | |||||
| public PayQueryAdapterResult queryPayStatus(WxPayOrder oldRecord, WxAppinfo appInfo, | |||||
| WxPayAccount payAccount) throws Exception { | |||||
| //return super.queryPayStatus(oldRecord,appInfo, payAccount); | |||||
| return null; | |||||
| } | |||||
| @Override | |||||
| public int queryPayStatus(PayQueryAdapterResult statusObject, String orderOutNo) throws Exception { | |||||
| //return super.queryPayStatus(statusObject, orderOutNo); | |||||
| return 0; | |||||
| } | |||||
| @Override | |||||
| public int queryPayStatusCode(WxPayOrder oldRecord, WxAppinfo appInfo, WxPayAccount payAccount) | |||||
| throws Exception { | |||||
| //return super.queryPayStatusCode(oldRecord, appInfo, payAccount); | |||||
| return 0; | |||||
| } | |||||
| @Override | |||||
| public PayAdapterResult payOrderClose(WxAppinfo appInfo, WxPayOrder record,WxPayAccount payAccount) throws Exception { | |||||
| //return super.closeOrder(appInfo, record, payAccount); | |||||
| return null; | |||||
| } | |||||
| @Override | |||||
| public PayAdapterResult payOrderReverse(WxAppinfo appInfo, WxPayOrder record, WxPayAccount payAccount) | |||||
| throws Exception { | |||||
| //return super.payOrderReverse(appInfo, record, payAccount); | |||||
| return null; | |||||
| } | |||||
| @Override | |||||
| public PayAdapterResult payOrderPush(String openId,WxAppinfo appInfo, WxBatchOrder batchOrder,WxPayOrder payOrder) throws Exception { | |||||
| return null; | |||||
| } | |||||
| @Override | |||||
| public File getQrcode(WxAppinfo appinfo,String pageUrl,int type,String sceneParam) throws Exception{ | |||||
| //return super.getQrCode(appinfo, pageUrl, type, sceneParam); | |||||
| return null; | |||||
| } | |||||
| @Override | |||||
| public PayAdapterResult noCreatePay(WxPayOrder record, WxComposeOrder composeOrder, List<WxOrder> childOrders) { | |||||
| throw new MallinkException(ErrorCode.SYS_PARAMETER_ERROR); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,275 @@ | |||||
| package com.iformall.service.pay.service.pay.wx.v3.miniApp.maPay; | |||||
| import java.io.File; | |||||
| import java.util.Date; | |||||
| import java.util.List; | |||||
| import java.util.Map; | |||||
| import com.iformall.domain.po.*; | |||||
| import org.apache.commons.lang3.StringUtils; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.stereotype.Service; | |||||
| import com.iformall.common.ErrorCode; | |||||
| import com.iformall.common.IdWorker; | |||||
| import com.iformall.domain.po.base.TenantEntity; | |||||
| import com.iformall.enums.EnumPayMode; | |||||
| import com.iformall.enums.EnumPayShare; | |||||
| import com.iformall.enums.EnumUserIsSubscribe; | |||||
| import com.iformall.exception.MallinkException; | |||||
| import com.iformall.mapper.WxCUserBasicInfoMapper; | |||||
| import com.iformall.mapper.WxCUserMapper; | |||||
| import com.iformall.mapper.WxMallMapper; | |||||
| import com.iformall.pay.WxMicroPayOrderP; | |||||
| import com.iformall.pay.WxMicroPayOrderSP; | |||||
| import com.iformall.pay.WxPay; | |||||
| import com.iformall.pay.WxPayment; | |||||
| import com.iformall.service.WxCUserService; | |||||
| import com.iformall.service.order.entity.WxComposeOrder; | |||||
| import com.iformall.service.pay.entity.PayExtraParam; | |||||
| import com.iformall.service.pay.service.pay.CPassivePayService; | |||||
| import com.iformall.service.pay.service.pay.entity.CreateUser; | |||||
| import com.iformall.service.pay.service.pay.entity.PayAdapterResult; | |||||
| import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult; | |||||
| import com.iformall.service.pay.service.pay.wx.v2.BaseWxPayAdapterService; | |||||
| import com.iformall.utils.BeanUtils; | |||||
| import com.iformall.utils.Utility; | |||||
| import lombok.extern.slf4j.Slf4j; | |||||
| import me.chanjar.weixin.common.error.WxErrorException; | |||||
| @Slf4j | |||||
| @Service | |||||
| public class WxMiniMaPayV3AdapterService implements CPassivePayService{ | |||||
| private WxMicroPayOrderP generateWxMicroPayOrderP(WxPayAccount payAccount, WxComposeOrder composeOrder, String productName,WxPayOrder record, EnumPayShare isShare, | |||||
| WxAppinfo appInfo, Date currentDate,String bAppId,String bUserPhone) throws Exception { | |||||
| String noncestr = Utility.generate32UUID(); | |||||
| WxMicroPayOrderP wxPayOrderP = new WxMicroPayOrderP(); | |||||
| wxPayOrderP.setAppid(bAppId); | |||||
| wxPayOrderP.setMch_id(payAccount.getMchId()); | |||||
| wxPayOrderP.setDevice_info(bUserPhone); | |||||
| wxPayOrderP.setNonce_str(noncestr); | |||||
| wxPayOrderP.setBody(productName); | |||||
| wxPayOrderP.setOut_trade_no(record.getPayOrderNo()); | |||||
| wxPayOrderP.setTotal_fee(record.getPayAmount()); | |||||
| wxPayOrderP.setSpbill_create_ip(record.getIp()); // 终端IP | |||||
| wxPayOrderP.setAuth_code(record.getAuthCode()); | |||||
| wxPayOrderP.setTime_start(Utility.getDataFormatStringYYYYMMDDHHmmss(currentDate)); | |||||
| Date futureDate = new Date(); | |||||
| futureDate.setTime(currentDate.getTime() + 15 * 60 * 1000); | |||||
| wxPayOrderP.setTime_expire(Utility.getDataFormatStringYYYYMMDDHHmmss(futureDate)); // 15分钟后结束 | |||||
| Map<String, String> payOrderMap = BeanUtils.toStringMap(wxPayOrderP); | |||||
| wxPayOrderP.setSign(WxPayment.createSign(payOrderMap, payAccount.getApiKey())); | |||||
| return wxPayOrderP; | |||||
| } | |||||
| private PayAdapterResult getWxMicroPayOrderPResult(Map<String, String> returnMap,WxPayOrder record,WxPayAccount payAccount) { | |||||
| String return_code = returnMap.get("return_code"); | |||||
| String result_code = returnMap.get("result_code"); | |||||
| PayAdapterResult pr = null; | |||||
| if ("SUCCESS".equalsIgnoreCase(return_code)) { | |||||
| if ("SUCCESS".equals(result_code)) { | |||||
| String openId = returnMap.get("openid"); | |||||
| String isSubscribe = returnMap.get("is_subscribe"); | |||||
| String transactionId = returnMap.get("transaction_id"); | |||||
| record.setTransactionId(transactionId); | |||||
| record.setUpdateTime(new Date()); | |||||
| pr = new PayAdapterResult(true, "success", returnMap,transactionId); | |||||
| } else { | |||||
| String err_code = returnMap.get("err_code"); | |||||
| String errMsg = returnMap.get("err_code_des"); | |||||
| if (errMsg.length() <= 0) { | |||||
| errMsg = returnMap.get("return_msg"); | |||||
| } | |||||
| record.setFailReason(errMsg); | |||||
| record.setUpdateTime(new Date()); | |||||
| pr = new PayAdapterResult(false, errMsg, returnMap,null); | |||||
| } | |||||
| } else { | |||||
| String errMsg = returnMap.get("return_msg"); | |||||
| record.setFailReason(errMsg); | |||||
| record.setUpdateTime(new Date()); | |||||
| pr = new PayAdapterResult(false, errMsg, returnMap,null); | |||||
| } | |||||
| return pr; | |||||
| } | |||||
| private WxMicroPayOrderSP generateWxMicroPayOrderSP(WxPayAccount payAccount, WxComposeOrder composeOrder, String productName,WxPayOrder record, EnumPayShare isShare, | |||||
| WxAppinfo appInfo, Date currentDate,String bUserPhone) throws Exception { | |||||
| String noncestr = Utility.generate32UUID(); | |||||
| WxMicroPayOrderSP wxPayOrderSP = new WxMicroPayOrderSP(); | |||||
| wxPayOrderSP.setAppid(appInfo.getParentAppId()); | |||||
| wxPayOrderSP.setMch_id(payAccount.getMchId()); | |||||
| wxPayOrderSP.setSub_appid(appInfo.getAppId()); | |||||
| wxPayOrderSP.setSub_mch_id(payAccount.getSubMchId()); | |||||
| wxPayOrderSP.setDevice_info(bUserPhone); | |||||
| wxPayOrderSP.setNonce_str(noncestr); | |||||
| wxPayOrderSP.setBody(productName); | |||||
| wxPayOrderSP.setOut_trade_no(record.getPayOrderNo()); | |||||
| wxPayOrderSP.setTotal_fee(record.getPayAmount()); | |||||
| wxPayOrderSP.setSpbill_create_ip(record.getIp()); | |||||
| wxPayOrderSP.setAuth_code(record.getAuthCode()); | |||||
| wxPayOrderSP.setTime_start(Utility.getDataFormatStringYYYYMMDDHHmmss(currentDate)); | |||||
| Date futureDate = new Date(); | |||||
| futureDate.setTime(currentDate.getTime() + 15 * 60 * 1000); | |||||
| wxPayOrderSP.setTime_expire(Utility.getDataFormatStringYYYYMMDDHHmmss(futureDate)); // 15分钟后结束 | |||||
| wxPayOrderSP.setSign_type("HMAC-SHA256"); | |||||
| wxPayOrderSP.setProfit_sharing(null); | |||||
| if (isShare == EnumPayShare.YES) { | |||||
| wxPayOrderSP.setProfit_sharing("Y"); | |||||
| } | |||||
| Map<String, String> payOrderMap = BeanUtils.toStringMap(wxPayOrderSP); | |||||
| wxPayOrderSP.setSign(WxPayment.createSignHMAC(payOrderMap, payAccount.getApiKey())); | |||||
| return wxPayOrderSP; | |||||
| } | |||||
| private PayAdapterResult getWxMicroPayOrderSPResutl(Map<String, String> returnMap,WxPayOrder record,WxPayAccount payAccount) { | |||||
| PayAdapterResult pr = null; | |||||
| String return_code = returnMap.get("return_code"); | |||||
| String result_code = returnMap.get("result_code"); | |||||
| if ("SUCCESS".equalsIgnoreCase(return_code)) { | |||||
| if ("SUCCESS".equals(result_code)) { | |||||
| String openId = returnMap.get("sub_openid"); | |||||
| String isSubscribe = returnMap.get("sub_is_subscribe"); | |||||
| String transactionId = returnMap.get("transaction_id"); | |||||
| record.setTransactionId(transactionId); | |||||
| record.setUpdateTime(new Date()); | |||||
| pr = new PayAdapterResult(true, "success", returnMap,transactionId); | |||||
| } else { | |||||
| String err_code = returnMap.get("err_code"); | |||||
| String errMsg = returnMap.get("err_code_des"); | |||||
| if (errMsg.length() <= 0) { | |||||
| errMsg = returnMap.get("return_msg"); | |||||
| } | |||||
| record.setFailReason(errMsg); | |||||
| record.setUpdateTime(new Date()); | |||||
| pr = new PayAdapterResult(false, errMsg, returnMap,null); | |||||
| } | |||||
| } else { | |||||
| String errMsg = returnMap.get("return_msg"); | |||||
| record.setFailReason(errMsg); | |||||
| record.setUpdateTime(new Date()); | |||||
| pr = new PayAdapterResult(false, errMsg, returnMap,null); | |||||
| } | |||||
| return pr; | |||||
| } | |||||
| @Override | |||||
| public PayAdapterResult pay(WxPayAccount payAccount, WxPayOrder record, WxComposeOrder composeOrder,String productName, EnumPayShare isShare, | |||||
| WxAppinfo appInfo, Date currentDate, PayExtraParam params) throws Exception { | |||||
| if (payAccount.getType() == EnumPayMode.MCH.getCode()) { | |||||
| // 扫码支付 普通商户模式 | |||||
| String bAppId = (String) params.getValue("bAppId"); | |||||
| if (StringUtils.isBlank(bAppId)) { | |||||
| throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"bAppId 不能为空"); | |||||
| } | |||||
| String bUserPhone = (String) params.getValue("bUserPhone"); | |||||
| if (StringUtils.isBlank(bUserPhone)) { | |||||
| throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"bUserPhone 不能为空"); | |||||
| } | |||||
| WxMicroPayOrderP wxPayOrderP = generateWxMicroPayOrderP(payAccount, composeOrder,productName,record, isShare, appInfo, currentDate, bAppId, bUserPhone); | |||||
| String response = WxPay.micropay(BeanUtils.toStringMap(wxPayOrderP)); | |||||
| log.info("pay order, wechat micropay, " + wxPayOrderP.toString() + ", response: " + response.toString()); | |||||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||||
| returnMap.put("payOrderId", record.getPayOrderNo()); | |||||
| returnMap.put("orderId", String.valueOf(composeOrder.getMainOrderId())); | |||||
| return getWxMicroPayOrderPResult(returnMap, record, payAccount); | |||||
| } else { | |||||
| // 统一下单 // 服务商模式 | |||||
| String bUserPhone = (String) params.getValue("bUserPhone"); | |||||
| if (StringUtils.isBlank(bUserPhone)) { | |||||
| throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"bUserPhone 不能为空"); | |||||
| } | |||||
| WxMicroPayOrderSP wxPayOrderSP = generateWxMicroPayOrderSP(payAccount, composeOrder,productName,record, isShare, appInfo, currentDate, bUserPhone); | |||||
| String response = WxPay.micropay(BeanUtils.toStringMap(wxPayOrderSP)); | |||||
| log.info("pay order, wechat micropay, " + wxPayOrderSP.toString() + ", response: " + response.toString()); | |||||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||||
| returnMap.put("payOrderId", record.getPayOrderNo()); | |||||
| returnMap.put("orderId", String.valueOf(composeOrder.getMainOrderId())); | |||||
| return getWxMicroPayOrderSPResutl(returnMap, record, payAccount); | |||||
| } | |||||
| } | |||||
| @Autowired | |||||
| WxCUserMapper wxCUserMapper; | |||||
| @Autowired | |||||
| WxCUserService wxCUserService; | |||||
| @Autowired | |||||
| WxCUserBasicInfoMapper wxCUserBasicInfoMapper; | |||||
| @Autowired | |||||
| WxMallMapper wxMallMapper; | |||||
| @Override | |||||
| public CreateUser getCUserAfterPay(Object result,WxAppinfo appInfo) throws Exception { | |||||
| // add c_user, 收银台支付和券支付可能不是同一个人 | |||||
| WxCUser userQ = new WxCUser(); | |||||
| Map<String, String> returnMap = (Map<String, String>) result; | |||||
| String openId = returnMap.get("sub_openid"); | |||||
| //String isSubscribe = returnMap.get("sub_is_subscribe"); | |||||
| userQ.setOpenId(openId); | |||||
| userQ.setAppId(appInfo.getAppId()); | |||||
| userQ.updateTenantInfo(appInfo); | |||||
| WxCUser user1 = wxCUserMapper.findByOpenId(userQ); | |||||
| if (user1 == null) { | |||||
| return null; | |||||
| }else { | |||||
| return new CreateUser(user1.getId(),user1.getUserId()); | |||||
| } | |||||
| } | |||||
| @Override | |||||
| public PayQueryAdapterResult queryPayStatus(WxPayOrder oldRecord, WxAppinfo appInfo, | |||||
| WxPayAccount payAccount) throws Exception { | |||||
| //return super.queryPayStatus(oldRecord,appInfo, payAccount); | |||||
| return null; | |||||
| } | |||||
| @Override | |||||
| public int queryPayStatus(PayQueryAdapterResult statusObject, String orderOutNo) throws Exception { | |||||
| //return super.queryPayStatus(statusObject, orderOutNo); | |||||
| return 0; | |||||
| } | |||||
| @Override | |||||
| public int queryPayStatusCode(WxPayOrder oldRecord, WxAppinfo appInfo, WxPayAccount payAccount) | |||||
| throws Exception { | |||||
| //return super.queryPayStatusCode(oldRecord, appInfo, payAccount); | |||||
| return 0; | |||||
| } | |||||
| @Override | |||||
| public PayAdapterResult payOrderClose(WxAppinfo appInfo, WxPayOrder record,WxPayAccount payAccount) throws Exception { | |||||
| //return super.closeOrder(appInfo, record, payAccount); | |||||
| return null; | |||||
| } | |||||
| @Override | |||||
| public PayAdapterResult payOrderReverse(WxAppinfo appInfo, WxPayOrder record, WxPayAccount payAccount) | |||||
| throws Exception { | |||||
| //return super.payOrderReverse(appInfo, record, payAccount); | |||||
| return null; | |||||
| } | |||||
| @Override | |||||
| public PayAdapterResult payOrderPush(String openId,WxAppinfo appInfo, WxBatchOrder batchOrder,WxPayOrder payOrder) throws Exception { | |||||
| return null; | |||||
| } | |||||
| @Override | |||||
| public File getQrcode(WxAppinfo appinfo,String pageUrl,int type,String sceneParam) throws Exception { | |||||
| //return super.getQrCode(appinfo, pageUrl, type, sceneParam); | |||||
| return null; | |||||
| } | |||||
| @Override | |||||
| public PayAdapterResult noCreatePay(WxPayOrder record, WxComposeOrder composeOrder, List<WxOrder> childOrders) { | |||||
| throw new MallinkException(ErrorCode.SYS_PARAMETER_ERROR); | |||||
| } | |||||
| } | |||||
| @@ -1,4 +1,4 @@ | |||||
| package com.iformall.service.pay.service.refund.wx; | |||||
| package com.iformall.service.pay.service.refund.wx.v2; | |||||
| import java.util.List; | import java.util.List; | ||||
| import java.util.Map; | import java.util.Map; | ||||
| @@ -0,0 +1,685 @@ | |||||
| package com.iformall.service.pay.service.refund.wx.v3; | |||||
| import java.util.List; | |||||
| import java.util.Map; | |||||
| import java.util.SortedMap; | |||||
| import java.util.TreeMap; | |||||
| import org.apache.commons.lang3.StringUtils; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.stereotype.Service; | |||||
| import com.alibaba.fastjson.JSON; | |||||
| import com.alibaba.fastjson.JSONObject; | |||||
| import com.iformall.common.ErrorCode; | |||||
| import com.iformall.common.Result; | |||||
| import com.iformall.common.ResultData; | |||||
| import com.iformall.domain.po.WxAppinfo; | |||||
| import com.iformall.domain.po.WxPayAccount; | |||||
| import com.iformall.domain.po.WxPayOrder; | |||||
| import com.iformall.domain.po.WxRefundOrder; | |||||
| import com.iformall.enums.EnumPayMode; | |||||
| import com.iformall.enums.EnumPayType; | |||||
| import com.iformall.enums.EnumPayWay; | |||||
| import com.iformall.enums.EnumRefundStatus; | |||||
| import com.iformall.exception.MallinkException; | |||||
| import com.iformall.mapper.WxAppinfoMapper; | |||||
| import com.iformall.mapper.WxPayAccountMapper; | |||||
| import com.iformall.mapper.WxPayOrderMapper; | |||||
| import com.iformall.mapper.WxRefundOrderMapper; | |||||
| import com.iformall.pay.WxPay; | |||||
| import com.iformall.pay.WxPayment; | |||||
| import com.iformall.pay.WxRefundOrderP; | |||||
| import com.iformall.pay.WxRefundOrderSP; | |||||
| import com.iformall.service.pay.service.refund.RefundPayAdapterService; | |||||
| import com.iformall.service.pay.service.refund.entity.RefundAdapterResult; | |||||
| import com.iformall.service.pay.service.refund.entity.RefundNotifyAdapterResult; | |||||
| import com.iformall.utils.BeanUtils; | |||||
| import com.iformall.utils.CipherUtil; | |||||
| import com.iformall.utils.Utility; | |||||
| import com.iformall.utils.XmlUtil; | |||||
| import lombok.extern.slf4j.Slf4j; | |||||
| @Slf4j | |||||
| @Service | |||||
| public class WxRefundV3AdapterService implements RefundPayAdapterService{ | |||||
| JSONObject errorRefundReqMap = JSON.parseObject("{\n" + | |||||
| " \"SYSTEMERROR\": {\n" + | |||||
| " \"detail\": \"接口返回错误\",\n" + | |||||
| " \"reason\": \"系统超时等\",\n" + | |||||
| " \"resolution\": \"请不要更换商户退款单号,请使用相同参数再次调用API。\"\n" + | |||||
| " },\n" + | |||||
| " \"BIZERR_NEED_RETRY\": {\n" + | |||||
| " \"detail\": \"退款业务流程错误,需要商户触发重试来解决\",\n" + | |||||
| " \"reason\": \"并发情况下,业务被拒绝,商户重试即可解决\",\n" + | |||||
| " \"resolution\": \"请不要更换商户退款单号,请使用相同参数再次调用API。\"\n" + | |||||
| " },\n" + | |||||
| " \"TRADE_OVERDUE\": {\n" + | |||||
| " \"detail\": \"订单已经超过退款期限\",\n" + | |||||
| " \"reason\": \"订单已经超过可退款的最大期限(支付后一年内可退款)\\t\",\n" + | |||||
| " \"resolution\": \"请选择其他方式自行退款\"\n" + | |||||
| " },\n" + | |||||
| " \"ERROR\": {\n" + | |||||
| " \"detail\": \"业务错误\",\n" + | |||||
| " \"reason\": \"申请退款业务发生错误\",\n" + | |||||
| " \"resolution\": \"该错误都会返回具体的错误原因,请根据实际返回做相应处理。\"\n" + | |||||
| " },\n" + | |||||
| " \"USER_ACCOUNT_ABNORMAL\": {\n" + | |||||
| " \"detail\": \"退款请求失败\",\n" + | |||||
| " \"reason\": \"用户帐号注销\",\n" + | |||||
| " \"resolution\": \"此状态代表退款申请失败,商户可自行处理退款。\"\n" + | |||||
| " },\n" + | |||||
| " \"INVALID_REQ_TOO_MUCH\": {\n" + | |||||
| " \"detail\": \"无效请求过多\",\n" + | |||||
| " \"reason\": \"连续错误请求数过多被系统短暂屏蔽\\t\",\n" + | |||||
| " \"resolution\": \"请检查业务是否正常,确认业务正常后请在1分钟后再来重试\"\n" + | |||||
| " },\n" + | |||||
| " \"NOTENOUGH\": {\n" + | |||||
| " \"detail\": \"余额不足\",\n" + | |||||
| " \"reason\": \"商户可用退款余额不足\",\n" + | |||||
| " \"resolution\": \"此状态代表退款申请失败,商户可根据具体的错误提示做相应的处理。\"\n" + | |||||
| " },\n" + | |||||
| " \"INVALID_TRANSACTIONID\": {\n" + | |||||
| " \"detail\": \"无效transaction_id\",\n" + | |||||
| " \"reason\": \"请求参数未按指引进行填写\",\n" + | |||||
| " \"resolution\": \"请求参数错误,检查原交易号是否存在或发起支付交易接口返回失败\"\n" + | |||||
| " },\n" + | |||||
| " \"PARAM_ERROR\": {\n" + | |||||
| " \"detail\": \"参数错误\",\n" + | |||||
| " \"reason\": \"请求参数未按指引进行填写\",\n" + | |||||
| " \"resolution\": \"请求参数错误,请重新检查再调用退款申请\"\n" + | |||||
| " },\n" + | |||||
| " \"APPID_NOT_EXIST\": {\n" + | |||||
| " \"detail\": \"APPID不存在\",\n" + | |||||
| " \"reason\": \"参数中缺少APPID\",\n" + | |||||
| " \"resolution\": \"请检查APPID是否正确\"\n" + | |||||
| " },\n" + | |||||
| " \"MCHID_NOT_EXIST\": {\n" + | |||||
| " \"detail\": \"MCHID不存在\",\n" + | |||||
| " \"reason\": \"参数中缺少MCHID\",\n" + | |||||
| " \"resolution\": \"请检查MCHID是否正确\"\n" + | |||||
| " },\n" + | |||||
| " \"REQUIRE_POST_METHOD\": {\n" + | |||||
| " \"detail\": \"请使用post方法\",\n" + | |||||
| " \"reason\": \"未使用post传递参数\",\n" + | |||||
| " \"resolution\": \"请检查请求参数是否通过post方法提交\"\n" + | |||||
| " },\n" + | |||||
| " \"SIGNERROR\": {\n" + | |||||
| " \"detail\": \"签名错误\",\n" + | |||||
| " \"reason\": \"参数签名结果不正确\",\n" + | |||||
| " \"resolution\": \"请检查签名参数和方法是否都符合签名算法要求\"\n" + | |||||
| " },\n" + | |||||
| " \"XML_FORMAT_ERROR\": {\n" + | |||||
| " \"detail\": \"XML格式错误\",\n" + | |||||
| " \"reason\": \"XML格式错误\",\n" + | |||||
| " \"resolution\": \"请检查XML参数格式是否正确\"\n" + | |||||
| " },\n" + | |||||
| " \"FREQUENCY_LIMITED\": {\n" + | |||||
| " \"detail\": \"频率限制\",\n" + | |||||
| " \"reason\": \"2个月之前的订单申请退款有频率限制\",\n" + | |||||
| " \"resolution\": \"该笔退款未受理,请降低频率后重试\"\n" + | |||||
| " }\n" + | |||||
| "}"); | |||||
| JSONObject errorRefundQueryMap = JSON.parseObject("{\n" + | |||||
| " \"SYSTEMERROR\": {\n" + | |||||
| " \"detail\": \"接口返回错误\",\n" + | |||||
| " \"reason\": \"系统超时等\",\n" + | |||||
| " \"resolution\": \"请不要更换商户退款单号,请使用相同参数再次调用API。\"\n" + | |||||
| " },\n" + | |||||
| " \"BIZERR_NEED_RETRY\": {\n" + | |||||
| " \"detail\": \"退款业务流程错误,需要商户触发重试来解决\",\n" + | |||||
| " \"reason\": \"并发情况下,业务被拒绝,商户重试即可解决\",\n" + | |||||
| " \"resolution\": \"请不要更换商户退款单号,请使用相同参数再次调用API。\"\n" + | |||||
| " },\n" + | |||||
| " \"TRADE_OVERDUE\": {\n" + | |||||
| " \"detail\": \"订单已经超过退款期限\",\n" + | |||||
| " \"reason\": \"订单已经超过可退款的最大期限(支付后一年内可退款)\\t\",\n" + | |||||
| " \"resolution\": \"请选择其他方式自行退款\"\n" + | |||||
| " },\n" + | |||||
| " \"ERROR\": {\n" + | |||||
| " \"detail\": \"业务错误\",\n" + | |||||
| " \"reason\": \"申请退款业务发生错误\",\n" + | |||||
| " \"resolution\": \"该错误都会返回具体的错误原因,请根据实际返回做相应处理。\"\n" + | |||||
| " },\n" + | |||||
| " \"USER_ACCOUNT_ABNORMAL\": {\n" + | |||||
| " \"detail\": \"退款请求失败\",\n" + | |||||
| " \"reason\": \"用户帐号注销\",\n" + | |||||
| " \"resolution\": \"此状态代表退款申请失败,商户可自行处理退款。\"\n" + | |||||
| " },\n" + | |||||
| " \"INVALID_REQ_TOO_MUCH\": {\n" + | |||||
| " \"detail\": \"无效请求过多\",\n" + | |||||
| " \"reason\": \"连续错误请求数过多被系统短暂屏蔽\\t\",\n" + | |||||
| " \"resolution\": \"请检查业务是否正常,确认业务正常后请在1分钟后再来重试\"\n" + | |||||
| " },\n" + | |||||
| " \"NOTENOUGH\": {\n" + | |||||
| " \"detail\": \"余额不足\",\n" + | |||||
| " \"reason\": \"商户可用退款余额不足\",\n" + | |||||
| " \"resolution\": \"此状态代表退款申请失败,商户可根据具体的错误提示做相应的处理。\"\n" + | |||||
| " },\n" + | |||||
| " \"INVALID_TRANSACTIONID\": {\n" + | |||||
| " \"detail\": \"无效transaction_id\",\n" + | |||||
| " \"reason\": \"请求参数未按指引进行填写\",\n" + | |||||
| " \"resolution\": \"请求参数错误,检查原交易号是否存在或发起支付交易接口返回失败\"\n" + | |||||
| " },\n" + | |||||
| " \"PARAM_ERROR\": {\n" + | |||||
| " \"detail\": \"参数错误\",\n" + | |||||
| " \"reason\": \"请求参数未按指引进行填写\",\n" + | |||||
| " \"resolution\": \"请求参数错误,请重新检查再调用退款申请\"\n" + | |||||
| " },\n" + | |||||
| " \"APPID_NOT_EXIST\": {\n" + | |||||
| " \"detail\": \"APPID不存在\",\n" + | |||||
| " \"reason\": \"参数中缺少APPID\",\n" + | |||||
| " \"resolution\": \"请检查APPID是否正确\"\n" + | |||||
| " },\n" + | |||||
| " \"MCHID_NOT_EXIST\": {\n" + | |||||
| " \"detail\": \"MCHID不存在\",\n" + | |||||
| " \"reason\": \"参数中缺少MCHID\",\n" + | |||||
| " \"resolution\": \"请检查MCHID是否正确\"\n" + | |||||
| " },\n" + | |||||
| " \"REQUIRE_POST_METHOD\": {\n" + | |||||
| " \"detail\": \"请使用post方法\",\n" + | |||||
| " \"reason\": \"未使用post传递参数\",\n" + | |||||
| " \"resolution\": \"请检查请求参数是否通过post方法提交\"\n" + | |||||
| " },\n" + | |||||
| " \"SIGNERROR\": {\n" + | |||||
| " \"detail\": \"签名错误\",\n" + | |||||
| " \"reason\": \"参数签名结果不正确\",\n" + | |||||
| " \"resolution\": \"请检查签名参数和方法是否都符合签名算法要求\"\n" + | |||||
| " },\n" + | |||||
| " \"XML_FORMAT_ERROR\": {\n" + | |||||
| " \"detail\": \"XML格式错误\",\n" + | |||||
| " \"reason\": \"XML格式错误\",\n" + | |||||
| " \"resolution\": \"请检查XML参数格式是否正确\"\n" + | |||||
| " },\n" + | |||||
| " \"FREQUENCY_LIMITED\": {\n" + | |||||
| " \"detail\": \"频率限制\",\n" + | |||||
| " \"reason\": \"2个月之前的订单申请退款有频率限制\",\n" + | |||||
| " \"resolution\": \"该笔退款未受理,请降低频率后重试\"\n" + | |||||
| " }\n" + | |||||
| "}"); | |||||
| private WxRefundOrderP generateWxRefundOrderP(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,EnumPayType payType) { | |||||
| String noncestr = Utility.generate32UUID(); | |||||
| WxRefundOrderP wxRefundOrderP = new WxRefundOrderP(); | |||||
| wxRefundOrderP.setAppid(appInfo.getAppId()); | |||||
| wxRefundOrderP.setMch_id(payAccount.getMchId()); | |||||
| wxRefundOrderP.setNonce_str(noncestr); | |||||
| // 微信内部订单号 | |||||
| if (record.getTransactionId() != null) | |||||
| wxRefundOrderP.setTransaction_id(record.getTransactionId()); | |||||
| // 支付订单号 | |||||
| wxRefundOrderP.setOut_trade_no(payOrder.getPayOrderNo()); | |||||
| // 退款支付订单号 | |||||
| wxRefundOrderP.setOut_refund_no(String.valueOf(record.getId())); | |||||
| wxRefundOrderP.setTotal_fee(record.getTotalFee()); | |||||
| wxRefundOrderP.setRefund_fee(record.getRefundFee()); | |||||
| if(null != payType) { | |||||
| if (payType == EnumPayType.PAY_B_REFUND) { | |||||
| wxRefundOrderP.setRefund_desc("B端商户退款"); | |||||
| } else if (payType == EnumPayType.PAY_ADMIN_REFUND) { | |||||
| wxRefundOrderP.setRefund_desc("管理端商户退款"); | |||||
| } else if (payType == EnumPayType.PAY_AUTO_REFUND) { | |||||
| wxRefundOrderP.setRefund_desc("超期自动退款"); | |||||
| } else { | |||||
| wxRefundOrderP.setRefund_desc("用户自己退款"); | |||||
| } | |||||
| } | |||||
| wxRefundOrderP.setNotify_url(payAccount.getRefundNotifyUrl()); | |||||
| return wxRefundOrderP; | |||||
| } | |||||
| private RefundAdapterResult getReusltFromp(String response,WxRefundOrder record,WxPayOrder payOrder) throws MallinkException{ | |||||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||||
| String result_no = returnMap.get("result_code"); | |||||
| String refund_id = returnMap.get("refund_id"); | |||||
| // 设置 微信退款订单号 | |||||
| record.setRefundId(refund_id); | |||||
| record.setRefundVendor(payOrder.getPayVendor()); | |||||
| if ("SUCCESS".equals(result_no)) { | |||||
| log.info("微信退款订单申请成功: " + returnMap.toString()); | |||||
| try { | |||||
| return new RefundAdapterResult(true,EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(),"退款订单申请成功",returnMap); | |||||
| } catch (Exception e) { | |||||
| log.error("微信退款订单更新入库出错: " + e.getMessage() + ", record: " + record.toString()); | |||||
| throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR); | |||||
| } | |||||
| } else { | |||||
| String errDesc = returnMap.get("err_code_des"); | |||||
| if (errDesc.equalsIgnoreCase("订单已全额退款")) { | |||||
| return new RefundAdapterResult(true,EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(),"退款订单申请成功",returnMap); | |||||
| } | |||||
| log.error("微信退款订单申请失败: " + response); | |||||
| String errMsg = ""; | |||||
| JSONObject errObj = errorRefundReqMap.getJSONObject(result_no); | |||||
| if (errObj != null) { | |||||
| errMsg = errObj.toJSONString(); | |||||
| record.setFailReason(errMsg); | |||||
| } else { | |||||
| errMsg = returnMap.get("return_msg"); | |||||
| record.setFailReason(errMsg); | |||||
| } | |||||
| if (errDesc.equalsIgnoreCase("超期订单不允许退款")) { | |||||
| // 更新券状态 | |||||
| throw new MallinkException(ErrorCode.REFUND_NOT_ALLOW); | |||||
| } | |||||
| return new RefundAdapterResult(false, EnumRefundStatus.REFUND_REQ_FAIL.getCode(), errMsg, returnMap); | |||||
| } | |||||
| } | |||||
| private WxRefundOrderSP generateWxRefundOrderSP(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,EnumPayType payType) { | |||||
| String noncestr = Utility.generate32UUID(); | |||||
| WxRefundOrderSP wxRefundOrderSP = new WxRefundOrderSP(); | |||||
| wxRefundOrderSP.setAppid(appInfo.getParentAppId()); | |||||
| wxRefundOrderSP.setSub_appid(appInfo.getAppId()); | |||||
| wxRefundOrderSP.setMch_id(payAccount.getMchId()); | |||||
| wxRefundOrderSP.setSub_mch_id(payAccount.getSubMchId()); | |||||
| wxRefundOrderSP.setNonce_str(noncestr); | |||||
| // 微信内部订单号 | |||||
| if (record.getTransactionId() != null) | |||||
| wxRefundOrderSP.setTransaction_id(record.getTransactionId()); | |||||
| // 支付订单号 | |||||
| wxRefundOrderSP.setOut_trade_no(payOrder.getPayOrderNo()); | |||||
| // 退款支付订单号 | |||||
| wxRefundOrderSP.setOut_refund_no(String.valueOf(record.getId())); | |||||
| wxRefundOrderSP.setTotal_fee(record.getTotalFee()); | |||||
| wxRefundOrderSP.setRefund_fee(record.getRefundFee()); | |||||
| if(null != payType) { | |||||
| if (payType == EnumPayType.PAY_B_REFUND) { | |||||
| wxRefundOrderSP.setRefund_desc("B端商户退款"); | |||||
| } else if (payType == EnumPayType.PAY_ADMIN_REFUND) { | |||||
| wxRefundOrderSP.setRefund_desc("管理端商户退款"); | |||||
| } else if (payType == EnumPayType.PAY_AUTO_REFUND) { | |||||
| wxRefundOrderSP.setRefund_desc("超期自动退款"); | |||||
| } else { | |||||
| wxRefundOrderSP.setRefund_desc("用户自己退款"); | |||||
| } | |||||
| } | |||||
| wxRefundOrderSP.setNotify_url(payAccount.getRefundNotifyUrl()); | |||||
| wxRefundOrderSP.setSign_type("HMAC-SHA256"); | |||||
| return wxRefundOrderSP; | |||||
| } | |||||
| private RefundAdapterResult getResultFromSp(String response,WxRefundOrder record,WxPayOrder payOrder) { | |||||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||||
| String result_no = returnMap.get("result_code"); | |||||
| String refund_id = returnMap.get("refund_id"); | |||||
| // 设置 微信退款订单号 | |||||
| record.setRefundId(refund_id); | |||||
| record.setRefundVendor(payOrder.getPayVendor()); | |||||
| if ("SUCCESS".equals(result_no)) { | |||||
| log.info("微信退款订单申请成功: " + returnMap.toString()); | |||||
| try { | |||||
| return new RefundAdapterResult(true, EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(), "退款订单申请成功", returnMap); | |||||
| } catch (Exception e) { | |||||
| log.error("微信退款订单更新入库出错: " + e.getMessage() + ", record: " + record.toString()); | |||||
| throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "订单状态更新失败"); | |||||
| } | |||||
| } else { | |||||
| // 特殊处理 | |||||
| String errDesc = returnMap.get("err_code_des"); | |||||
| if (errDesc.equalsIgnoreCase("订单已全额退款")) { | |||||
| return new RefundAdapterResult(true, EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(), "退款订单申请成功", returnMap); | |||||
| } | |||||
| log.error("微信退款订单申请失败: " + response); | |||||
| String errMsg = ""; | |||||
| JSONObject errObj = errorRefundReqMap.getJSONObject(result_no); | |||||
| if (errObj != null) { | |||||
| errMsg = errObj.toJSONString(); | |||||
| record.setFailReason(errMsg); | |||||
| } else { | |||||
| errMsg = returnMap.get("err_code_des"); | |||||
| record.setFailReason(errMsg); | |||||
| } | |||||
| if (errDesc.equalsIgnoreCase("超期订单不允许退款")) { | |||||
| // 更新券状态 | |||||
| throw new MallinkException(ErrorCode.REFUND_NOT_ALLOW); | |||||
| } | |||||
| return new RefundAdapterResult(false,EnumRefundStatus.REFUND_REQ_FAIL.getCode(),errMsg,returnMap); | |||||
| } | |||||
| } | |||||
| @Override | |||||
| public RefundAdapterResult refund(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,EnumPayType payType) { | |||||
| if (StringUtils.isBlank(payAccount.getApiKey())) { | |||||
| log.error("支付密钥为空"); | |||||
| throw new MallinkException(ErrorCode.API_KEY_NOT_FOUND.getCode(), "支付密钥为空,请联系商城管理员"); | |||||
| } | |||||
| if (StringUtils.isBlank(payAccount.getCertPath())) { | |||||
| log.error("证书路径为空"); | |||||
| throw new MallinkException(ErrorCode.CERT_PATH_NOT_FOUND.getCode(), "证书路径为空,请联系商城管理员"); | |||||
| } | |||||
| if (!Utility.isFileExist(payAccount.getCertPath())) { | |||||
| log.error("证书文件不存在"); | |||||
| throw new MallinkException(ErrorCode.CERT_PATH_NOT_FOUND.getCode(), "证书文件不存在,请联系商城管理员"); | |||||
| } | |||||
| // 实际支付 | |||||
| // 向微信提交退款申请 | |||||
| if (payAccount.getType() == EnumPayMode.MCH.getCode()) { | |||||
| // 普通商户模式 | |||||
| WxRefundOrderP wxRefundOrderP = generateWxRefundOrderP(payAccount, appInfo, record, payOrder, payType); | |||||
| Map signMap = null; | |||||
| try { | |||||
| signMap = BeanUtils.toStringMap(wxRefundOrderP); | |||||
| } catch (Exception e) { | |||||
| log.error("退款命令生辰: " + e.getMessage()); | |||||
| throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "退款签名异常"); | |||||
| } | |||||
| String signAgent = WxPayment.createSign(signMap, payAccount.getApiKey()); | |||||
| signMap.put("sign", signAgent); | |||||
| String response = null; | |||||
| try { | |||||
| response = WxPay.orderRefund(signMap, payAccount.getCertPath(), payAccount.getMchId()); | |||||
| } catch (Exception e) { | |||||
| log.error("退款异常: " + e.getMessage()); | |||||
| throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "退款异常"); | |||||
| } | |||||
| log.info("微信退款订单:" + wxRefundOrderP.toString() + ", response: " + response.toString()); | |||||
| return getReusltFromp(response, record, payOrder); | |||||
| } else { | |||||
| // 服务商模式 | |||||
| WxRefundOrderSP wxRefundOrderSP = generateWxRefundOrderSP(payAccount, appInfo, record, payOrder, payType); | |||||
| Map signMap = null; | |||||
| try { | |||||
| signMap = BeanUtils.toStringMap(wxRefundOrderSP); | |||||
| } catch (Exception e) { | |||||
| log.error("退款命令生成: " + e.getMessage()); | |||||
| throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "退款签名异常"); | |||||
| } | |||||
| String signAgent = WxPayment.createSignHMAC(signMap, payAccount.getApiKey()); | |||||
| signMap.put("sign", signAgent); | |||||
| String response = null; | |||||
| try { | |||||
| response = WxPay.orderRefund(signMap, payAccount.getCertPath(), payAccount.getMchId()); | |||||
| } catch (Exception e) { | |||||
| log.error("退款异常: " + e.getMessage()); | |||||
| throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "退款异常"); | |||||
| } | |||||
| log.info("微信退款订单:" + wxRefundOrderSP.toString() + ", response: " + response.toString()); | |||||
| return getResultFromSp(response, record, payOrder); | |||||
| } | |||||
| } | |||||
| @Override | |||||
| public RefundAdapterResult queryRefund(WxAppinfo appInfo,WxPayAccount payAccount, WxRefundOrder record) { | |||||
| if (payAccount.getType() == EnumPayMode.MCH.getCode()) { | |||||
| Map<String, String> paramMap = WxPayment.buildWeappRefundQueryMap( | |||||
| appInfo.getAppId(), payAccount.getMchId(), | |||||
| record.getTransactionId(), record.getPayOrderNo(), String.valueOf(record.getId()), | |||||
| record.getRefundId(), payAccount.getApiKey()); | |||||
| String response = WxPay.orderRefundQuery(paramMap); | |||||
| log.info("微信退款订单:" + record.toString() + ", response: " + response.toString()); | |||||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||||
| String return_code = returnMap.get("return_code"); | |||||
| if("SUCCESS".equals(return_code)){ | |||||
| String result_code = returnMap.get("result_code"); | |||||
| if("SUCCESS".equals(result_code)){ | |||||
| String refund_status_0 = returnMap.get("refund_status_0"); | |||||
| if("SUCCESS".equals(refund_status_0)){ | |||||
| return new RefundAdapterResult(true,EnumRefundStatus.REFUND_SUCCESS.getCode(),"退款成功",returnMap); | |||||
| }else if("REFUNDCLOSE".equals(refund_status_0)){ | |||||
| return new RefundAdapterResult(true,EnumRefundStatus.REFUND_FAIL.getCode(),"退款关闭,指商户发起退款失败的情况",returnMap); | |||||
| }else if("PROCESSING".equals(refund_status_0)){ | |||||
| return new RefundAdapterResult(true,EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(),"退款中",returnMap); | |||||
| }else if("CHANGE".equals(refund_status_0)){ | |||||
| return new RefundAdapterResult(true,EnumRefundStatus.REFUND_FAIL.getCode(), | |||||
| "退款异常,退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败。",returnMap); | |||||
| }else{ | |||||
| throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(),"查询状态异常 非法状态"); | |||||
| } | |||||
| }else{ | |||||
| throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(),"查询状态异常 "+returnMap.get("err_code_des")); | |||||
| } | |||||
| }else{ | |||||
| throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(),"查询状态异常 "+returnMap.get("return_msg")); | |||||
| } | |||||
| // String result_no = returnMap.get("result_code"); | |||||
| // if ("SUCCESS".equals(result_no)) { | |||||
| // String refund_id = returnMap.get("refund_id"); | |||||
| // return new RefundAdapterResult(true,0,"退款",returnMap); | |||||
| // } else { | |||||
| // String errMsg = ""; | |||||
| // JSONObject errObj = errorRefundReqMap.getJSONObject(result_no); | |||||
| // if (errObj != null) { | |||||
| // errMsg = errObj.toJSONString(); | |||||
| // } else { | |||||
| // errMsg = returnMap.get("return_msg"); | |||||
| // } | |||||
| // return new RefundAdapterResult(false,ErrorCode.REFUND_ORDER_ERROR.getCode(),errMsg,returnMap); | |||||
| // } | |||||
| } else { | |||||
| Map<String, String> paramMap = WxPayment.buildSWeappRefundQueryMap( | |||||
| appInfo.getParentAppId(), appInfo.getAppId(), payAccount.getMchId(), payAccount.getSubMchId(), | |||||
| record.getTransactionId(), record.getPayOrderNo(), String.valueOf(record.getId()), record.getRefundId(), payAccount.getApiKey()); | |||||
| String response = WxPay.orderRefundQuery(paramMap); | |||||
| log.info("微信退款订单:" + record.toString() + ", response: " + response.toString()); | |||||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||||
| String return_code = returnMap.get("return_code"); | |||||
| if("SUCCESS".equals(return_code)){ | |||||
| String result_code = returnMap.get("result_code"); | |||||
| if("SUCCESS".equals(result_code)){ | |||||
| String refund_status_0 = returnMap.get("refund_status_0"); | |||||
| if("SUCCESS".equals(refund_status_0)){ | |||||
| return new RefundAdapterResult(true,EnumRefundStatus.REFUND_SUCCESS.getCode(),"退款成功",returnMap); | |||||
| }else if("REFUNDCLOSE".equals(refund_status_0)){ | |||||
| return new RefundAdapterResult(true,EnumRefundStatus.REFUND_FAIL.getCode(),"退款关闭,指商户发起退款失败的情况",returnMap); | |||||
| }else if("PROCESSING".equals(refund_status_0)){ | |||||
| return new RefundAdapterResult(true,EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(),"退款中",returnMap); | |||||
| }else if("CHANGE".equals(refund_status_0)){ | |||||
| return new RefundAdapterResult(true,EnumRefundStatus.REFUND_FAIL.getCode(),"退款异常",returnMap); | |||||
| }else{ | |||||
| throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(),"查询状态异常 非法状态"); | |||||
| } | |||||
| }else{ | |||||
| throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(),"查询状态异常 "+returnMap.get("err_code_des")); | |||||
| } | |||||
| }else{ | |||||
| throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(),"查询状态异常 "+returnMap.get("return_msg")); | |||||
| } | |||||
| // String result_no = returnMap.get("result_code"); | |||||
| // if ("SUCCESS".equals(result_no)) { | |||||
| // String refund_id = returnMap.get("refund_id"); | |||||
| // return new RefundAdapterResult(true,0,"退款",returnMap); | |||||
| // } else { | |||||
| // String errMsg = ""; | |||||
| // JSONObject errObj = errorRefundQueryMap.getJSONObject(result_no); | |||||
| // if (errObj != null) { | |||||
| // errMsg = errObj.toJSONString(); | |||||
| // } else { | |||||
| // errMsg = returnMap.get("return_msg"); | |||||
| // } | |||||
| // return new RefundAdapterResult(false,ErrorCode.REFUND_ORDER_ERROR.getCode(),errMsg,returnMap); | |||||
| // } | |||||
| } | |||||
| } | |||||
| @Autowired | |||||
| WxAppinfoMapper wxAppinfoMapper; | |||||
| @Autowired | |||||
| WxPayAccountMapper wxPayAccountMapper; | |||||
| @Autowired | |||||
| WxPayOrderMapper wxPayOrderMapper; | |||||
| @Autowired | |||||
| WxRefundOrderMapper wxRefundOrderMapper; | |||||
| private RefundNotifyAdapterResult notifyErrorResult(String msg) { | |||||
| SortedMap resultMap = new TreeMap(); | |||||
| resultMap.put("return_code", "FAIL"); | |||||
| resultMap.put("return_msg", msg); | |||||
| return new RefundNotifyAdapterResult(false,ErrorCode.REFUND_ORDER_ERROR.getCode(),msg,XmlUtil.getRequestXml(resultMap)); | |||||
| } | |||||
| private RefundNotifyAdapterResult notifySuccessResult(String transactionId,String refundId,WxRefundOrder refundOrder) { | |||||
| SortedMap resultMap = new TreeMap(); | |||||
| resultMap.put("return_code", "SUCCESS"); | |||||
| resultMap.put("return_msg", "OK"); | |||||
| return new RefundNotifyAdapterResult(transactionId, refundId,refundOrder,XmlUtil.getRequestXml(resultMap)); | |||||
| } | |||||
| @Override | |||||
| public RefundNotifyAdapterResult notify(Map<String, String> paramMap, EnumPayWay payWay) { | |||||
| // how to get wechatAppId, wechatMchId, partnerKey | |||||
| String appId = paramMap.get("appid"); | |||||
| String subAppId = paramMap.get("sub_appid"); | |||||
| String mchId = paramMap.get("mch_id"); | |||||
| String subMchId = paramMap.get("sub_mch_id"); | |||||
| if (StringUtils.isBlank(subAppId) && StringUtils.isBlank(subMchId)) { | |||||
| // 普通商户号 | |||||
| WxAppinfo appinfo = wxAppinfoMapper.findByAppId(appId); | |||||
| if (appinfo == null) { | |||||
| log.error("未找到appid信息:" + appId); | |||||
| throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND); | |||||
| } | |||||
| WxPayAccount payAccount = wxPayAccountMapper.selectById(appinfo.getPayId()); | |||||
| if (payAccount == null) { | |||||
| log.error("未找到mch_id信息:" + mchId); | |||||
| throw new MallinkException(ErrorCode.MCH_INFO_NOT_FOUND); | |||||
| } | |||||
| if (!mchId.equalsIgnoreCase(payAccount.getMchId())) { | |||||
| log.error("mch_id不对应:" + mchId + ",account:" + payAccount.getMchId()); | |||||
| throw new MallinkException(ErrorCode.MCH_INFO_NOT_EQUAL); | |||||
| } | |||||
| String partnerKey = payAccount.getApiKey(); | |||||
| try { | |||||
| if (payWay.getType() == EnumPayWay.EnumPayWayType.WX_MINIPAY) { | |||||
| if (!"SUCCESS".equals(paramMap.get("return_code"))) { | |||||
| log.warn("notify refund, wxpay status not success, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||||
| return notifyErrorResult("订单状态码非SUCCESS"); | |||||
| } | |||||
| // 解密req_info | |||||
| String req_info = CipherUtil.decryptReqInfo(paramMap.get("req_info"), partnerKey); | |||||
| Map<String, String> reqMap = WxPayment.xmlToMap(req_info); | |||||
| String payOrderNo = reqMap.get("out_trade_no"); | |||||
| Long payOrderId = Long.valueOf(payOrderNo); | |||||
| WxPayOrder payOrder = wxPayOrderMapper.selectById(payOrderId,payAccount.getTenantId()); | |||||
| if (payOrder == null) { | |||||
| log.warn("notify refund, wxpay check pay order not exists, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||||
| return notifyErrorResult("支付订单不存在"); | |||||
| } | |||||
| // 验证支付金额 | |||||
| if (!reqMap.get("total_fee").equals(payOrder.getPayAmount().toString())) { | |||||
| log.warn("notify refund, wxpay check total_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||||
| return notifyErrorResult("支付订单总金额不一致"); | |||||
| } | |||||
| String refundIdStr = reqMap.get("out_refund_no"); | |||||
| Long refundOrderId = Long.valueOf(refundIdStr); | |||||
| WxRefundOrder refundOrder = wxRefundOrderMapper.selectById(refundOrderId); | |||||
| if (refundOrder == null) { | |||||
| log.warn("notify refund, wxpay check pay order not exists, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||||
| return notifyErrorResult("退款订单不存在"); | |||||
| } | |||||
| // 验证支付金额 | |||||
| if (!reqMap.get("total_fee").equals(refundOrder.getTotalFee().toString())) { | |||||
| log.warn("notify refund, wxpay check total_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||||
| return notifyErrorResult("订单总金额不一致"); | |||||
| } | |||||
| // 验证退款金额 | |||||
| if (!reqMap.get("refund_fee").equals(refundOrder.getRefundFee().toString())) { | |||||
| log.warn("notify refund, wxpay check refund_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||||
| return notifyErrorResult("退款总金额不一致"); | |||||
| } | |||||
| // 处理支付成功 | |||||
| //handleRefundSuccess(refundOrder, reqMap.get("transaction_id"), reqMap.get("refund_id")); | |||||
| log.info("notify refund, wxpay checksign success, paramMap:{}, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||||
| return notifySuccessResult(reqMap.get("transaction_id"), reqMap.get("refund_id"), refundOrder); | |||||
| } | |||||
| } catch (RuntimeException e) { | |||||
| log.warn("notify refund paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString() + ", e:" + e.getMessage()); | |||||
| throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), e.getMessage()); | |||||
| } catch (Exception e) { | |||||
| log.warn("notify refund, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString() + ", e:" + e.getMessage()); | |||||
| throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), e.getMessage()); | |||||
| } | |||||
| } else { | |||||
| // 服务号回调 | |||||
| WxAppinfo appinfo = wxAppinfoMapper.findByAppId(subAppId); | |||||
| if (appinfo == null) { | |||||
| log.error("未找到appid信息:" + appId); | |||||
| throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND); | |||||
| } | |||||
| WxPayAccount payAccount = wxPayAccountMapper.selectById(appinfo.getPayId()); | |||||
| if (payAccount == null) { | |||||
| log.error("未找到mch_id信息:" + mchId); | |||||
| throw new MallinkException(ErrorCode.MCH_INFO_NOT_FOUND); | |||||
| } | |||||
| if (!mchId.equalsIgnoreCase(payAccount.getMchId())) { | |||||
| log.error("mch_id不对应:" + mchId + ",account:" + payAccount.getMchId()); | |||||
| throw new MallinkException(ErrorCode.MCH_INFO_NOT_EQUAL); | |||||
| } | |||||
| String partnerKey = payAccount.getApiKey(); | |||||
| try { | |||||
| if (payWay.getType() == EnumPayWay.EnumPayWayType.WX_MINIPAY) { | |||||
| if (!"SUCCESS".equals(paramMap.get("return_code"))) { | |||||
| log.warn("notify order, wxpay status not success, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||||
| return notifyErrorResult("订单状态码非SUCCESS"); | |||||
| } | |||||
| // 解密req_info | |||||
| String req_info = CipherUtil.decryptReqInfo(paramMap.get("req_info"), partnerKey); | |||||
| log.info(req_info); | |||||
| Map<String, String> reqMap = WxPayment.xmlToMap(req_info); | |||||
| String payOrderNo = reqMap.get("out_trade_no"); | |||||
| if (payOrderNo == null) { | |||||
| return notifySuccessResult(reqMap.get("transaction_id"), reqMap.get("refund_id"), null); | |||||
| } | |||||
| Long payOrderId = Long.valueOf(payOrderNo); | |||||
| WxPayOrder payOrder = wxPayOrderMapper.selectById(payOrderId,payAccount.getTenantId()); | |||||
| if (payOrder == null) { | |||||
| log.warn("notify refund, wxpay check pay order not exists, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||||
| return notifyErrorResult("支付订单不存在"); | |||||
| } | |||||
| // 验证支付金额 | |||||
| if (!reqMap.get("total_fee").equals(payOrder.getPayAmount().toString())) { | |||||
| log.warn("notify refund, wxpay check total_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||||
| return notifyErrorResult("支付订单总金额不一致"); | |||||
| } | |||||
| String refundIdStr = reqMap.get("out_refund_no"); | |||||
| Long refundOrderId = Long.valueOf(refundIdStr); | |||||
| WxRefundOrder refundOrder = wxRefundOrderMapper.selectById(refundOrderId); | |||||
| if (refundOrder == null) { | |||||
| log.warn("notify refund, wxpay check pay order not exists, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||||
| return notifyErrorResult("退款订单不存在"); | |||||
| } | |||||
| // 验证支付金额 | |||||
| if (!reqMap.get("total_fee").equals(refundOrder.getTotalFee().toString())) { | |||||
| log.warn("notify refund, wxpay check total_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||||
| return notifyErrorResult("订单总金额不一致"); | |||||
| } | |||||
| // 验证退款金额 | |||||
| if (!reqMap.get("refund_fee").equals(refundOrder.getRefundFee().toString())) { | |||||
| log.warn("notify refund, wxpay check refund_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||||
| return notifyErrorResult("退款总金额不一致"); | |||||
| } | |||||
| log.info("notify refund, wxpay checksign success, paramMap:{}, paramMap: " + reqMap.toString() + ", payWay:" + payWay.toString()); | |||||
| return notifySuccessResult(reqMap.get("transaction_id"), reqMap.get("refund_id"), refundOrder); | |||||
| } | |||||
| } catch (RuntimeException e) { | |||||
| log.warn("notify refund, wepay checksign error, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString() + ", e:" + e.getMessage()); | |||||
| throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR); | |||||
| } catch (Exception e) { | |||||
| log.warn("notify refund, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString() + ", e:" + e.getMessage()); | |||||
| throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), e.getMessage()); | |||||
| } | |||||
| } | |||||
| return notifyErrorResult("FAILED"); | |||||
| } | |||||
| } | |||||
| @@ -1,4 +1,4 @@ | |||||
| package com.iformall.service.pay.service.share.wx; | |||||
| package com.iformall.service.pay.service.share.wx.v2; | |||||
| import java.text.ParseException; | import java.text.ParseException; | ||||
| import java.util.*; | import java.util.*; | ||||
| @@ -0,0 +1,602 @@ | |||||
| package com.iformall.service.pay.service.share.wx.v3; | |||||
| import java.text.ParseException; | |||||
| import java.util.*; | |||||
| import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | |||||
| import com.iformall.common.IdWorker; | |||||
| import com.iformall.domain.dto.WxSharingOrderDto; | |||||
| import com.iformall.domain.po.*; | |||||
| import com.iformall.domain.po.base.TenantEntity; | |||||
| import com.iformall.douyin.pay.enums.MerchantImportStatus; | |||||
| import com.iformall.enums.*; | |||||
| import com.iformall.mapper.*; | |||||
| import com.iformall.service.pay.service.pay.douyin.miniApp.EnumTtPayChannel; | |||||
| import net.sf.saxon.trans.Err; | |||||
| import org.apache.commons.lang3.StringUtils; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.stereotype.Service; | |||||
| import com.alibaba.fastjson.JSON; | |||||
| import com.alibaba.fastjson.JSONArray; | |||||
| import com.alibaba.fastjson.JSONObject; | |||||
| import com.iformall.common.ErrorCode; | |||||
| import com.iformall.common.ResultData; | |||||
| import com.iformall.exception.MallinkException; | |||||
| import com.iformall.pay.WxPayment; | |||||
| import com.iformall.pay.WxProfitSharing; | |||||
| import com.iformall.pay.WxProfitSharingFinishP; | |||||
| import com.iformall.pay.WxProfitSharingP; | |||||
| import com.iformall.pay.WxProfitSharingQueryP; | |||||
| import com.iformall.pay.WxProfitSharingReceiverP; | |||||
| import com.iformall.service.order.util.OrderHelper; | |||||
| import com.iformall.service.pay.service.share.PayShareAdapterService; | |||||
| import com.iformall.service.pay.service.share.PayShareBaseAdapterService; | |||||
| import com.iformall.service.pay.service.share.entity.ShareAccountResult; | |||||
| import com.iformall.service.pay.service.share.entity.PayShareCalculateAmount; | |||||
| import com.iformall.service.pay.service.share.entity.PayShareQueryResult; | |||||
| import com.iformall.service.pay.service.share.entity.PayShareResult; | |||||
| import com.iformall.service.pay.service.share.entity.ShareNotifyAdapterResult; | |||||
| import com.iformall.utils.BeanUtils; | |||||
| import com.iformall.utils.Utility; | |||||
| import com.iformall.utils.XmlUtil; | |||||
| import lombok.extern.slf4j.Slf4j; | |||||
| @Slf4j | |||||
| @Service | |||||
| public class WxPayShareV3Service extends PayShareBaseAdapterService{ | |||||
| @Autowired | |||||
| WxProfitSharingOrderMapper wxProfitSharingOrderMapper; | |||||
| final JSONObject statusMap = JSON.parseObject( | |||||
| "{\"ACCEPTED\":3," + | |||||
| "\"PROCESSING\": 4," + | |||||
| "\"FINISHED\": 5," + | |||||
| "\"CLOSED\": 6}"); | |||||
| @Override | |||||
| public Integer getSubsidyType() { | |||||
| return EnumMerchantSubsidyType.WECHAT.getCode(); | |||||
| } | |||||
| @Override | |||||
| public Integer getProfitSharingType() { | |||||
| return EnumProfitSharingType.PROFIT_SHARING_TYPE_WECHAT.getCode(); | |||||
| } | |||||
| @Override | |||||
| public Integer getSharingOrderInitialStatus() { | |||||
| return EnumProfitSharingOrderStatus.PROFIT_SHARING_READY.getCode(); | |||||
| } | |||||
| @Override | |||||
| public PayShareCalculateAmount calculateAmount(Integer payAmount,Integer officialCommissionRate, WxPayAccount payAccount) { | |||||
| int mallCharge = OrderHelper.getMallCharge(payAmount, payAccount); | |||||
| Integer realRateAmount = OrderHelper.getRealRateAmount(payAmount, payAccount); | |||||
| return new PayShareCalculateAmount(payAmount,mallCharge,realRateAmount,0); | |||||
| } | |||||
| @Override | |||||
| public PayShareResult noReciverShare(WxAppinfo appInfo,WxPayAccount payAccount,WxProfitSharingOrder record,String transcationId,Integer amount) { | |||||
| WxProfitSharingFinishP psFCmd = new WxProfitSharingFinishP(); | |||||
| psFCmd.setMch_id(payAccount.getMchId()); | |||||
| psFCmd.setSub_mch_id(payAccount.getSubMchId()); | |||||
| psFCmd.setAppid(appInfo.getParentAppId()); | |||||
| psFCmd.setNonce_str(Utility.generate32UUID()); | |||||
| psFCmd.setTransaction_id(transcationId); | |||||
| psFCmd.setOut_order_no(record.getId().toString()); | |||||
| //psFCmd.setAmount(amount); | |||||
| psFCmd.setDescription("分账已完结"); | |||||
| psFCmd.setSign_type("HMAC-SHA256"); | |||||
| String response; | |||||
| try { | |||||
| psFCmd.setSign(WxPayment.createSignHMAC(BeanUtils.toStringMap(psFCmd), payAccount.getApiKey())); | |||||
| log.info("request:" + psFCmd.toString()); | |||||
| response = WxProfitSharing.finishOrder(BeanUtils.toStringMap(psFCmd), payAccount.getCertPath(), payAccount.getMchId()); | |||||
| } catch (Exception e) { | |||||
| log.error("wx noreciver share error:",e); | |||||
| return new PayShareResult(false, EnumProfitSharingOrderStatus.PROFIT_SHARING_REQ_FAILED.getCode(),ErrorCode.PROFIT_SHARING_REQUEST_FAILED.getMessage()+":"+e.getMessage(), null,null); | |||||
| } | |||||
| log.info("response: " + response); | |||||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||||
| String return_code = returnMap.get("return_code"); | |||||
| if (!"SUCCESS".equals(return_code)) { | |||||
| return new PayShareResult(false, EnumProfitSharingOrderStatus.PROFIT_SHARING_REQ_FAILED.getCode(),returnMap.get("return_msg"), null,null); | |||||
| } | |||||
| if (!WxPayment.verifyNotifyHMAC(returnMap,payAccount.getApiKey())){ | |||||
| return new PayShareResult(false, EnumProfitSharingOrderStatus.PROFIT_SHARING_REQ_FAILED.getCode(),ErrorCode.PROFIT_SHARING_RETURN_INVALID.getMessage(), null,null); | |||||
| } | |||||
| String result_code = returnMap.get("result_code"); | |||||
| if (!"SUCCESS".equals(result_code)) { | |||||
| return new PayShareResult(false, EnumProfitSharingOrderStatus.PROFIT_SHARING_APPLY_FAILED.getCode(),returnMap.get("err_code_des"), null,null); | |||||
| } | |||||
| return new PayShareResult(true, null,"success", returnMap,returnMap.get("order_id")); | |||||
| } | |||||
| @Override | |||||
| public PayShareResult haveReciversShare(WxAppinfo appInfo,WxPayAccount payAccount,WxProfitSharingOrder record,String transcationId,JSONArray receivers,EnumProfitSharingOrderType shareType ) throws MallinkException { | |||||
| //分账提交 | |||||
| WxProfitSharingP psCmd = new WxProfitSharingP(); | |||||
| psCmd.setMch_id(payAccount.getMchId()); | |||||
| psCmd.setSub_mch_id(payAccount.getSubMchId()); | |||||
| psCmd.setAppid(appInfo.getParentAppId()); | |||||
| psCmd.setSub_appid(appInfo.getAppId()); | |||||
| psCmd.setNonce_str(Utility.generate32UUID()); | |||||
| psCmd.setTransaction_id(transcationId); | |||||
| psCmd.setOut_order_no(record.getId().toString()); | |||||
| psCmd.setSign_type("HMAC-SHA256"); | |||||
| psCmd.setReceivers(receivers.toJSONString()); | |||||
| String response; | |||||
| try { | |||||
| psCmd.setSign(WxPayment.createSignHMAC(BeanUtils.toStringMap(psCmd), payAccount.getApiKey())); | |||||
| log.info("request:" + psCmd.toString()); | |||||
| if(shareType.getCode().intValue()==EnumProfitSharingOrderType.PROFIT_SHARING_SINGLE.getCode().intValue()) { | |||||
| response = WxProfitSharing.pushOrder(BeanUtils.toStringMap(psCmd), payAccount.getCertPath(), payAccount.getMchId()); | |||||
| } else if(shareType.getCode().intValue()==EnumProfitSharingOrderType.PROFIT_SHARING_MULTI.getCode().intValue()) { | |||||
| response = WxProfitSharing.pushMultiOrder(BeanUtils.toStringMap(psCmd), payAccount.getCertPath(), payAccount.getMchId()); | |||||
| } else { | |||||
| throw new MallinkException(ErrorCode.SYS_PARAMETER_ERROR); | |||||
| } | |||||
| } catch (Exception e) { | |||||
| log.error("wx recivers share error:",e); | |||||
| return new PayShareResult(false, EnumProfitSharingOrderStatus.PROFIT_SHARING_REQ_FAILED.getCode(), ErrorCode.PROFIT_SHARING_REQUEST_FAILED.getMessage()+":"+e.getMessage(), null, null); | |||||
| } | |||||
| log.info("response: " + response); | |||||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||||
| String return_code = returnMap.get("return_code"); | |||||
| if (!"SUCCESS".equals(return_code)) { | |||||
| return new PayShareResult(false, EnumProfitSharingOrderStatus.PROFIT_SHARING_REQ_FAILED.getCode(), returnMap.get("return_msg"), null, null); | |||||
| } | |||||
| if (!WxPayment.verifyNotifyHMAC(returnMap,payAccount.getApiKey())){ | |||||
| return new PayShareResult(false, EnumProfitSharingOrderStatus.PROFIT_SHARING_REQ_FAILED.getCode(), ErrorCode.PROFIT_SHARING_RETURN_INVALID.getMessage(), null, null); | |||||
| } | |||||
| String result_code = returnMap.get("result_code"); | |||||
| if (!"SUCCESS".equals(result_code)) { | |||||
| return new PayShareResult(false, EnumProfitSharingOrderStatus.PROFIT_SHARING_APPLY_FAILED.getCode(), returnMap.get("err_code_des"), null, null); | |||||
| } | |||||
| return new PayShareResult(true, null, "success",returnMap, returnMap.get("order_id")); | |||||
| } | |||||
| @Override | |||||
| public PayShareQueryResult shareQuery(WxAppinfo appInfo, WxPayAccount payAccount, WxProfitSharingOrder record) throws MallinkException { | |||||
| WxProfitSharingQueryP wxProfitSharingQueryP = new WxProfitSharingQueryP();; | |||||
| wxProfitSharingQueryP.setMch_id(payAccount.getMchId()); | |||||
| wxProfitSharingQueryP.setSub_mch_id(payAccount.getSubMchId()); | |||||
| wxProfitSharingQueryP.setNonce_str(Utility.generate32UUID()); | |||||
| wxProfitSharingQueryP.setTransaction_id(record.getTransactionId()); | |||||
| wxProfitSharingQueryP.setOut_order_no(record.getId().toString()); | |||||
| wxProfitSharingQueryP.setSign_type("HMAC-SHA256"); | |||||
| String response; | |||||
| try { | |||||
| wxProfitSharingQueryP.setSign(WxPayment.createSignHMAC(BeanUtils.toStringMap(wxProfitSharingQueryP),payAccount.getApiKey())); | |||||
| response = WxProfitSharing.queryOrder(BeanUtils.toStringMap(wxProfitSharingQueryP), payAccount.getCertPath(), payAccount.getMchId()); | |||||
| }catch (Exception e){ | |||||
| throw new MallinkException(ErrorCode.PROFIT_SHARING_QUERY_REQUEST_FAILED.getCode(), ErrorCode.PROFIT_SHARING_QUERY_REQUEST_FAILED.getMessage()+e.getMessage()); | |||||
| } | |||||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||||
| String return_code = returnMap.get("return_code"); | |||||
| if (!"SUCCESS".equals(return_code)) { | |||||
| throw new MallinkException(ErrorCode.PROFIT_SHARING_QUERY_REQUEST_FAILED.getCode(), returnMap.get("return_msg")); | |||||
| } | |||||
| if (!WxPayment.verifyNotifyHMAC(returnMap,payAccount.getApiKey())){ | |||||
| throw new MallinkException(ErrorCode.PROFIT_SHARING_QUERY_RETURN_INVALID); | |||||
| } | |||||
| String result_code = returnMap.get("result_code"); | |||||
| if (!"SUCCESS".equals(result_code)) { | |||||
| throw new MallinkException(ErrorCode.PROFIT_SHARING_QUERY_APPLY_FAILED.getCode(), returnMap.get("err_code_des")); | |||||
| } | |||||
| String out_order_no = returnMap.get("out_order_no"); | |||||
| if (StringUtils.isBlank(out_order_no) || !out_order_no.equals(record.getId().toString())){ | |||||
| throw new MallinkException(ErrorCode.PROFIT_SHARING_QUERY_RETURN_INVALID.getCode(),"out_order_no:["+out_order_no+"] WxProfitSharingOrder:["+record.getId()+"]"); | |||||
| } | |||||
| Integer code = (Integer) statusMap.get(returnMap.get("status")); | |||||
| return new PayShareQueryResult(true, code, "success",returnMap, returnMap.get("receivers")); | |||||
| } | |||||
| @Autowired | |||||
| WxAppinfoMapper wxAppinfoMapper; | |||||
| @Autowired | |||||
| WxPayAccountMapper wxPayAccountMapper; | |||||
| @Autowired | |||||
| WxPayOrderMapper wxPayOrderMapper; | |||||
| private ShareNotifyAdapterResult getErrorResult(String msg) { | |||||
| SortedMap resultMap = new TreeMap(); | |||||
| resultMap.put("return_code", "FAIL"); | |||||
| resultMap.put("return_msg", msg); | |||||
| return new ShareNotifyAdapterResult(false,ErrorCode.PAY_ORDER_NOTIFY_CHECK_SIGN_ERROR.getCode(),msg,XmlUtil.getRequestXml(resultMap)); | |||||
| } | |||||
| private ShareNotifyAdapterResult getSuccessResult(WxPayOrder payOrder, String transcationId){ | |||||
| SortedMap resultMap = new TreeMap(); | |||||
| resultMap.put("return_code", "SUCCESS"); | |||||
| resultMap.put("return_msg", "OK"); | |||||
| return new ShareNotifyAdapterResult(transcationId, payOrder, XmlUtil.getRequestXml(resultMap)); | |||||
| } | |||||
| @Override | |||||
| public ShareNotifyAdapterResult notify(Map<String, String> paramMap,EnumPayWay payWay) { | |||||
| // how to get wechatAppId, wechatMchId, partnerKey | |||||
| String appId = paramMap.get("appid"); | |||||
| String subAppId = paramMap.get("sub_appid"); | |||||
| String mchId = paramMap.get("mch_id"); | |||||
| String subMchId = paramMap.get("sub_mch_id"); | |||||
| WxAppinfo appinfo = null; | |||||
| boolean isNormal = true; | |||||
| if (StringUtils.isBlank(subAppId) && StringUtils.isBlank(subMchId)) { | |||||
| // 普通商户号 | |||||
| appinfo = wxAppinfoMapper.findByAppId(appId); | |||||
| if (appinfo == null) { | |||||
| log.error("appid not found: " + appId); | |||||
| throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND); | |||||
| } | |||||
| isNormal = true; | |||||
| } else { | |||||
| // 服务号 现在用hmac-sha256 | |||||
| appinfo = wxAppinfoMapper.findByAppId(subAppId); | |||||
| if (appinfo == null) { | |||||
| log.error("subappid not found: " + subAppId); | |||||
| throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND); | |||||
| } | |||||
| isNormal = false; | |||||
| } | |||||
| WxPayAccount payAccount = wxPayAccountMapper.selectById(appinfo.getPayId()); | |||||
| if (payAccount == null) { | |||||
| throw new MallinkException(ErrorCode.MCH_INFO_NOT_FOUND); | |||||
| } | |||||
| String partnerKey = payAccount.getApiKey(); | |||||
| try { | |||||
| if (payWay == EnumPayWay.PAY_WAY_WECHAT) { | |||||
| boolean signVerified = false; | |||||
| if (isNormal) { | |||||
| // 普通商户号支付 | |||||
| signVerified = WxPayment.verifyNotify(paramMap, partnerKey); | |||||
| if (!signVerified) { | |||||
| log.warn("notify order, wxpay checksign error, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||||
| throw new MallinkException(ErrorCode.PAY_ORDER_NOTIFY_CHECK_SIGN_ERROR); | |||||
| } | |||||
| } else { | |||||
| // 服务号 现在用hmac-sha256 | |||||
| signVerified = WxPayment.verifyNotifyHMAC(paramMap, partnerKey); | |||||
| if (!signVerified) { | |||||
| log.warn("notify order, wxpay checksign error, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||||
| throw new MallinkException(ErrorCode.PAY_ORDER_NOTIFY_CHECK_SIGN_ERROR); | |||||
| } | |||||
| } | |||||
| if (!"SUCCESS".equals(paramMap.get("return_code"))) { | |||||
| log.warn("notify order, wxpay status not success, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||||
| return getErrorResult("订单状态码非SUCCESS"); | |||||
| } | |||||
| String payOrderNo = paramMap.get("out_trade_no"); | |||||
| String timEndStr = paramMap.get("time_end"); | |||||
| Long payOrderId = Long.valueOf(payOrderNo); | |||||
| WxPayOrder payOrder = wxPayOrderMapper.selectById(payOrderId,payAccount.getTenantId()); | |||||
| if (payOrder == null) { | |||||
| log.warn("notify order, wxpay check pay order not exists, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||||
| return getErrorResult("订单不存在"); | |||||
| } | |||||
| // 验证支付金额 | |||||
| if (!paramMap.get("total_fee").equals(payOrder.getPayAmount().toString())) { | |||||
| log.warn("notify order, wxpay check total_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||||
| return getErrorResult("订单总金额不一致"); | |||||
| } | |||||
| Date timeEnd = null; | |||||
| try { | |||||
| timeEnd = Utility.getDateFromString(timEndStr); | |||||
| } catch (ParseException e) { | |||||
| log.error("解析timeEnd失败"); | |||||
| timeEnd = new Date(); | |||||
| } | |||||
| payOrder.setPayTimeEnd(timeEnd); | |||||
| log.info("notify order, wxpay checksign success, paramMap:{}, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); | |||||
| return getSuccessResult(payOrder, paramMap.get("transaction_id")); | |||||
| } | |||||
| } catch (RuntimeException e) { | |||||
| log.warn("notify order, checksign error, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString() + ", e:" + e.getMessage()); | |||||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR); | |||||
| } | |||||
| return getErrorResult("FAILED"); | |||||
| } | |||||
| @Override | |||||
| public ShareAccountResult createShareAccount(WxAppinfo appInfo,WxPayAccount payAccount,WxProfitSharingReceiver receiver) { | |||||
| WxProfitSharingReceiverP wxProfitSharingReceiverP = new WxProfitSharingReceiverP(); | |||||
| if (StringUtils.isNotBlank(appInfo.getParentAppId())) { | |||||
| wxProfitSharingReceiverP.setAppid(appInfo.getParentAppId()); | |||||
| wxProfitSharingReceiverP.setMch_id(payAccount.getMchId()); | |||||
| wxProfitSharingReceiverP.setSub_appid(appInfo.getAppId()); | |||||
| wxProfitSharingReceiverP.setSub_mch_id(payAccount.getSubMchId()); | |||||
| } else { | |||||
| wxProfitSharingReceiverP.setAppid(appInfo.getAppId()); | |||||
| wxProfitSharingReceiverP.setMch_id(payAccount.getMchId()); | |||||
| } | |||||
| wxProfitSharingReceiverP.setNonce_str(Utility.generate32UUID()); | |||||
| wxProfitSharingReceiverP.setSign_type("HMAC-SHA256"); | |||||
| JSONObject receiverJSON = new JSONObject(); | |||||
| receiverJSON.put("type", EnumProfitSharingReceiverType.getEnum(receiver.getReceiverType()).getMessage()); | |||||
| receiverJSON.put("account", receiver.getReceiverAccount()); | |||||
| receiverJSON.put("name", receiver.getTrueName()); | |||||
| wxProfitSharingReceiverP.setReceiver(receiverJSON.toJSONString()); | |||||
| String response; | |||||
| try { | |||||
| wxProfitSharingReceiverP.setSign(WxPayment.createSignHMAC(BeanUtils.toStringMap(wxProfitSharingReceiverP), payAccount.getApiKey())); | |||||
| response = WxProfitSharing.addReceiver(BeanUtils.toStringMap(wxProfitSharingReceiverP)); | |||||
| log.info(response); | |||||
| } catch (Exception e) { | |||||
| log.error(ErrorCode.PROFIT_SHARING_RECEIVER_ADD_FAILED.getMessage() + e.getMessage()); | |||||
| return new ShareAccountResult(false, ErrorCode.PROFIT_SHARING_RECEIVER_ADD_FAILED.getCode(), e.getMessage(), null); | |||||
| } | |||||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||||
| String return_code = returnMap.get("return_code"); | |||||
| if (!"SUCCESS".equals(return_code)) { | |||||
| log.error(ErrorCode.PROFIT_SHARING_RECEIVER_ADD_FAILED.getMessage() + returnMap.get("return_msg")+":"+JSON.toJSONString(returnMap)); | |||||
| return new ShareAccountResult(false, ErrorCode.PROFIT_SHARING_RECEIVER_ADD_FAILED.getCode(), returnMap.get("return_msg"), null); | |||||
| } | |||||
| String result_code = returnMap.get("result_code"); | |||||
| if (!"SUCCESS".equals(result_code)) { | |||||
| log.error(ErrorCode.PROFIT_SHARING_RECEIVER_ADD_FAILED.getMessage() + returnMap.get("err_code_des")+":"+JSON.toJSONString(returnMap)); | |||||
| return new ShareAccountResult(false, ErrorCode.PROFIT_SHARING_RECEIVER_ADD_FAILED.getCode(), returnMap.get("err_code_des"), null); | |||||
| } | |||||
| if (!WxPayment.verifyNotifyHMAC(returnMap, payAccount.getApiKey())) { | |||||
| log.error(ErrorCode.PROFIT_SHARING_RECEIVER_ADD_FAILED.getMessage() + "verifyNotifyHMAC"+":"+JSON.toJSONString(returnMap)); | |||||
| return new ShareAccountResult(false, ErrorCode.PROFIT_SHARING_RECEIVER_ADD_FAILED.getCode(), ErrorCode.PROFIT_SHARING_RECEIVER_ADD_FAILED.getMessage(), null); | |||||
| } | |||||
| return new ShareAccountResult(true, null, "success", returnMap); | |||||
| } | |||||
| @Autowired | |||||
| WxProfitSharingReceiverMapper wxProfitSharingReceiverMapper; | |||||
| @Override | |||||
| public ShareAccountResult deleteShareAccount(WxAppinfo appInfo, WxPayAccount payAccount, | |||||
| WxProfitSharingReceiver receiver) { | |||||
| //删除分账账户从微信服务器 | |||||
| WxProfitSharingReceiverP wxProfitSharingReceiverP = new WxProfitSharingReceiverP(); | |||||
| if (StringUtils.isNotBlank(appInfo.getParentAppId())) { | |||||
| wxProfitSharingReceiverP.setAppid(appInfo.getParentAppId()); | |||||
| wxProfitSharingReceiverP.setMch_id(payAccount.getMchId()); | |||||
| wxProfitSharingReceiverP.setSub_appid(appInfo.getAppId()); | |||||
| wxProfitSharingReceiverP.setSub_mch_id(payAccount.getSubMchId()); | |||||
| } else { | |||||
| wxProfitSharingReceiverP.setAppid(appInfo.getAppId()); | |||||
| wxProfitSharingReceiverP.setMch_id(payAccount.getMchId()); | |||||
| } | |||||
| wxProfitSharingReceiverP.setNonce_str(Utility.generate32UUID()); | |||||
| wxProfitSharingReceiverP.setSign_type("HMAC-SHA256"); | |||||
| JSONObject receiverJSON = new JSONObject(); | |||||
| receiverJSON.put("type", EnumProfitSharingReceiverType.getEnum(receiver.getReceiverType()).getMessage()); | |||||
| receiverJSON.put("account", receiver.getReceiverAccount()); | |||||
| wxProfitSharingReceiverP.setReceiver(receiverJSON.toJSONString()); | |||||
| String response; | |||||
| try { | |||||
| wxProfitSharingReceiverP.setSign(WxPayment.createSignHMAC(BeanUtils.toStringMap(wxProfitSharingReceiverP), payAccount.getApiKey())); | |||||
| response = WxProfitSharing.delReceiver(BeanUtils.toStringMap(wxProfitSharingReceiverP)); | |||||
| } catch (Exception e) { | |||||
| log.error(ErrorCode.PROFIT_SHARING_RECEIVER_DEL_FAILED.getMessage() + e.getMessage()); | |||||
| return new ShareAccountResult(false, ErrorCode.PROFIT_SHARING_RECEIVER_DEL_FAILED.getCode(), e.getMessage(), null); | |||||
| } | |||||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||||
| String return_code = returnMap.get("return_code"); | |||||
| if (!"SUCCESS".equals(return_code)) { | |||||
| log.error(ErrorCode.PROFIT_SHARING_RECEIVER_DEL_FAILED.getMessage() + returnMap.get("return_msg")+":"+JSON.toJSONString(returnMap)); | |||||
| return new ShareAccountResult(false, ErrorCode.PROFIT_SHARING_RECEIVER_DEL_FAILED.getCode(), returnMap.get("return_msg"), null); | |||||
| } | |||||
| String result_code = returnMap.get("result_code"); | |||||
| if (!"SUCCESS".equals(result_code)) { | |||||
| if (returnMap.get("err_code").contains("USER_NOT_EXIST")) { | |||||
| receiver.setStatus(EnumProfitSharingReceiverStatus.PROFIT_SHARING_RECEIVER_STATUS_INVALID.getCode()); | |||||
| receiver.setUpdateTime(new Date()); | |||||
| wxProfitSharingReceiverMapper.updateById(receiver); | |||||
| } | |||||
| log.error(ErrorCode.PROFIT_SHARING_RECEIVER_DEL_FAILED.getMessage() + returnMap.get("err_code_des")+":"+JSON.toJSONString(returnMap)); | |||||
| return new ShareAccountResult(false, ErrorCode.PROFIT_SHARING_RECEIVER_DEL_FAILED.getCode(), returnMap.get("err_code_des"), null); | |||||
| } | |||||
| if (!WxPayment.verifyNotifyHMAC(returnMap, payAccount.getApiKey())) { | |||||
| log.error(ErrorCode.PROFIT_SHARING_RECEIVER_DEL_FAILED.getMessage()+":"+JSON.toJSONString(returnMap)); | |||||
| return new ShareAccountResult(false, ErrorCode.PROFIT_SHARING_RECEIVER_DEL_FAILED.getCode(), "verifyNotifyHMAC", null); | |||||
| } | |||||
| return new ShareAccountResult(true, null, "success", returnMap); | |||||
| } | |||||
| @Override | |||||
| public int getOfficialCommission(WxOrder o, WxPayAccount payAccount) { | |||||
| return 0; | |||||
| } | |||||
| @Override | |||||
| public ResultData handerSharingOrder(WxPayOrder payOrder, WxProfitSharingOrder sharingOrder) { | |||||
| return new ResultData(ErrorCode.SYS_PARAMETER_TYPE_ERROR.getCode(),"微信分账无需处理"); | |||||
| } | |||||
| @Override | |||||
| public WxProfitSharingOrder createSharingOrder(WxSharingOrderDto sharingOrderDto, Integer mchType,Integer share) { | |||||
| if(EnumPayMchType.DIRECT.getCode().equals(mchType)){ | |||||
| throw new MallinkException(ErrorCode.SYS_PARAMETER_TYPE_ERROR.getCode(),"微信直连模式待开发"); | |||||
| } | |||||
| if(EnumYesOrNo.NO.getCode().equals(share)){ | |||||
| throw new MallinkException(ErrorCode.SYS_PARAMETER_TYPE_ERROR.getCode(),"微信不分账"); | |||||
| } | |||||
| //是否已创建分账订单 | |||||
| WxProfitSharingOrder record = new WxProfitSharingOrder(); | |||||
| record.updateTenantInfo(sharingOrderDto); | |||||
| record.setOrderId(sharingOrderDto.getOrderId()); | |||||
| record = wxProfitSharingOrderMapper.selectOne(new QueryWrapper(record)); | |||||
| if (record == null) { | |||||
| //创建分账订单 | |||||
| Date currentDate = new Date(); | |||||
| record = new WxProfitSharingOrder(); | |||||
| final IdWorker idworker = IdWorker.get(); | |||||
| record.setId(idworker.nextId()); | |||||
| record.updateTenantInfo(sharingOrderDto); | |||||
| record.setTransactionId(sharingOrderDto.getTransactionId()); | |||||
| record.setOrderId(sharingOrderDto.getOrderId()); | |||||
| record.setPayAmount(sharingOrderDto.getPayAmount()); | |||||
| record.setMerchantId(sharingOrderDto.getMerchantId()); | |||||
| record.setSharingStatus(this.getSharingOrderInitialStatus()); | |||||
| record.setCreateTime(currentDate); | |||||
| record.setUpdateTime(currentDate); | |||||
| record.setPayTimeStart(sharingOrderDto.getPayTimeStart()); | |||||
| record.setPayTimeEnd(sharingOrderDto.getPayTimeEnd()); | |||||
| record.setType(sharingOrderDto.getType()); | |||||
| wxProfitSharingOrderMapper.insert(record); | |||||
| } | |||||
| List<WxProfitSharingReceiver> psReceiverList = getReceiverList(sharingOrderDto, sharingOrderDto.getMerchantId(), null); | |||||
| if (psReceiverList != null && psReceiverList.size() > 50) { | |||||
| throw new MallinkException(ErrorCode.PROFIT_SHARING_RECEIVER_INVALID); | |||||
| } | |||||
| if (psReceiverList == null || psReceiverList.size() == 0) { //没有分账账户, | |||||
| throw new MallinkException(ErrorCode.PROFIT_SHARING_RECEIVER_UNKNOWN); | |||||
| } | |||||
| if (psReceiverList.size() > 1 &&//计算分账账户合法性 | |||||
| psReceiverList.stream().filter(r->(r.getParameter() == null)).count() > 0) { | |||||
| throw new MallinkException(ErrorCode.PROFIT_SHARING_RECEIVER_INVALID); | |||||
| } | |||||
| //计算分账金额合法性 | |||||
| psReceiverList.stream().forEach(r-> | |||||
| { | |||||
| if (r.getParameter() == null){ | |||||
| r.setSharingAmount(sharingOrderDto.getShareAmount()); | |||||
| r.setRateAmount(sharingOrderDto.getRateAmount()); | |||||
| r.setRealRateAmount(sharingOrderDto.getRealRateAmount()); | |||||
| r.setCommissionAmount(sharingOrderDto.getCommissionAmount()); | |||||
| } else { | |||||
| r.setSharingAmount(sharingOrderDto.getShareAmount()*Integer.valueOf(r.getParameter())/10000); | |||||
| } | |||||
| }); | |||||
| if (psReceiverList.stream().mapToInt(r->r.getSharingAmount()).sum() > sharingOrderDto.getShareAmount()){ | |||||
| throw new MallinkException(ErrorCode.PROFIT_SHARING_RECEIVER_UNKNOWN); | |||||
| } | |||||
| // 添加分账接收方 | |||||
| JSONArray receivers = new JSONArray(); | |||||
| psReceiverList.stream().forEach(receiver->{ | |||||
| JSONObject jo = new JSONObject(); | |||||
| jo.put("type",this.getShareAccount(receiver.getReceiverType()).getMessage()); | |||||
| jo.put("account",receiver.getReceiverAccount()); | |||||
| jo.put("amount", receiver.getSharingAmount()); | |||||
| jo.put("rateAmount", receiver.getRateAmount()); | |||||
| jo.put("realRateAmount", receiver.getRateAmount()); | |||||
| jo.put("commissionAmount", receiver.getCommissionAmount()); | |||||
| //jo.put("description",receiver.getReceiverComments()); //改为存ID, | |||||
| jo.put("description",receiver.getId().toString()); //为重试做准备 | |||||
| receivers.add(jo); | |||||
| }); | |||||
| record.setReceivers(receivers.toJSONString()); | |||||
| wxProfitSharingOrderMapper.updateById(record); | |||||
| return record; | |||||
| } | |||||
| @Override | |||||
| public List<WxProfitSharingReceiver> getReceiverList(TenantEntity tenantEntity, Long merchantId, Integer ttPayWay) { | |||||
| WxProfitSharingReceiver psReceiverQ = new WxProfitSharingReceiver(); | |||||
| psReceiverQ.updateTenantInfo(tenantEntity); | |||||
| psReceiverQ.setMerchantId(merchantId); | |||||
| psReceiverQ.setSharingType(getProfitSharingType()); | |||||
| psReceiverQ.setStatus(EnumProfitSharingReceiverStatus.PROFIT_SHARING_RECEIVER_STATUS_VALID.getCode()); | |||||
| psReceiverQ.setPlat(EnumAppPlat.WX.getCode()); | |||||
| List<WxProfitSharingReceiver> psReceiverList = wxProfitSharingReceiverMapper.findList(psReceiverQ); | |||||
| if (null == psReceiverList || psReceiverList.size() == 0) { | |||||
| throw new MallinkException(ErrorCode.PROFIT_SHARING_RECEIVER_INVALID.getCode(),"该商户未设置分账账号."); | |||||
| }else { | |||||
| for (WxProfitSharingReceiver receiver:psReceiverList) { | |||||
| if (EnumProfitSharingReceiverType.PROFIT_SHARING_RECEIVER_PERSONAL_WECHATID.getCode().intValue() | |||||
| == receiver.getReceiverType().intValue()) { | |||||
| throw new MallinkException(ErrorCode.PROFIT_SHARING_RECEIVER_INVALID.getCode(),"该商户收款账号存在个人微信号方式,微信已停止支持,请重新设置."); | |||||
| } | |||||
| } | |||||
| } | |||||
| return psReceiverList; | |||||
| } | |||||
| private static String queryOrderShareAmount(String mchId,String transcationId,String apiKey) { | |||||
| WxProfitSharingP psCmd = new WxProfitSharingP(); | |||||
| psCmd.setMch_id(mchId);//服务商商户id | |||||
| psCmd.setNonce_str(Utility.generate32UUID()); | |||||
| psCmd.setTransaction_id(transcationId); | |||||
| psCmd.setSign_type("HMAC-SHA256"); | |||||
| try { | |||||
| psCmd.setSign(WxPayment.createSignHMAC(BeanUtils.toStringMap(psCmd), apiKey)); | |||||
| return WxProfitSharing.queryOrderShareAmount(BeanUtils.toStringMap(psCmd)); | |||||
| } catch (Exception e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| return null; | |||||
| } | |||||
| // public static void main(String[] args) { | |||||
| // System.out.println(queryOrderShareAmount("1511925291","4200001516202205010431149938","XHZfpVA0NzoXgLEjsujctUTcyj8Zur2C")); | |||||
| // //System.out.println(test("1511925291", "1604439800", "wxed2f44705544b892", "4200001455202205127949391954", "XHZfpVA0NzoXgLEjsujctUTcyj8Zur2C", "684670745960046592", "D:\\apiclient_cert.p12")); | |||||
| // } | |||||
| // | |||||
| // private static String test(String mchId,String subMchId,String parentAppId,String transcationId,String apiKey,String orderNo,String certPaht) { | |||||
| // WxProfitSharingFinishP psFCmd = new WxProfitSharingFinishP(); | |||||
| // psFCmd.setMch_id(mchId); | |||||
| // psFCmd.setSub_mch_id(subMchId); | |||||
| // psFCmd.setAppid(parentAppId); | |||||
| // psFCmd.setNonce_str(Utility.generate32UUID()); | |||||
| // psFCmd.setTransaction_id(transcationId); | |||||
| // psFCmd.setOut_order_no(orderNo); | |||||
| // //psFCmd.setAmount(amount); | |||||
| // psFCmd.setDescription("分账已完结"); | |||||
| // psFCmd.setSign_type("HMAC-SHA256"); | |||||
| // | |||||
| // String response; | |||||
| // try { | |||||
| // psFCmd.setSign(WxPayment.createSignHMAC(BeanUtils.toStringMap(psFCmd), apiKey)); | |||||
| // log.info("request:" + psFCmd.toString()); | |||||
| // response = WxProfitSharing.finishOrder(BeanUtils.toStringMap(psFCmd), certPaht, mchId); | |||||
| // return response; | |||||
| // } catch (Exception e) { | |||||
| // e.printStackTrace(); | |||||
| // } | |||||
| // return null; | |||||
| // | |||||
| // } | |||||
| } | |||||