一、參考官方文檔: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.回調地址一定是正常連接或者安全連接,不安全連接會造成無法接收到回調請求
如果有感興趣的盆友可以一起探討支付寶支付的相關問題,共同進步;