## 微信支付
框架集成了微信支付的業務邏輯,只需要按照我案例演示的流程執行,就可輕松實現。免去了閱讀大篇幅的原文檔,而且還會遇坑的風險。
<br>
### 微信內調起支付
```
// 1. 前端通過 pnpm 安裝 weixin-jsapi
pnpm install weixin-jsapi
import wx from 'weixin-jsapi'
```
```
// 2. 通過靜默授權回調的方式拿到code
// 重定向
goRedirect(isForce = false){
let code = this.getQueryString('code')
if(!code || isForce){
const appid = 'wx520c63a7a02b8859'
const redirect_uri = encodeURIComponent('http://h5pay.zhangyubk.com')
window.location.replace(`https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${redirect_uri}&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect`)
}
}
```
```
// 3. 動態獲取當前網址并去后端換取載入jssdk的配置參數
// 載入jssdk
// jssdk不只可以用來做支付,微信公眾號網頁開發內的所有功能都可使用
initJsSdk(){
let url = window.location.href
this.$api.jssdk({url: url.split("#")[0]}).then(result => {
wx.config(result.data)
})
}
```
```
// 4. 后端獲取 ACCESS_TOKEN 換取 TICKET 然后組裝成配置參數
// 獲取ACCESS_TOKEN
async getAccessToken() {
// 判斷緩存里是否有ACCESS_TOKEN
const ACCESS_TOKEN = await this.RDb().get('THINKJS_ACCESS_TOKEN')
if (ACCESS_TOKEN) {
return ACCESS_TOKEN
} else {
const url = `https: //api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${wxConfig.wechat.appid}&secret=${wxConfig.wechat.secret}`
const result = await this.Fetch({
url
})
this.RDb().set('THINKJS_ACCESS_TOKEN', result.access_token, 7200)
return result.access_token
}
}
// 獲取JSAPI_TICKET
async getJsapiTicket() {
// 判斷緩存里是否有JSAPI_TICKET
const JSAPI_TICKET = await this.RDb().get('THINKJS_JSAPI_TICKET')
const ACCESS_TOKEN = await this.getAccessToken() if (JSAPI_TICKET) {
return JSAPI_TICKET
} else {
const url = `https: //api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${ACCESS_TOKEN}&type=jsapi`
const result = await this.Fetch({
url
})
this.RDb().set('THINKJS_JSAPI_TICKET', result.ticket, 7200)
return result.ticket
}
}
// 獲取js-sdk注入的配置信息
async getJsSdkConfig(url) {
let obj = {
jsapi_ticket: await this.getJsapiTicket(),
nonceStr: this.Utils.getNonceStr(32),
timestamp: String(Math.floor(Date.now() / 1000)),
url
}
let str = this.Utils.raw(obj) obj.signature = this.Utils.sha1(str) obj.appId = wxConfig.wechat.appid obj.jsApiList = ['chooseWXPay'] obj.debug = false delete obj.url
return obj
}
```
```
// 5. 用CODE換取調取支付臺所需參數
let code = this.getQueryString('code') this.$api.wxpay({
code
}).then(result = >{
wx.ready(() = >{
wx.chooseWXPay({...result.data,
timestamp: result.data.timeStamp,
success: () = >{
// 支付成
},
cancel: () = >{
// 取消支付
},
fail: (e) = >{
// 支付失敗
console.log(e)
}
})
})
})
```
```
// 6. 后臺返回支付臺所需參數
// 獲取支付臺所需參數
async getWxPayConfig(code) {
// 獲取openid
let url = `https: //api.weixin.qq.com/sns/oauth2/access_token?appid=${wxConfig.wechat.appid}&secret=${wxConfig.wechat.secret}&code=${code}&grant_type=authorization_code`
let result = await this.Fetch({
url
}) let prepay_id = await this.getPrepayId(result.openid) let obj = {
appId: wxConfig.wechat.appid,
timeStamp: String(Math.floor(Date.now() / 1000)),
nonceStr: this.Utils.getNonceStr(32),
package: `prepay_id = $ {
prepay_id
}`,
signType: 'RSA'
}
let str = `$ {
obj.appId
}\n$ {
obj.timeStamp
}\n$ {
obj.nonceStr
}\n$ {
obj.package
}\n`obj.paySign = this.Utils.rsaSign(str, wxConfig.wechat.private_key) return obj
}
// 微信內支付獲取prepay_id
async getPrepayId(openid) {
let result = await this.WxPay().jsapi({
description: 'ThinkJS實戰',
// 商品描述
out_trade_no: this.Utils.orderCode(),
// 商戶訂單號
amount: {
total: 100,
// 總金額
currency: 'CNY' // 人民幣
},
payer: {
openid
}
}) if (result.status == 200) {
return JSON.parse(result.data).prepay_id
} else {
return null
}
}
```
### 微信外H5調起支付
```
// 前端部分
this.$api.h5pay().then(result => {
window.location.replace(result.data.h5_url)
})
```
```
// 后端部分
// 微信外支付獲取跳轉鏈接
async getPayUrl(ctx) {
let result = await this.WxPay().h5({
description: 'ThinkJS實戰',
// 商品描述
out_trade_no: this.Utils.orderCode(),
// 商戶訂單號
amount: {
total: 100,
// 總金額
currency: 'CNY' // 人民幣
},
scene_info: {
payer_client_ip: this.Utils.getIP(ctx),
// 用戶終端IP
h5_info: {
type: 'Wap' // 場景類型
}
}
}) if (result.status == 200) {
return JSON.parse(result.data)
} else {
return null
}
}
```
> 微信支付文檔:https://pay.weixin.qq.com/wiki/doc/apiv3/index.shtml
> 公眾號網頁開發:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html
> wxpay-v3文檔:https://www.npmjs.com/package/wxpay-v3
- 序言
- 新手指南
- 安裝
- 開發規范
- 目錄結構
- 配置
- 路由
- 路由定義
- 路由中間件
- 控制器
- 控制器定義
- 內置showSuccess方法
- 內置ApiException方法
- 參數獲取器getParams
- 網絡請求器Fetch
- 內置工具函數
- JWT的使用
- 驗證
- 驗證器
- 驗證規則
- 自定義驗證規則
- 混合驗證規則
- 分場景驗證
- 數據庫
- 連接數據庫
- 查詢數據
- 鏈式操作
- where
- whereOr
- whereBetweenTime
- limit
- page
- count
- order
- field
- alias
- group
- distinct
- 添加數據
- 更新數據
- 刪除數據
- 聯表查詢
- SQL調試
- 模型
- 視圖
- 模板渲染(廢棄)
- 模板變量(廢棄)
- 錯誤和日志
- 異常處理
- 日志處理
- 命令行
- 擴展庫
- 使用Redis
- get
- set
- del
- hget
- hset
- hdel
- decrby
- incrby
- rpush
- rpop
- 使用MongoDB
- 模型
- 新增
- 刪除
- 修改
- 查詢
- 使用ElasticSearch
- 使用阿里云OSS
- 阿里短信服務
- 微信支付
- 支付寶支付
- 部署
- 更新日志