uni-app 支付集成
核心知识点
1. 支付基础
- 支付概念:在线支付、移动支付、跨境支付等
- 支付流程:下单、支付、回调、查询等
- 支付安全:签名验证、加密传输、防篡改等
- 支付状态:待支付、支付中、支付成功、支付失败等
2. 支付方式
- 微信支付:APP支付、小程序支付、H5支付等
- 支付宝支付:APP支付、小程序支付、H5支付等
- 银联支付:云闪付、银联在线支付等
- 其他支付:百度支付、京东支付、 PayPal 等
- 聚合支付:集成多种支付方式
3. 支付API
- **uni.requestPayment()**:uni-app 统一支付接口
- 支付参数:不同支付方式的参数配置
- 支付回调:处理支付结果
- 支付查询:查询支付状态
- 退款接口:处理退款请求
4. 支付配置
- 商户资质:申请支付商户号
- APPID配置:绑定应用
- 密钥管理:API密钥、证书等
- 支付授权:获取支付权限
- 平台配置:不同平台的支付配置
5. 支付流程
- 前端流程:发起支付请求、调用支付API、处理支付结果
- 后端流程:生成订单、签名验证、调用支付接口、处理回调
- 异常处理:支付超时、支付失败、重复支付等
- 订单管理:订单状态更新、对账等
6. 支付安全
- 签名验证:防止请求被篡改
- 加密传输:保护敏感信息
- 防重放攻击:防止重复支付
- 数据校验:验证支付结果的真实性
- 安全存储:保护商户密钥和证书
7. 跨平台支付处理
- 平台差异:不同平台的支付方式支持
- 条件编译:为不同平台提供不同的支付方案
- 原生能力:使用平台原生的支付能力
- 第三方服务:使用第三方支付服务
8. 支付优化
- 支付体验:简化支付流程,减少支付步骤
- 支付成功率:优化支付参数,减少支付失败
- 支付速度:提高支付响应速度
- 错误处理:友好的错误提示和处理
实用案例
案例 1:电商应用支付功能
需求分析
- 支持微信支付和支付宝支付
- 实现商品购买支付流程
- 处理支付结果和订单状态
- 支持支付记录查询
实现方案
- 支付集成
<template> <view class="payment-app"> <view class="order-info"> <text class="order-title">订单信息</text> <text class="order-price">总价:¥{{ orderPrice }}</text> <text class="order-id">订单号:{{ orderId }}</text> </view> <view class="payment-methods"> <text class="method-title">选择支付方式</text> <view v-for="(method, index) in paymentMethods" :key="index" @click="selectPaymentMethod(method)" :class="{ active: selectedMethod === method.id }" class="payment-method" > <view class="method-icon">{{ method.icon }}</view> <view class="method-info"> <text class="method-name">{{ method.name }}</text> <text class="method-desc">{{ method.description }}</text> </view> <view class="method-check" v-if="selectedMethod === method.id">✓</view> </view> </view> <button @click="submitPayment" type="primary" class="pay-btn"> 确认支付 ¥{{ orderPrice }} </button> </view> </template> <script> export default { data() { return { orderId: 'ORD' + Date.now(), orderPrice: 99.99, selectedMethod: 'wechat', paymentMethods: [ { id: 'wechat', name: '微信支付',
description: '推荐使用微信支付',
icon: '💳'
},
{
id: 'alipay',
name: '支付宝',
description: '支付宝快捷支付',
icon: '💰'
}
]
}
},
methods: {
selectPaymentMethod(method) {
this.selectedMethod = method.id
},
submitPayment() {
// 1. 后端生成订单
this.createOrder()
},
createOrder() {
// 调用后端API生成订单
uni.request({
url: 'https://example.com/api/order/create',
method: 'POST',
data: {
orderId: this.orderId,
price: this.orderPrice,
paymentMethod: this.selectedMethod
},
success: (res) => {
if (res.data.code === 0) {
// 2. 发起支付
this.requestPayment(res.data.paymentParams)
} else {
uni.showToast({
title: '订单创建失败',
icon: 'none'
})
}
},
fail: (err) => {
console.error('创建订单失败', err)
uni.showToast({
title: '网络错误,请重试',
icon: 'none'
})
}
})
},
requestPayment(paymentParams) {
uni.requestPayment({
provider: this.selectedMethod === 'wechat' ? 'wxpay' : 'alipay',
timeStamp: paymentParams.timeStamp,
nonceStr: paymentParams.nonceStr,
package: paymentParams.package,
signType: paymentParams.signType,
paySign: paymentParams.paySign,
success: (res) => {
console.log('支付成功', res)
this.handlePaymentSuccess()
},
fail: (err) => {
console.error('支付失败', err)
this.handlePaymentFail(err)
},
complete: (res) => {
console.log('支付完成', res)
}
})
},
handlePaymentSuccess() {
uni.showToast({
title: '支付成功',
icon: 'success'
})
// 更新订单状态
this.updateOrderStatus('success')
// 跳转到支付成功页面
setTimeout(() => {
uni.navigateTo({
url: `/pages/payment/success?orderId=${this.orderId}&price=${this.orderPrice}`
})
}, 1500)
},
handlePaymentFail(err) {
uni.showToast({
title: '支付失败,请重试',
icon: 'none'
})
// 更新订单状态
this.updateOrderStatus('fail')
},
updateOrderStatus(status) {
// 调用后端API更新订单状态
uni.request({
url: 'https://example.com/api/order/updateStatus',
method: 'POST',
data: {
orderId: this.orderId,
status: status
},
success: (res) => {
console.log('订单状态更新成功', res)
},
fail: (err) => {
console.error('订单状态更新失败', err)
}
})
}
} }
2. **支付回调处理**
- 处理支付结果通知
- 验证支付结果的真实性
- 更新订单状态
- 发送支付成功通知
### 案例 2:会员订阅支付功能
#### 需求分析
- 支持多种订阅套餐
- 实现周期性支付(月付、年付等)
- 处理订阅状态和续费
- 支持订阅管理(暂停、取消等)
#### 实现方案
1. **订阅支付**
```vue
<template>
<view class="subscription-app">
<view class="subscription-plans">
<text class="plans-title">选择订阅套餐</text>
<view
v-for="(plan, index) in subscriptionPlans"
:key="index"
@click="selectPlan(plan)"
:class="{ active: selectedPlan.id === plan.id }"
class="plan-item"
>
<text class="plan-name">{{ plan.name }}</text>
<text class="plan-price">{{ plan.price }}</text>
<text class="plan-period">{{ plan.period }}</text>
<text class="plan-features" v-for="(feature, idx) in plan.features" :key="idx">
• {{ feature }}
</text>
</view>
</view>
<button @click="submitSubscription" type="primary" class="subscribe-btn">
立即订阅
</button>
</view>
</template>
<script>
export default {
data() {
return {
selectedPlan: null,
subscriptionPlans: [
{
id: 'monthly',
name: '月度会员',
price: '¥19.99/月',
period: '30天',
features: [
'无限访问所有内容',
'高清视频观看',
'无广告体验',
'基础客服支持'
]
},
{
id: 'yearly',
name: '年度会员',
price: '¥199.99/年',
period: '365天',
features: [
'无限访问所有内容',
'4K视频观看',
'无广告体验',
'优先客服支持',
'专属内容' ]
},
{
id: 'lifetime',
name: '终身会员',
price: '¥999.99',
period: '永久',
features: [
'无限访问所有内容',
'8K视频观看',
'无广告体验',
'24小时客服支持',
'专属内容',
'终身免费升级'
]
}
]
}
},
onLoad() {
// 默认选择月度会员
this.selectedPlan = this.subscriptionPlans[0]
},
methods: {
selectPlan(plan) {
this.selectedPlan = plan
},
submitSubscription() {
if (!this.selectedPlan) {
uni.showToast({
title: '请选择订阅套餐',
icon: 'none'
})
return
}
// 生成订阅订单
this.createSubscriptionOrder()
},
createSubscriptionOrder() {
uni.request({
url: 'https://example.com/api/subscription/create',
method: 'POST',
data: {
planId: this.selectedPlan.id,
planName: this.selectedPlan.name,
price: this.selectedPlan.price,
period: this.selectedPlan.period
},
success: (res) => {
if (res.data.code === 0) {
// 发起支付
this.requestPayment(res.data.paymentParams)
} else {
uni.showToast({
title: '订单创建失败',
icon: 'none'
})
}
},
fail: (err) => {
console.error('创建订单失败', err)
uni.showToast({
title: '网络错误,请重试',
icon: 'none'
})
}
})
},
requestPayment(paymentParams) {
uni.requestPayment({
provider: 'wxpay', // 或 'alipay'
timeStamp: paymentParams.timeStamp,
nonceStr: paymentParams.nonceStr,
package: paymentParams.package,
signType: paymentParams.signType,
paySign: paymentParams.paySign,
success: (res) => {
console.log('支付成功', res)
this.handleSubscriptionSuccess()
},
fail: (err) => {
console.error('支付失败', err)
this.handleSubscriptionFail(err)
}
})
},
handleSubscriptionSuccess() {
uni.showToast({
title: '订阅成功',
icon: 'success'
})
// 更新用户订阅状态
this.updateSubscriptionStatus('active')
// 跳转到会员中心
setTimeout(() => {
uni.navigateTo({
url: '/pages/member/center'
})
}, 1500)
},
handleSubscriptionFail(err) {
uni.showToast({
title: '订阅失败,请重试',
icon: 'none'
})
},
updateSubscriptionStatus(status) {
uni.request({
url: 'https://example.com/api/subscription/updateStatus',
method: 'POST',
data: {
status: status,
planId: this.selectedPlan.id
},
success: (res) => {
console.log('订阅状态更新成功', res)
},
fail: (err) => {
console.error('订阅状态更新失败', err)
}
})
}
}
}
</script>- 订阅管理
- 处理订阅续费
- 管理订阅状态
- 处理订阅取消和退款
- 提供订阅历史记录
案例 3:虚拟商品支付功能
需求分析
- 支持虚拟商品购买(如游戏币、会员点数等)
- 实现快速支付流程
- 处理商品发放和库存管理
- 支持购买历史查询
实现方案
- 虚拟商品支付
<template> <view class="virtual-goods-app"> <view class="goods-list"> <text class="list-title">虚拟商品</text> <view v-for="(goods, index) in virtualGoods" :key="index" @click="selectGoods(goods)" :class="{ active: selectedGoods.id === goods.id }" class="goods-item" > <text class="goods-name">{{ goods.name }}</text> <text class="goods-price">{{ goods.price }}</text> <text class="goods-desc">{{ goods.description }}</text> </view> </view> <button @click="purchaseGoods" type="primary" class="purchase-btn"> 立即购买 </button> </view> </template> <script> export default { data() { return { selectedGoods: null, virtualGoods: [ { id: 'coin_100', name: '100游戏币', price: '¥10.00',
description: '可用于游戏内购买道具'
},
{
id: 'coin_500',
name: '500游戏币',
price: '¥45.00',
description: '可用于游戏内购买道具'
},
{
id: 'coin_1000',
name: '1000游戏币',
price: '¥80.00',
description: '可用于游戏内购买道具'
},
{
id: 'vip_30',
name: '30天VIP',
price: '¥29.99',
description: '享受VIP特权'
}
]
}
},
onLoad() {
// 默认选择第一个商品
this.selectedGoods = this.virtualGoods[0]
},
methods: {
selectGoods(goods) {
this.selectedGoods = goods
},
purchaseGoods() {
if (!this.selectedGoods) {
uni.showToast({
title: '请选择商品',
icon: 'none'
})
return
}
// 生成购买订单
this.createOrder()
},
createOrder() {
uni.request({
url: 'https://example.com/api/goods/createOrder',
method: 'POST',
data: {
goodsId: this.selectedGoods.id,
goodsName: this.selectedGoods.name,
price: this.selectedGoods.price
},
success: (res) => {
if (res.data.code === 0) {
// 发起支付
this.requestPayment(res.data.paymentParams)
} else {
uni.showToast({
title: '订单创建失败',
icon: 'none'
})
}
},
fail: (err) => {
console.error('创建订单失败', err)
uni.showToast({
title: '网络错误,请重试',
icon: 'none'
})
}
})
},
requestPayment(paymentParams) {
uni.requestPayment({
provider: 'wxpay', // 或 'alipay'
timeStamp: paymentParams.timeStamp,
nonceStr: paymentParams.nonceStr,
package: paymentParams.package,
signType: paymentParams.signType,
paySign: paymentParams.paySign,
success: (res) => {
console.log('支付成功', res)
this.handlePurchaseSuccess()
},
fail: (err) => {
console.error('支付失败', err)
this.handlePurchaseFail(err)
}
})
},
handlePurchaseSuccess() {
uni.showToast({
title: '购买成功',
icon: 'success'
})
// 发放虚拟商品
this.deliverGoods()
// 跳转到购买成功页面
setTimeout(() => {
uni.navigateTo({
url: '/pages/purchase/success?goodsId=' + this.selectedGoods.id
})
}, 1500)
},
handlePurchaseFail(err) {
uni.showToast({
title: '购买失败,请重试',
icon: 'none'
})
},
deliverGoods() {
uni.request({
url: 'https://example.com/api/goods/deliver',
method: 'POST',
data: {
goodsId: this.selectedGoods.id,
userId: 'current_user_id' // 实际项目中使用真实用户ID
},
success: (res) => {
console.log('商品发放成功', res)
},
fail: (err) => {
console.error('商品发放失败', err)
// 记录发放失败,后续处理
}
})
}
} }
2. **商品管理**
- 处理虚拟商品库存
- 管理商品发放记录
- 提供商品购买历史
- 处理商品退换货
## 学习目标
1. 掌握 uni-app 中支付功能的集成方法
2. 学会实现微信支付、支付宝支付等多种支付方式
3. 了解支付流程和安全处理
4. 能够开发电商、订阅、虚拟商品等不同场景的支付功能
5. 掌握支付异常处理和订单管理
6. 提升支付体验和成功率
## 总结
支付集成是 uni-app 应用开发中的重要组成部分,通过合理使用 uni.requestPayment() API、配置不同支付方式的参数、处理支付结果和订单状态,可以实现安全、可靠的支付功能。在实际开发中,开发者应该根据具体场景选择合适的支付方式,优化支付流程,提升支付体验和成功率。
同时,开发者还需要注意支付安全,保护商户密钥和用户信息,防止支付欺诈和安全漏洞。对于不同平台的支付差异,需要使用条件编译或平台特定的配置来处理,确保应用在所有平台上都能正常运行支付功能。
通过本教程的学习,开发者将能够掌握 uni-app 中支付功能的集成方法,为应用添加安全、便捷的支付能力,提升用户体验和商业价值。