帮助地址
[支付宝自测demo下载地址](https://openclub.alipay.com/club/history/read/2376)
[ALIN10146-自查方案](https://openclub.alipay.com/club/history/read/6918)
[沙箱环境](https://openhome.alipay.com/platform/appDaily.htm)
[本地测试 本地地址映射网络地址](https://www.ngrok.cc/user.html) 教程 http://www.ngrok.cc/_book/start/ngrok_linux.html
csr证书生成
包
compile group: 'com.alipay.sdk', name: 'alipay-sdk-java', version: '4.9.79.ALL'
配置信息
defray:
alipay-config:
# 商户appid
appId: 1111
# 私钥 pkcs8格式的 非证书环境下使用的 应用
rsaPtivateKey: 111
# 服务器异步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 写线上接口地址
notifyUrl: 111
notifyCertUrl: 11111
# 页面跳转同步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 商户可以自定义同步跳转地址
returnUrl: 111
# 请求网关沙箱地址
# url: https://openapi.alipaydev.com/gateway.do?charset=utf-8
# 请求网关正式地址
url: https://openapi.alipay.com/gateway.do
# 编码
charset: UTF-8
# 返回格式
format: json
# 支付宝公钥
alipayPublicKey: 111
# 日志记录目录
logPath: /log
#RSA2
signType: RSA2
# 超时时间
timeOut: 30m
# 销售产品码 快速支付
productCode: QUICK_MSECURITY_PAY
# 商户私钥 注意证书模式下商户密钥是你申请crs证书 打开文件位置 域名_私钥.txt 里面数据
appPrivateKey: 1111
# 应用公钥证书路径
appCertPath: appCertPublicKey_1111.crt
# 支付宝公钥证书文件路径
alipayCertPath: alipayCertPublicKey_RSA2.crt
#支付宝CA根证书文件路径
alipayRootCertPath: alipayRootCert.crt
配置类
/**
* 支付属性 对应配置信息
*/
@Component
@ConfigurationProperties(prefix = "defray.alipay-config")
@Data
public static class DefrayProperties {
private String appId;
private String rsaPtivateKey;
private String notifyUrl;
private String notifyCertUrl;
private String returnUrl;
private String url;
private String charset;
private String format;
private String alipayPublicKey;
private String logPath;
private String signType;
private String timeOut;
private String productCode;
private String appPrivateKey;
private String appCertPath;
private String alipayCertPath;
private String alipayRootCertPath;
}
支付信息公共方法
/**
* 支付宝 支付 信息
*
* @param goods 商品信息表数据
* @param outTradeNo 生成的商品订单号
* @return
*/
private AlipayTradeAppPayRequest appPayRequestInfo(CommerceGoods goods, String outTradeNo) {
// 实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
AlipayTradeAppPayRequest appPayRequest = new AlipayTradeAppPayRequest();
// SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
//商品描述
model.setBody(goods.getMemo());
//商品标题
model.setSubject(goods.getGoodsName());
//订单号
model.setOutTradeNo(outTradeNo);
//超时时间 该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天 (屁股后面的字母一定要带,不然报错)
model.setTimeoutExpress(defrayProperties.getTimeOut());
//金额 金额 必须 两个小数点
String amount = BigDecimal.valueOf(Long.valueOf(goods.getPrice())).divide(new BigDecimal(100), 2, HALF_DOWN).toString();
model.setTotalAmount(amount);
//销售产品码
model.setProductCode(defrayProperties.getProductCode());
appPayRequest.setBizModel(model);
//异步通知地址
appPayRequest.setNotifyUrl(defrayProperties.getNotifyUrl());
log.info(" appPayRequestInfo is:{} ", JSON.toJSONString(appPayRequest));
return appPayRequest;
}
密钥方式
/**
* 支付宝 支付 非证书模式
*
* @param goods
* @return
*/
public AlipayTradeAppPayResponse aliPayUnifiedOrder(CommerceGoods goods, String outTradeNo) {
// 实例化客户端
AlipayClient alipayClient = new DefaultAlipayClient(
defrayProperties.getUrl(),
defrayProperties.getAppId(),
defrayProperties.getRsaPtivateKey(),
defrayProperties.getFormat(),
defrayProperties.getCharset(),
defrayProperties.getAlipayPublicKey(),
defrayProperties.getSignType());
try {
AlipayTradeAppPayRequest appPayRequest = appPayRequestInfo(goods, outTradeNo);
//异步通知地址 非证书模式 地址
appPayRequest.setNotifyUrl(defrayProperties.getNotifyUrl());
// 这里和普通的接口调用不同,使用的是sdkExecute
AlipayTradeAppPayResponse appPayResponse = alipayClient.sdkExecute(appPayRequest);
log.info(" AlipayTradeAppPayResponse info is:{} ", JSON.toJSONString(appPayResponse));
return appPayResponse;
} catch (AlipayApiException e) {
log.error(" aliPayUnifiedOrder error is:{}", e);
}
return null;
}
证书方式
/**
* 支付宝支付 证书方式
*
* @param goods
* @param outTradeNo
* @return
*/
public AlipayTradeAppPayResponse aliPayCertUnifiedOrder(CommerceGoods goods, String outTradeNo) {
AlipayTradeAppPayRequest appPayRequestInfo = appPayRequestInfo(goods, outTradeNo);
//异步通知地址
appPayRequestInfo.setNotifyUrl(defrayProperties.getNotifyCertUrl());
//实例化客户端
CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
//设置网关地址
certAlipayRequest.setServerUrl(defrayProperties.getUrl());
//设置应用Id
certAlipayRequest.setAppId(defrayProperties.getAppId());
//设置应用私钥
certAlipayRequest.setPrivateKey(defrayProperties.getAppPrivateKey());
//设置请求格式,固定值json
certAlipayRequest.setFormat(defrayProperties.getFormat());
//设置字符集
certAlipayRequest.setCharset(defrayProperties.getCharset());
//设置签名类型
certAlipayRequest.setSignType(defrayProperties.getSignType());
//设置应用公钥证书路径
certAlipayRequest.setCertPath(defrayProperties.getAppCertPath());
//设置支付宝公钥证书路径
certAlipayRequest.setAlipayPublicCertPath(defrayProperties.getAlipayCertPath());
//设置支付宝根证书路径
certAlipayRequest.setRootCertPath(defrayProperties.getAlipayRootCertPath());
try {
//构造client
AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest);
AlipayTradeAppPayResponse appPayResponse = alipayClient.sdkExecute(appPayRequestInfo);
log.info(" aliPayCertUnifiedOrder info is:{} ", JSON.toJSONString(appPayResponse));
return appPayResponse;
} catch (AlipayApiException e) {
log.error(e.getMessage(), e);
}
return null;
}
支付回调
/**
* 支付宝支付结束回调接口 非证书
*
* @param request
* @param response
*/
public void aliPayNotify(HttpServletRequest request, HttpServletResponse response) {
// 获取支付宝POST过来反馈信息
Map<String, String> params = appAliPayNotifyParams(request);
if (ObjectUtils.isEmpty(params)) {
log.info(" appAliPayNotify params is null ");
return;
}
try {
boolean flag = rsaCheckV1(params);
checkAliPayResponse(request, response, flag);
} catch (AlipayApiException e) {
log.error(" appAliPayNotify error is:{} ", e);
}
}
/**
* 支付宝支付结束回调接口 证书方式
*
* @param request
* @param response
*/
public void aliPayCertNotify(HttpServletRequest request, HttpServletResponse response) {
// 获取支付宝POST过来反馈信息
Map<String, String> params = appAliPayNotifyParams(request);
if (ObjectUtils.isEmpty(params)) {
log.info(" appAliPayCertNotify params is null ");
return;
}
try {
boolean flag = rsaCertCheckV1(params);
checkAliPayResponse(request, response, flag);
} catch (AlipayApiException e) {
log.error(" appAliPayCertNotify error is:{} ", e);
}
}
private void checkAliPayResponse(HttpServletRequest request, HttpServletResponse response, boolean flag) {
try {
String result = "failure";
// 商户订单号
String orderNo = new String(request.getParameter("out_trade_no").getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
// 支付宝交易号
String tradeNo = new String(request.getParameter("trade_no").getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
// 交易状态
String tradeStatus = new String(request.getParameter("trade_status").getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
//交易金额
String totalAmount = new String(request.getParameter("total_amount").getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
log.info(" flag is:{}, outTradeNo is:{}, tradeNo is:{}, tradeStatus is:{}, totalAmount is:{}", flag, orderNo, tradeNo, tradeStatus, totalAmount);
if (flag && "TRADE_SUCCESS".equals(tradeStatus)) {
// 修改订单状态
int status = updateOrderStatus(orderNo, tradeNo, totalAmount, 2);
if (status > 0) {
//添加用户会员信息
Integer saveCommerceUser = saveCommerceUser(orderNo, tradeNo, 2);
if (saveCommerceUser != null && saveCommerceUser > 0) {
//返回给支付宝success 不然会一直回调 官方说明地址:https://opensupport.alipay.com/support/knowledge/20070/201602062547
result = "success";
}
// 指定编码为utf-8
response.getOutputStream().write(result.getBytes(defrayProperties.getCharset()));
}
}
log.info(" alipayNotify flag is:{} ", flag);
} catch (Exception e) {
log.error(" alipayNotify error is:{} ", e);
}
}
/**
* 获取支付宝POST过来反馈信息
*
* @param request
* @return
*/
private Map<String, String> appAliPayNotifyParams(HttpServletRequest request) {
Map<String, String> params = new HashMap<>();
Map requestParams = request.getParameterMap();
for (Object o : requestParams.keySet()) {
String name = (String) o;
String[] values = (String[]) requestParams.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
}
// 乱码解决,这段代码在出现乱码时使用。(有时加上这段代码 会乱码)
// valueStr = new String(valueStr.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
params.put(name, valueStr);
}
log.info(" appAliPayNotifyParams params is:{}, defrayProperties is:{} ", JSON.toJSONString(params), JSON.toJSONString(defrayProperties));
return params;
}
/**
* 支付宝验签 非证书模式
* 切记alipaypublickey是支付宝的公钥,open.alipay.com对应应用下查看。
*
* @param params
* @return
* @throws AlipayApiException
*/
private boolean rsaCertCheckV1(Map<String, String> params) throws AlipayApiException {
return AlipaySignature.rsaCertCheckV1(params,
defrayProperties.getAlipayCertPath(),
defrayProperties.getCharset(),
defrayProperties.getSignType());
}