fix: 支持关闭App后续付抖音原订单
This commit is contained in:
+56
-15
@@ -52,7 +52,57 @@ function showState(state, key, orderNum) {
|
||||
? '支付未成功,请查看订单' : '支付结果待确认,请稍后查看订单', icon: 'none', duration: 2500 });
|
||||
}
|
||||
|
||||
// Runs BEFORE creating an order. Never start another payment while an earlier result is unknown.
|
||||
// Called only by a user payment action, never by onShow. Renew the SAME transaction on the server.
|
||||
async function continuePendingPayment(key, orderNum) {
|
||||
const response = await request({ url: '/payment/douyin/resume', method: 'POST',
|
||||
data: { orderNum }, isShowLoading: false });
|
||||
if (key !== accountKey()) return { state: 'pending' };
|
||||
if (response?.bizcode !== 100) throw new Error('暂时无法续付,请查看订单后重试');
|
||||
const result = response.data;
|
||||
if (!result || result.orderNum !== orderNum) throw new Error('续付订单不匹配,请查看订单');
|
||||
if (result.state === 'paid' || result.state === 'closed') {
|
||||
// The existing query endpoint also reconciles business orders when a webhook was missed.
|
||||
const state = result.state === 'paid' ? await query(orderNum) : { state: 'failed' };
|
||||
showState(state, key, orderNum);
|
||||
return state;
|
||||
}
|
||||
if (result.state !== 'unpaid') {
|
||||
const state = { state: 'pending' };
|
||||
showState(state, key, orderNum);
|
||||
return state;
|
||||
}
|
||||
if (result.payment?.orderNum !== orderNum) throw new Error('续付订单不匹配,请查看订单');
|
||||
// Validate before the confirmation dialog. Never store the SDK signature locally.
|
||||
toSdkPayInfo(result.payment);
|
||||
const confirmed = await new Promise(resolve => uni.showModal({
|
||||
title: '继续上一笔支付',
|
||||
content: `上一笔抖音支付尚未完成,是否继续支付原订单?${result.payment.amount != null
|
||||
? `金额:¥${result.payment.amount}。` : ''}不会创建新订单。`,
|
||||
confirmText: '继续支付', cancelText: '暂不支付',
|
||||
success: res => resolve(res.confirm === true), fail: () => resolve(false)
|
||||
}));
|
||||
if (!confirmed || key !== accountKey()) return { state: 'pending' };
|
||||
return executePayment(result.payment, key);
|
||||
}
|
||||
|
||||
async function executePayment(payment, key) {
|
||||
// #ifdef APP-PLUS
|
||||
if (key !== accountKey()) return { state: 'pending' };
|
||||
const payInfo = toSdkPayInfo(payment);
|
||||
if (!canOpenDypay()) throw new Error('请先安装或升级抖音客户端');
|
||||
if (!initDypay({ appId: payInfo.appid, callbackScheme: payment.douyin.callbackScheme || 'trustbridgeapp' })) {
|
||||
throw new Error('支付初始化失败,请稍后重试');
|
||||
}
|
||||
// Persist before entering native code so a killed process remains recoverable.
|
||||
uni.setStorageSync(key, payment.orderNum);
|
||||
await new Promise(resolve => openDypay({ payInfo, showLoading: true }, resolve));
|
||||
const state = await query(payment.orderNum);
|
||||
showState(state, key, payment.orderNum);
|
||||
return state;
|
||||
// #endif
|
||||
}
|
||||
|
||||
// Runs BEFORE creating an order. A pending record offers explicit continuation, not a new order.
|
||||
export async function prepareDouyinPay(payway) {
|
||||
if (payway !== 'douyin') return true;
|
||||
try {
|
||||
@@ -66,7 +116,7 @@ export async function prepareDouyinPay(payway) {
|
||||
const previous = uni.getStorageSync(key);
|
||||
if (previous) {
|
||||
resuming = true;
|
||||
try { showState(await query(previous), key, previous); }
|
||||
try { await continuePendingPayment(key, previous); }
|
||||
finally { resuming = false; }
|
||||
return false;
|
||||
}
|
||||
@@ -86,26 +136,17 @@ export async function appDypayFun(payment) {
|
||||
return;
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
if (active) return;
|
||||
if (active || resuming) return;
|
||||
active = true;
|
||||
const key = accountKey();
|
||||
try {
|
||||
if (!key || !payment.orderNum) throw new Error('登录身份或支付订单编号缺失');
|
||||
const payInfo = toSdkPayInfo(payment);
|
||||
const previous = uni.getStorageSync(key);
|
||||
if (previous) {
|
||||
const state = await query(previous);
|
||||
showState(state, key, previous);
|
||||
if (state.state === 'pending' || previous === payment.orderNum) return state;
|
||||
// Even legacy callers must not open a different payment while the saved one is unresolved.
|
||||
return await continuePendingPayment(key, previous);
|
||||
}
|
||||
uni.setStorageSync(key, payment.orderNum);
|
||||
if (!initDypay({ appId: payInfo.appid, callbackScheme: payment.douyin.callbackScheme || 'trustbridgeapp' })) {
|
||||
throw new Error('支付初始化失败,请先查询订单');
|
||||
}
|
||||
await new Promise(resolve => openDypay({ payInfo, showLoading: true }, resolve));
|
||||
const state = await query(payment.orderNum);
|
||||
showState(state, key, payment.orderNum);
|
||||
return state;
|
||||
return await executePayment(payment, key);
|
||||
} catch (error) {
|
||||
if (key === accountKey()) uni.showToast({ title: error.message || '支付结果待确认,请查看订单', icon: 'none' });
|
||||
return { state: 'error', message: error.message || '支付结果待确认,请查看订单' };
|
||||
|
||||
Reference in New Issue
Block a user