Sfoglia il codice sorgente

add pay v3

release_toaliyun_real
zhengfangyuan 3 anni fa
parent
commit
5123d19551
20 ha cambiato i file con 915 aggiunte e 21 eliminazioni
  1. +1
    -1
      mallinkService/src/main/java/com/iformall/enums/EnumPayVersion.java
  2. +75
    -0
      mallinkService/src/main/java/com/iformall/pay/WxPayV3.java
  3. +13
    -7
      mallinkService/src/main/java/com/iformall/service/pay/PayServiceFactory.java
  4. +2
    -2
      mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/sft/WxCashOutSFTAdapterService.java
  5. +6
    -0
      mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v2/WxCashOutAdapterService.java
  6. +317
    -0
      mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v2/WxCashOutQYFKAdapterService.java
  7. +6
    -0
      mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/BaseWxPayAdapterService.java
  8. +6
    -11
      mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/sft/miniApp/appPay/WxMiniAppPaySFTAdapterService.java
  9. +11
    -0
      mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/V3CombineCloseItemOrder.java
  10. +39
    -0
      mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/V3CombineCloseReq.java
  11. +33
    -0
      mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/V3CombineItemOrder.java
  12. +11
    -0
      mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/V3CombinePayAmountReq.java
  13. +17
    -0
      mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/V3CombinePayCommonMiniAppReq.java
  14. +10
    -0
      mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/V3CombinePayerReq.java
  15. +11
    -0
      mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/V3PayAmountReq.java
  16. +18
    -0
      mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/V3PayCommonMiniAppReq.java
  17. +16
    -0
      mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/V3PayQueryReq.java
  18. +10
    -0
      mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/V3PaySettleReq.java
  19. +10
    -0
      mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/V3PayerReq.java
  20. +303
    -0
      mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/miniApp/appPay/WxMiniAppPayV3AdapterService.java

+ 1
- 1
mallinkService/src/main/java/com/iformall/enums/EnumPayVersion.java Vedi File

@@ -6,7 +6,7 @@ package com.iformall.enums;
public enum EnumPayVersion {

WX_PAY_V2(1, "微信支付2.0,老版本"),
WX_PAY_V3(2, "微信支付3.0,暂时还未接"),
WX_PAY_V3(2, "微信支付3.0"),
WX_PAY_V3_SFT(7,"对接电商收付通版本"),
DY_PAY_V2(3,"抖音支付2.0,对接商品库"),
NEU_POS_V1(4,"东软POS支付1.0版本"),


+ 75
- 0
mallinkService/src/main/java/com/iformall/pay/WxPayV3.java Vedi File

@@ -14,6 +14,14 @@ import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.v3.util.AesUtils;
import com.github.binarywang.wxpay.v3.util.RsaCryptoUtil;
import com.iformall.service.pay.service.pay.wx.sft.entity.SFTCombineCloseReq;
import com.iformall.service.pay.service.pay.wx.sft.entity.SFTCombinePayCommonMiniAppReq;
import com.iformall.service.pay.service.pay.wx.sft.entity.SFTPayCommonMiniAppReq;
import com.iformall.service.pay.service.pay.wx.sft.entity.SFTPayQueryReq;
import com.iformall.service.pay.service.pay.wx.v3.entity.V3CombinePayCommonMiniAppReq;
import com.iformall.service.pay.service.pay.wx.v3.entity.V3PayCommonMiniAppReq;
import com.iformall.service.pay.service.pay.wx.v3.entity.V3PayQueryReq;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@@ -25,6 +33,22 @@ public class WxPayV3 {
//查询商家转账到零钱
private static final String MERCHANT_TRANSFER_QUERY_URL = "https://api.mch.weixin.qq.com/v3/transfer/batches/out-batch-no/%s";
//小程序下单-普通支付
private static final String PAY_COMMON_MINIAPP_URL = "https://api.mch.weixin.qq.com/v3/pay/partner/transactions/jsapi";
//小程序下单-普通支付-查询
private static final String PAY_COMMON_QUERY_URL = "https://api.mch.weixin.qq.com/v3/pay/partner/transactions/out-trade-no/%s";
//小程序下单-合单支付
private static final String PAY_COMBINE_MINIAPP_URL = "https://api.mch.weixin.qq.com/v3/combine-transactions/jsapi";
//小程序下单-合单支付-查询
private static final String PAY_COMBINE_QUERY_URL = "https://api.mch.weixin.qq.com/v3/combine-transactions/out-trade-no/%s";
//小程序下单-普通支付-关闭订单
private static final String PAY_COMMON_CLOSE_ORDER_URL = "https://api.mch.weixin.qq.com/v3/pay/partner/transactions/out-trade-no/%s/close";
//小程序下单-合单支付-关闭订单
private static final String PAY_COMBINE_CLOSE_ORDER_URL = "https://api.mch.weixin.qq.com/v3/combine-transactions/out-trade-no/%s/close";
//小程序下单-分账
private static final String SHARE_URL = "https://api.mch.weixin.qq.com/v3/ecommerce/profitsharing/orders";
private WxPayV3() {
}

@@ -84,4 +108,55 @@ public class WxPayV3 {
return payService.postV3WithWechatpaySerial(String.format(MERCHANT_TRANSFER_QUERY_URL, batchNo), JSON.toJSONString(param));
}
/**
* 普通支付-小程序下单 https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_5_1.shtml
* @throws WxPayException
*/
public static String payCommonWithMiniApp(WxPayService payService,V3PayCommonMiniAppReq payReq) throws WxPayException {
return payService.postV3WithWechatpaySerial(PAY_COMMON_MINIAPP_URL, JSON.toJSONString(payReq));
}
/**
* 普通支付-查询https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_5_2.shtml
* @throws WxPayException
*/
public static String payCommonQuery(WxPayService payService,V3PayQueryReq payQuery) throws WxPayException {
return payService.postV3WithWechatpaySerial(String.format(PAY_COMMON_QUERY_URL, payQuery.getOut_trade_no()), JSON.toJSONString(payQuery));
}
/**
* 合单支付-小程序下单https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter5_1_4.shtml
* @throws WxPayException
*/
public static String payCombineCommonWithMiniApp(WxPayService payService,V3CombinePayCommonMiniAppReq payReq) throws WxPayException {
return payService.postV3WithWechatpaySerial(PAY_COMBINE_MINIAPP_URL, JSON.toJSONString(payReq));
}
/**
* 合单支付-查询 https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter5_1_11.shtml
* @throws WxPayException
*/
public static String payCombineQuery(WxPayService payService,V3PayQueryReq payQuery) throws WxPayException {
return payService.postV3WithWechatpaySerial(String.format(PAY_COMBINE_QUERY_URL, payQuery.getOut_trade_no()), null);
}
/**
* 普通支付-关闭 https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_5_3.shtml
* @throws WxPayException
*/
public static String payCommonClose(WxPayService payService,SFTPayQueryReq payQuery) throws WxPayException {
return payService.postV3WithWechatpaySerial(String.format(PAY_COMMON_CLOSE_ORDER_URL, payQuery.getOut_trade_no()), JSON.toJSONString(payQuery));
}
/**
* 合单支付-关闭 https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter5_1_12.shtml
* @throws WxPayException
*/
public static String payCombineClose(WxPayService payService,SFTCombineCloseReq closeOrder) throws WxPayException {
return payService.postV3WithWechatpaySerial(String.format(PAY_COMBINE_CLOSE_ORDER_URL, closeOrder.getCombine_out_trade_no()), JSON.toJSONString(closeOrder));
}
}

+ 13
- 7
mallinkService/src/main/java/com/iformall/service/pay/PayServiceFactory.java Vedi File

@@ -10,15 +10,14 @@ 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.wx.sft.WxPayShareSFTService;
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.stereotype.Service;
import com.iformall.common.ErrorCode;
import com.iformall.enums.EnumPayWay;
import com.iformall.exception.MallinkException;
import com.iformall.service.pay.service.cashout.CashOutAdapterService;
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.cashout.wx.sft.WxCashOutSFTAdapterService;
import com.iformall.service.pay.service.cashout.wx.v2.WxCashOutQYFKAdapterService;
import com.iformall.service.pay.service.pay.CDrivingPayService;
import com.iformall.service.pay.service.pay.CPassivePayService;
import com.iformall.service.pay.service.pay.PayAdapterService;
@@ -28,6 +27,7 @@ import com.iformall.service.pay.service.pay.wx.sft.miniApp.appPay.WxMiniAppPaySF
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.miniApp.appPay.WxMiniAppPayV3AdapterService;
import com.iformall.service.pay.service.refund.RefundPayAdapterService;
import com.iformall.service.pay.service.share.PayShareAdapterService;

@@ -48,6 +48,8 @@ public class PayServiceFactory {
WxMiniAppPayAdapterService wxMiniAppPayService;
@Autowired
WxMiniAppPaySFTAdapterService wxMiniAppPaySFTAdapterService;
@Autowired
WxMiniAppPayV3AdapterService wxMiniAppPayV3AdapterService;
@Autowired
WxMiniMaPayAdapterService wxMiniAppMaPayService;
@@ -77,9 +79,9 @@ public class PayServiceFactory {
TtRefundAdapterService ttRefundService;
@Autowired
WxCashOutAdapterService wxCashOutService;
WxCashOutQYFKAdapterService wxCashOutService;
@Autowired
WxCashOutV3AdapterService wxCashOutV3AdapterService;
WxCashOutSFTAdapterService wxCashOutSFTAdapterService;

@@ -88,7 +90,11 @@ public class PayServiceFactory {
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_SFT.getCode(), wxMiniAppPaySFTAdapterService);
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(), wxMiniAppMaPayService);
//电商收付通没有收款码支付
//serviceMap.put(EnumPayWay.PAY_WAY_WECHAT_MA.getCode()+"_"+EnumPayVersion.WX_PAY_V3_SFT.getCode(), wxMiniAppMaPayService);
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_SFT.getCode(), wxH5PaySFTService);
@@ -160,8 +166,8 @@ public class PayServiceFactory {
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_SFT.getCode(), wxCashOutV3AdapterService);
cashoutMap.put(EnumPayWay.PAY_WAY_WECHAT_MA.getCode()+"_"+EnumPayVersion.WX_PAY_V3_SFT.getCode(), wxCashOutV3AdapterService);
cashoutMap.put(EnumPayWay.PAY_WAY_WECHAT.getCode()+"_"+EnumPayVersion.WX_PAY_V3_SFT.getCode(), wxCashOutSFTAdapterService);
cashoutMap.put(EnumPayWay.PAY_WAY_WECHAT_MA.getCode()+"_"+EnumPayVersion.WX_PAY_V3_SFT.getCode(), wxCashOutSFTAdapterService);
}
return cashoutMap;
}


mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/WxCashOutV3AdapterService.java → mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/sft/WxCashOutSFTAdapterService.java Vedi File

@@ -1,4 +1,4 @@
package com.iformall.service.pay.service.cashout.wx.v3;
package com.iformall.service.pay.service.cashout.wx.sft;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
@@ -60,7 +60,7 @@ import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class WxCashOutV3AdapterService implements CashOutAdapterService{
public class WxCashOutSFTAdapterService implements CashOutAdapterService{
@Autowired
WxAppinfoService wxAppinfoService;

+ 6
- 0
mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v2/WxCashOutAdapterService.java Vedi File

@@ -58,6 +58,12 @@ import com.iformall.utils.XmlUtil;

import lombok.extern.slf4j.Slf4j;


/**
* 商家转账到零钱(因会自动开通运营账户,暂时无法使用)
* @author iformall
*
*/
@Slf4j
@Service
public class WxCashOutAdapterService implements CashOutAdapterService{


+ 317
- 0
mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v2/WxCashOutQYFKAdapterService.java Vedi File

@@ -0,0 +1,317 @@
package com.iformall.service.pay.service.cashout.wx.v2;

import java.util.Map;
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.domain.po.WxAppinfo;
import com.iformall.domain.po.WxCashOut;
import com.iformall.domain.po.WxPayAccount;
import com.iformall.enums.EnumCashOutStatus;
import com.iformall.exception.MallinkException;
import com.iformall.pay.WxCashOutP;
import com.iformall.pay.WxCashOutQueryP;
import com.iformall.pay.WxPay;
import com.iformall.pay.WxPayment;
import com.iformall.service.pay.service.cashout.CashOutAdapterService;
import com.iformall.service.pay.service.cashout.entity.CashOutAdapterResult;
import com.iformall.utils.BeanUtils;
import com.iformall.utils.Utility;
import lombok.extern.slf4j.Slf4j;

/**
* 企业付款到零钱
* @author iformall
*
*/
@Slf4j
@Service
public class WxCashOutQYFKAdapterService implements CashOutAdapterService{

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" +
"}");
/**
* https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2
*
* 在wx_pay_account里面要设置merchant_cert_path,登陆特约商户的商户后台,账号中心-API安全。
*/
@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.transfers(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);
}
}
}

+ 6
- 0
mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/BaseWxPayAdapterService.java Vedi File

