|
@@ -0,0 +1,279 @@ |
|
|
|
|
|
package com.iformall.service.pay.service.pay.wx.v3.nativePay; |
|
|
|
|
|
|
|
|
|
|
|
import com.alibaba.fastjson.JSON; |
|
|
|
|
|
import com.alibaba.fastjson.JSONArray; |
|
|
|
|
|
import com.alibaba.fastjson.JSONObject; |
|
|
|
|
|
import com.github.binarywang.wxpay.exception.WxPayException; |
|
|
|
|
|
import com.github.binarywang.wxpay.service.WxPayService; |
|
|
|
|
|
import com.iformall.common.ErrorCode; |
|
|
|
|
|
import com.iformall.domain.po.*; |
|
|
|
|
|
import com.iformall.enums.*; |
|
|
|
|
|
import com.iformall.exception.MallinkException; |
|
|
|
|
|
import com.iformall.pay.WxPayV3; |
|
|
|
|
|
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.SFTPayQueryReq; |
|
|
|
|
|
import com.iformall.service.pay.service.pay.wx.v3.BaseWxPayV3AdapterService; |
|
|
|
|
|
import com.iformall.service.pay.service.pay.wx.v3.entity.*; |
|
|
|
|
|
import com.iformall.utils.DateUtils; |
|
|
|
|
|
import com.iformall.utils.MaUtil; |
|
|
|
|
|
import com.iformall.utils.Utility; |
|
|
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
|
|
import org.apache.commons.lang3.StringUtils; |
|
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
|
|
import org.springframework.stereotype.Service; |
|
|
|
|
|
|
|
|
|
|
|
import java.io.File; |
|
|
|
|
|
import java.io.UnsupportedEncodingException; |
|
|
|
|
|
import java.util.*; |
|
|
|
|
|
|
|
|
|
|
|
@Slf4j |
|
|
|
|
|
@Service |
|
|
|
|
|
public class WxNativePayV3AdapterService extends BaseWxPayV3AdapterService implements CDrivingPayService{ |
|
|
|
|
|
|
|
|
|
|
|
@Autowired |
|
|
|
|
|
MaUtil maUtil; |
|
|
|
|
|
|
|
|
|
|
|
private V3CreatePayReq generateCreatePayRequest(ProductOrder productOrder,WxAppinfo appInfo,WxPayAccount payAccount) throws Exception { |
|
|
|
|
|
V3CreatePayReq req = new V3CreatePayReq(); |
|
|
|
|
|
req.setAppid(appInfo.getAppId()); |
|
|
|
|
|
req.setMchid(payAccount.getSubMchId()); |
|
|
|
|
|
try { |
|
|
|
|
|
//中文必须要这样,否则会双方签名失败 |
|
|
|
|
|
req.setDescription(WxPayV3.handleChinese(appInfo.getName()+"-"+productOrder.getProductTitle())); |
|
|
|
|
|
} catch (UnsupportedEncodingException e) { |
|
|
|
|
|
req.setDescription("weixin miniApp product"); |
|
|
|
|
|
} |
|
|
|
|
|
req.setOut_trade_no(productOrder.getOrderNumber()); |
|
|
|
|
|
req.setNotify_url(payAccount.getPayNotifyV3Url(appInfo.getProjectType())); |
|
|
|
|
|
|
|
|
|
|
|
V3PayAmountReq amout = new V3PayAmountReq(); |
|
|
|
|
|
amout.setTotal(productOrder.getOrderPrice()); |
|
|
|
|
|
req.setAmount(amout); |
|
|
|
|
|
|
|
|
|
|
|
V3Payer payer = new V3Payer(); |
|
|
|
|
|
payer.setOpenid(productOrder.getOpenId()); |
|
|
|
|
|
req.setPayer(payer); |
|
|
|
|
|
|
|
|
|
|
|
return req; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private PayAdapterResult getOrderPResult(String response,WxPayService payService,WxAppinfo appInfo,WxPayAccount payAccount,String order_no) { |
|
|
|
|
|
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 codeUrl = result.getString("code_url"); |
|
|
|
|
|
if (StringUtils.isBlank(codeUrl)) { |
|
|
|
|
|
par.setSuccess(false); |
|
|
|
|
|
par.setMsg("pay v3 has no response."); |
|
|
|
|
|
}else { |
|
|
|
|
|
par.setSuccess(true); |
|
|
|
|
|
par.setMsg("success."); |
|
|
|
|
|
par.setData(getPayRetMap(codeUrl, order_no)); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
return par; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private Map getPayRetMap(String codeUrl,String order_no) { |
|
|
|
|
|
Map returnMap = new HashMap(); |
|
|
|
|
|
returnMap.put("codeUrl", codeUrl); |
|
|
|
|
|
returnMap.put("payOrderId", order_no); |
|
|
|
|
|
return returnMap; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@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 { |
|
|
|
|
|
return null; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
public PayAdapterResult createPay(ProductOrder order, WxAppinfo appInfo, WxPayAccount payAccount) throws Exception { |
|
|
|
|
|
|
|
|
|
|
|
WxPayService payService = maUtil.getWxPayServiceBySelfModel(appInfo, payAccount); |
|
|
|
|
|
|
|
|
|
|
|
V3CreatePayReq payReq = generateCreatePayRequest(order,appInfo,payAccount); |
|
|
|
|
|
try { |
|
|
|
|
|
String response = WxPayV3.payCommonNative(payService, payReq); |
|
|
|
|
|
return getOrderPResult(response,payService,appInfo,payAccount,order.getOrderNumber()); |
|
|
|
|
|
}catch(WxPayException e) { |
|
|
|
|
|
log.error("wexin pay v3 error",e); |
|
|
|
|
|
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),e.getCustomErrorMsg()); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
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 getPayQueryResult(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"); |
|
|
|
|
|
JSONObject payer = result.getJSONObject("payer"); |
|
|
|
|
|
String openid = null; |
|
|
|
|
|
if(payer != null){ |
|
|
|
|
|
openid = payer.getString("openid"); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
EnumProductOrderStatus payStatus = WxPayOrderServiceHelper.getProductOrderStatus(tradeState); |
|
|
|
|
|
if (null == payStatus) { |
|
|
|
|
|
throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), "订单查询微信支付状态非法["+tradeState+"]"); |
|
|
|
|
|
} |
|
|
|
|
|
if (StringUtils.isBlank(tradeStateDesc)) { |
|
|
|
|
|
tradeStateDesc = payStatus.getMessage(); |
|
|
|
|
|
} |
|
|
|
|
|
PayQueryAdapterResult qresult = new PayQueryAdapterResult(); |
|
|
|
|
|
qresult.setCode(payStatus.getCode()); |
|
|
|
|
|
qresult.setMsg(tradeStateDesc); |
|
|
|
|
|
qresult.setTransactionId(transtionId); |
|
|
|
|
|
qresult.setOpenId(openid); |
|
|
|
|
|
if(StringUtils.isNotBlank(successTime)){ |
|
|
|
|
|
qresult.setPayTime(DateUtils.rfc3339Formatter(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()); |
|
|
|
|
|
//总分 |
|
|
|
|
|
if (payAccount.getMchType() == EnumPayMchType.TOTAL.getCode()) { |
|
|
|
|
|
req.setSub_mchid(payAccount.getSubMchId()); |
|
|
|
|
|
}else if (payAccount.getMchType() == EnumPayMchType.DIRECT.getCode()) { |
|
|
|
|
|
req.setSub_mchid(oldRecord.getSingleChildOrderShare().getMerchantUid()); |
|
|
|
|
|
} |
|
|
|
|
|
req.setOut_trade_no(oldRecord.getPayOrderNo()); |
|
|
|
|
|
try { |
|
|
|
|
|
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); |
|
|
|
|
|
}catch(WxPayException e) { |
|
|
|
|
|
log.error("pay common v3 query response error",e); |
|
|
|
|
|
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),e.getCustomErrorMsg()); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
}else { |
|
|
|
|
|
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"合单查询无法处理,暂时不支持合单支付查询"); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 单商户模式 |
|
|
|
|
|
* @param order |
|
|
|
|
|
* @param appInfo |
|
|
|
|
|
* @param payAccount |
|
|
|
|
|
* @return |
|
|
|
|
|
* @throws Exception |
|
|
|
|
|
*/ |
|
|
|
|
|
@Override |
|
|
|
|
|
public PayQueryAdapterResult queryPayStatus(ProductOrder order, WxAppinfo appInfo, WxPayAccount payAccount) throws Exception { |
|
|
|
|
|
WxPayService payService = maUtil.getWxPayServiceBySelfModel(appInfo, payAccount); |
|
|
|
|
|
V3PayQuery req = new V3PayQuery(); |
|
|
|
|
|
req.setMchid(payAccount.getSubMchId()); |
|
|
|
|
|
req.setOut_trade_no(order.getOrderNumber()); |
|
|
|
|
|
try { |
|
|
|
|
|
String response = WxPayV3.payQuery(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 getPayQueryResult(response); |
|
|
|
|
|
}catch(WxPayException e) { |
|
|
|
|
|
log.error("pay common v3 query response error",e); |
|
|
|
|
|
if("ORDER_CLOSED".equals(e.getErrCode())){ |
|
|
|
|
|
PayQueryAdapterResult result = new PayQueryAdapterResult(); |
|
|
|
|
|
result.setCode(EnumProductOrderStatus.ORDER_STATUS_OVERTIME_CANCEL.getCode()); |
|
|
|
|
|
result.setMsg(EnumProductOrderStatus.ORDER_STATUS_OVERTIME_CANCEL.getMessage()); |
|
|
|
|
|
return result; |
|
|
|
|
|
}else if("ORDER_NOT_EXIST".equals(e.getErrCode()) || "ORDERNOTEXIST".equals(e.getErrCode())){ |
|
|
|
|
|
PayQueryAdapterResult result = new PayQueryAdapterResult(); |
|
|
|
|
|
result.setCode(EnumProductOrderStatus.ORDER_STATUS_PENDING_PAYMENT.getCode()); |
|
|
|
|
|
result.setMsg(EnumProductOrderStatus.ORDER_STATUS_PENDING_PAYMENT.getMessage()); |
|
|
|
|
|
return result; |
|
|
|
|
|
} |
|
|
|
|
|
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),e.getCustomErrorMsg()); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@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 { |
|
|
|
|
|
return 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 String getScheme(WxAppinfo appinfo, String pageUrl, String sceneParam,Long expireTime) throws Exception { |
|
|
|
|
|
return super.generateScheme(appinfo, pageUrl, sceneParam,expireTime); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
public PayAdapterResult noCreatePay(WxPayOrder record, WxComposeOrder composeOrder, List<WxOrder> childOrders) { |
|
|
|
|
|
throw new MallinkException(ErrorCode.SYS_PARAMETER_ERROR); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
public void sendSubscribeMsg(WxAppinfo appinfo, WxTemplateMsg wxTemplateMsg, String openId, String toPage, Map<String, String> param) throws Exception { |
|
|
|
|
|
super.subscribeMsg(appinfo,wxTemplateMsg,openId,toPage,param); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |