前言:最近開發(fā)支付寶支付功能,總結(jié)一下做個(gè)分享
官方文檔:https://opendocs.alipay.com/apis
支付寶沙箱地址: https://openhome.alipay.com/platform/appDaily.htm?tab=info
支付寶支付流程:
準(zhǔn)備工作:獲取支付寶沙箱數(shù)據(jù)(appid,支付寶網(wǎng)關(guān),rsa2秘,沙箱支付賬號(hào)等)
集成springboot,使用java代碼發(fā)起支付請(qǐng)求
支付寶收到支付請(qǐng)求后,返回html代碼片段,用于前端展示二維碼
掃碼支付成功后,支付寶發(fā)送同步、異步通知請(qǐng)求,同步、異步通知路徑可在配置文件中進(jìn)行配置
收到異步通知結(jié)果后,進(jìn)行驗(yàn)簽,驗(yàn)簽通過,返回成功信息通知支付寶不在進(jìn)行異步通知
此時(shí)支付寶支付流程完成,調(diào)用支付寶查詢接口,確認(rèn)支付成功
一、獲取支付寶沙箱數(shù)據(jù)
打開上述沙箱地址,獲取沙箱配置,查看下圖信息
二、集成springboot,使用java代碼發(fā)起支付請(qǐng)求
1、在pom.xml文件添加支付寶依賴
1
2
3
4
5
6
|
<!-- 支付寶支付 --> <dependency> <groupid>com.alipay.sdk</groupid> <artifactid>alipay-sdk-java</artifactid> <version> 3.7 . 26 .all</version> </dependency> |
2、在項(xiàng)目中新建一個(gè)支付寶工具類
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
53
54
55
56
57
58
59
|
public class alipayconfig { // ↓↓↓↓↓↓↓↓↓↓請(qǐng)?jiān)谶@里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ // 應(yīng)用id,您的appid,收款賬號(hào)既是您的appid對(duì)應(yīng)支付寶賬號(hào) public static string app_id = "" ; // 商戶私鑰,您的pkcs8格式rsa2私鑰 public static string merchant_private_key = "" ; // 支付寶公鑰,查看地址:https://openhome.alipay.com/platform/keymanage.htm 對(duì)應(yīng)appid下的支付寶公鑰。 public static string alipay_public_key = "" ; // 服務(wù)器異步通知頁面路徑 需http://格式的完整路徑,不能加?id=123這類自定義參數(shù),必須外網(wǎng)可以正常訪問 // 這里需要配置支付寶回調(diào)的后端路徑,必須要外網(wǎng)可以訪問 public static string notify_url = "http://localhost:8080/alipay.trade.page.pay-java-utf-8/notify_url.jsp" ; // 頁面跳轉(zhuǎn)同步通知頁面路徑 需http://格式的完整路徑,不能加?id=123這類自定義參數(shù),必須外網(wǎng)可以正常訪問 // todo 這里需要配置支付寶回調(diào)的前端路徑,必須要外網(wǎng)可以訪問 public static string return_url = "http://localhost:8080/alipay.trade.page.pay-java-utf-8/return_url.jsp" ; // 簽名方式 public static string sign_type = "rsa2" ; // 字符編碼格式 public static string charset = "utf-8" ; // 支付寶網(wǎng)關(guān) public static string gatewayurl = "https://openapi.alipaydev.com/gateway.do" ; // 日志路徑 public static string log_path = "c:\\" ; // ↑↑↑↑↑↑↑↑↑↑請(qǐng)?jiān)谶@里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ /** * 寫日志,方便測(cè)試(看網(wǎng)站需求,也可以改成把記錄存入數(shù)據(jù)庫) * * @param sword 要寫入日志里的文本內(nèi)容 */ public static void logresult(string sword) { filewriter writer = null ; try { writer = new filewriter(log_path + "alipay_log_" + system.currenttimemillis() + ".txt" ); writer.write(sword); } catch (exception e) { e.printstacktrace(); } finally { if (writer != null ) { try { writer.close(); } catch (ioexception e) { e.printstacktrace(); } } } } } |
3、定義service
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
public interface alipayservice { /** * 發(fā)起支付 * @param outtradeno 訂單編號(hào)(唯一) * @param totalamount 訂單價(jià)格 * @param subject 商品名稱 */ string gopay(string outtradeno,bigdecimal totalamount,string subject) throws exception; /** * 交易查詢 * @param outtradeno 訂單編號(hào)(唯一) */ string query(string outtradeno) throws alipayapiexception; /** * 交易關(guān)閉 * @param outtradeno訂單編號(hào)(唯一) */ string close(string outtradeno) throws alipayapiexception; } |
4、實(shí)現(xiàn)serviceimpl,發(fā)起支付請(qǐng)求,交易查詢等
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
53
54
55
56
57
|
public class alipayserviceimpl implements alipayservice { @autowired private rechargedetailservice rechargedetailservice; @override public string gopay(string outtradeno, bigdecimal totalamount, string subject) throws exception { alipayclient alipayclient = new defaultalipayclient(alipayconfig.gatewayurl, alipayconfig.app_id, alipayconfig.merchant_private_key, "json" , alipayconfig.charset, alipayconfig.alipay_public_key, alipayconfig.sign_type); alipaytradepagepayrequest alipayrequest = new alipaytradepagepayrequest(); /** 同步通知,支付完成后,支付成功頁面 */ alipayrequest.setreturnurl(alipayconfig.return_url); /** 異步通知,支付完成后,需要進(jìn)行的異步處理 */ alipayrequest.setnotifyurl(alipayconfig.notify_url); alipayrequest.setbizcontent( "{\"out_trade_no\":\"" + outtradeno + "\"," + "\"total_amount\":\"" + totalamount + "\"," + "\"subject\":\"" + subject + "\"," + "\"body\":\"付款\"," + "\"timeout_express\":\"15m\"," + "\"product_code\":\"fast_instant_trade_pay\"}" ); /** 轉(zhuǎn)換格式 */ string form = "" ; form = alipayclient.pageexecute(alipayrequest).getbody(); return form; } @override public string query(string outtradeno) throws alipayapiexception { alipayclient alipayclient = new defaultalipayclient(alipayconfig.gatewayurl, alipayconfig.app_id, alipayconfig.merchant_private_key, "json" , alipayconfig.charset, alipayconfig.alipay_public_key, alipayconfig.sign_type); alipaytradequeryrequest alipayrequest = new alipaytradequeryrequest(); /** 請(qǐng)求接口 */ alipayrequest.setbizcontent( "{\"out_trade_no\":\"" + outtradeno + "\"," + "\"trade_no\":\"" + "" + "\"}" ); /** 轉(zhuǎn)換格式 */ string result = alipayclient.execute(alipayrequest).getbody(); return result; } @override public string close(string outtradeno) throws alipayapiexception { alipaytradecloserequest alipayrequest = new alipaytradecloserequest(); alipayclient alipayclient = new defaultalipayclient(alipayconfig.gatewayurl, alipayconfig.app_id, alipayconfig.merchant_private_key, "json" , alipayconfig.charset, alipayconfig.alipay_public_key, alipayconfig.sign_type); alipayrequest.setbizcontent( "{\"out_trade_no\":\"" + outtradeno + "\"," + "\"trade_no\":\"" + "" + "\"}" ); string result = alipayclient.execute(alipayrequest).getbody(); return result; } } |
5、創(chuàng)建支付寶controller
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
public class alipaycontroller { @autowired private alipayservice alipayservice; /** * 訂單支付 */ @getmapping ( "gopay" ) public map<object, object> gopay() throws exception{ /** 模仿數(shù)據(jù)庫,從后臺(tái)調(diào)數(shù)據(jù)*/ string outtradeno = "202101010001" ; bigdecimaltotalamount = new bigdecimal( 10000 ); string subject = "蘋果12" ; string pay = alipayservice.gopay(outtradeno, totalamount, subject); map<object, object> pays = new hashmap<>(); pays.put( "pay" , pay); return pays; } /** * 交易查詢 */ @postmapping ( "aipayquery" ) public result<object> alipayquery() throws exception{ /**調(diào)取支付訂單號(hào)*/ string outtradeno = "13123" ; string query = alipayservice.query(outtradeno); object json = jsonobject.tojson(query); /*jsonobject jobject = new jsonobject(); jobject.get(query);*/ return result.success(json); } /** * 交易關(guān)閉 * @throws alipayapiexception */ @postmapping("alipayclose") public result<object> alipaycolse() throws alipayapiexception{ /** 調(diào)取數(shù)據(jù)*/ string outtradeno = "13123"; string close = alipayservice.close(outtradeno); return result.success(close); } /** * 異步通知支付結(jié)果 * * @param request * @return string * @throws alipayapiexception * @throws parseexception */ @postmapping ( "/callback" ) public string alipaynotify(httpservletrequest request) throws exception { // 獲取支付寶的請(qǐng)求信息 map<string, string> map = new hashmap<>(); map<string, string[]> requestparams = request.getparametermap(); if (requestparams.isempty()) { return "failure" ; } // 將 map<string,string[]> 轉(zhuǎn)為 map<string,string> for (iterator<string> iter = requestparams.keyset().iterator(); iter.hasnext();) { string name = iter.next(); string[] values = requestparams.get(name); string valuestr = "" ; for ( int i = 0 ; i < values.length; i++) { valuestr = (i == values.length - 1 ) ? valuestr + values[i] : valuestr + values[i] + "," ; } map.put(name, valuestr); } // 驗(yàn)簽 boolean signverified = alipaysignature.rsacheckv1(map, alipayconfig.alipay_public_key, alipayconfig.charset, alipayconfig.sign_type); // 驗(yàn)簽通過 if (signverified) { //支付成功后進(jìn)行操作 } return "failure" ; } } |
到此springboot整合支付寶掃碼支付,就完成了
到此這篇關(guān)于java中spring boot支付寶掃碼支付及支付回調(diào)的實(shí)現(xiàn)代碼的文章就介紹到這了,更多相關(guān)spring boot支付寶掃碼支付內(nèi)容請(qǐng)搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!
原文鏈接:https://blog.csdn.net/qq954724583/article/details/113860419