Files
soul-yongping/miniprogram/utils/payment.js

212 lines
4.9 KiB
JavaScript
Raw Normal View History

// miniprogram/utils/payment.js
// 微信支付工具类
const app = getApp()
/**
* 发起微信支付
* @param {Object} options - 支付选项
* @param {String} options.orderId - 订单ID
* @param {Number} options.amount - 支付金额()
* @param {String} options.description - 商品描述
* @param {Function} options.success - 成功回调
* @param {Function} options.fail - 失败回调
*/
function wxPay(options) {
const { orderId, amount, description, success, fail } = options
wx.showLoading({
title: '正在支付...',
mask: true
})
// 1. 调用后端创建支付订单
wx.request({
url: `${app.globalData.apiBase}/payment/create`,
method: 'POST',
header: {
'Authorization': `Bearer ${wx.getStorageSync('token')}`
},
data: {
orderId,
amount,
description,
paymentMethod: 'wechat'
},
success: (res) => {
wx.hideLoading()
if (res.statusCode === 200) {
const paymentData = res.data
// 2. 调起微信支付
wx.requestPayment({
timeStamp: paymentData.timeStamp,
nonceStr: paymentData.nonceStr,
package: paymentData.package,
signType: paymentData.signType || 'RSA',
paySign: paymentData.paySign,
success: (payRes) => {
console.log('支付成功', payRes)
// 3. 通知后端支付成功
notifyPaymentSuccess(orderId, paymentData.prepayId)
wx.showToast({
title: '支付成功',
icon: 'success',
duration: 2000
})
success && success(payRes)
},
fail: (payErr) => {
console.error('支付失败', payErr)
if (payErr.errMsg.indexOf('cancel') !== -1) {
wx.showToast({
title: '支付已取消',
icon: 'none'
})
} else {
wx.showToast({
title: '支付失败',
icon: 'none'
})
}
fail && fail(payErr)
}
})
} else {
wx.showToast({
title: res.data.message || '创建订单失败',
icon: 'none'
})
fail && fail(res)
}
},
fail: (err) => {
wx.hideLoading()
console.error('请求失败', err)
wx.showToast({
title: '网络请求失败',
icon: 'none'
})
fail && fail(err)
}
})
}
/**
* 通知后端支付成功
* @param {String} orderId
* @param {String} prepayId
*/
function notifyPaymentSuccess(orderId, prepayId) {
wx.request({
url: `${app.globalData.apiBase}/payment/notify`,
method: 'POST',
header: {
'Authorization': `Bearer ${wx.getStorageSync('token')}`
},
data: {
orderId,
prepayId,
status: 'success'
},
success: (res) => {
console.log('支付通知成功', res)
},
fail: (err) => {
console.error('支付通知失败', err)
}
})
}
/**
* 查询订单状态
* @param {String} orderId
* @param {Function} callback
*/
function queryOrderStatus(orderId, callback) {
wx.request({
url: `${app.globalData.apiBase}/payment/query`,
method: 'GET',
header: {
'Authorization': `Bearer ${wx.getStorageSync('token')}`
},
data: { orderId },
success: (res) => {
if (res.statusCode === 200) {
callback && callback(true, res.data)
} else {
callback && callback(false, null)
}
},
fail: () => {
callback && callback(false, null)
}
})
}
/**
* 购买完整电子书
* @param {Function} success
* @param {Function} fail
*/
function purchaseFullBook(success, fail) {
// 计算动态价格9.9 + (天数 * 1元)
const basePrice = 9.9
const startDate = new Date('2025-01-01') // 书籍上架日期
const today = new Date()
const daysPassed = Math.floor((today - startDate) / (1000 * 60 * 60 * 24))
const currentPrice = basePrice + daysPassed
const orderId = `ORDER_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
wxPay({
orderId,
amount: currentPrice,
description: 'Soul派对·创业实验 完整版',
success: (res) => {
// 更新本地购买状态
updatePurchaseStatus(true)
success && success(res)
},
fail
})
}
/**
* 更新购买状态
* @param {Boolean} isPurchased
*/
function updatePurchaseStatus(isPurchased) {
const userInfo = app.getUserInfo()
if (userInfo) {
userInfo.isPurchased = isPurchased
wx.setStorageSync('userInfo', userInfo)
app.globalData.userInfo = userInfo
}
}
/**
* 检查是否已购买
* @returns {Boolean}
*/
function checkPurchaseStatus() {
const userInfo = app.getUserInfo()
return userInfo ? userInfo.isPurchased : false
}
module.exports = {
wxPay,
queryOrderStatus,
purchaseFullBook,
checkPurchaseStatus,
updatePurchaseStatus
}