@@ -34,6 +34,7 @@ import com.iformall.pay.WxPayOrderSQ;
import com.iformall.pay.WxPayment;
import com.iformall.service.QrCodeService;
import com.iformall.service.helper.WxPayOrderServiceHelper;
import com.iformall.service.order.entity.WxComposeChildOrderShare;
import com.iformall.service.pay.service.pay.PayAdapterService;
import com.iformall.service.pay.service.pay.entity.PayAdapterResult;
import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult;
@@ -56,6 +57,11 @@ public class BaseWxPayAdapterService {
@Autowired
MaUtil maUtil;
protected String getMerchantUid(WxPayOrder payOrder,WxOrder order) {
WxComposeChildOrderShare share = payOrder.getChildOrderShare(order.getId());
return share.getMerchantUid();
}
protected File getQrCode(WxAppinfo appinfo,String pageUrl,int type,String sceneParam) throws WxErrorException {
boolean isFmOpen = false;


+ 6
- 11
mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/sft/miniApp/appPay/WxMiniAppPaySFTAdapterService.java Vedi File

@@ -88,11 +88,6 @@ public class WxMiniAppPaySFTAdapterService extends BaseWxPaySFTAdapterService i
return req;
}
private String getMerchantUid(WxPayOrder payOrder,WxOrder order) {
WxComposeChildOrderShare share = payOrder.getChildOrderShare(order.getId());
return share.getMerchantUid();
}
private SFTCombinePayCommonMiniAppReq generateCombinePayReqeust(WxPayAccount payAccount,WxComposeOrder composeOrder,List<WxOrder> childOrders,String productName,
WxPayOrder record,WxAppinfo appInfo,String openId,String appId,Date currentDate,EnumPayShare isShare) throws Exception {
@@ -122,13 +117,13 @@ public class WxMiniAppPaySFTAdapterService extends BaseWxPaySFTAdapterService i
PayAdapterResult par = new PayAdapterResult();
if (StringUtils.isBlank(response)) {
par.setSuccess(false);
par.setMsg("pay v3 has no response.");
par.setMsg("pay SFT has no response.");
}else {
JSONObject result = JSON.parseObject(response);
String prepayId = result.getString("prepay_id");
if (StringUtils.isBlank(prepayId)) {
par.setSuccess(false);
par.setMsg("pay v3 has no response.");
par.setMsg("pay SFT has no response.");
}else {
par.setSuccess(true);
par.setMsg("success.");
@@ -180,8 +175,8 @@ public class WxMiniAppPaySFTAdapterService extends BaseWxPaySFTAdapterService i
} else {
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"因电商收付通合单查询无法处理,暂时不支持合单支付");
//合单支付/小程序支付
// CombinePayCommonMiniAppReq payReq = generateCombinePayReqeust(payAccount,composeOrder,childOrders,productName,record,appInfo,openId,appInfo.getAppId(),currentDate,isShare);
// String response = WxPayV3.payCombineCommonWithMiniApp(payService, payReq);
// SFTCombinePayCommonMiniAppReq payReq = generateCombinePayReqeust(payAccount,composeOrder,childOrders,productName,record,appInfo,openId,appInfo.getAppId(),currentDate,isShare);
// String response = WxPayV3SFT.payCombineCommonWithMiniApp(payService, payReq);
// log.info("pay order v3," + payReq.toString() + ", response: " + response.toString());
// return getOrderPResult(response);
}
@@ -233,8 +228,8 @@ public class WxMiniAppPaySFTAdapterService extends BaseWxPaySFTAdapterService i
req.setOut_trade_no(String.valueOf(oldRecord.getId()));
String response = WxPayV3SFT.payCommonQuery(payService, req);
if (StringUtils.isBlank(response)){
log.error("pay common v3 query response is null."+JSON.toJSONString(req));
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"pay common v3 query response is null."+JSON.toJSONString(req));
log.error("pay common sft query response is null."+JSON.toJSONString(req));
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"pay common sft query response is null."+JSON.toJSONString(req));
}
return getPayCommonQueryResult(response);
}else {


+ 11
- 0
mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/V3CombineCloseItemOrder.java Vedi File

@@ -0,0 +1,11 @@
package com.iformall.service.pay.service.pay.wx.v3.entity;

import lombok.Data;

@Data
public class V3CombineCloseItemOrder {

private String mchid;//子单发起方商户号,必须与发起方appid有绑定关系
private String out_trade_no;//子单商户订单号
private String sub_mchid;//二级商户号,服务商子商户的商户号,被合单方。直连商户不用传二级商户号
}

+ 39
- 0
mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/V3CombineCloseReq.java Vedi File

@@ -0,0 +1,39 @@
package com.iformall.service.pay.service.pay.wx.v3.entity;

import java.util.ArrayList;
import java.util.List;
import com.alibaba.fastjson.annotation.JSONField;
import com.iformall.domain.po.WxPayAccount;
import com.iformall.domain.po.WxPayOrder;
import com.iformall.service.order.entity.WxComposeChildOrderShare;
import lombok.Data;

@Data
public class V3CombineCloseReq {

private String combine_appid;//合单发起方的appid
@JSONField(serialize = false)
private String combine_out_trade_no;//不放到body
private List<V3CombineCloseItemOrder> sub_orders;
public void initSubOrders(WxPayAccount payAccount,WxPayOrder payOrder) {
List<WxComposeChildOrderShare> childs = payOrder.getAllChilds();
if (null != childs) {
List<V3CombineCloseItemOrder> suborders = new ArrayList<V3CombineCloseItemOrder>();
for (WxComposeChildOrderShare child : childs) {
V3CombineCloseItemOrder ccio = new V3CombineCloseItemOrder();
ccio.setMchid(payAccount.getMchId());
ccio.setSub_mchid(child.getMerchantUid());
ccio.setOut_trade_no(String.valueOf(child.getOrderId()));
suborders.add(ccio);
}
if (suborders.size() > 0) {
this.setSub_orders(suborders);
}
}
}
}

+ 33
- 0
mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/V3CombineItemOrder.java Vedi File

@@ -0,0 +1,33 @@
package com.iformall.service.pay.service.pay.wx.v3.entity;

import com.iformall.domain.po.WxAppinfo;
import com.iformall.domain.po.WxOrder;
import com.iformall.domain.po.WxPayAccount;

import lombok.Data;

@Data
public class V3CombineItemOrder {

private String mchid;//子单发起方商户号,必须与发起方appid有绑定关系
private String attach;//附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用
private V3CombinePayAmountReq amount;//订单金额
private String out_trade_no;//子单商户订单号
private String sub_mchid;//二级商户号,服务商子商户的商户号,被合单方。直连商户不用传二级商户号
private String description;//商品描述,需传入应用市场上的APP名字-实际商品名称
private V3PaySettleReq settle_info;//结算信息
public void initByWxOrder(WxPayAccount payAccount,WxOrder order,String subMchId,WxAppinfo appInfo,String productName,String extParam) {
this.mchid = payAccount.getMchId();
this.attach = extParam;
V3CombinePayAmountReq amount = new V3CombinePayAmountReq();
amount.setTotal_amount(order.getPayment());
this.setAmount(amount);
this.out_trade_no = String.valueOf(order.getId());
this.sub_mchid = subMchId;
this.description = appInfo.getName()+"-"+productName;
V3PaySettleReq settle = new V3PaySettleReq();
settle.setProfit_sharing(true);
this.setSettle_info(settle);
}
}

+ 11
- 0
mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/V3CombinePayAmountReq.java Vedi File

@@ -0,0 +1,11 @@
package com.iformall.service.pay.service.pay.wx.v3.entity;

import lombok.Data;

@Data
public class V3CombinePayAmountReq {

private int total_amount;//总金额,单位为分。
private String currency="CNY";//货币类型
}

+ 17
- 0
mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/V3CombinePayCommonMiniAppReq.java Vedi File

@@ -0,0 +1,17 @@
package com.iformall.service.pay.service.pay.wx.v3.entity;

import java.util.List;

import lombok.Data;

@Data
public class V3CombinePayCommonMiniAppReq {

private String combine_appid;//合单发起方的appid
private String combine_mchid;//合单发起方商户号,服务商和电商模式下,传服务商商户号
private String combine_out_trade_no;//合单支付总订单号
private List<V3CombineItemOrder> sub_orders;//商品描述
private V3CombinePayerReq combine_payer_info;// 支付者信息
private String sub_appid;//子商户申请的应用ID
private String notify_url;//接收微信支付异步通知回调地址
}

+ 10
- 0
mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/V3CombinePayerReq.java Vedi File

@@ -0,0 +1,10 @@
package com.iformall.service.pay.service.pay.wx.v3.entity;

import lombok.Data;

@Data
public class V3CombinePayerReq {

private String sub_openid;//使用合单appid获取的对应用户openid
}

+ 11
- 0
mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/V3PayAmountReq.java Vedi File

@@ -0,0 +1,11 @@
package com.iformall.service.pay.service.pay.wx.v3.entity;

import lombok.Data;

@Data
public class V3PayAmountReq {

private int total;//总金额,单位为分。
private String currency="CNY";//货币类型
}

+ 18
- 0
mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/V3PayCommonMiniAppReq.java Vedi File

@@ -0,0 +1,18 @@
package com.iformall.service.pay.service.pay.wx.v3.entity;

import lombok.Data;

@Data
public class V3PayCommonMiniAppReq {

private String sp_appid;//服务商应用ID
private String sp_mchid;//服务商户号
private String sub_appid;//子商户申请的应用ID
private String sub_mchid;//二级商户号
private String description;//商品描述
private String out_trade_no;//商户订单号
private String notify_url;//通知地址,不允许携带查询串
private V3PaySettleReq settle_info;//结算信息
private V3PayAmountReq amount;//订单金额
private V3PayerReq payer;//支付者
}

+ 16
- 0
mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/V3PayQueryReq.java Vedi File

@@ -0,0 +1,16 @@
package com.iformall.service.pay.service.pay.wx.v3.entity;

import com.alibaba.fastjson.annotation.JSONField;

import lombok.Data;

@Data
public class V3PayQueryReq {

private String sp_mchid;//服务商户号。
private String sub_mchid;//二级商户号
@JSONField(serialize = false)
private String out_trade_no;//商户订单号
}

+ 10
- 0
mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/V3PaySettleReq.java Vedi File

@@ -0,0 +1,10 @@
package com.iformall.service.pay.service.pay.wx.v3.entity;

import lombok.Data;

@Data
public class V3PaySettleReq {

private boolean profit_sharing;//是否指定分账
private int subsidy_amount;//补差金额;profit_sharing为true时,该金额才生效
}

+ 10
- 0
mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/V3PayerReq.java Vedi File

@@ -0,0 +1,10 @@
package com.iformall.service.pay.service.pay.wx.v3.entity;

import lombok.Data;

@Data
public class V3PayerReq {

private String sub_openid;//用户在子商户appid下的唯一标识
}

+ 303
- 0
mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/miniApp/appPay/WxMiniAppPayV3AdapterService.java Vedi File

@@ -0,0 +1,303 @@
package com.iformall.service.pay.service.pay.wx.v3.miniApp.appPay;

import java.io.File;
import java.util.ArrayList;
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.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
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.enums.EnumOrderStatus;
import com.iformall.enums.EnumPayMchType;
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.WxPayV3;
import com.iformall.pay.WxPayV3SFT;
import com.iformall.pay.WxPayment;
import com.iformall.service.helper.WxPayOrderServiceHelper;
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.sft.entity.SFTCombineItemOrder;
import com.iformall.service.pay.service.pay.wx.sft.entity.SFTCombinePayCommonMiniAppReq;
import com.iformall.service.pay.service.pay.wx.sft.entity.SFTCombinePayerReq;
import com.iformall.service.pay.service.pay.wx.sft.entity.SFTPayAmountReq;
import com.iformall.service.pay.service.pay.wx.sft.entity.SFTPayCommonMiniAppReq;
import com.iformall.service.pay.service.pay.wx.sft.entity.SFTPayQueryReq;
import com.iformall.service.pay.service.pay.wx.sft.entity.SFTPaySettleReq;
import com.iformall.service.pay.service.pay.wx.sft.entity.SFTPayerReq;
import com.iformall.service.pay.service.pay.wx.v2.BaseWxPayV2AdapterService;
import com.iformall.service.pay.service.pay.wx.v3.BaseWxPayV3AdapterService;
import com.iformall.service.pay.service.pay.wx.v3.entity.V3CombineItemOrder;
import com.iformall.service.pay.service.pay.wx.v3.entity.V3CombinePayCommonMiniAppReq;
import com.iformall.service.pay.service.pay.wx.v3.entity.V3CombinePayerReq;
import com.iformall.service.pay.service.pay.wx.v3.entity.V3PayAmountReq;
import com.iformall.service.pay.service.pay.wx.v3.entity.V3PayCommonMiniAppReq;
import com.iformall.service.pay.service.pay.wx.v3.entity.V3PayQueryReq;
import com.iformall.service.pay.service.pay.wx.v3.entity.V3PaySettleReq;
import com.iformall.service.pay.service.pay.wx.v3.entity.V3PayerReq;
import com.iformall.utils.BeanUtils;
import com.iformall.utils.MaUtil;
import com.iformall.utils.MapUtil;
import com.iformall.utils.Utility;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class WxMiniAppPayV3AdapterService extends BaseWxPayV3AdapterService implements CDrivingPayService{
@Autowired
MaUtil maUtil;
private V3PayCommonMiniAppReq generatePayCommonRequest(WxPayAccount payAccount,WxComposeOrder composeOrder,String productName, WxPayOrder record,String openId,WxAppinfo appInfo,Date currentDate) throws Exception {
V3PayCommonMiniAppReq req = new V3PayCommonMiniAppReq();
req.setSp_appid(String.valueOf(appInfo.getParentAppId()));
req.setSp_mchid(payAccount.getMchId());
req.setSub_appid(appInfo.getAppId());
req.setSub_mchid(getMerchantUid(record,composeOrder.getSingleOrder()));
req.setDescription(appInfo.getName()+"-"+productName);
req.setOut_trade_no(String.valueOf(composeOrder.getMainOrderId()));
req.setNotify_url(payAccount.getPayNotifyV3Url());
V3PaySettleReq settle = new V3PaySettleReq();
settle.setProfit_sharing(true);
req.setSettle_info(settle);
V3PayAmountReq amout = new V3PayAmountReq();
amout.setTotal(record.getPayAmount());
req.setAmount(amout);
V3PayerReq payer = new V3PayerReq();
payer.setSub_openid(openId);
req.setPayer(payer);
return req;
}
private PayAdapterResult getOrderPResult(String response,WxPayOrder record) {
PayAdapterResult par = new PayAdapterResult();
if (StringUtils.isBlank(response)) {
par.setSuccess(false);
par.setMsg("pay v3 has no response.");
}else {
JSONObject result = JSON.parseObject(response);
String prepayId = result.getString("prepay_id");
if (StringUtils.isBlank(prepayId)) {
par.setSuccess(false);
par.setMsg("pay v3 has no response.");
}else {
par.setSuccess(true);
par.setMsg("success.");
record.setPrepayId(prepayId);
record.setUpdateTime(new Date());
}
}
return par;
}
private V3CombinePayCommonMiniAppReq generateCombinePayReqeust(WxPayAccount payAccount,WxComposeOrder composeOrder,List<WxOrder> childOrders,String productName,
WxPayOrder record,WxAppinfo appInfo,String openId,String appId,Date currentDate,EnumPayShare isShare) throws Exception {
V3CombinePayCommonMiniAppReq req = new V3CombinePayCommonMiniAppReq();
req.setCombine_appid(appInfo.getAppId());
req.setCombine_mchid(payAccount.getMchId());
req.setCombine_out_trade_no(String.valueOf(composeOrder.getMainOrderId()));
List<V3CombineItemOrder> suborders = new ArrayList<V3CombineItemOrder>();
for (WxOrder order : childOrders) {
V3CombineItemOrder so = new V3CombineItemOrder();
String subMchId = getMerchantUid(record,order);
so.initByWxOrder(payAccount, order, subMchId, appInfo, productName, String.valueOf(record.getId()));
suborders.add(so);
}
req.setSub_orders(suborders);
V3CombinePayerReq payer = new V3CombinePayerReq();
payer.setSub_openid(openId);
req.setCombine_payer_info(payer);
req.setNotify_url(payAccount.getPayNotifyV3Url());
return req;
}
@Override
public PayAdapterResult pay(WxPayAccount payAccount,WxPayOrder record,WxComposeOrder composeOrder,List<WxOrder> childOrders,
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()) {
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"当前支付配置非服务商模式,不能使用该产品.");
}
//只能直连模式,
if (payAccount.getMchType() != EnumPayMchType.DIRECT.getCode()) {
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"当前支付版本不支持非直连模式");
}
WxPayService payService = maUtil.getWxPayService(appInfo, payAccount);
if (null == childOrders || childOrders.size() <= 0 ) {
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"子订单为空");
}
/*
* 普通支付/小程序支付
* https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_2_3.shtml
*/
if (childOrders.size() == 1) {
V3PayCommonMiniAppReq payReq = generatePayCommonRequest(payAccount,composeOrder,productName,record,openId,appInfo,currentDate);
String response = WxPayV3.payCommonWithMiniApp(payService, payReq);
log.info("pay order v3, " + payReq.toString() + ", response: " + response.toString());
return getOrderPResult(response,record);
} else {
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"合单查询无法处理,暂时不支持合单支付");
//合单支付/小程序支付
// V3CombinePayCommonMiniAppReq payReq = generateCombinePayReqeust(payAccount,composeOrder,childOrders,productName,record,appInfo,openId,appInfo.getAppId(),currentDate,isShare);
// String response = WxPayV3.payCombineCommonWithMiniApp(payService, payReq);
// log.info("pay order v3," + payReq.toString() + ", response: " + response.toString());
// return getOrderPResult(response);
}
}

private PayQueryAdapterResult getPayCommonQueryResult(String response) {
JSONObject result = JSON.parseObject(response);
String transtionId = result.getString("transaction_id");
String tradeState = result.getString("trade_state");
String tradeStateDesc = result.getString("trade_state_desc");
String successTime = result.getString("success_time");
EnumPayStatus payStatus = WxPayOrderServiceHelper.getPayStatus(tradeState);
if (null == payStatus) {
throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), "订单查询微信支付状态非法["+tradeState+"]");
}
if (StringUtils.isBlank(tradeStateDesc)) {
tradeStateDesc = payStatus.getMessage();
}
PayQueryAdapterResult qresult = new PayQueryAdapterResult(payStatus.getCode(), tradeStateDesc,null, response,transtionId,successTime);
return qresult;
}
private PayQueryAdapterResult getPayCombineQueryResult(String response) {
JSONObject result = JSON.parseObject(response);
//TODO 只有各子订单的状态,没有统一的状态,暂时无法处理
JSONArray subOrders = result.getJSONArray("sub_orders");
///######待处理
String transtionId = result.getString("transaction_id");
String tradeState = result.getString("trade_state");
String tradeStateDesc = result.getString("trade_state_desc");
String successTime = result.getString("success_time");
EnumPayStatus payStatus = WxPayOrderServiceHelper.getPayStatus(tradeState);
if (null == payStatus) {
throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), "订单查询微信支付状态非法["+tradeState+"]");
}
PayQueryAdapterResult qresult = new PayQueryAdapterResult(payStatus.getCode(), tradeStateDesc,null, response,transtionId,successTime);
return qresult;
}
@Override
public PayQueryAdapterResult queryPayStatus(WxPayOrder oldRecord, WxAppinfo appInfo,
WxPayAccount payAccount) throws Exception {
WxPayService payService = maUtil.getWxPayService(appInfo, payAccount);
V3PayQueryReq req = new V3PayQueryReq();
if (!oldRecord.isMulity()) {
req.setSp_mchid(payAccount.getMchId());
req.setSub_mchid(oldRecord.getSingleChildOrderShare().getMerchantUid());
req.setOut_trade_no(String.valueOf(oldRecord.getId()));
String response = WxPayV3.payCommonQuery(payService, req);
if (StringUtils.isBlank(response)){
log.error("pay common v3 query response is null."+JSON.toJSONString(req));
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"pay common v3 query response is null."+JSON.toJSONString(req));
}
return getPayCommonQueryResult(response);
}else {
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"合单查询无法处理,暂时不支持合单支付查询");
// req.setOut_trade_no(String.valueOf(oldRecord.getId()));
// String response = WxPayV3.payCombineQuery(payService, req);
// if (StringUtils.isBlank(response)){
// log.error("pay combine v3 query response is null."+JSON.toJSONString(req));
// throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"pay common v3 query response is null."+JSON.toJSONString(req));
// }
// return getPayCombineQueryResult(response);
}
}

