前端-小程序微信支付接入
1. 调用后端创建支付订单
javascript
// api/pay.js
import request from '@/utils/request.js'
export function pay(orderId) {
return request({
url: `/api/wx-pay/user/createWxPay/${orderId}`,
method: 'post'
})
}2. 支付流程
用户点击支付 -> 调用后端API -> 获取支付参数 -> 调起微信支付 -> 支付结果回调3. 完整支付实现
javascript
// 支付参数缓存配置
const PAYMENT_CACHE_KEY = 'payment_params'
const PAYMENT_CACHE_EXPIRY = 14 * 60 * 1000 // 14分钟
// 缓存支付参数
const cachePaymentParams = (payData) => {
try {
const cacheData = {
data: payData,
expiry: Date.now() + PAYMENT_CACHE_EXPIRY
}
uni.setStorageSync(PAYMENT_CACHE_KEY, JSON.stringify(cacheData))
} catch (e) {
console.error('缓存支付参数失败:', e)
}
}
// 获取缓存的支付参数
const getCachedPaymentParams = () => {
try {
const jsonStr = uni.getStorageSync(PAYMENT_CACHE_KEY)
if (!jsonStr) return null
const cacheData = JSON.parse(jsonStr)
if (Date.now() > cacheData.expiry) {
uni.removeStorageSync(PAYMENT_CACHE_KEY)
return null
}
return cacheData.data
} catch (e) {
return null
}
}
// 清除支付参数缓存
const clearPaymentCache = () => {
uni.removeStorageSync(PAYMENT_CACHE_KEY)
}
// 调用后端创建支付订单
const createPayment = async (orderId) => {
try {
const res = await pay(orderId)
if (res.code === 200) {
// 缓存支付参数
cachePaymentParams(res.data)
return res.data
}
throw new Error(res.msg || '创建支付订单失败')
} catch (e) {
throw e
}
}
// 执行微信支付
const executeWechatPayment = (payData) => {
return new Promise((resolve, reject) => {
uni.getProvider({
service: 'payment',
success: (providerRes) => {
if (providerRes.provider && providerRes.provider.includes('wxpay')) {
uni.requestPayment({
provider: 'wxpay',
signType: payData.signType,
package: payData.packageValue,
nonceStr: payData.nonceStr,
timeStamp: payData.timeStamp,
paySign: payData.paySign,
success: (res) => {
clearPaymentCache()
uni.showToast({ title: '支付成功', icon: 'success' })
resolve(res)
},
fail: (err) => {
uni.showToast({ title: '支付失败', icon: 'none' })
reject(err)
}
})
} else {
reject(new Error('不支持微信支付'))
}
},
fail: (err) => {
reject(err)
}
})
})
}
// 完整的支付流程
const handlePayment = async (orderId) => {
try {
// 1. 调用后端创建支付订单
const payData = await createPayment(orderId)
// 2. 调起微信支付
await executeWechatPayment(payData)
// 3. 支付成功后刷新订单状态
await getOrderDetail()
} catch (e) {
console.error('支付失败:', e)
}
}4. 订单页面集成示例
vue
<template>
<view class="order-page">
<view v-if="orderDetail">
<!-- 订单信息 -->
<view class="order-info">
<text>订单金额: ¥{{ orderDetail.deposit }}</text>
</view>
<!-- 立即支付按钮 -->
<up-button
v-if="orderDetail.orderStatus === '0' && orderDetail.depositStatus === '11'"
type="primary"
@click="handlePayment"
:loading="loading"
>
立即支付
</up-button>
</view>
</view>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { pay } from '@/api/pay'
import { getOrderDetail } from '@/api/order'
const orderDetail = ref(null)
const loading = ref(false)
const handlePayment = async () => {
if (loading.value) return
loading.value = true
try {
// 调用后端创建支付订单
const res = await pay(orderDetail.value.id)
const payData = res.data
// 调起微信支付
await new Promise((resolve, reject) => {
uni.getProvider({
service: 'payment',
success: (providerRes) => {
if (providerRes.provider.includes('wxpay')) {
uni.requestPayment({
provider: 'wxpay',
signType: payData.signType,
package: payData.packageValue,
nonceStr: payData.nonceStr,
timeStamp: payData.timeStamp,
paySign: payData.paySign,
success: resolve,
fail: reject
})
} else {
reject(new Error('不支持微信支付'))
}
},
fail: reject
})
})
uni.showToast({ title: '支付成功', icon: 'success' })
// 刷新订单数据
await getOrderDetailData()
} catch (e) {
console.error('支付失败:', e)
} finally {
loading.value = false
}
}
onMounted(() => {
getOrderDetailData()
})
</script>5. 后端返回的支付参数
json
{
"code": 200,
"data": {
"outTradeNo": "654573755628130304",
"timeStamp": "1765521745",
"nonceStr": "2Zf7IcDLIRSRekd1jokTMabUrbkM8U0G",
"packageValue": "prepay_id=wx12144220348995c58017ac64913b050000",
"signType": "RSA",
"paySign": "h2dav6D83onQjQH+JGIjPvzB0fUXQTIzbgSfxUxOpFL..."
}
}6. 支付结果回调
| 结果 | 说明 |
|---|---|
| success | 支付成功,刷新订单状态 |
| fail | 支付失败,提示用户重试 |
7. 注意事项
| 场景 | 解决方案 |
|---|---|
| 用户取消支付 | 保留缓存,允许重试 |
| 支付参数过期 | 提示用户返回重新操作 |
| 非微信环境 | 提示不支持微信支付 |
| 网络异常 | 缓存支付参数,支持重试 |
8. 缓存策略
- 支付参数缓存 14 分钟
- 支付成功后立即清除缓存
- 支付失败时保留缓存供重试