前段时间,公司需要接入支付宝,现在腾出了一点时间,所以做一下总结,分享一些自己项目中遇到的坑,本文
app支付为例。对于支付宝的对接,无疑官方文档是最全,最完善的,所以给大家一个传送
集成开发
本文使用支付宝sdk进行支付宝对接,请到支付宝java demo进行下载
1.参数说明
FireShot Capture 2 - 开放平台文档中心 - https___docs.open.alipay.com_204_105465_.png2.APP客户端请求orderString的生成
// 请求网关地址
public static final String ALIPAY_URL = "https://openapi.alipay.com/gateway.do";
// 异回调地址
public static final String ALIPAY_NOTIFY_URL = "https://www.nickbi.com/alipay/notify";
// 商户appid
public static final String ALIPAY_APPID = "xxxxxx";
// 私钥 pkcs8格式的(可用支付宝秘钥工具生成)
public static final String ALIPAY_RSA_PRIVATE_KEY = “xxxxx”
// 返回格式
public static final String ALIPAY_ALI_FORMAT = "json";
// 返回格式
public static final String ALIPAY_ALI_FORMAT = "json";
// 支付宝公钥(可在设置了公钥私钥后,在支付宝商户后台查看)
public static final String ALI_PUBLIC_KEY = “xxxxx”
// RSA2
public static final String ALIPAY_SIGNTYPE = "RSA2";
/**
* 获得app端支付宝参数
*/
public String getAlipayReqeustString(String orderNo, String totalAmount)
throws AlipayApiException {
//app Request
AlipayClient alipayClient = new DefaultAlipayClient(ALIPAY_URL,
ALIPAY_APPID, ALIPAY_RSA_PRIVATE_KEY, ALIPAY_ALI_FORMAT,
ALIPAY_CHARSET, ALI_PUBLIC_KEY,ALIPAY_SIGNTYPE);
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
//SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
//model.setBody(body);
model.setSubject(“简书打赏”);
model.setOutTradeNo(orderNo);
//订单超时时间:取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天
model.setTimeoutExpress(“30m”);
//订单总支付金额
model.setTotalAmount(totalAmount);
//销售产品码:商家和支付宝签约的产品码,为固定值QUICK_MSECURITY_PAY
model.setProductCode("QUICK_MSECURITY_PAY");
request.setBizModel(model);
request.setNotifyUrl(ALIPAY_NOTIFY_URL);
//这里和普通的接口调用不同,使用的是sdkExecute
AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
return response.getBody();//就是orderString 可以直接给客户端请求,无需再做处理。
}
3.回调处理
@ResponseBody
@RequestMapping(value = "/alipay/notify", method = RequestMethod.POST)
public String getPayNotify(HttpServletRequest request) throws Exception {
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();
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] + ",";
}
//乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转
// valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
params.put(name, valueStr);
}
//获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
// 商户订单号
String out_trade_no = new String(
request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
//支付宝交易号
String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),
"UTF-8");
//支付金额
String total_fee = "0.00";
if (request.getParameter("total_amount") != null) {
total_fee = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"),
"UTF-8");
}
//交易状态
String trade_status = new String(
request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");
//异步通知ID
String notify_id = request.getParameter("notify_id");
if (notify_id != null && !"".equals(notify_id)) {
boolean verify_result = AlipaySignature
.rsaCheckV1(params, ALI_PUBLIC_KEY, AppContents.ALI_CHARSET,
ALIPAY_SIGNTYPE);
if (verify_result) {
//使用支付宝公钥验签
//订单支付成功
//if (trade_status.equals("TRADE_FINISHED") || trade_status.equals("TRADE_SUCCESS")) {
if (trade_status.equals("TRADE_SUCCESS")) {
//业务处理,使用自己的接口,进行订单处理
boolean result = orderService.getNotify(......)
if (result) {
return "success";
}
}
//订单超时关闭,修改订单
if (trade_status.equals("TRADE_CLOSED")) {
boolean result = orderService.getCloseNotify(......)
if (result) {
return "success";
}
}
return "fail";
} else {
//验证签名失败
return "fail";
}
} else {
return "fail";
}
}
总结
遇到的一些坑:
在项目的前期,使用app端的同步回调去处理订单信息,但是由于用户操作的确定性,所以在回调过程中会出现很多
意向不到的结果,所以订单处理异步回调更稳妥(老哥如果觉得想飙车,去试一把那我也是不拒绝的)。另外对于异步
回调也会出现未知原因,所以关于订单的轮询查询,订单矫正请自行尝试,到时可以一起交流下。
网友评论