@Override
public int queryPayStatus(PayQueryAdapterResult statusObject, String orderOutNo) throws Exception {
return getPayCommonQueryResult((String)statusObject.getData()).getCode();
}

@Override
public int queryPayStatusCode(WxPayOrder oldRecord, WxAppinfo appInfo, WxPayAccount payAccount)
throws Exception {
return queryPayStatus(oldRecord, appInfo, payAccount).getCode();
}

@Override
public PayAdapterResult payOrderClose(WxAppinfo appInfo, WxPayOrder record,WxPayAccount payAccount) throws Exception {
WxPayService payService = maUtil.getWxPayService(appInfo, payAccount);
if (!record.isMulity()) {
SFTPayQueryReq req = new SFTPayQueryReq();
req.setSp_mchid(payAccount.getMchId());
req.setSub_mchid(record.getSingleChildOrderShare().getMerchantUid());
req.setOut_trade_no(String.valueOf(record.getId()));
WxPayV3SFT.payCommonClose(payService, req);
return new PayAdapterResult(true, "close success", req, null);
}else {
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"因合单查询无法处理,暂时不支持合单支付关闭");
// CombineCloseReq req = new CombineCloseReq();
// req.setCombine_appid(appInfo.getAppId());
// req.setCombine_out_trade_no(String.valueOf(record.getId()));
// req.initSubOrders(payAccount, record);
//
// String response = WxPayV3.payCombineClose(payService, req);
// return new PayAdapterResult(true, "close success", req, null);
}
}

@Override
public PayAdapterResult payOrderReverse(WxAppinfo appInfo, WxPayOrder record, WxPayAccount payAccount)
throws Exception {
return super.payOrderReverse(appInfo, record, payAccount,payAccount.getSubMchId());
}

@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);
}

@Override
public PayAdapterResult noCreatePay(WxPayOrder record, WxComposeOrder composeOrder, List<WxOrder> childOrders) {
throw new MallinkException(ErrorCode.SYS_PARAMETER_ERROR);
}

}

Caricamento…
Annulla
Salva