支付协议
This commit is contained in:
@@ -5,16 +5,16 @@
|
||||
import { EventTarget, game, Game } from "cc";
|
||||
import { PaymentApi } from "./PaymentApi";
|
||||
import { PaymentOpenerFactory, type OpenStrategy } from "./PaymentOpener";
|
||||
import { PendingOrderRepo } from "./PendingOrderRepo";
|
||||
import PaymentPoller from "./PaymentPoller";
|
||||
import type { PaymentResult, PendingOrder, OrderStatus } from "./types";
|
||||
import proto from 'db://assets/Scripts/proto/proto.pb.js';
|
||||
import { DataManager, DataId } from "db://assets/Scripts/chat18x/data/DataManager";
|
||||
import { OrderData } from "db://assets/Scripts/chat18x/data/OrderData";
|
||||
|
||||
export const PaymentEvents = {
|
||||
Started: "pay-started", // { orderId }
|
||||
UrlOpened: "pay-url-opened",
|
||||
PollTick: "pay-poll-tick", // { orderId, status }
|
||||
Finished: "pay-finished", // PaymentResult
|
||||
Finished: "pay-finished",
|
||||
};
|
||||
|
||||
export class PaymentService {
|
||||
@@ -41,8 +41,9 @@ export class PaymentService {
|
||||
const { orderId, payUrl } = create.data;
|
||||
this.bus.emit(PaymentEvents.Started, { orderId });
|
||||
|
||||
// 存为未决订单(用于异常恢复)
|
||||
PendingOrderRepo.instance.add({ orderId, channel: req.channel, createdAt: Date.now(), expireAt, productId: req.productId });
|
||||
// 保存订单数据
|
||||
const orderData = DataManager.I.getDataById<OrderData>(DataId.Order);
|
||||
orderData.saveOrderData(create.data);
|
||||
|
||||
// 打开支付页
|
||||
await PaymentOpenerFactory.create(open).open(payUrl);
|
||||
@@ -62,7 +63,8 @@ export class PaymentService {
|
||||
jitter: true,
|
||||
}, (d) => this.bus.emit(PaymentEvents.PollTick, { orderId, status: d.status }));
|
||||
|
||||
PendingOrderRepo.instance.remove(orderId);
|
||||
// 刷新订单数据
|
||||
orderData.applyQueryOrder(orderId, data);
|
||||
// 返回结果
|
||||
this.bus.emit(PaymentEvents.Finished, data);
|
||||
return data;
|
||||
@@ -70,45 +72,20 @@ export class PaymentService {
|
||||
|
||||
/** App 回到前台后恢复未完成订单的轮询(在 onShow 时调用) */
|
||||
async resumePending(): Promise<void> {
|
||||
const now = Date.now();
|
||||
const list = PendingOrderRepo.instance.all();
|
||||
|
||||
// 去重:同 orderId 只保留 createdAt 最新的一条
|
||||
const uniq = new Map<string, PendingOrder>();
|
||||
for (const o of list) {
|
||||
const ex = uniq.get(o.orderId);
|
||||
if (!ex || (o.createdAt ?? 0) > (ex.createdAt ?? 0)) {
|
||||
uniq.set(o.orderId, o);
|
||||
}
|
||||
}
|
||||
|
||||
for (const o of uniq.values()) {
|
||||
// 只处理未过期
|
||||
if (this.isOrderExpired(o, now)) {
|
||||
PendingOrderRepo.instance.remove(o.orderId);
|
||||
this.bus.emit(PaymentEvents.Finished, {
|
||||
orderId: o.orderId,
|
||||
status: "EXPIRED" as OrderStatus,
|
||||
message: "order expired",
|
||||
} as PaymentResult);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 所有需要继续轮询查询的订单 id
|
||||
const orderData = DataManager.I.getDataById<OrderData>(DataId.Order);
|
||||
const idList = orderData.getAllShouldPollId();
|
||||
for (const o of idList) {
|
||||
// 轮询最新且未过期的订单
|
||||
const r = await this.startPollingOnly(o.orderId);
|
||||
const r = await this.startPollingOnly(o);
|
||||
if (r && r.status !== 1) {
|
||||
PendingOrderRepo.instance.remove(o.orderId);
|
||||
orderData.applyQueryOrder(o, r);
|
||||
this.bus.emit(PaymentEvents.Finished, r);
|
||||
}
|
||||
// r === null(轮询超时)时保留在仓库,等待下一次 resume 再查
|
||||
}
|
||||
}
|
||||
|
||||
/** 判断订单是否过期:有 expireAt 且 now >= expireAt 才认为过期 */
|
||||
private isOrderExpired(o: PendingOrder, now = Date.now()): boolean {
|
||||
return typeof o.expireAt === "number" && now >= o.expireAt;
|
||||
}
|
||||
|
||||
/** 仅轮询(用于 resumePending 或手动刷新) */
|
||||
private async startPollingOnly(orderId: string) {
|
||||
const poller = new PaymentPoller();
|
||||
|
||||
Reference in New Issue
Block a user