關鍵字:支付寶支付、支付寶掃碼支付
一、支付場景
用戶使用支付寶錢包上的“掃一掃”功能,掃碼商戶針對每個訂單實時生成的訂單二維碼,並在手機端確認支付。
二、調用流程
圖2.1 支付寶掃碼支付調用流程
a. 商戶系統調用支付寶【預下單接口alipay.trade.precreate】,獲得該訂單二維碼圖片地址。
b. 發起輪詢獲得支付結果:等待5秒后調用【交易查詢接口alipay.trade.query】,通過支付時傳入的商戶訂單號(out_trade_no)查詢支付結果(返回參數TRADE_STATUS),如果仍然返回等待用戶付款(WAIT_BUYER_PAY),則再次等待5秒后繼續查詢,直到返回確切的支付結果(成功TRADE_SUCCESS或已撤銷關閉TRADE_CLOSED),或是超出輪詢時間。在最后一次查詢仍然返回等待用戶付款的情況下,必須立即調用【交易撤銷接口alipay.trade.cancel】將這筆交易撤銷,避免用戶繼續支付。
c. 除了主動輪詢,也可以通過接收異步通知獲得支付結果,詳見掃碼異步通知,注意一定要對異步通知做驗證簽名,確保通知是支付寶發出的。
三、參數格式
請求和接收均為JSON格式
四、接口地址
正式環境:https://openapi.alipay.com/gateway.do
沙箱測試環境:https://openapi.alipaydev.com/gateway.do
五、統一收單線下交易預創建
1.請求參數
公共參數
參數 |
類型 |
必填 |
最大長度 |
示例值 |
描述 |
app_id |
String |
是 |
32 |
2014072300007148 |
支付寶分配給開發者的應用ID |
method |
String |
是 |
128 |
接口名稱 |
alipay.trade.precreate |
format |
String |
否 |
40 |
僅支持JSON |
JSON |
charset |
String |
是 |
10 |
utf-8 |
請求使用的編碼格式,如utf-8,gbk,gb2312等 |
sign_type |
String |
是 |
10 |
RSA2 |
商戶生成簽名字符串所使用的簽名算法類型,目前支持RSA2和RSA,推薦使用RSA2 |
sign |
String |
是 |
256 |
詳見示例 |
商戶請求參數的簽名串,詳見簽名 |
timestamp |
String |
是 |
19 |
2014-07-24 03:07:50 |
發送請求的時間,格式"yyyy-MM-dd HH:mm:ss" |
version |
String |
是 |
3 |
1.0 |
調用的接口版本,固定為:1.0 |
notify_url |
String |
否 |
256 |
http://api.test.alipay.net/atinterface/receive_notify.htm |
支付寶服務器主動通知商戶服務器里指定的頁面http/https路徑。 |
app_auth_token |
String |
否 |
40 |
|
|
biz_content |
String |
是 |
- |
|
請求參數的集合,最大長度不限,除公共參數外所有請求參數都必須放在這個參數中傳遞,具體參照各產品快速接入文檔 |
請求參數(以下只列出了必填參數及少數重要選填參數)
參數 |
類型 |
必填 |
最大長度 |
示例值 |
描述 |
out_trade_no |
String |
必須 |
64 |
20150320010101001 |
商戶訂單號,64個字符以內、只能包含字母、數字、下划線;需保證在商戶端不重復 |
seller_id |
String |
可選 |
28 |
2088102146225135 |
賣家支付寶用戶ID。 如果該值為空,則默認為商戶簽約賬號對應的支付寶用戶ID |
total_amount |
Price |
必須 |
11 |
88.88 |
訂單總金額,單位為元,精確到小數點后兩位,取值范圍[0.01,100000000] 如果同時傳入了【打折金額】,【不可打折金額】,【訂單總金額】三者,則必須滿足如下條件:【訂單總金額】=【打折金額】+【不可打折金額】 |
discountable_amount |
Price |
可選 |
11 |
88.88 |
可打折金額. 參與優惠計算的金額,單位為元,精確到小數點后兩位,取值范圍[0.01,100000000] 如果該值未傳入,但傳入了【訂單總金額】,【不可打折金額】則該值默認為【訂單總金額】-【不可打折金額】 |
buyer_logon_id |
String |
可選 |
100 |
15901825620 |
買家支付寶賬號 |
subject |
String |
必須 |
256 |
Iphone6 16G |
訂單標題 |
body |
String |
可選 |
128 |
Iphone6 16G |
對交易或商品的描述 |
goods_detail |
GoodsDetail [] |
|
- |
- |
訂單包含的商品列表信息.Json格式. 其它說明詳見:“商品明細說明” |
operator_id |
String |
可選 |
28 |
yx_001 |
商戶操作員編號 |
store_id |
String |
可選 |
32 |
NJ_001 |
商戶門店編號 |
terminal_id |
String |
可選 |
32 |
NJ_T_001 |
商戶機具終端編號 |
...更多參數,請移步支付寶開發者文檔中心: https://doc.open.alipay.com/docs/api.htm?spm=a219a.7629065.0.0.5GZNbY&apiId=862&docType=4 |
2.返回參數
公共參數
參數 |
類型 |
必填 |
最大長度 |
示例值 |
描述 |
code |
String |
是 |
- |
40004 |
|
msg |
String |
是 |
- |
Business Failed |
|
sub_code |
String |
否 |
- |
ACQ.TRADE_HAS_SUCCESS |
|
sub_msg |
String |
否 |
- |
交易已被支付 |
|
sign |
String |
是 |
- |
DZXh8eeTuAHoYE3w1J+POiPhfDxOYBfUNn1lkeT/V7P4zJdyojWEa6IZs6Hz0yDW5Cp/viufUb5I0/V5WENS3OYR8zRedqo6D+fUTdLHdc+EFyCkiQhBxIzgngPdPdfp1PIS7BdhhzrsZHbRqb7o4k3Dxc+AAnFauu4V6Zdwczo= |
|
響應參數
參數 |
類型 |
必填 |
最大長度 |
示例值 |
描述 |
out_trade_no |
String |
必填 |
64 |
6823789339978248 |
商戶的訂單號 |
qr_code |
String |
必填 |
1024 |
https://qr.alipay.com/bavh4wjlxf12tper3a |
當前預下單請求生成的二維碼碼串,可以用二維碼生成工具根據該碼串值生成對應的二維碼 |
3.請求示例
1 <?php 2 $params = array( 3 //公共參數 4 5 'app_id' => '2016080200150898', 6 7 'method' => 'alipay.trade.precreate', 8 9 'format' => 'json', 10 11 'charset' => 'utf-8', 12 13 'sign_type' => 'RSA2' 14 15 'timestamp' => '2017-03-31 15:53:42', 16 17 'version' => '1.0', 18 19 'notify_url' => 'http://www.xxxxx.com/notify_url.php', 20 21 'biz_content' => '{"out_trade_no":1490946822,"total_amount":"0.01","subject":"\u6d4b\u8bd5\u5546\u54c1"}', 22 23 'sign'=> 'idFoPOgosWazzgTjKj3MWVdICEw9mNQEj+mJr7TB8uhxacwcASlzN7Qfeqn7v6gncth/oV4uaZ8F2KBkBYenZb2563xJ+foYWFj2HZ8vhcdnVGYMl7U7SJ7jurjTKYOWqILDtIGDw8HcSFNNn+e3ryqMOJjc9neTSIXAqftFNojmHUGnEc9g7y4HH2pnXIri618jZ7wy2HfcpYd1JW5Ku46q+vAEHkTW9u4+hBQ37QwI10Gfi6c+aB21sabj2gjvyEdSHGdy3SbDHeinOM/CqEnw32ArfSfqjGVecJAkRwq/dXhqJlrIukED0scaT6sDepqcUZ2xSGbQMj2djByiqA==', 24 25 26 //請求參數 27 28 'out_trade_no' => '1490946822', 29 30 'total_amount' => '0.01', 31 32 'subject' => '測試商品', 33 );
a. 將公共參數按照URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串stringA:
app_id=2016080200150898&method=alipay.trade.precreate&charset=utf-8&sign_type=RSA2×tamp=2017-03-31+16%3A09%3A34&version=1.0¬ify_url=http%3A%2F%2F10.10.19.39%2Fqhshop%2Fali_notify_url.php&format=json&biz_content=%7B%22out_trade_no%22%3A1490947774%2C%22total_amount%22%3A%220.01%22%2C%22subject%22%3A%22%5Cu6d4b%5Cu8bd5%5Cu5546%5Cu54c1%22%7D&sign=vAs%2Bpy%2BQWxed0qdHXEuuyz5VKGgvrMgy2v%2FK85zUg3lMe5YjJ7WC0OESdB4SHPh0r675wQ%2FPPpPPhE%2Bb%2BNGTGpS%2F49r3j6AodcytkYmP8%2FSadxTQ2ah0j0culPxdDmRRD0%2FzRXHWZOWS9s4K52k6XP0i6dGjAhVOP%2Ffh59SIuK8YWuzfLEAss6CSyv3BDs4RPQ%2FNVE6HFIJJRNBFKQTFoRIqeo9Oan3Pc%2BKhPhLzadjo811wj01MqEmXMc8aQ75wdjvnWm1FBBhZga1lHZ0wlpgbQb0hXyakhwlJFZNx4CBCAI%2Fl%2FVMKerTpp8%2F%2FJWTd6xd%2Fi96C6Pt8UQhIVWiYKQ%3D%3D
b. 將字符串stringA拼接在接口地址后面,得到新的URL地址:
https://openapi.alipaydev.com/gateway.do?app_id=2016080200150898&method=alipay.trade.precreate&charset=utf-8&sign_type=RSA2×tamp=2017-03-31+16%3A09%3A34&version=1.0¬ify_url=http%3A%2F%2F10.10.19.39%2Fqhshop%2Fali_notify_url.php&format=json&biz_content=%7B%22out_trade_no%22%3A1490947774%2C%22total_amount%22%3A%220.01%22%2C%22subject%22%3A%22%5Cu6d4b%5Cu8bd5%5Cu5546%5Cu54c1%22%7D&sign=vAs%2Bpy%2BQWxed0qdHXEuuyz5VKGgvrMgy2v%2FK85zUg3lMe5YjJ7WC0OESdB4SHPh0r675wQ%2FPPpPPhE%2Bb%2BNGTGpS%2F49r3j6AodcytkYmP8%2FSadxTQ2ah0j0culPxdDmRRD0%2FzRXHWZOWS9s4K52k6XP0i6dGjAhVOP%2Ffh59SIuK8YWuzfLEAss6CSyv3BDs4RPQ%2FNVE6HFIJJRNBFKQTFoRIqeo9Oan3Pc%2BKhPhLzadjo811wj01MqEmXMc8aQ75wdjvnWm1FBBhZga1lHZ0wlpgbQb0hXyakhwlJFZNx4CBCAI%2Fl%2FVMKerTpp8%2F%2FJWTd6xd%2Fi96C6Pt8UQhIVWiYKQ%3D%3D
c. 最后將請求參數post到新的URL地址;
4.返回示例
請求接口后,返回的數據格式為JSON格式的字符串。
接口調用成功:
接口調用失敗:
六、支付結果通知
1. 說明
a. 用戶通過手機掃碼二維碼進行支付,支付寶會將該筆訂單的變更信息,沿着商戶調用預下單請求時所傳入的通知地址notify_url主動推送給商戶。
b. 支付寶使用POST方式發送通知信息,因此notify_url頁面中獲取參數的方式為:$_POST[‘out_trade_no’];
c. 程序執行完,如果交易付款成功必須打印輸出“success”(不包含引號)。否則支付寶服務器會不斷重發通知,直到24小時22分鍾。一般情況下,25小時以內完成8次通知(通知的間隔頻率一般是:4m,10m,10m,1h,2h,6h,15h);
d. cookie、session等在此頁面會失效,即無法獲取這些數據;
2. 通知參數(部分重要參數)
參數 |
參數名稱 |
類型 |
必填 |
描述 |
范例 |
notify_time |
通知時間 |
Date |
是 |
通知的發送時間。格式為yyyy-MM-dd HH:mm:ss |
2015-14-27 15:45:58 |
notify_type |
通知類型 |
String(64) |
是 |
通知的類型 |
trade_status_sync |
notify_id |
通知校驗ID |
String(128) |
是 |
通知校驗ID |
ac05099524730693a8b330c5ecf72da9786 |
sign_type |
簽名類型 |
String(10) |
是 |
商戶生成簽名字符串所使用的簽名算法類型,目前支持RSA2和RSA,推薦使用RSA2 |
RSA2 |
sign |
簽名 |
String(256) |
是 |
請參考異步返回結果的驗簽 |
601510b7970e52cc63db0f44997cf70e |
trade_no |
支付寶交易號 |
String(64) |
是 |
支付寶交易憑證號 |
2013112011001004330000121536 |
app_id |
開發者的app_id |
String(32) |
是 |
支付寶分配給開發者的應用Id |
2014072300007148 |
out_trade_no |
商戶訂單號 |
String(64) |
是 |
原支付請求的商戶訂單號 |
6823789339978248 |
seller_id |
賣家支付寶用戶號 |
String(30) |
否 |
賣家支付寶用戶號 |
2088101106499364 |
seller_email |
賣家支付寶賬號 |
String(100) |
否 |
賣家支付寶賬號 |
zhuzhanghu@alitest.com |
trade_status |
交易狀態 |
String(32) |
是 |
TRADE_CLOSED |
|
total_amount |
訂單金額 |
Number(9,2) |
否 |
本次交易支付的訂單金額,單位為人民幣(元) |
20 |
receipt_amount |
實收金額 |
Number(9,2) |
否 |
商家在交易中實際收到的款項,單位為元 |
15 |
subject |
訂單標題 |
String(256) |
否 |
商品的標題/交易標題/訂單標題/訂單關鍵字等,是請求時對應的參數,原樣通知回來 |
當面付交易 |
body |
商品描述 |
String(400) |
否 |
該訂單的備注、描述、明細等。對應請求時的body參數,原樣通知回來 |
當面付交易內容 |
...更多參數,請移步支付寶開發者文檔中心: https://doc.open.alipay.com/docs/doc.htm?treeId=194&articleId=103296&docType=1 |
3. 簽名驗證
第一步: 在通知返回參數列表中,除去sign、sign_type兩個參數外,凡是通知返回回來的參數皆是待驗簽的參數。
第二步: 將剩下參數進行url_decode, 然后進行字典排序,組成字符串,得到待簽名字符串:
第三步: 將簽名參數(sign)使用base64解碼為字節碼串。
第四步: 使用RSA的驗簽方法,通過簽名字符串、簽名參數(經過base64解碼)及支付寶公鑰驗證簽名。
第五步:需要嚴格按照如下描述校驗通知數據的正確性:
* 驗證該通知數據中的out_trade_no是否為商戶系統中創建的訂單號;
* 判斷total_amount是否確實為該訂單的實際金額(即商戶訂單創建時的金額);
* 校驗通知中的seller_id(或者seller_email) 是否為out_trade_no這筆單據的對應的操作方(有的時候,一個商戶可能有多個seller_id/seller_email);
* 在支付寶的業務通知中,只有交易通知狀態為TRADE_SUCCESS或TRADE_FINISHED時,支付寶才會認定為買家付款成功;
4. 返回參數
支付成功則返回“success”,否則返回其他字符;
七、訂單查詢
該接口提供所有支付寶支付訂單的查詢,商戶可以通過該接口主動查詢訂單狀態,完成下一步的業務邏輯。
1. 請求參數
公共參數
參數 |
類型 |
必填 |
最大長度 |
示例值 |
描述 |
app_id |
String |
是 |
32 |
2014072300007148 |
支付寶分配給開發者的應用ID |
method |
String |
是 |
128 |
接口名稱 |
alipay.trade.query |
format |
String |
否 |
40 |
僅支持JSON |
JSON |
charset |
String |
是 |
10 |
utf-8 |
請求使用的編碼格式,如utf-8,gbk,gb2312等 |
sign_type |
String |
是 |
10 |
RSA2 |
商戶生成簽名字符串所使用的簽名算法類型,目前支持RSA2和RSA,推薦使用RSA2 |
sign |
String |
是 |
256 |
詳見示例 |
商戶請求參數的簽名串,詳見簽名 |
timestamp |
String |
是 |
19 |
2014-07-24 03:07:50 |
發送請求的時間,格式"yyyy-MM-dd HH:mm:ss" |
version |
String |
是 |
3 |
1.0 |
調用的接口版本,固定為:1.0 |
app_auth_token |
String |
否 |
40 |
|
|
biz_content |
String |
是 |
- |
|
請求參數的集合,最大長度不限,除公共參數外所有請求參數都必須放在這個參數中傳遞,具體參照各產品快速接入文檔 |
請求參數
參數 |
類型 |
必填 |
最大長度 |
示例值 |
描述 |
out_trade_no |
String |
特殊可選 |
64 |
20150320010101001 |
訂單支付時傳入的商戶訂單號,和支付寶交易號不能同時為空。 trade_no,out_trade_no如果同時存在優先取trade_no |
trade_no |
String |
特殊可選 |
64 |
2014112611001004680 073956707 |
支付寶交易號,和商戶訂單號不能同時為空 |
2. 返回參數
公共參數
參數 |
類型 |
必填 |
最大長度 |
示例值 |
描述 |
code |
String |
是 |
- |
40004 |
|
msg |
String |
是 |
- |
Business Failed |
|
sub_code |
String |
否 |
- |
ACQ.TRADE_HAS_SUCCESS |
|
sub_msg |
String |
否 |
- |
交易已被支付 |
|
sign |
String |
是 |
- |
DZXh8eeTuAHoYE3w1J+POiPhfDxOYBfUNn1lkeT/V7P4zJdyojWEa6IZs6Hz0yDW5Cp/viufUb5I0/V5WENS3OYR8zRedqo6D+fUTdLHdc+EFyCkiQhBxIzgngPdPdfp1PIS7BdhhzrsZHbRqb7o4k3Dxc+AAnFauu4V6Zdwczo= |
|
響應參數(以下只列出了必填參數及少數重要選填參數)
參數 |
類型 |
必填 |
最大長度 |
示例值 |
描述 |
trade_no |
String |
必填 |
64 |
2013112011001004330000121536 |
支付寶交易號 |
out_trade_no |
String |
必填 |
64 |
6823789339978248 |
商家訂單號 |
trade_status |
String |
必填 |
32 |
TRADE_CLOSED |
交易狀態:WAIT_BUYER_PAY(交易創建,等待買家付款)、TRADE_CLOSED(未付款交易超時關閉,或支付完成后全額退款)、TRADE_SUCCESS(交易支付成功)、TRADE_FINISHED(交易結束,不可退款) |
total_amount |
Price |
必填 |
11 |
88.88 |
交易的訂單金額,單位為元,兩位小數。該參數的值為支付時傳入的total_amount |
receipt_amount |
Price |
必填 |
11 |
15.25 |
實收金額,單位為元,兩位小數。該金額為本筆交易,商戶賬戶能夠實際收到的金額 |
...更多參數,請移步支付寶開發者文檔中心: https://doc.open.alipay.com/doc2/apiDetail.htm?spm=a219a.7629065.0.0.1hBqdQ&apiId=757&docType=4 |
3. 請求示例
1 <?php 2 $params = array( 3 //公共參數 4 5 'app_id' => '2016080200150898', 6 7 'method' => 'alipay.trade.query', 8 9 'format' => 'JSON', 10 11 'charset' => 'utf-8', 12 13 'sign_type' => 'RSA2', 14 15 'timestamp' => '2017-03-31 17:40:53', 16 17 'version' => '1.0', 18 19 'biz_content' => '{"out_trade_no":"20170331125451"}', 20 21 'sign' => 'CqVzz7bZ2PCnAGczJcciEqMsbtBe2eEArNoiOjD2iY7DwGsGrXicYLk6lnlc6Pq5uJaOwHRGbae8Y6R7bvGpX9lPEH/zlTkT56fTtfQ1EQbk5UYcW/Z8q5mhje3c/DNIQ4tOiRX5K9RSctbvC/8kQMx4MUDMc9xiJZfzl9WRfAH45Bn3PGme91QoX1lcw8Ztyz+rKF7UCAIjerIVXrAcrHWL9e7B7UEM1BJJ8WEwMQ1nIsW7tiTuKWfbZ/vOHeyUsFUqWShQoXV38v3qADAotYDtQt6v0y4Uell+A4NlXuDT7++jmGsa+NTPaTM4mhXfFt3Sa1rkmO9fky/6sR+CkQ==', 22 23 24 //請求參數 25 26 'out_trade_no' => '20170331125451' 27 );
剩下操作步驟,參考【五、統一收單線下交易創建 -> 3.請求示例】,此處不再贅述。
4. 返回示例
請求接口后,返回的數據格式為JSON格式的字符串。
接口調用成功:
接口調用失敗: