## 微信支付
框架集成了微信支付的业务逻辑,只需要按照我案例演示的流程执行,就可轻松实现。免去了阅读大篇幅的原文档,而且还会遇坑的风险。
<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
- 阿里短信服务
- 微信支付
- 支付宝支付
- 部署
- 更新日志