|
|
|
@@ -3,10 +3,12 @@ package com.iformall.service.pay.impl; |
|
|
|
import java.util.Date; |
|
|
|
import java.util.Map; |
|
|
|
|
|
|
|
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.WxOrder; |
|
|
|
import com.iformall.domain.po.WxPayAccount; |
|
|
|
import com.iformall.domain.po.WxPayOrder; |
|
|
|
@@ -23,114 +25,165 @@ import com.iformall.utils.BeanUtils; |
|
|
|
import com.iformall.utils.MapUtil; |
|
|
|
import com.iformall.utils.Utility; |
|
|
|
|
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
|
|
|
|
@Slf4j |
|
|
|
public class WxPayAdapterService implements PayAdapterService{ |
|
|
|
|
|
|
|
|
|
|
|
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, WxOrder order, 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(order.getDetail()); |
|
|
|
wxPayOrderP.setOut_trade_no(record.getPayOrderNo()); |
|
|
|
wxPayOrderP.setTotal_fee(order.getPayment()); |
|
|
|
wxPayOrderP.setSpbill_create_ip(record.getIp()); // 终端IP |
|
|
|
wxPayOrderP.setGoods_tag(String.valueOf(order.getProductId())); |
|
|
|
wxPayOrderP.setNotify_url(payAccount.getPayNotifyUrl()); |
|
|
|
wxPayOrderP.setTrade_type(WxPay.TradeType.JSAPI.name()); // 终端类型 |
|
|
|
wxPayOrderP.setProduct_id(String.valueOf(order.getId())); // 订单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,String noncestr) { |
|
|
|
returnMap.put("payOrderId", String.valueOf(record.getId())); |
|
|
|
String result_code = returnMap.get("result_code"); |
|
|
|
if ("SUCCESS".equals(result_code)) { |
|
|
|
String prepay_id = returnMap.get("prepay_id"); |
|
|
|
// update payOrder with prepay_id |
|
|
|
record.setPrepayId(prepay_id); |
|
|
|
record.setUpdateTime(new Date()); |
|
|
|
try { |
|
|
|
wxPayOrderMapper.updateById(record); |
|
|
|
} catch (Exception e) { |
|
|
|
log.error("pay order update error: " + record.toString()); |
|
|
|
throw new MallinkException(ErrorCode.DB_FAIL); |
|
|
|
} |
|
|
|
|
|
|
|
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()); |
|
|
|
return new ResultData(Result.SUCCESS, "创建支付订单成功", returnMap); |
|
|
|
} 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()); |
|
|
|
try { |
|
|
|
wxPayOrderMapper.updateById(record); |
|
|
|
} catch (Exception e) { |
|
|
|
logger.error("pay order update error: " + record.toString()); |
|
|
|
throw new MallinkException(ErrorCode.DB_FAIL); |
|
|
|
} |
|
|
|
return new ResultData(ErrorCode.PAY_ORDER_ERROR.getCode(), errMsg, returnMap); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private WxPayOrderSP generateWxPayOrderSP(WxPayAccount payAccount, WxOrder order, WxPayOrder record,WxAppinfo appInfo,String openId,String parentAppId,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(order.getDetail()); |
|
|
|
wxPayOrderSP.setOut_trade_no(record.getPayOrderNo()); |
|
|
|
wxPayOrderSP.setTotal_fee(order.getPayment().toString()); |
|
|
|
wxPayOrderSP.setSpbill_create_ip(record.getIp()); // 终端IP |
|
|
|
wxPayOrderSP.setGoods_tag(String.valueOf(order.getProductId())); // 券ID |
|
|
|
wxPayOrderSP.setNotify_url(payAccount.getPayNotifyUrl()); |
|
|
|
wxPayOrderSP.setTrade_type(WxPay.TradeType.JSAPI.name()); // 终端类型 |
|
|
|
wxPayOrderSP.setProduct_id(String.valueOf(order.getProductId())); // 券ID |
|
|
|
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; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
public PayAdapterResult pay(WxPayAccount payAccount, WxOrder order, WxPayOrder record, Object... params) { |
|
|
|
WxAppinfo appInfo = (WxAppinfo) params[01]; |
|
|
|
String openId = (String) params[1]; |
|
|
|
String appId = (String) params[2]; |
|
|
|
Date currentDate = (Date) params[3]; |
|
|
|
EnumPayShare isShare = (EnumPayShare) params[4]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (payAccount.getType() == EnumPayMode.MCH.getCode()) { |
|
|
|
// 统一下单 普通商户模式 |
|
|
|
String noncestr = Utility.generate32UUID(); |
|
|
|
WxPayOrderP wxPayOrderP = new WxPayOrderP(); |
|
|
|
wxPayOrderP.setOpenid(user.getOpenId()); |
|
|
|
wxPayOrderP.setAppid(user.getAppId()); |
|
|
|
wxPayOrderP.setMch_id(payAccount.getMchId()); |
|
|
|
wxPayOrderP.setNonce_str(noncestr); |
|
|
|
wxPayOrderP.setBody(order.getDetail()); |
|
|
|
wxPayOrderP.setOut_trade_no(record.getPayOrderNo()); |
|
|
|
wxPayOrderP.setTotal_fee(order.getPayment()); |
|
|
|
wxPayOrderP.setSpbill_create_ip(record.getIp()); // 终端IP |
|
|
|
wxPayOrderP.setGoods_tag(String.valueOf(order.getProductId())); |
|
|
|
wxPayOrderP.setNotify_url(payAccount.getPayNotifyUrl()); |
|
|
|
wxPayOrderP.setTrade_type(WxPay.TradeType.JSAPI.name()); // 终端类型 |
|
|
|
wxPayOrderP.setProduct_id(String.valueOf(order.getId())); // 订单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())); |
|
|
|
WxPayOrderP wxPayOrderP = generateWxPayOrderP(payAccount,order,record,openId,appId,currentDate); |
|
|
|
String response = WxPay.pushOrder(BeanUtils.toStringMap(wxPayOrderP)); |
|
|
|
logger.info("pay order, wechat pushOrder, " + wxPayOrderP.toString() + ", response: " + response.toString()); |
|
|
|
log.info("pay order, wechat pushOrder, " + wxPayOrderP.toString() + ", response: " + response.toString()); |
|
|
|
|
|
|
|
Map<String, String> returnMap = WxPayment.xmlToMap(response); |
|
|
|
returnMap.put("payOrderId", String.valueOf(record.getId())); |
|
|
|
String result_code = returnMap.get("result_code"); |
|
|
|
if ("SUCCESS".equals(result_code)) { |
|
|
|
String prepay_id = returnMap.get("prepay_id"); |
|
|
|
// update payOrder with prepay_id |
|
|
|
record.setPrepayId(prepay_id); |
|
|
|
record.setUpdateTime(new Date()); |
|
|
|
try { |
|
|
|
wxPayOrderMapper.updateById(record); |
|
|
|
} catch (Exception e) { |
|
|
|
logger.error("pay order update error: " + record.toString()); |
|
|
|
throw new MallinkException(ErrorCode.DB_FAIL); |
|
|
|
} |
|
|
|
|
|
|
|
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); |
|
|
|
logger.info("back to UI: " + returnMap.toString()); |
|
|
|
return new ResultData(Result.SUCCESS, "创建支付订单成功", returnMap); |
|
|
|
} 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()); |
|
|
|
try { |
|
|
|
wxPayOrderMapper.updateById(record); |
|
|
|
} catch (Exception e) { |
|
|
|
logger.error("pay order update error: " + record.toString()); |
|
|
|
throw new MallinkException(ErrorCode.DB_FAIL); |
|
|
|
} |
|
|
|
return new ResultData(ErrorCode.PAY_ORDER_ERROR.getCode(), errMsg, returnMap); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
// 统一下单 // 服务商模式 |
|
|
|
String noncestr = Utility.generate32UUID(); |
|
|
|
WxPayOrderSP wxPayOrderSP = new WxPayOrderSP(); |
|
|
|
wxPayOrderSP.setSub_openid(user.getOpenId()); |
|
|
|
wxPayOrderSP.setAppid(appInfo.getParentAppId()); |
|
|
|
wxPayOrderSP.setMch_id(payAccount.getMchId()); |
|
|
|
wxPayOrderSP.setSub_appid(user.getAppId()); |
|
|
|
wxPayOrderSP.setSub_mch_id(payAccount.getSubMchId()); |
|
|
|
wxPayOrderSP.setNonce_str(noncestr); |
|
|
|
wxPayOrderSP.setBody(order.getDetail()); |
|
|
|
wxPayOrderSP.setOut_trade_no(record.getPayOrderNo()); |
|
|
|
wxPayOrderSP.setTotal_fee(order.getPayment().toString()); |
|
|
|
wxPayOrderSP.setSpbill_create_ip(record.getIp()); // 终端IP |
|
|
|
wxPayOrderSP.setGoods_tag(String.valueOf(order.getProductId())); // 券ID |
|
|
|
wxPayOrderSP.setNotify_url(payAccount.getPayNotifyUrl()); |
|
|
|
wxPayOrderSP.setTrade_type(WxPay.TradeType.JSAPI.name()); // 终端类型 |
|
|
|
wxPayOrderSP.setProduct_id(String.valueOf(order.getProductId())); // 券ID |
|
|
|
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())); |
|
|
|
WxPayOrderSP wxPayOrderSP = generateWxPayOrderSP(payAccount,order,record,openId,parentAppId,appId,currentDate,isShare); |
|
|
|
String response = WxPay.pushOrder(BeanUtils.toStringMap(wxPayOrderSP)); |
|
|
|
logger.info("pay order, wechat pushOrder, " + wxPayOrderSP.toString() + ", response: " + response.toString()); |
|
|
|
log.info("pay order, wechat pushOrder, " + wxPayOrderSP.toString() + ", response: " + response.toString()); |
|
|
|
|
|
|
|
Map<String, String> returnMap = WxPayment.xmlToMap(response); |
|
|
|
returnMap.put("payOrderId", String.valueOf(record.getId())); |
|
|
|
String result_code = returnMap.get("result_code"); |
|
|
|
|