bindbox-mini/utils/payment.js

135 lines
3.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 通用支付流程工具函数
*
* 用于统一 一番赏、无限赏、对对碰 三种玩法的支付流程
*/
import { createWechatOrder } from '../api/appUser'
import { hasPhoneBound } from './checkPhone'
/**
* 从API响应中提取订单号
* @param {Object} res - API 响应
* @returns {string|null}
*/
export function extractOrderNo(res) {
if (!res) return null
return res.order_no || res.orderNo || res.data?.order_no || res.data?.orderNo || res.result?.order_no || res.result?.orderNo || null
}
/**
* 执行微信支付流程
*
* @param {Object} options
* @param {string} options.orderNo - 订单号(必须)
* @param {string} [options.openid] - 用户 openid可选默认从 storage 读取)
* @returns {Promise<void>} - 支付完成(成功)时 resolve取消或失败时 reject
*/
export async function doWechatPayment({ orderNo, openid }) {
if (!orderNo) {
throw new Error('订单号不能为空')
}
const finalOpenid = openid || uni.getStorageSync('openid')
if (!finalOpenid) {
throw new Error('缺少OpenID请重新登录')
}
// 1. 获取微信支付参数
const payRes = await createWechatOrder({ openid: finalOpenid, order_no: orderNo })
if (!payRes || !payRes.package) {
throw new Error('获取支付参数失败')
}
// 2. 调起微信支付
return new Promise((resolve, reject) => {
uni.requestPayment({
provider: 'wxpay',
timeStamp: payRes.timeStamp || payRes.timestamp,
nonceStr: payRes.nonceStr || payRes.noncestr,
package: payRes.package,
signType: payRes.signType || 'RSA',
paySign: payRes.paySign,
success: resolve,
fail: (err) => {
if (err?.errMsg && String(err.errMsg).includes('cancel')) {
const cancelErr = new Error('支付已取消')
cancelErr.cancelled = true
reject(cancelErr)
} else {
reject(err)
}
}
})
})
}
/**
* 完整支付流程(创建订单 + 支付)
*
* @param {Object} options
* @param {Function} options.createOrder - 创建订单的函数,返回 Promise结果需包含 order_no
* @param {string} [options.openid] - 用户 openid
* @param {Function} [options.onOrderCreated] - 订单创建后的回调,参数为 (orderNo, response)
* @returns {Promise<{orderNo: string, orderResponse: any}>}
*/
export async function executePaymentFlow({ createOrder, openid, onOrderCreated }) {
// 1. 创建订单
const orderResponse = await createOrder()
const orderNo = extractOrderNo(orderResponse)
if (!orderNo) {
throw new Error('未获取到订单号')
}
// 2. 回调通知(用于保存游戏数据等)
if (typeof onOrderCreated === 'function') {
await onOrderCreated(orderNo, orderResponse)
}
// 3. 执行支付
await doWechatPayment({ orderNo, openid })
return { orderNo, orderResponse }
}
/**
* 检查登录状态
* @returns {{ok: boolean, openid?: string, message?: string}}
*/
export function checkLoginStatus() {
const token = uni.getStorageSync('token')
const openid = uni.getStorageSync('openid')
if (!token) {
return { ok: false, message: '请先登录' }
}
// 使用统一的手机号绑定检查
if (!hasPhoneBound()) {
return { ok: false, message: '请先绑定手机号' }
}
if (!openid) {
return { ok: false, message: '缺少OpenID请重新登录' }
}
return { ok: true, openid }
}
/**
* 显示登录提示弹窗
*/
export function showLoginPrompt() {
uni.showModal({
title: '提示',
content: '请先登录并绑定手机号',
confirmText: '去登录',
success: (res) => {
if (res.confirm) {
uni.navigateTo({ url: '/pages/login/index' })
}
}
})
}