前段时间对接了全民付的支付宝小程序和微信小程序支付,
支付宝是可以直接唤起全民付主体的小程序,
微信则必须申请自己主体的小程序,
进而两者流程上有一定的不同,
项目整体框架包括:原生壳子,页面为jsp(SpringMVC框架)。
支付宝小程序支付对接流程:
1.支付确认页js请求自己的支付接口
2.自己的支付接口内拼装好参数调用全民付支付接口
3.全民付支付接口将支付结果返回(appPayRequest:APP支付用的请求报文,带有签名信息)给自己的支付接口
4.自己的支付接口将支付结果的APP支付用的请求报文(appPayRequest)返回给js
5.js拿到将APP支付用的请求报文(appPayRequest)作为参数,调用原生方法
6.原生加载APP支付用的请求报文(appPayRequest),唤起全民付支付宝小程序,
7.用户通过唤起的支付宝小程序进行支付操作,支付结果通过回调url(支付请求参数中传入)返回给系统。
8.支付确认页通过调用接口一直监听支付结果,拿到结果后跳转到支付结果页
微信小程序支付对接流程:
1.支付确认页js将支付请求参数拼接好作为参数调用原生方法
2.原生唤起自己主体的微信小程序,将支付请求参数传给小程序
3.自己主体的小程序携带支付请求参数调用自己的支付接口
4.自己的支付接口内拼装好参数调用全民付支付接口
5.全民付支付接口将支付结果返回(miniPayRequest:小程序支付用的请求报文,带有签名信息)给自己的支付接口
6.自己的支付接口将支付结果的小程序支付用的请求报文(miniPayRequest)返回给自己主体的微信小程序
7.微信小程序拿到支付用的请求报文(miniPayRequest)作为参数调用小程序方法wx.requestPayment,唤起支付页面
8.用户通过唤起的微信小程序支付页面进行支付操作,支付结果通过回调url(支付请求参数中传入)返回给系统
9.支付确认页通过调用接口一直监听支付结果,拿到结果后跳转到支付结果页
支付宝小程序js主要代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| function toQmfZfbPay(order_code,poundage,orderIds){ var cookiePlatform=getCookie("platform"); if (cookiePlatform != 'android'&& cookiePlatform != 'ios') { $("#payTimeAlert").children("p").text("请在XXXXAPP内打开").end().show(1).delay(2000).hide(1); return; }
$(".l_tcSquare").show(); payDomain =$("#payDomain").val();
$.ajax({ type:'post', url:payDomain+'/IHDouApiPay/api/pay/qmfZfbPay/request', data:JSON.stringify({orderCode:order_code,payFee:poundage}), dataType:'json', contentType:'application/json', success:function(json){ $(".l_tcSquare").hide(); if(json.retCode=='0000'){ var platform = getCookie("platform"); var redata = json.retData; var flag = redata[0].flag; if(flag=="success"){ var appPayRequest = redata[0].appPayRequest; if(platform == 'android'){ window.pos.goQmfZfbXcXPay(appPayRequest); }else if(platform == 'ios'){ window.webkit.messageHandlers.goQmfZfbXcXPay.postMessage({"zfbPayXbStr":appPayRequest}); } }else{ $("#payTimeAlert").children("p").text("支付请求异常,请稍后重试").end().show(1).delay(2000).hide(1); } }else{ $("#payTimeAlert").children("p").text(json.retMsg).end().show(1).delay(2000).hide(1); } }, error:function(data){ $(".l_tcSquare").hide(); $("#payTimeAlert").children("p").text("网络错误").end().show(1).delay(2000).hide(1); } }); setTimeout(function () { goToPaySuccess(orderIds) },3000); }
|
微信小程序js主要代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| function toQmfWxPay(order_code,poundage,orderIds){ payDomain =$("#payDomain").val(); var totalAmount = $("#actualPayAmount").val(); var date = new Date(); var year = date.getFullYear(); var month = date.getMonth() + 1; var day = date.getDate(); var hours = date.getHours(); var minutes = date.getMinutes(); var seconds = date.getSeconds(); if (month >= 1 && month <= 9) { month = "0" + month; } if (day >= 0 && day <= 9) { day = "0" + day; } if (hours >= 0 && hours <= 9) { hours = "0" + hours; } if (minutes >= 0 && minutes <= 9) { minutes = "0" + minutes; } if (seconds >= 0 && seconds <= 9) { seconds = "0" + seconds; } var currentFormatDate = year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds; var pathStr = 'orderCode='+order_code+'&totalAmount='+totalAmount+'&requestTimestamp='+currentFormatDate+'&payFee='+poundage+'&payType=36&domain='+payDomain;
var cookiePlatform=getCookie("platform"); if(cookiePlatform == 'android'){ window.pos.OrderPayProgramPage(pathStr); }else if(cookiePlatform == 'ios'){ window.webkit.messageHandlers.OrderPayProgramPage.postMessage({"pathStr":pathStr}); }else{ $("#payTimeAlert").children("p").text("请在XXXXAPP内打开").end().show(1).delay(2000).hide(1); return; } setTimeout(function () { goToPaySuccess(orderIds) },3000); }
|
支付请求相关代码(java):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| JSONObject json = new JSONObject(); json.put("requestTimestamp", DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss")); json.put("merOrderId", payCode); json.put("notifyUrl", QmfpayUtil.notifyUrl_ZFB); json.put("mid", QmfpayUtil.MID_ZFB); json.put("tid", QmfpayUtil.TID_ZFB);
json.put("instMid", "APPDEFAULT"); json.put("totalAmount", total_amount);
json.put("tradeType", "APP"); String placeOrderUrl = QmfpayUtil.request_url_ZFB;
log.info("QmfZfbPayServiceImpl payRequestHandler json:[{}]", json); String response = QmfpayUtil.placeOrder(placeOrderUrl,json.toString(),QmfpayUtil.appid_ZFB,QmfpayUtil.appkey_ZFB); log.info("QmfZfbPayServiceImpl payRequestHandler response:"+response); JSONObject result = JSONObject.fromObject(response); String errCode = result.getString("errCode"); if ("SUCCESS".equals(errCode)) { List<Map<String,String>> ls = new ArrayList<Map<String,String>>(); Map<String,String> map = new HashMap<>(); JSONObject appPayRequest = result.getJSONObject("appPayRequest"); if (appPayRequest != null) {
map.put("appPayRequest", appPayRequest.toString()); } map.put("flag","success"); map.put("payCode",payCode); ls.add(map); return BaseResultResponse.success(ls); }
|
QmfpayUtil相关代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| public static String placeOrder(String url, String entity,String appId,String appKey) throws Exception {
String send = send(url, entity,appId,appKey); return send; }
public static String send(String url, String entity,String appId,String appKey) throws Exception{ authorization = getOpenBodySig(appId, appKey, entity); CloseableHttpClient httpClient = HttpClients.createDefault(); HttpPost httpPost = new HttpPost(url); httpPost.addHeader("Authorization", authorization); StringEntity se = new StringEntity(entity,"UTF-8"); se.setContentType("application/json"); httpPost.setEntity(se); CloseableHttpResponse response = httpClient.execute(httpPost); HttpEntity entity1 = response.getEntity(); String resStr = null; if(entity1 != null){ resStr = EntityUtils.toString(entity1, "UTF-8"); } httpClient.close(); response.close(); return resStr; } public static String getOpenBodySig(String appId, String appKey, String body) throws Exception{ String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()); String nonce = UUID.randomUUID().toString().replace("-", ""); byte[] data = body.getBytes("UTF-8"); System.out.println("data:\n" + body); InputStream is = new ByteArrayInputStream(data); String bodyDigest = testSHA256(is); String str1_C = appId+timestamp+nonce+bodyDigest; byte[] localSignature = hmacSHA256(str1_C.getBytes(), appKey.getBytes()); String localSignatureStr = Base64.encodeBase64String(localSignature); System.out.println("Authorization:\n" + "OPEN-BODY-SIG AppId="+"\""+appId+"\""+", Timestamp="+"\""+timestamp+"\""+", Nonce="+"\""+nonce+"\""+", Signature="+"\""+localSignatureStr+"\""); return ("OPEN-BODY-SIG AppId="+"\""+appId+"\""+", Timestamp="+"\""+timestamp+"\""+", Nonce="+"\""+nonce+"\""+", Signature="+"\""+localSignatureStr+"\""); }
|