React網頁應用調起支付寶沙箱測試實現
React+Redux網頁應用調起支付寶沙箱測試實現
1、新建React+Redux專案,建立空頁面,增加一個支付連結,編寫Redux方法呼叫Api生成支付連結
render() { let searchParam = { loginState: this.props.loginFailed, schcode: this.props.schcode, stucode: this.props.stucode } return ( <div> <Profile name={this.props.username} image={this.props.photo} /> <div id='testreducer' style={{ color: 'red', textAlign: 'center' }}>{this.state.helloValue}</div> <div onClick={this.alipay.bind(this)} style={{ color: 'red', textAlign: 'center', border: '1px solid blue', marginTop: '100px' }}> 點選跳轉支付寶支付 </div> </div> ); }
alipay() { let obj = {} obj.total_amount = 100; obj.stucode = this.props.stucode; obj.schcode = this.props.schcode; obj.subject = '支付寶沙箱環境支付測試'; this.props.getAlipay.call(this, obj); }
2、支付寶沙箱註冊應用和支付寶沙箱版本安裝
https://openhome.alipay.com/platform/appDaily.htm?tab=info 支付寶登入後檢視個人測試AppID
使用支付寶公鑰私鑰工具,生成公鑰:https://docs.open.alipay.com/291/105971/
在沙箱工具掃描二維碼安裝安卓版本支付寶沙箱測試版本
3、Api專案編寫支付寶調起相關程式碼邏輯
定義appid、閘道器等引數
//支付寶引數 const app_id = 'xxxxxx'; const return_url = 'http://172.16.117.43:3001'; const notify_url = 'http://172.16.117.43:8001/api/alipay/alipaynotify'; const gateway = 'https://openapi.alipaydev.com/gateway.do?';宣告api方法alipaysign,post型別,用於接收React頁面的api請求,最終res.json(util.success(finalparams))返回支付寶支付連結
/** * 獲取支付寶支付地址帶參 */ router.post('/alipaysign', function (req, res) { let total_amount = req.body.total_amount; let schcode = req.body.schcode; let stucode = req.body.stucode; let subject = req.body.subject; let out_trade_no = moment().format('YYYYMMDDHHmmss') + moment().millisecond(); // + '_' + schcode + '_' + stucode; console.log(out_trade_no) //生成系統訂單併入庫 let addJson = { out_trade_no: out_trade_no, schcode: schcode, stucode: stucode }; // alipay.addNewOrder(addJson,function(err,data){ ... }); let params = new Map(); params.set('app_id', app_id); params.set('method', 'alipay.trade.wap.pay'); params.set('charset', 'utf-8'); params.set('sign_type', 'RSA2'); params.set('timestamp', moment().format('YYYY-MM-DD HH:mm:ss')); params.set('version', '1.0'); params.set('return_url', return_url); params.set('notify_url', notify_url); params.set('biz_content', buildBizContent(subject, out_trade_no, total_amount)); params.set('sign', buildSign(params)); let finalparams = gateway + Array.from(params).map(([k, v]) => `${k}=${encodeURIComponent(v)}`).join('&'); console.log(finalparams) res.json(util.success(finalparams)); })
生成業務請求引數的集合
function buildBizContent(subject, outTradeNo, totalAmount) { let bizContent = { subject: subject, out_trade_no: outTradeNo, total_amount: totalAmount, product_code: 'QUICK_MSECURITY_PAY', }; return JSON.stringify(bizContent); }
根據引數構建簽名
function buildSign(paramsMap) { let paramsList = Array.from(paramsMap); paramsList.sort(); let paramsString = paramsList.map(([k, v]) => `${k}=${v}`).join('&'); let privateKey = fs.readFileSync(path.join(__dirname, 'alipay_private.pem'), 'utf8'); let signType = paramsMap.get('sign_type'); return signWithPrivateKey(signType, paramsString, privateKey); }
通過私鑰給字串簽名
function signWithPrivateKey(signType, content, privateKey) { let sign; if (signType.toUpperCase() === 'RSA2') { sign = crypto.createSign("RSA-SHA256"); } else if (signType.toUpperCase() === 'RSA') { sign = crypto.createSign("RSA-SHA1"); } else { throw new Error('請傳入正確的簽名方式,signType:' + signType); } sign.update(content); return sign.sign(privateKey, 'base64'); }
上面的程式碼就是一個完整的生成合規的支付寶支付連結,需要注意要用支付寶工具生成公鑰私鑰檔案放在合適的位置。
4、測試支付
5、接收支付寶非同步通知
/** * 通過私鑰給字串簽名 * @param signType 返回引數的簽名型別:RSA2或RSA * @param content 需要加密的字串 * @param privateKey 私鑰 * @returns {number | PromiseLike<ArrayBuffer>} * @private */ function signWithPrivateKey(signType, content, privateKey) { let sign; if (signType.toUpperCase() === 'RSA2') { sign = crypto.createSign("RSA-SHA256"); } else if (signType.toUpperCase() === 'RSA') { sign = crypto.createSign("RSA-SHA1"); } else { throw new Error('請傳入正確的簽名方式,signType:' + signType); } sign.update(content); return sign.sign(privateKey, 'base64'); } /** * 驗證支付寶非同步通知的合法性 * @param params 支付寶非同步通知結果的引數 * @returns {*} */ function verifySign(params) { try { let sign = params['sign']; //簽名 let signType = params['sign_type']; //簽名型別 let paramsMap = new Map(); for (let key in params) { paramsMap.set(key, params[key]); } let paramsList = Array.from(paramsMap); paramsList.sort(); let paramsString = paramsList.map(([k, v]) => `${k}=${decodeURIComponent(v)}`).join('&'); let publicKey = fs.readFileSync(path.join(__dirname, 'alipay_public.pem'), 'utf8'); return verifyWithPublicKey(signType, sign, paramsString, publicKey); } catch (e) { console.error(e); return false; } } /** * 驗證簽名 * @param signType 返回引數的簽名型別:RSA2或RSA * @param sign 返回引數的簽名 * @param content 引數組成的待驗籤串 * @param publicKey 支付寶公鑰 * @returns {*} 是否驗證成功 * @private */ function verifyWithPublicKey(signType, sign, content, publicKey) { try { let verify; if (signType.toUpperCase() === 'RSA2') { verify = crypto.createVerify('RSA-SHA256'); } else if (signType.toUpperCase() === 'RSA') { verify = crypto.createVerify('RSA-SHA1'); } else { throw new Error('未知signType:' + signType); } verify.update(content); return verify.verify(publicKey, sign, 'base64') } catch (err) { console.error(err); return false; } } /** * 獲取支付寶支付非同步通知 */ router.post('/alipaynotify', function (req, res) { let signType = req.body.sign_type; //簽名型別:商戶生成簽名字串所使用的簽名演算法型別,目前支援RSA2和RSA,推薦使用RSA2 let sign = req.body.sign; //簽名:請參考<a href="#yanqian" class="bi-link">非同步返回結果的驗籤</a> let tradeNo = req.body.trade_no; //支付寶交易號:支付寶交易憑證號 let outTradeNo = req.body.out_trade_no; //商戶訂單號:原支付請求的商戶訂單號 let buyerLogonId = req.body.buyer_logon_id; //買家支付寶賬號:買家支付寶賬號 let sellerId = req.body.seller_id; //賣家支付寶使用者號:賣家支付寶使用者號 let tradeStatus = req.body.trade_status; //交易狀態:交易目前所處的狀態,見<a href="#jiaoyi" class="bi-link">交易狀態說明</a> let totalAmount = req.body.total_amount; //訂單金額:本次交易支付的訂單金額,單位為人民幣(元) let receiptAmount = req.body.receipt_amount; //實收金額:商家在交易中實際收到的款項,單位為元 let gmtPayment = req.body.gmt_payment;//交易付款時間:該筆交易的買家付款時間。格式為yyyy-MM-dd HH:mm:ss let isSuccess = verifySign(req.body); console.log(isSuccess) if (isSuccess) { if (tradeStatus === 'TRADE_FINISHED') { //交易狀態TRADE_FINISHED的通知觸發條件是商戶簽約的產品不支援退款功能的前提下,買家付款成功;或者,商戶簽約的產品支援退款功能的前提下,交易已經成功並且已經超過可退款期限。 } else if (tradeStatus === 'TRADE_SUCCESS') { //狀態TRADE_SUCCESS的通知觸發條件是商戶簽約的產品支援退款功能的前提下,買家付款成功 } else if (tradeStatus === 'WAIT_BUYER_PAY') { //交易建立,等待買家付款 } else if (tradeStatus === 'TRADE_CLOSED') { //未付款交易超時關閉,或支付完成後全額退款 } res.send('success'); } else { res.send('fail'); } });
由請喊我大龍哥最後編輯於:7個月前
內容均為作者獨立觀點,不代表八零IT人立場,如涉及侵權,請及時告知。
相關文章
- SpringMVC 實現支付寶支付功能(沙箱環境)SpringMVC
- java實現沙箱測試環境支付寶支付(demo)和整合微信支付和支付寶支付到springmvc+spring+mybatis環境全過程(支付寶和微信支付、附原始碼)JavaSpringMVCMyBatis原始碼
- pc端實現支付寶支付
- 沙箱環境開發支付寶支付,收不到非同步通知(使用Ngrok內網穿透)非同步內網穿透
- Laravel 整合 EasyAlipay 實現支付寶手機網站 Wap 支付Laravel網站
- 網際網路新貴向支付寶、微信支付發起挑戰
- [譯] 測試 React & Redux 應用良心指南ReactRedux
- Laravel實現支付寶分賬Laravel
- 下個月起,微信支付寶迎來調整,出門請帶點現金
- 支付寶沙箱除錯時遭到攔截,提示存在釣魚網站風險除錯網站
- 【翻譯】基於 Cypress 測試 React 應用React
- 支付寶怎麼刪除已授權應用?支付寶刪除已授權應用的方法
- 用RecyclerView實現類似支付寶應用圖示拖拽排序以及增刪管理的功能View排序
- Android 透過scheme跳轉支付寶實現支付AndroidScheme
- 微軟允許測試人員在 Windows 11 上試用 Android 應用程式:已支援執行支付寶等APP微軟WindowsAndroidAPP
- 【譯】React 應用效能調優React
- 微前端中實現沙箱環境的方案調研前端
- 支付寶小遊戲調研遊戲
- 支付寶截圖反饋功能實現
- 應用<測試專案>官網
- 讓react用起來更得心應手——(react-redux)ReactRedux
- Deeplink實現華為應用外商品支付功能
- [譯] 使用 Puppeteer 和 Jest 測試你的 React 應用React
- Chrome實現自動化測試:錄製回放網頁動作Chrome網頁
- 支付寶裡如何使用網銀支付?
- 在 React 應用程式中實現簡單的頁面檢視跟蹤器React
- 在網頁上調起本機C#程式網頁C#
- 網際網路App應用程式測試流程及測試總結APP
- SSM 實現支付寶支付功能(圖文詳解+完整程式碼)SSM
- 支付寶 v3 驗籤如何實現
- 微信,支付寶小程式實現原理概述
- day114:MoFang:基於支付寶沙箱測試環境完成建立充值訂單介面&服務端處理支付結果的同步通知和非同步通知服務端非同步
- 測試嵌入GeoGebra網頁網頁
- java對接支付寶支付(手機網站支付)Java網站
- 智慧支付穩定性測試實戰
- 手把手教你快應用接入微信H5網頁支付H5網頁
- 讓react用起來更得心應手——(React 基礎簡析)React
- React Native 原生模組封裝:支付寶示例React Native封裝