一、参考官方文档:https://docs.open.alipay.com/204/105301/
二、业务流程:
1.app请求;
2.校验必传参数;
3.创建预支付订单;
4.支付宝签名;
5.将支付宝签名字符串传递给app
三、业务代码:
1.支付宝业务逻辑:
package com.yqs.pay.thridpay;
import java.util.Map;
import org.apache.log4j.Logger;
import com.alibaba.fastjson.JSONObject;
import com.dev.util.message.Msg;
import com.pay.service.Pay;
import com.yqs.pay.deal.server.PayServer;
import com.yqs.pay.entity.dim.PayStatus;
import com.yqs.pay.util.ThirdNotifyCheck;
import com.yqs.pay.util.alipay.AlipayUtil;
public class Alipay implements ThridPay{
private static Logger log = Logger.getLogger(Alipay.class);
public Msg<Object> doAdvanceOrder(Pay pay) throws Exception {
String billCode = pay.getPars().get("billCode");
// Double amt=pay.getAmount()*100;
Double amt=0.01;//支付宝支付金额是元
String alipayResponse = pay.getTerminal()==3?AlipayUtil.alipayQrCodePay(billCode, String.valueOf(amt)):AlipayUtil.alipayOrderPay("支付宝支付",billCode,String.valueOf(amt));
if(alipayResponse!=null &&alipayResponse.trim().length()!=0){
Msg<Object> msg = PayServer.preRecharge(pay,billCode);//维护订单(创建未支付记录和订单)
if(!msg.status)
return msg;
if(pay.getTerminal()==3){
Msg<Object> msg2 = new Msg<Object>(true,billCode);
msg2.setData(alipayResponse);
return msg2;
}
return msgFactory.success("支付宝预订单成功!",alipayResponse);
}
return msgFactory.fail("支付宝预订单失败!");
}
public Msg<Object> callBackNotify(Map<String, String> map) throws Exception {
String out_trade_no = map.get("out_trade_no");
int rechargeStatus = map.get("trade_status").equals("TRADE_SUCCESS") ? PayStatus.SUCCESS : PayStatus.FAIL;
ThirdNotifyCheck.putNotifyOrderID(out_trade_no, System.currentTimeMillis() + ";" + rechargeStatus);
Msg<Object> msg=PayServer.rechargeNotify(out_trade_no,rechargeStatus);
if (msg==null || !msg.status){
log.fatal("支付宝支付成功,回调异常"+JSONObject.toJSONString(msg));
return msgFactory.fail("支付宝支付回调处理失败");
}
return msgFactory.success("支付宝支付回调处理成功");
}
}
2.支付宝工具类:
package com.yqs.pay.util.alipay;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;
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.AlipayTradePrecreateModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.yqs.pay.entity.AlipayConfig;
public class AlipayUtil {
private static Logger log = Logger.getLogger(AlipayUtil.class);
/**
* @param body 商品信息
* @param subject 商品名称
* @param out_trade_no 商户订单号
* @param amount 订单金额
* @param productCode
* @return
*/
public static String alipayOrderPay(String body,String out_trade_no,String amount){
//实例化客户端
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APP_ID, AlipayConfig.RSA_PRIVATE_KEY,AlipayConfig.FORMAT , AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGNTYPE);
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
//SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
Map<String, Object> biz_content = new HashMap<String,Object>();
biz_content.put("subject", AlipayConfig.subject);
biz_content.put("out_trade_no", out_trade_no);
biz_content.put("total_amount", amount);
biz_content.put("product_code","QUICK_MSECURITY_PAY");
biz_content.put("body",body);
biz_content.put("timeout_express","30m");
request.setBizContent(JSONObject.toJSONString(biz_content));
request.setNotifyUrl(AlipayConfig.notify_url); //回调地址不可以带参数
String orderStr = "";
try {
//这里和普通的接口调用不同,使用的是sdkExecute
AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
orderStr = response.getBody();
log.info(orderStr);//就是orderString 可以直接给客户端请求,无需再做处理。
} catch (AlipayApiException e) {
e.printStackTrace();
}
return orderStr;
}
public static String alipayQrCodePay(String out_trade_no,String total_amount){
//实例化客户端
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APP_ID, AlipayConfig.RSA_PRIVATE_KEY,AlipayConfig.FORMAT , AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGNTYPE);
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
request.setNotifyUrl(AlipayConfig.notify_url);
AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
request.setBizModel(model);
model.setSubject(AlipayConfig.subject);
model.setTotalAmount(total_amount);
model.setStoreId("");
model.setTimeoutExpress("90m");
model.setOutTradeNo(out_trade_no);
try {
String resultStr = alipayClient.execute(request).getBody();
JSONObject jsonObject = JSONObject.parseObject(resultStr);
String qr_code = jsonObject.getJSONObject("alipay_trade_precreate_response").getString("qr_code");
log.info("二维码地址:"+qr_code);
return qr_code;
} catch (AlipayApiException e) {
e.printStackTrace();
log.fatal("支付宝预订单异常",e);
}
return null;
}
}
四、项目对接过程中的问题:
iOS调试一直不成功,一直返回ALI38173;
然后找了一天半的时间,最后在阿里的博客上面贴了签名的字符串,说是iOS客户端的问题;
但是重要的是前一天晚上被另外一个同事查到iOS出错的原因
五.后台开发当中需要注意以下情况:
1.需要注意对接支付宝配置信息当中的公私钥,公钥是支付宝公钥,私钥是商户私钥
2.回调地址一定是正常连接或者安全连接,不安全连接会造成无法接收到回调请求
如果有感兴趣的盆友可以一起探讨支付宝支付的相关问题,共同进步;