微信支付寶一碼付
- 2019 年 10 月 30 日
- 筆記
版權聲明:本文為部落客原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
本文鏈接:https://blog.csdn.net/luo4105/article/details/80514731
路由
一碼付指的是一個二維碼同時指出支付寶、微信掃描並支付。
微信和支付寶支援掃描一個url二維碼並通過內置的瀏覽器跳轉。
我們可以通過js獲得是來自支付寶的還是微信的瀏覽器,通過user-agent
,有MicroMessenger是微信,有AlipayClient是支付寶。
var ua = navigator.userAgent.toLowerCase(); if (/MicroMessenger/.test(window.navigator.userAgent)) { //微信 } else if (/AlipayClient/.test(window.navigator.userAgent)) { //支付寶 }
接著就是查看支付寶和微信中關於網頁支付的教程了。
支付寶:https://docs.open.alipay.com/203/
微信: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1
notice
1.網址必須以http://
或https://
開頭。
流程時序圖

支付寶
在一碼付中,支付寶屬於手機網站支付
一類。官方api地址:https://docs.open.alipay.com/203/
測試程式碼
@Test public void main() throws AlipayApiException { alipayClient = new DefaultAlipayClient(alipayConfig.getAlipayGateway(), alipayConfig.getAppId(), alipayConfig.getAppPrivateKey(), "json", DEFAULT_ENCODING, alipayConfig.getAppPublicKey(), SIGN_RSA); AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();//創建API對應的request alipayRequest.setReturnUrl("http://domain.com/CallBack/return_url.jsp"); alipayRequest.setNotifyUrl("http://domain.com/CallBack/notify_url.jsp"); alipayRequest.setBizContent("{" + ""out_trade_no":"fc00001"," + ""total_amount":0.01," + ""product_code":"QUICK_WAP_WAY","+ ""subject":"測試"" + "}"); AlipayTradeWapPayResponse response = alipayClient.pageExecute(alipayRequest); if(response.isSuccess()){ System.out.println("調用成功"); System.out.println(response.getBody()); } else { System.out.println("調用失敗"); System.out.println(response.getBody()); } }
支付寶API
請求地址:
環境 |
HTTPS請求地址 |
---|---|
正式環境 |
https://openapi.alipay.com/gateway.do |
公共請求參數:
參數 |
類型 |
是否必填 |
最大長度 |
描述 |
示例值 |
---|---|---|---|---|---|
app_id |
String |
是 |
32 |
支付寶分配給開發者的應用ID |
2014072300007148 |
method |
String |
是 |
128 |
介面名稱 |
alipay.trade.wap.pay |
format |
String |
否 |
40 |
僅支援JSON |
JSON |
return_url |
String |
否 |
256 |
HTTP/HTTPS開頭字元串 |
https://m.alipay.com/Gk8NF23 |
charset |
String |
是 |
10 |
請求使用的編碼格式,如utf-8,gbk,gb2312等 |
utf-8 |
sign_type |
String |
是 |
10 |
商戶生成簽名字元串所使用的簽名演算法類型,目前支援RSA2和RSA,推薦使用RSA2 |
RSA2 |
sign |
String |
是 |
256 |
商戶請求參數的簽名串,詳見簽名 |
詳見示例 |
timestamp |
String |
是 |
19 |
發送請求的時間,格式」yyyy-MM-dd HH:mm:ss」 |
2014-07-24 03:07:50 |
version |
String |
是 |
3 |
調用的介面版本,固定為:1.0 |
1.0 |
notify_url |
String |
否 |
256 |
支付寶伺服器主動通知商戶伺服器里指定的頁面http/https路徑。 |
https://api.xx.com/receive_notify.htm |
biz_content |
String |
是 |
– |
業務請求參數的集合,最大長度不限,除公共參數外所有請求參數都必須放在這個參數中傳遞,具體參照各產品快速接入文檔 |
|
請求參數
參數 |
類型 |
是否必填 |
最大長度 |
描述 |
示例值 |
---|---|---|---|---|---|
subject |
String |
是 |
256 |
商品的標題/交易標題/訂單標題/訂單關鍵字等。 |
大樂透 |
out_trade_no |
String |
是 |
64 |
商戶網站唯一訂單號 |
70501111111S001111119 |
total_amount |
Price |
是 |
9 |
訂單總金額,單位為元,精確到小數點後兩位,取值範圍[0.01,100000000] |
9.00 |
支付寶還支援交易具體描述、逾期自動關閉等。
更多api詳情查看官方api: https://docs.open.alipay.com/203/107090/
微信
微信,微信使用的是公眾號支付
,官方api:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842,https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1,微信的支付流程如下
- 微信網頁授權
- 授權憑證
- 下單介面
下單詳細步驟程式碼和api
1.獲得code,等待微信回調,get請求https://open.weixin.qq.com/connect/oauth2/authorize
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
參數
參數 |
是否必須 |
說明 |
---|---|---|
appid |
是 |
公眾號的唯一標識 |
redirect_uri |
是 |
授權後重定向的回調鏈接地址, 請使用 urlEncode 對鏈接進行處理 |
response_type |
是 |
返回類型,請填寫code |
scope |
是 |
應用授權作用域,snsapi_base (不彈出授權頁面,直接跳轉,只能獲取用戶openid),snsapi_userinfo (彈出授權頁面,可通過openid拿到昵稱、性別、所在地。並且, 即使在未關注的情況下,只要用戶授權,也能獲取其資訊 ) |
state |
否 |
重定向後會帶上state參數,開發者可以填寫a-zA-Z0-9的參數值,最多128位元組 |
wechat_redirect |
是 |
無論直接打開還是做頁面302重定向時候,必須帶此參數 |
2.獲得openid,請求https://api.weixin.qq.com/sns/oauth2/access_token
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
參數說明
參數 |
是否必須 |
說明 |
---|---|---|
appid |
是 |
應用唯一標識,在微信開放平台提交應用審核通過後獲得 |
secret |
是 |
應用密鑰AppSecret,在微信開放平台提交應用審核通過後獲得 |
code |
是 |
填寫第一步獲取的code參數 |
grant_type |
是 |
填authorization_code |
返回說明
正確的返回:
{ "access_token":"ACCESS_TOKEN", "expires_in":7200, "refresh_token":"REFRESH_TOKEN", "openid":"OPENID", "scope":"SCOPE", "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" }
參數說明
參數 |
說明 |
---|---|
access_token |
介面調用憑證 |
expires_in |
access_token介面調用憑證超時時間,單位(秒) |
refresh_token |
用戶刷新access_token |
openid |
授權用戶唯一標識 |
scope |
用戶授權的作用域,使用逗號(,)分隔 |
unionid |
當且僅當該網站應用已獲得該用戶的userinfo授權時,才會出現該欄位。 |
3.微信預下單,請求https://api.mch.weixin.qq.com/pay/unifiedorder
{ String reqBody = WXPayUtil.mapToXml(params); byte[] bytes = LockerHttpClient.postTypedBinary("https://api.mch.weixin.qq.com/pay/unifiedorder", reqBody .getBytes(DEFAULT_ENCODING), TEXT_XML); Map<String, String> resultMap = WXPayUtil.xmlToMap(new String(bytes, DEFAULT_ENCODING)); } private Map<String, String> populateReq(String orderId, String totalFee, String openId) throws Exception { Map<String, String> params = new HashMap<>(); params.put("appid", wechatConfig.getWechatAppId()); params.put("mch_id", wechatConfig.getWechatMchId()); params.put("nonce_str", STRING_GENERATOR.generate(30)); params.put("sign_type", "MD5"); params.put("openid", openId); params.put("body", wechatConfig.getPayTitle()); params.put("total_fee", totalFee); params.put("spbill_create_ip", DEFAULT_IP); params.put("trade_type", "JSAPI"); //限制用戶不能使用信用卡支付 params.put("limit_pay", "no_credit"); params.put("out_trade_no", orderId); params.put("notify_url", wechatConfig.getWechatPayNotifyUrl()); params.put("product_id", orderId); params.put("sign", WXPayUtil.generateSignature(params, wechatConfig.getWechatApiKey())); return params; }
請求參數
欄位名 |
變數名 |
必填 |
類型 |
示例值 |
描述 |
---|---|---|---|---|---|
公眾帳號ID |
appid |
是 |
String(32) |
wxd678efh567hg6787 |
微信支付分配的公眾帳號ID(企業號corpid即為此appId) |
商戶號 |
mch_id |
是 |
String(32) |
1230000109 |
微信支付分配的商戶號 |
設備號 |
device_info |
否 |
String(32) |
013467007045764 |
自定義參數,可以為終端設備號(門店號或收銀設備ID),PC網頁或公眾號內支付可以傳」WEB」 |
隨機字元串 |
nonce_str |
是 |
String(32) |
5K8264ILTKCH16CQ2502SI8ZNMTM67VS |
隨機字元串,長度要求在32位以內。推薦隨機數生成演算法 |
簽名 |
sign |
是 |
String(32) |
C380BEC2BFD727A4B6845133519F3AD6 |
通過簽名演算法計算得出的簽名值,詳見簽名生成演算法 |
簽名類型 |
sign_type |
否 |
String(32) |
MD5 |
簽名類型,默認為MD5,支援HMAC-SHA256和MD5。 |
商品描述 |
body |
是 |
String(128) |
騰訊充值中心-QQ會員充值 |
商品簡單描述,該欄位請按照規範傳遞,具體請見參數規定 |
商戶訂單號 |
out_trade_no |
是 |
String(32) |
20150806125346 |
商戶系統內部訂單號,要求32個字元內,只能是數字、大小寫字母_-|* 且在同一個商戶號下唯一。詳見商戶訂單號 |
標價金額 |
total_fee |
是 |
Int |
88 |
訂單總金額,單位為分,詳見支付金額 |
終端IP |
spbill_create_ip |
是 |
String(16) |
123.12.12.123 |
APP和網頁支付提交用戶端ip,Native支付填調用微信支付API的機器IP。 |
通知地址 |
notify_url |
是 |
String(256) |
http://www.weixin.qq.com/wxpay/pay.php |
非同步接收微信支付結果通知的回調地址,通知url必須為外網可訪問的url,不能攜帶參數。 |
交易類型 |
trade_type |
是 |
String(16) |
JSAPI |
JSAPI 公眾號支付NATIVE 掃碼支付APP APP支付說明詳見參數規定 |
商品ID |
product_id |
否 |
String(32) |
12235413214070356458058 |
trade_type=NATIVE時(即掃碼支付),此參數必傳。此參數為二維碼中包含的商品ID,商戶自行定義。 |
指定支付方式 |
limit_pay |
否 |
String(32) |
no_credit |
上傳此參數no_credit–可限制用戶不能使用信用卡支付 |
用戶標識 |
openid |
否 |
String(128) |
oUpF8uMuAJO_M2pxb1Q9zNjWeS6o |
trade_type=JSAPI時(即公眾號支付),此參數必傳,此參數為微信用戶在商戶對應appid下的唯一標識。openid如何獲取,可參考【獲取openid】。企業號請使用【企業號OAuth2.0介面】獲取企業號內成員userid,再調用【企業號userid轉openid介面】進行轉換 |
舉例如下:
<xml> <appid>wx2421b1c4370ec43b</appid> <attach>支付測試</attach> <body>JSAPI支付測試</body> <mch_id>10000100</mch_id> <detail><![CDATA[{ "goods_detail":[ { "goods_id":"iphone6s_16G", "wxpay_goods_id":"1001", "goods_name":"iPhone6s 16G", "quantity":1, "price":528800, "goods_category":"123456", "body":"蘋果手機" }, { "goods_id":"iphone6s_32G", "wxpay_goods_id":"1002", "goods_name":"iPhone6s 32G", "quantity":1, "price":608800, "goods_category":"123789", "body":"蘋果手機" } ] }]]></detail> <nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str> <notify_url>http://wxpay.wxutil.com/pub_v2/pay/notify.v2.php</notify_url> <openid>oUpF8uMuAJO_M2pxb1Q9zNjWeS6o</openid> <out_trade_no>1415659990</out_trade_no> <spbill_create_ip>14.23.150.211</spbill_create_ip> <total_fee>1</total_fee> <trade_type>JSAPI</trade_type> <sign>0CB01533B8C1EF103065174F50BCA001</sign> </xml>
註:參數值用XML轉義即可,CDATA標籤用於說明數據不被XML解析器解析。
歸納
優點:一碼支援兩碼,可能方便
缺點:微信支付鏈路太長,耗時極長,特別是access_token介面,特別是生成access_token,耗時可能會達到5s。