前端H5微信支付寶支付實(shí)現(xiàn)方法(uniapp為例)
以u(píng)niapp項(xiàng)目為例
支付寶的
首先是一個(gè)支付類型選擇頁面,在選擇支付寶支付后,跳轉(zhuǎn)到一個(gè)空白頁,用于支付寶支付的中轉(zhuǎn)頁面。
在點(diǎn)擊立即支付之后,直接跳轉(zhuǎn)至自行設(shè)置好的空白頁就好,并把你生成訂單所需要的數(shù)據(jù)一并帶過去。
uni.navigateTo({ url: `/pages/alipaying/alipay?orderNum=${this.orderNum}&price=${this.orderinfo.price}`, });
接下來就是重點(diǎn)操作了(其實(shí)非常簡(jiǎn)單),在跳轉(zhuǎn)這個(gè)頁面之后直接調(diào)用后端接口,將數(shù)據(jù)傳給后端生成訂單,并且還需要兩個(gè)地址,一個(gè)是取消支付的回調(diào)地址(quitUrl),一個(gè)是支付完之后的回調(diào)地址(returnUrl),后端會(huì)根據(jù)這些信息生成一個(gè)form表單返回給你,我們只需要將這個(gè)表單渲染到這個(gè)空白頁面,并進(jìn)行提交表單的操作,就會(huì)跳轉(zhuǎn)至支付寶的頁面去進(jìn)行支付操作,在取消或支付完成會(huì)跳轉(zhuǎn)至之前傳給后端規(guī)定好的地址,在那里去調(diào)后端接口查詢支付結(jié)果或者重新支付等其他操作就行了。
空白頁面內(nèi)容如下:
<template> <!-- #ifdef H5 --> <div v-html="html"> </div> <!-- #endif --> </template> <script> import api from "../../utils/api"; //這個(gè)utils是對(duì)一些東西做了處理,其實(shí)沒必要,utils.getStorage直接用uni.getStorage一樣的 import utils from "../../utils"; export default { onLoad(options) { this.orderNum=options.orderNum this.price=options.price this.couponId = options.couponId }, mounted(){ const result = utils.getStorage("weixinCallback"); if(result!=3){//這是弄了個(gè)變量來判斷是否已經(jīng)進(jìn)入了支付,防止用戶直接左滑的返回一直在觸發(fā)支付 this.alipay() } }, data() { return { orderNum:"", price:"", html:"", couponId:"" }; }, methods: { async alipay(){ //這里是獲取支付寶返回的表單用的接口,那兩個(gè)地址我在api里面寫了默認(rèn)值,所以這個(gè)地方就不傳了,接口詳細(xì)內(nèi)容就和普通調(diào)接口一樣,該傳傳,該接接 const res = await api.alipayOrder(this.orderNum,this.price,this.couponId) //將表單渲染進(jìn)頁面 document.querySelector('body').innerHTML = res; //在渲染完立即提交表單,就會(huì)進(jìn)入支付寶支付的界面 this.$nextTick(()=>{ utils.setStorage("weixinCallback", 3); window.document.forms[0].submit() }) } }, }; </script>
不過這里的實(shí)現(xiàn)支持正常瀏覽器h5,但是微信內(nèi)置瀏覽器的話會(huì)提示在瀏覽器打開該鏈接,非常的繁瑣,查了一下午解決方案,就是沒有解決方案(可能也是我沒找到),索性直接微信內(nèi)置瀏覽器的話就不顯示支付寶支付,反正需求很奇怪,都打開微信了還要支付寶干啥,對(duì)吧
微信的
微信支付比支付寶支付稍微麻煩一點(diǎn)點(diǎn),但也不難,對(duì)于前端來說調(diào)接口就完事了。
微信的話有兩種,一種外部瀏覽器,一種微信內(nèi)置瀏覽器
所以首先需要一個(gè)方法來判斷瀏覽器的類型
isWeiXin(){ let ua = window.navigator.userAgent.toLowerCase(); if (ua.match(/MicroMessenger/i) == 'micromessenger') { this.payway.forEach(item=>{ if(item.value==1){ item.flag = false } }) return true; } else { return false; } },
是微信內(nèi)置就返回true,不是返回false
先說外部瀏覽器的情況,在立即支付之后去判斷一下瀏覽器是什么,返回false就走下面代碼,調(diào)接口就完了
//把生成訂單需要的數(shù)據(jù)傳給后端,然后后端會(huì)返回一個(gè)地址 const res2 = await api.weixinPayOrder(this.orderNum,this.couponId); const name = "_self"; //因?yàn)槲⑿胖Ц稕]有傳什么回調(diào)地址,在支付完之后還會(huì)回到這個(gè)頁面,所以防止重復(fù)觸發(fā)這里設(shè)置一個(gè)值來控制 utils.setStorage("weixinCallback", 1); //打開后端返回的地址,就可以去微信支付了 window.open(res2.mweb_url, name);
在頁面展示的時(shí)候onShow鉤子,判斷weixinCallback這個(gè)值來執(zhí)行不同的操作,如果是1說明已經(jīng)發(fā)起過支付,那么需要一個(gè)執(zhí)行另一個(gè)方法來調(diào)用查詢支付結(jié)果的接口來跳轉(zhuǎn)頁面,下面是查詢結(jié)果的方法
getOrderDetail() { clearTimeout(this.timer); this.timer = setTimeout(() => { let initTime = +new Date(); let loop = () => { //這里調(diào)用后端給的查詢支付結(jié)果的接口, api.weixinPayOrderBack(this.orderNum).then((res) => { if (res.status == 1) { //支付成功跳轉(zhuǎn) uni.navigateTo({ url: `/pages/payWeixinSuccess/payWeixinSuccess?orderNum=${this.orderNum}&result=yes`, }); } else { let now = +new Date(); if (now - initTime < 45000) { loop(); } else { //支付失敗跳轉(zhuǎn) uni.navigateTo({ url: `/pages/payWeixinSuccess/payWeixinSuccess?orderNum=${this.orderNum}&result=no`, }); } } }); }; loop(); }, 2000); },
這樣其實(shí)就完成了外部瀏覽器的微信支付前端部分,可能還有不足或bug,至少現(xiàn)在我沒發(fā)現(xiàn)。
接下來是微信內(nèi)置瀏覽器支付,首先需要一個(gè)(jweixin-module),下載這個(gè)依賴npm、yarn都行
在調(diào)用isWeiXin()為true時(shí),表示是微信內(nèi)置瀏覽器
首先,調(diào)用微信官方提供的鏈接獲取用戶授權(quán)信息code
//應(yīng)用的appid const appId = "wxxxxxxxxxxxx"; //重定向的地址,重定向回當(dāng)前頁面 const local = window.location.href //打開微信官方提供的鏈接,傳入appid和回調(diào)地址,在用戶確認(rèn)授權(quán)后會(huì)在回調(diào)地址后面拼接上code window.location. + encodeURIComponent(local) + '&response_type=code&scope=snsapi_base&state=1#wechat_redirect';
在授權(quán)后回到這個(gè)頁面看看地址上有沒有code,有則進(jìn)行下一步
寫一個(gè)方法取出地址里的code
getUrlParam(name) { var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)') let url = window.location.href let search = url.split('?')[1] if (search) { var r = search.substr(0).match(reg) if (r !== null)return unescape(r[2]) return null } else return null },
判斷當(dāng)前地址有沒有code,有則準(zhǔn)備進(jìn)行支付操作,沒有則去到讓用戶授權(quán)
const code = this.getUrlParam("code") if(code==null || code == ""){ //這里走讓用戶授權(quán)的操作 }else{ //這里走支付的操作,下面詳寫 }
在else中,使用前面下載的依賴(jweixin-module)來走支付流程
//這里是將code傳給后端來獲取openId const res2 = await api.sendCode(code); //然后將后端給的openId和訂單信息繼續(xù)給后端,在后端返回支付所需的一些參數(shù)在依賴中需要配置 //這兩個(gè)接口后端可以合并成一個(gè)的吧,我不太理解為啥分成兩個(gè),繁瑣 const res3 = await api.weixinPayOrder(this.orderNum,res2.data); //下面就是使用這個(gè)依賴包了,具體配置什么意思網(wǎng)上復(fù)制來的,一查一大堆 jweixin.config({//初始化配置 debug: false, // 是否開啟調(diào)試模式,調(diào)用的所有api的返回值會(huì)在客戶端alert出來,若要查看傳入的參數(shù),可以在pc端打開,參數(shù)信息會(huì)通過log打出,僅在pc端時(shí)才會(huì)打印。 appId: appId, // 必填,公眾號(hào)的唯一標(biāo)識(shí) timestamp: res3.timeStamp, // 必填,生成簽名的時(shí)間戳 nonceStr: res3.nonceStr, // 必填,生成簽名的隨機(jī)串 signature:res3.paySign, // 必填,簽名, jsApiList: ['chooseWXPay'] // 必填,需要使用的JS接口列表 }); jweixin.ready(function() { jweixin.chooseWXPay({//下面這些參數(shù)都是在上面接口返回給我的 timestamp: res3.timeStamp, // 支付簽名時(shí)間戳,注意微信jssdk中的所有使用timestamp字段均為小寫。但最新版的支付后臺(tái)生成簽名使用的timeStamp字段名需大寫其中的S字符 nonceStr: res3.nonceStr, // 支付簽名隨機(jī)串,不長(zhǎng)于 32 位 package: res3.package, // 統(tǒng)一支付接口返回的prepay_id參數(shù)值,提交格式如:prepay_id=***) signType: res3.signType, // 簽名方式,默認(rèn)為'SHA1',使用新版支付需傳入'MD5' paySign: res3.paySign, // 支付簽名 success: function(res) { // 支付成功后的回調(diào)函數(shù) uni.showToast({ icon: 'none', title: '支付成功', duration: 4000 }); uni.navigateTo({ url: `/pages/payWeixinSuccess/payWeixinSuccess?orderNum=${this.orderNum}&result=yes`, }); }, cancel: function(r) {}, fail: function(res) { console.log('payfail') } }); }); jweixin.error(function(res) { uni.showToast({ icon: 'none', title: '支付失敗了', duration: 4000 }); uni.navigateTo({ url: `/pages/payWeixinSuccess/payWeixinSuccess?orderNum=${this.orderNum}&result=no`, }); });
走到這里h5的微信支付也完成了,其實(shí)大部分邏輯在后端,前端只管調(diào)接口就完事了,不明白接口什么意思可以去問問后端就行,是不是非常簡(jiǎn)單,如果看官方文檔那樣詳細(xì)的流程圖其實(shí)很多流程在后端走了,想要更多的學(xué)習(xí)的話那就去掌握后端知識(shí)咯
總結(jié)
到此這篇關(guān)于前端H5微信支付寶支付實(shí)現(xiàn)方法的文章就介紹到這了,更多相關(guān)前端H5微信支付寶支付內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue實(shí)例中el和data的兩種寫法小結(jié)
這篇文章主要介紹了Vue實(shí)例中el和data的兩種寫法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-11-11vue實(shí)現(xiàn)兩列水平時(shí)間軸的示例代碼
本文主要介紹了vue實(shí)現(xiàn)兩列水平時(shí)間軸的示例代碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11vue中for循環(huán)更改數(shù)據(jù)的實(shí)例代碼(數(shù)據(jù)變化但頁面數(shù)據(jù)未變)
這篇文章主要介紹了vue中for循環(huán)更改數(shù)據(jù)的實(shí)例代碼(數(shù)據(jù)變化但頁面數(shù)據(jù)未變)的相關(guān)資料,需要的朋友可以參考下2017-09-09