/** * 通用支付流程工具函数 * * 用于统一 一番赏、无限赏、对对碰 三种玩法的支付流程 */ 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} - 支付完成(成功)时 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' }) } } }) }