feat(subscription): 对齐续费接口为一步生成支付码
- 修正续费请求路径为后端实际的 /renew-pay/{id},避免 404 错误
- 续费接口新增 method 和 envVersion 参数支持余额与微信支付
- 续费请求返回支付结果,微信支付返回小程序码,余额支付直接成功
- 续费不再分步调起支付,前端确认续费逻辑简化为一步调用后端接口
- 后端 renewPay 优化,避免放弃支付导致服务中断及时长丢失
- 后端续费激活逻辑调整,续费保留原订阅有效期累计时长
- 排查并解决微信小程序支付配置缺失导致续费失败的问题
- 代码及注释同步更新,完善续费流程整体一致性与稳定性
This commit is contained in:
@@ -221,19 +221,25 @@ export async function mpConfirm(
|
||||
}
|
||||
|
||||
/**
|
||||
* 续费:基于已有订阅创建续费订单(pending),返回新 subscriptionId
|
||||
* POST /app/subscription/renew/{id}?period=month|year
|
||||
* 返回结构与 subscribe 一致(含 subscriptionId),前端再调 pay 生成支付码
|
||||
* 续费:基于已有订阅创建续费订单并生成支付码(一步完成,对齐后端 /renew-pay)
|
||||
* POST /app/subscription/renew-pay/{id}?period=month&method=wechat&envVersion=trial
|
||||
* - method=balance:余额支付,返回 PayResult(paid/balance)
|
||||
* - method=wechat:微信支付,返回小程序码 WechatNativePayResult(miniappQrcode)
|
||||
* 后端会基于原 expireTime 或 now(取较大者)延长到期时间
|
||||
*/
|
||||
export async function renewSubscription(
|
||||
id: number,
|
||||
period: 'month' | 'year' = 'month'
|
||||
): Promise<SubscribeResult> {
|
||||
const res = await request.post<ApiResult<SubscribeResult>>(`${BASE}/renew/${id}`, undefined, {
|
||||
params: { period }
|
||||
});
|
||||
period: 'month' | 'year' = 'month',
|
||||
method: 'balance' | 'wechat' = 'wechat',
|
||||
envVersion?: string
|
||||
): Promise<PayResult | WechatNativePayResult> {
|
||||
const res = await request.post<ApiResult<PayResult | WechatNativePayResult>>(
|
||||
`${BASE}/renew-pay/${id}`,
|
||||
undefined,
|
||||
{ params: { period, method, envVersion } }
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data as SubscribeResult;
|
||||
return res.data.data as PayResult | WechatNativePayResult;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
@@ -286,13 +286,20 @@ export const useAppSubscriptionStore = defineStore('appSubscription', {
|
||||
// ============================================================
|
||||
|
||||
/**
|
||||
* 续费:基于已有订阅创建续费订单,返回新 subscriptionId(再调 pay 发起支付)
|
||||
* 续费:基于已有订阅创建续费订单并生成支付码(一步完成,对齐后端 /renew-pay)
|
||||
* @param id 订阅ID
|
||||
* @param period 周期:month/year
|
||||
* @param method 支付方式:balance/wechat
|
||||
* @param envVersion 小程序版本(微信支付时使用)
|
||||
*/
|
||||
async renew(id: number, period: 'month' | 'year' = 'month'): Promise<SubscribeResult> {
|
||||
async renew(
|
||||
id: number,
|
||||
period: 'month' | 'year' = 'month',
|
||||
method: 'balance' | 'wechat' = 'wechat',
|
||||
envVersion?: string
|
||||
): Promise<PayResult | WechatNativePayResult> {
|
||||
try {
|
||||
const result = await renewSubscription(id, period);
|
||||
const result = await renewSubscription(id, period, method, envVersion);
|
||||
this.invalidateCache();
|
||||
return result;
|
||||
} catch (error) {
|
||||
|
||||
@@ -544,32 +544,31 @@ const onRenew = () => {
|
||||
subscribeModalVisible.value = true;
|
||||
};
|
||||
|
||||
// 确认续费(方案1:renew 创建续费订单 → pay 生成小程序码 → 扫码,与 confirmSubscribe 对称)
|
||||
// 确认续费(后端 renew-pay 一步完成:创建续费订单 + 生成支付码,无需再调 pay)
|
||||
const confirmRenew = async () => {
|
||||
const sub = currentSubscription.value;
|
||||
if (!sub?.id) return;
|
||||
renewing.value = true;
|
||||
try {
|
||||
// 1. 续费:基于原订阅创建续费订单,返回新 subscriptionId
|
||||
const renewResult = await subscriptionStore.renew(sub.id, selectedPeriod.value);
|
||||
// 免费应用:renew 直接激活,status=active
|
||||
if (renewResult.status === 'active') {
|
||||
// renew-pay 直接返回支付结果(微信支付返回小程序码,余额支付返回 paid)
|
||||
const result = await subscriptionStore.renew(
|
||||
sub.id,
|
||||
selectedPeriod.value,
|
||||
'wechat',
|
||||
envVersion
|
||||
);
|
||||
// 余额支付:直接成功
|
||||
if ('paid' in result && result.paid) {
|
||||
message.success('续费成功');
|
||||
subscribeModalVisible.value = false;
|
||||
refreshSubscription();
|
||||
return;
|
||||
}
|
||||
// 2. 付费应用:用 pay 生成支付小程序码
|
||||
const payResult = await subscriptionStore.pay(
|
||||
renewResult.subscriptionId,
|
||||
'wechat',
|
||||
envVersion
|
||||
);
|
||||
if ('miniappQrcode' in payResult) {
|
||||
paySubscriptionNo.value =
|
||||
payResult.subscriptionNo || renewResult.subscriptionNo;
|
||||
payQrcode.value = payResult.miniappQrcode;
|
||||
payPrice.value = Number(payResult.payPrice) || 0;
|
||||
// 微信支付:弹小程序码扫码
|
||||
if ('miniappQrcode' in result) {
|
||||
paySubscriptionNo.value = result.subscriptionNo;
|
||||
payQrcode.value = result.miniappQrcode;
|
||||
payPrice.value = Number(result.payPrice) || 0;
|
||||
payProductName.value = currentProduct.value?.productName || '应用续费';
|
||||
subscribeModalVisible.value = false;
|
||||
payModalVisible.value = true;
|
||||
|
||||
Reference in New Issue
Block a user