Commit aa8011de authored by jmdhappy's avatar jmdhappy
Browse files

升级支付宝为最新接口

parent 6bb11b08
......@@ -3,15 +3,12 @@ package org.xxpay.service.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.xxpay.common.util.MyBase64;
import org.xxpay.common.util.MyLog;
import org.xxpay.dal.dao.model.MchInfo;
import org.xxpay.service.channel.alipay.sign.Base64;
import org.xxpay.service.service.MchInfoService;
/**
......
package org.xxpay.service.controller;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.xxpay.common.constant.PayConstant;
import org.xxpay.common.util.MyLog;
import org.xxpay.dal.dao.model.PayChannel;
import org.xxpay.dal.dao.model.PayOrder;
import org.xxpay.service.channel.alipay.config.AlipayConfig;
import org.xxpay.service.channel.alipay.util.AlipayNotify;
import org.xxpay.service.channel.tencent.common.Util;
import org.xxpay.service.channel.tencent.protocol.notify_protocol.NotifyUnifiedOrderResData;
import org.xxpay.service.channel.alipay.AlipayConfig;
import org.xxpay.service.service.PayChannelService;
import org.xxpay.service.service.PayOrderService;
......@@ -21,6 +18,7 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
......@@ -56,16 +54,28 @@ public class Notify4AliPayController extends Notify4BasePay {
* @throws IOException
*/
@RequestMapping(value = "/pay/aliPayNotifyRes.htm")
@ResponseBody
public String aliPayNotifyRes(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
return doAliPayRes(request, response);
public void aliPayNotifyRes(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String result = doAliPayRes(request, response);
if(result != null) {
_log.info("alipay notify response: {}", result);
response.setContentType("text/html");
PrintWriter pw;
try {
pw = response.getWriter();
pw.print(result);
} catch (IOException e) {
_log.error("Pay response write exception.", e);
}
}
}
public String doAliPayRes(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String logPrefix = "【支付宝支付回调通知】";
_log.info("====== 开始接收支付宝支付回调通知 ======");
//获取支付宝POST过来反馈信息
Map<String,String> params = new HashMap<>();
Map<String,String> params = new HashMap<String,String>();
Map requestParams = request.getParameterMap();
for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
......@@ -82,23 +92,17 @@ public class Notify4AliPayController extends Notify4BasePay {
_log.info("{}通知请求数据:reqStr={}", logPrefix, params);
if(params.isEmpty()) {
_log.error("{}请求参数为空", logPrefix);
return makeRetData(PayConstant.RETURN_VALUE_FAIL, "请求参数为空");
return PayConstant.RETURN_ALIPAY_VALUE_FAIL;
}
Map<String, Object> payContext = new HashMap();
PayOrder payOrder;
payContext.put("parameters", params);
if(!verifyAliPayParams(payContext)) {
return makeRetData(PayConstant.RETURN_VALUE_FAIL, (String) payContext.get("retMsg"));
return PayConstant.RETURN_ALIPAY_VALUE_FAIL;
}
_log.info("{}验证请求数据及签名通过", logPrefix);
String out_trade_no = params.get("out_trade_no"); // 商户订单号
String trade_no = params.get("trade_no"); // 支付宝订单号
String trade_status = params.get("trade_status"); // 交易状态
String buyer_email = params.get("buyer_email"); // 买家支付宝账号
// 支付状态成功或者完成
if (trade_status.equals(PayConstant.AlipayConstant.TRADE_STATUS_SUCCESS) ||
trade_status.equals(PayConstant.AlipayConstant.TRADE_STATUS_FINISHED)) {
......@@ -133,38 +137,18 @@ public class Notify4AliPayController extends Notify4BasePay {
public boolean verifyAliPayParams(Map<String, Object> payContext) {
Map<String,String> params = (Map<String,String>)payContext.get("parameters");
String out_trade_no = params.get("out_trade_no"); // 商户订单号
String seller_email = params.get("seller_email"); // 卖家支付宝账号
String total_fee = params.get("total_fee"); // 支付金额
String buyer_email = params.get("buyer_email"); // 买家支付宝账号
String sign = params.get("sign"); // 签名
String total_amount = params.get("total_amount"); // 支付金额
if (StringUtils.isEmpty(out_trade_no)) {
_log.error("AliPay Notify parameter out_trade_no is empty. out_trade_no={}", out_trade_no);
payContext.put("retMsg", "out_trade_no is empty");
return false;
}
if (StringUtils.isEmpty(seller_email)) {
_log.error("AliPay Notify parameter seller_email is empty. seller_email={}", seller_email);
payContext.put("retMsg", "seller_email is empty");
return false;
}
if (StringUtils.isEmpty(total_fee)) {
_log.error("AliPay Notify parameter total_fee is empty. total_fee={}", total_fee);
payContext.put("retMsg", "total_fee is empty");
return false;
}
if (StringUtils.isEmpty(buyer_email)) {
_log.error("AliPay Notify parameter buyer_email is empty. buyer_email={}", buyer_email);
payContext.put("retMsg", "buyer_email is empty");
if (StringUtils.isEmpty(total_amount)) {
_log.error("AliPay Notify parameter total_amount is empty. total_fee={}", total_amount);
payContext.put("retMsg", "total_amount is empty");
return false;
}
if (StringUtils.isEmpty(sign)) {
_log.error("AliPay Notify parameter sign is empty. sign={}", sign);
payContext.put("retMsg", "sign is empty");
return false;
}
String errorMessage;
// 查询payOrder记录
String payOrderId = out_trade_no;
PayOrder payOrder = payOrderService.selectPayOrder(payOrderId);
......@@ -173,7 +157,6 @@ public class Notify4AliPayController extends Notify4BasePay {
payContext.put("retMsg", "Can't found payOrder");
return false;
}
// 查询payChannel记录
String mchId = payOrder.getMchId();
String channelId = payOrder.getChannelId();
......@@ -183,20 +166,26 @@ public class Notify4AliPayController extends Notify4BasePay {
payContext.put("retMsg", "Can't found payChannel");
return false;
}
boolean verify_result = false;
try {
verify_result = AlipaySignature.rsaCheckV1(params, alipayConfig.init(payChannel.getParam()).getAlipay_public_key(), AlipayConfig.CHARSET, "RSA2");
} catch (AlipayApiException e) {
_log.error(e, "AlipaySignature.rsaCheckV1 error");
}
// 验证签名
if (!AlipayNotify.verify(alipayConfig.init(payChannel.getParam()), params)) {
errorMessage = "Verify VV pay sign failed.";
if (!verify_result) {
errorMessage = "rsaCheckV1 failed.";
_log.error("AliPay Notify parameter {}", errorMessage);
payContext.put("retMsg", errorMessage);
return false;
}
// 核对金额
long aliPayAmt = new BigDecimal(total_fee).movePointRight(2).longValue();
long aliPayAmt = new BigDecimal(total_amount).movePointRight(2).longValue();
long dbPayAmt = payOrder.getAmount().longValue();
if (dbPayAmt != aliPayAmt) {
_log.error("db payOrder record payPrice not equals total_fee. total_fee={},payOrderId={}", total_fee, payOrderId);
_log.error("db payOrder record payPrice not equals total_amount. total_amount={},payOrderId={}", total_amount, payOrderId);
payContext.put("retMsg", "");
return false;
}
......@@ -204,15 +193,4 @@ public class Notify4AliPayController extends Notify4BasePay {
return true;
}
String makeRetData(String retCode, String retMsg) {
NotifyUnifiedOrderResData data = new NotifyUnifiedOrderResData();
data.setReturn_code(retCode);
data.setReturn_msg(retMsg);
return Util.objectToXML(data);
}
String makeRetData(String retCode) {
return makeRetData(retCode, "");
}
}
......@@ -119,7 +119,7 @@ public class Notify4BasePay {
pw = response.getWriter();
pw.print(message);
} catch (IOException e) {
_log.error("JDPay response write exception.", e);
_log.error("Pay response write exception.", e);
}
_log.info(">>>>>> PAY回调通知业务系统完成 <<<<<<");
}
......
......@@ -2,34 +2,35 @@ package org.xxpay.service.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.xxpay.common.constant.PayConstant;
import org.xxpay.common.constant.PayEnum;
import org.xxpay.common.util.*;
import org.xxpay.common.util.AmountUtil;
import org.xxpay.common.util.MyBase64;
import org.xxpay.common.util.MyLog;
import org.xxpay.common.util.XXPayUtil;
import org.xxpay.dal.dao.model.MchInfo;
import org.xxpay.dal.dao.model.PayChannel;
import org.xxpay.dal.dao.model.PayOrder;
import org.xxpay.service.channel.alipay.config.AlipayConfig;
import org.xxpay.service.channel.alipay.sign.RSA;
import org.xxpay.service.channel.alipay.util.AlipayCore;
import org.xxpay.service.channel.tencent.common.Configure;
import org.xxpay.service.channel.tencent.common.Signature;
import org.xxpay.service.channel.tencent.common.Util;
import org.xxpay.service.channel.tencent.protocol.order_protocol.UnifiedOrderReqData;
import org.xxpay.service.channel.tencent.protocol.order_protocol.UnifiedOrderResData;
import org.xxpay.service.channel.tencent.service.UnifiedOrderService;
import org.xxpay.service.channel.alipay.AlipayConfig;
import org.xxpay.service.service.MchInfoService;
import org.xxpay.service.service.PayChannelService;
import org.xxpay.service.service.PayOrderService;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
/**
......@@ -44,18 +45,12 @@ public class PayChannel4AlipayController {
private final MyLog _log = MyLog.getLog(PayChannel4AlipayController.class);
@Autowired
private DiscoveryClient client;
@Autowired
private PayOrderService payOrderService;
@Autowired
private PayChannelService payChannelService;
@Autowired
UnifiedOrderService unifiedOrderService;
@Autowired
private AlipayConfig alipayConfig;
......@@ -63,8 +58,8 @@ public class PayChannel4AlipayController {
private MchInfoService mchInfoService;
/**
* 支付宝WAP支付
* 文档:https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.ZGobeF&treeId=60&articleId=104790&docType=1
* 支付宝手机网站支付
* 文档:https://docs.open.alipay.com/203/107090/
* @param jsonParam
* @return
*/
......@@ -81,62 +76,41 @@ public class PayChannel4AlipayController {
if("".equals(resKey)) return XXPayUtil.makeRetFail(XXPayUtil.makeRetMap(PayConstant.RETURN_VALUE_FAIL, "", PayConstant.RETURN_VALUE_FAIL, PayEnum.ERR_0001));
PayChannel payChannel = payChannelService.selectPayChannel(channelId, mchId);
alipayConfig.init(payChannel.getParam());
Map<String, String> payMap = new HashMap<>();
payMap.put("service", "alipay.wap.create.direct.pay.by.user"); // 接口名称
payMap.put("partner", alipayConfig.getPartner()); // 签约的支付宝账号对应的支付宝唯一用户号
payMap.put("_input_charset", "utf-8"); // 商户网站使用的编码格式,仅支持UTF-8
payMap.put("notify_url", alipayConfig.getNotify_url()); // 支付宝服务器主动通知商户网站里指定的页面http路径
//if (!StringUtils.isEmpty(params.get("respUrl"))) {
// payMap.put("return_url", params.get("respUrl")); // 支付宝处理完请求后,当前页面自动跳转到商户网站里指定页面的http路径(该字段可以不参与签名,但值不能为空!)
//}
payMap.put("out_trade_no", payOrderId); // 支付宝合作商户网站唯一订单号
payMap.put("subject", payOrder.getSubject()); // 商品的标题/交易标题/订单标题/订单关键字等
payMap.put("total_fee", AmountUtil.convertCent2Dollar(payOrder.getAmount().toString())); // 该笔订单的资金总额,单位为RMB-Yuan。取值范围为[0.01,100000000.00],精确到小数点后两位
payMap.put("seller_id", alipayConfig.getPartner()); // 卖家支付宝账号对应的支付宝唯一用户号
payMap.put("payment_type", "1"); // 支付类型。仅支持:1(商品购买)
AlipayClient client = new DefaultAlipayClient(alipayConfig.getUrl(), alipayConfig.getApp_id(), alipayConfig.getRsa_private_key(), AlipayConfig.FORMAT, AlipayConfig.CHARSET, alipayConfig.getAlipay_public_key(), AlipayConfig.SIGNTYPE);
AlipayTradeWapPayRequest alipay_request = new AlipayTradeWapPayRequest();
// 封装请求支付信息
AlipayTradeWapPayModel model=new AlipayTradeWapPayModel();
model.setOutTradeNo(payOrderId);
model.setSubject(payOrder.getSubject());
model.setTotalAmount(AmountUtil.convertCent2Dollar(payOrder.getAmount().toString()));
model.setBody(payOrder.getBody());
model.setProductCode("QUICK_WAP_PAY");
// 获取objParams参数
String objParams = payOrder.getExtra();
String show_url = "http://www.xxpay.org";
if (!org.springframework.util.StringUtils.isEmpty(objParams)) {
if (StringUtils.isNotEmpty(objParams)) {
try {
JSONObject objParamsJson = JSONObject.parseObject(objParams);
show_url = ObjectUtils.toString(objParamsJson.getString("ali_show_url"), "http://www.xxpay.org");
JSONObject objParamsJson = JSON.parseObject(objParams);
if(StringUtils.isNotBlank(objParamsJson.getString("quit_url"))) {
model.setQuitUrl(objParamsJson.getString("quit_url"));
}
} catch (Exception e) {
_log.error("{}objParams参数格式错误!", logPrefix);
}
}
payMap.put("show_url", show_url); // 用户付款中途退出返回商户网站的地址
payMap.put("body", payOrder.getBody()); // 对一笔交易的具体描述信息
payMap.put("it_b_pay", "60m"); // 设置未付款交易的超时时间,一旦超时,该笔交易就会自动被关闭
payMap.put("app_pay", "Y"); // app_pay=Y:尝试唤起支付宝客户端进行支付,若用户未安装支付宝,则继续使用wap收银台进行支付
String signContent = AlipayCore.createLinkString(payMap);
String paySign = RSA.sign(signContent, alipayConfig.getPrivate_key(), AlipayConfig.input_charset);
alipay_request.setBizModel(model);
// 设置异步通知地址
alipay_request.setNotifyUrl(alipayConfig.getNotify_url());
// 设置同步地址
alipay_request.setReturnUrl(alipayConfig.getReturn_url());
String payUrl = null;
try {
/**
* 仅需对sign 做URL编码
*/
paySign = URLEncoder.encode(paySign, "UTF-8");
} catch (UnsupportedEncodingException e) {
_log.error(e, "URLEncoder AliPay Sign Exception");
}
_log.info("{}生成请求支付宝签名,sign={}", logPrefix, paySign);
payMap.put("sign_type", "RSA"); // 签名类型
payMap.put("sign", paySign); // 签名
// 对有中文的参数转码
try {
payMap.put("subject", URLEncoder.encode(payOrder.getSubject(), "UTF-8"));
payMap.put("body", URLEncoder.encode(payOrder.getBody(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
payUrl = client.pageExecute(alipay_request).getBody();
} catch (AlipayApiException e) {
e.printStackTrace();
}
String payUrl = alipayConfig.getGateway().concat("?").concat(AlipayCore.createLinkString(payMap));
_log.info("{}生成跳转路径:payUrl={}", logPrefix, payUrl);
payOrderService.updateStatus4Ing(payOrderId, null);
_log.info("{}生成请求支付宝数据,req={}", logPrefix, payMap);
_log.info("{}生成请求支付宝数据,req={}", logPrefix, alipay_request.getBizModel());
_log.info("###### 商户统一下单处理完成 ######");
Map<String, Object> map = XXPayUtil.makeRetMap(PayConstant.RETURN_VALUE_SUCCESS, "", PayConstant.RETURN_VALUE_SUCCESS, null);
map.put("payOrderId", payOrderId);
......@@ -145,8 +119,8 @@ public class PayChannel4AlipayController {
}
/**
* 支付宝PC支付(即时到帐接口)
* 文档:https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.M7NEo1&treeId=62&articleId=104743&docType=1
* 支付宝电脑网站支付
* 文档:https://docs.open.alipay.com/270/105899/
* @param jsonParam
* @return
*/
......@@ -163,60 +137,44 @@ public class PayChannel4AlipayController {
if("".equals(resKey)) return XXPayUtil.makeRetFail(XXPayUtil.makeRetMap(PayConstant.RETURN_VALUE_FAIL, "", PayConstant.RETURN_VALUE_FAIL, PayEnum.ERR_0001));
PayChannel payChannel = payChannelService.selectPayChannel(channelId, mchId);
alipayConfig.init(payChannel.getParam());
Map<String, String> payMap = new HashMap<>();
payMap.put("service", "create_direct_pay_by_user"); // 接口名称
payMap.put("partner", alipayConfig.getPartner()); // 签约的支付宝账号对应的支付宝唯一用户号
payMap.put("_input_charset", "utf-8"); // 编码字符集
payMap.put("notify_url", alipayConfig.getNotify_url()); // 支付宝服务器主动通知商户网站里指定的页面http路径
//if (!StringUtils.isEmpty(params.get("respUrl"))) {
// payMap.put("return_url", params.get("respUrl")); // 支付宝处理完请求后,当前页面自动跳转到商户网站里指定页面的http路径(该字段可以不参与签名,但值不能为空!)
//}
payMap.put("out_trade_no", payOrderId); // 商户网站唯一订单号
payMap.put("subject", payOrder.getSubject()); // 订单标题
payMap.put("payment_type", "1"); // 支付类型,只支持取值为1(商品购买)
payMap.put("total_fee", AmountUtil.convertCent2Dollar(payOrder.getAmount().toString())); // 订单总金额
payMap.put("seller_id", alipayConfig.getPartner()); // 卖家支付宝用户号
payMap.put("body", payOrder.getBody()); // 对交易或商品的描述
// 附加参数
payMap.put("qr_pay_mode", "4");
AlipayClient client = new DefaultAlipayClient(alipayConfig.getUrl(), alipayConfig.getApp_id(), alipayConfig.getRsa_private_key(), AlipayConfig.FORMAT, AlipayConfig.CHARSET, alipayConfig.getAlipay_public_key(), AlipayConfig.SIGNTYPE);
AlipayTradePagePayRequest alipay_request = new AlipayTradePagePayRequest();
// 封装请求支付信息
AlipayTradePagePayModel model=new AlipayTradePagePayModel();
model.setOutTradeNo(payOrderId);
model.setSubject(payOrder.getSubject());
model.setTotalAmount(AmountUtil.convertCent2Dollar(payOrder.getAmount().toString()));
model.setBody(payOrder.getBody());
model.setProductCode("FAST_INSTANT_TRADE_PAY");
// 获取objParams参数
String objParams = payOrder.getExtra();
if (!org.springframework.util.StringUtils.isEmpty(objParams)) {
String qr_pay_mode = "2";
String qrcode_width = "200";
if (StringUtils.isNotEmpty(objParams)) {
try {
JSONObject objParamsJson = JSONObject.parseObject(objParams);
payMap.put("qr_pay_mode", ObjectUtils.toString(objParamsJson.getString("qr_pay_mode"), "4")); // 扫码支付的方式,支持前置模式和跳转模式。(4:直接显示二维码)
payMap.put("qrcode_width", ObjectUtils.toString(objParamsJson.getString("qrcode_width"), "200")); // 扫码支付的方式,支持前置模式和跳转模式。(定义二维码大小)
JSONObject objParamsJson = JSON.parseObject(objParams);
qr_pay_mode = ObjectUtils.toString(objParamsJson.getString("qr_pay_mode"), "2");
qrcode_width = ObjectUtils.toString(objParamsJson.getString("qrcode_width"), "200");
} catch (Exception e) {
_log.error("{}objParams参数格式错误!", logPrefix);
}
}
String signContent = AlipayCore.createLinkString(payMap);
String paySign = RSA.sign(signContent, alipayConfig.getPrivate_key(), AlipayConfig.input_charset);
model.setQrPayMode(qr_pay_mode);
model.setQrcodeWidth(Long.parseLong(qrcode_width));
alipay_request.setBizModel(model);
// 设置异步通知地址
alipay_request.setNotifyUrl(alipayConfig.getNotify_url());
// 设置同步地址
alipay_request.setReturnUrl(alipayConfig.getReturn_url());
String payUrl = null;
try {
/**
* 仅需对sign 做URL编码
*/
paySign = URLEncoder.encode(paySign, "UTF-8");
} catch (UnsupportedEncodingException e) {
_log.error(e, "URLEncoder AliPay Sign Exception");
}
_log.info("{}生成请求支付宝签名,sign={}", logPrefix, paySign);
payMap.put("sign_type", "RSA"); // 签名类型
payMap.put("sign", paySign); // 签名
// 对有中文的参数转码
try {
payMap.put("subject", URLEncoder.encode(payOrder.getSubject(), "UTF-8"));
payMap.put("body", URLEncoder.encode(payOrder.getBody(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
payUrl = client.pageExecute(alipay_request).getBody();
} catch (AlipayApiException e) {
e.printStackTrace();
}
String payUrl = alipayConfig.getGateway().concat("?").concat(AlipayCore.createLinkString(payMap));
_log.info("{}生成跳转路径:payUrl={}", logPrefix, payUrl);
payOrderService.updateStatus4Ing(payOrderId, null);
_log.info("{}生成请求支付宝数据,req={}", logPrefix, payMap);
_log.info("{}生成请求支付宝数据,req={}", logPrefix, alipay_request.getBizModel());
_log.info("###### 商户统一下单处理完成 ######");
Map<String, Object> map = XXPayUtil.makeRetMap(PayConstant.RETURN_VALUE_SUCCESS, "", PayConstant.RETURN_VALUE_SUCCESS, null);
map.put("payOrderId", payOrderId);
......@@ -225,13 +183,14 @@ public class PayChannel4AlipayController {
}
/**
* 支付宝支付,生产签名及请求支付宝的参数(注:不会向支付宝发请求)
* 支付宝APP支付,生产签名及请求支付宝的参数(注:不会向支付宝发请求)
* 文档: https://docs.open.alipay.com/204/105465/
* @param jsonParam
* @return
*/
@RequestMapping(value = "/pay/channel/ali_mobile")
public String doAliPayMobileReq(@RequestParam String jsonParam) {
String logPrefix = "【支付宝支付下单】";
String logPrefix = "【支付宝APP支付下单】";
JSONObject paramObj = JSON.parseObject(new String(MyBase64.decode(jsonParam)));
PayOrder payOrder = paramObj.getObject("payOrder", PayOrder.class);
String payOrderId = payOrder.getPayOrderId();
......@@ -242,43 +201,32 @@ public class PayChannel4AlipayController {
if("".equals(resKey)) return XXPayUtil.makeRetFail(XXPayUtil.makeRetMap(PayConstant.RETURN_VALUE_FAIL, "", PayConstant.RETURN_VALUE_FAIL, PayEnum.ERR_0001));
PayChannel payChannel = payChannelService.selectPayChannel(channelId, mchId);
alipayConfig.init(payChannel.getParam());
Map<String, String> payMap = new HashMap<>();
payMap.put("service", "mobile.securitypay.pay"); // 接口名称
payMap.put("partner", alipayConfig.getPartner()); // 合作者身份ID
payMap.put("_input_charset", "utf-8"); // 参数编码字符集
payMap.put("notify_url", alipayConfig.getNotify_url()); // 服务器异步通知页面路径
//payMap.put("app_id", ""); // 客户端号
//payMap.put("appenv", ""); // 客户端来源
payMap.put("out_trade_no", payOrderId); // 商户网站唯一订单号
payMap.put("subject", payOrder.getSubject()); // 商品名称
payMap.put("payment_type", "1"); // 支付类型
payMap.put("seller_id", alipayConfig.getAli_account()); // 卖家支付宝账号
payMap.put("total_fee", AmountUtil.convertCent2Dollar(payOrder.getAmount().toString())); // 总金额,需要分转元.
payMap.put("body", payOrder.getBody()); // 商品详情
//payMap.put("goods_type", ""); // 商品类型
//payMap.put("hb_fq_param", ""); // 花呗分期参数
//payMap.put("rn_check", ""); // 是否发起实名校验
//payMap.put("it_b_pay", "30m"); // 未付款交易的超时时间
//payMap.put("extern_token", ""); // 授权令牌
String signContent = AlipayCore.createLinkString(payMap);
String paySign = RSA.sign(signContent, alipayConfig.getPrivate_key(), AlipayConfig.input_charset);
AlipayClient client = new DefaultAlipayClient(alipayConfig.getUrl(), alipayConfig.getApp_id(), alipayConfig.getRsa_private_key(), AlipayConfig.FORMAT, AlipayConfig.CHARSET, alipayConfig.getAlipay_public_key(), AlipayConfig.SIGNTYPE);
AlipayTradeAppPayRequest alipay_request = new AlipayTradeAppPayRequest();
// 封装请求支付信息
AlipayTradeAppPayModel model=new AlipayTradeAppPayModel();
model.setOutTradeNo(payOrderId);
model.setSubject(payOrder.getSubject());
model.setTotalAmount(AmountUtil.convertCent2Dollar(payOrder.getAmount().toString()));
model.setBody(payOrder.getBody());
model.setProductCode("QUICK_MSECURITY_PAY");
alipay_request.setBizModel(model);
// 设置异步通知地址
alipay_request.setNotifyUrl(alipayConfig.getNotify_url());
// 设置同步地址
alipay_request.setReturnUrl(alipayConfig.getReturn_url());
String payParams = null;
try {
/**
* 仅需对sign 做URL编码
*/
paySign = URLEncoder.encode(paySign, "UTF-8");
} catch (UnsupportedEncodingException e) {
_log.error(e, "URLEncoder AliPay Sign Exception");
payParams = client.sdkExecute(alipay_request).getBody();
} catch (AlipayApiException e) {
e.printStackTrace();
}
_log.info("{}生成请求支付宝签名,sign={}", logPrefix, paySign);
payMap.put("sign_type", "RSA"); // 签名类型
payMap.put("sign", paySign); // 签名
payOrderService.updateStatus4Ing(payOrderId, null);
_log.info("{}生成请求支付宝数据,req={}", logPrefix, payMap);
_log.info("{}生成请求支付宝数据,payParams={}", logPrefix, payParams);
_log.info("###### 商户统一下单处理完成 ######");
Map<String, Object> map = XXPayUtil.makeRetMap(PayConstant.RETURN_VALUE_SUCCESS, "", PayConstant.RETURN_VALUE_SUCCESS, null);
map.put("payOrderId", payOrderId);
map.put("payParams", payMap);
map.put("payParams", payParams);
return XXPayUtil.makeRetData(map, resKey);
}
}
......@@ -159,7 +159,7 @@ public class Mq4PayNotify {
}
// 修改通知次数
try {
int result = payOrderService.updateNotify(orderId);
int result = payOrderService.updateNotify(orderId, (byte) 1);
_log.info("修改payOrderId={},通知业务系统次数->{}", orderId, result == 1 ? "成功" : "失败");
}catch (Exception e) {
_log.error(e, "修改通知次数异常");
......@@ -167,20 +167,21 @@ public class Mq4PayNotify {
return ; // 通知成功结束
}else {
// 通知失败,延时再通知
int cnt = count++;
int cnt = count+1;
_log.info("notify count={}", cnt);
if (cnt > 5) {
_log.info("notify count>5 stop. url={}", respUrl);
return ;
}
// 修改通知次数
try {
int result = payOrderService.updateNotify(orderId);
int result = payOrderService.updateNotify(orderId, (byte) cnt);
_log.info("修改payOrderId={},通知业务系统次数->{}", orderId, result == 1 ? "成功" : "失败");
}catch (Exception e) {
_log.error(e, "修改通知次数异常");
}
msgObj.put("count", cnt);
this.send(msgObj.toJSONString(), cnt*60*1000);
this.send(msgObj.toJSONString(), cnt * 60 * 1000);
}
_log.warn("notify failed. url:{}, response body:{}", respUrl, sb.toString());
} catch(Exception e) {
......
......@@ -63,10 +63,10 @@ public class PayOrderService {
return payOrderMapper.updateByExampleSelective(payOrder, example);
}
public int updateNotify(String payOrderId) {
PayOrder payOrder = selectPayOrder(payOrderId);
public int updateNotify(String payOrderId, byte count) {
PayOrder newPayOrder = new PayOrder();
newPayOrder.setNotifyCount((byte) (payOrder.getNotifyCount()+1));
// TODO 并发下次数问题待解决
newPayOrder.setNotifyCount(count);
newPayOrder.setLastNotifyTime(System.currentTimeMillis());
newPayOrder.setPayOrderId(payOrderId);
return payOrderMapper.updateByPrimaryKeySelective(newPayOrder);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment