From b6b702d0dd9e3526c44e0225ce43e775beb4715a Mon Sep 17 00:00:00 2001 From: chen wei bo <1025839511@qq.com> Date: Thu, 18 Sep 2025 18:28:14 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E4=BB=98=E5=8D=8F=E8=AE=AE=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/Scripts/chat18x/data/OrderData.ts | 67 ++++++++++++++++++- assets/Scripts/chat18x/payment/CashInrFlow.ts | 46 +++++++++++++ .../chat18x/payment/CashInrFlow.ts.meta | 9 +++ assets/Scripts/chat18x/payment/PaymentFlow.ts | 14 ++++ .../chat18x/payment/PaymentFlow.ts.meta | 9 +++ .../Scripts/chat18x/payment/PaymentService.ts | 38 +++++------ assets/Scripts/chat18x/payment/WebUsdFlow.ts | 45 +++++++++++++ .../chat18x/payment/WebUsdFlow.ts.meta | 9 +++ 8 files changed, 213 insertions(+), 24 deletions(-) create mode 100644 assets/Scripts/chat18x/payment/CashInrFlow.ts create mode 100644 assets/Scripts/chat18x/payment/CashInrFlow.ts.meta create mode 100644 assets/Scripts/chat18x/payment/PaymentFlow.ts create mode 100644 assets/Scripts/chat18x/payment/PaymentFlow.ts.meta create mode 100644 assets/Scripts/chat18x/payment/WebUsdFlow.ts create mode 100644 assets/Scripts/chat18x/payment/WebUsdFlow.ts.meta diff --git a/assets/Scripts/chat18x/data/OrderData.ts b/assets/Scripts/chat18x/data/OrderData.ts index 2dd6deab..f4f4e052 100644 --- a/assets/Scripts/chat18x/data/OrderData.ts +++ b/assets/Scripts/chat18x/data/OrderData.ts @@ -38,10 +38,10 @@ export class OrderData extends BaseData { wallet: res.wallet || "", // 充值钱包地址 amount: res.amount || "", // 充值金额 expire: res.Expire || 0, // 过期时间,单位: 秒 - expireUnix: res.ExpireUnix || "", // 过期时间戳 + expireUnix: res.ExpireUnix || "", // 过期时间戳,秒 status: "CREATED" as OrderStatus, // 订单状态 retCode: 0, // 失败时的原因码 - createdAt: Date.now(), // 订单创建时间 + createdAt: Date.now(), // 订单创建时间,毫秒 }; this._orders.set(orderId, vo); console.log("保存订单数据:", this._orders); @@ -83,6 +83,69 @@ export class OrderData extends BaseData { return ids; } + /** 根据订单 id 获取支付url */ + public getPayUrlById(id: string): string { + let oneData = this.getOrderDataById(id); + if (!oneData) return ""; + return oneData.payUrl; + } + + /** 根据订单 id 获取支付类型 */ + public getPayTypeById(id: string): number { + let oneData = this.getOrderDataById(id); + if (!oneData) return 0; + return oneData.payType; + } + + /** 根据订单 id 获取网络类型 */ + public getNetworkById(id: string): number { + let oneData = this.getOrderDataById(id); + if (!oneData) return 0; + return oneData.network; + } + + /** 根据订单 id 获取充值钱包地址 */ + public getWalletById(id: string): string { + let oneData = this.getOrderDataById(id); + if (!oneData) return ""; + return oneData.wallet; + } + + /** 根据订单 id 获取充值金额 */ + public getAmountById(id: string): string { + let oneData = this.getOrderDataById(id); + if (!oneData) return ""; + return oneData.amount; + } + + /** 根据订单 id 获取过期时间,单位: 秒 */ + public getExpireById(id: string): number { + let oneData = this.getOrderDataById(id); + if (!oneData) return 0; + return oneData.expire; + } + + /** 根据订单 id 获取过期时间戳,秒 */ + public getExpireUnixById(id: string): string { + let oneData = this.getOrderDataById(id); + if (!oneData) return ""; + return oneData.expireUnix; + } + + /** 根据订单 id 获取订单失败时的原因码 */ + public getRetCodeById(id: string): number { + let oneData = this.getOrderDataById(id); + if (!oneData) return 0; + return oneData.retCode; + } + + /** 根据订单 id 获取订单创建时间,毫秒 */ + public getCreatedAtById(id: string): number { + let oneData = this.getOrderDataById(id); + if (!oneData) return 0; + return oneData.createdAt; + } + /** --------------------------------------------------------- 缓存逻辑 --------------------------------------------------------- */ private ensureMap(): Map { diff --git a/assets/Scripts/chat18x/payment/CashInrFlow.ts b/assets/Scripts/chat18x/payment/CashInrFlow.ts new file mode 100644 index 00000000..6147d4e8 --- /dev/null +++ b/assets/Scripts/chat18x/payment/CashInrFlow.ts @@ -0,0 +1,46 @@ +/** + * 现金支付流程 + * + */ +import { PaymentOpenerFactory } from "./PaymentOpener"; +import PaymentPoller from "./PaymentPoller"; +import type { PaymentFlow } from "./PaymentFlow"; +import type proto from "db://assets/Scripts/proto/proto.pb.js"; +import { type OpenStrategy } from "./PaymentOpener"; +import { DataManager, DataId } from "db://assets/Scripts/chat18x/data/DataManager"; +import { OrderData } from "db://assets/Scripts/chat18x/data/OrderData"; + +export class CashInrFlow implements PaymentFlow { + constructor(private waitAppResume: (open: OpenStrategy) => Promise) {} + + async run(orderId: string, payUrl: string, open: OpenStrategy): Promise { + // 打开支付页 + await PaymentOpenerFactory.create(open).open(payUrl); + // 等待回到前台(系统浏览器策略下) + // - 如果是 inapp/minigame,可在 WebView/回跳时立即开始轮询; + // - 这里给一个通用的“等待前台”方法(可用 Cocos 的 onShow/onHide 自行接入) + await this.waitAppResume(open); + // 开始轮询 + const data = await this.pollOrder(orderId); + // 刷新订单数据 + const orderData = DataManager.I.getDataById(DataId.Order); + orderData.applyQueryOrder(orderId, data); + // 返回结果 + return data; + } + + async resume(orderId: string, _payUrl: string): Promise { + // 直接恢复轮询 + return this.pollOrder(orderId); + } + + private async pollOrder(orderId: string) { + const poller = new PaymentPoller(); + return poller.poll(orderId, { + maxDurationMs: 2 * 60 * 1000, + startIntervalMs: 2000, + maxIntervalMs: 10000, + jitter: true, + }, (d) => console.log()); + } +} diff --git a/assets/Scripts/chat18x/payment/CashInrFlow.ts.meta b/assets/Scripts/chat18x/payment/CashInrFlow.ts.meta new file mode 100644 index 00000000..6385ba2d --- /dev/null +++ b/assets/Scripts/chat18x/payment/CashInrFlow.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "806a1ac4-3dd3-4744-b846-c6915c171a32", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/chat18x/payment/PaymentFlow.ts b/assets/Scripts/chat18x/payment/PaymentFlow.ts new file mode 100644 index 00000000..032a34d6 --- /dev/null +++ b/assets/Scripts/chat18x/payment/PaymentFlow.ts @@ -0,0 +1,14 @@ +/** + * 支付流程的相关接口 + * + */ +import type proto from "db://assets/Scripts/proto/proto.pb.js"; +import { type OpenStrategy } from "./PaymentOpener"; + +export interface PaymentFlow { + /** 开始支付流程 */ + run(orderId: string, payUrl: string, open: OpenStrategy): Promise; + + /** 恢复未完成订单 */ + resume(orderId: string, payUrl: string): Promise; +} \ No newline at end of file diff --git a/assets/Scripts/chat18x/payment/PaymentFlow.ts.meta b/assets/Scripts/chat18x/payment/PaymentFlow.ts.meta new file mode 100644 index 00000000..80e16536 --- /dev/null +++ b/assets/Scripts/chat18x/payment/PaymentFlow.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "61bfae9e-5202-4dce-8ce6-1d31ca7e5593", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/chat18x/payment/PaymentService.ts b/assets/Scripts/chat18x/payment/PaymentService.ts index e3782873..df51b679 100644 --- a/assets/Scripts/chat18x/payment/PaymentService.ts +++ b/assets/Scripts/chat18x/payment/PaymentService.ts @@ -6,6 +6,9 @@ import { EventTarget, game, Game } from "cc"; import { PaymentApi } from "./PaymentApi"; import { PaymentOpenerFactory, type OpenStrategy } from "./PaymentOpener"; import PaymentPoller from "./PaymentPoller"; +import { PaymentFlow } from "./PaymentFlow"; +import { CashInrFlow } from "./CashInrFlow"; +import { WebUsdFlow } from "./WebUsdFlow"; 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"; @@ -15,7 +18,16 @@ import { InnerMsgCode } from "../../Main/Config/InnerMsgCode"; export class PaymentService { private static _I: PaymentService | null = null; static get I() { return this._I ?? (this._I = new PaymentService()); } - private constructor() {} + /** 策略表 */ + private flowMap: Record = {}; + + private constructor() { + this.flowMap = {}; + let num1 = proto.cs.EnmPayType.EPT_Cash_INR; + this.flowMap[num1] = new CashInrFlow(this.waitAppResumeIfNeeded.bind(this)); + let num2 = proto.cs.EnmPayType.EPT_WEB3_USD; + this.flowMap[num2] = new WebUsdFlow(5000); + } /** 发起支付:创建订单→打开URL→回到App后开始轮询 */ async startPayment(req: proto.cs.ICSCreateOrderReq, open: OpenStrategy = "system"): Promise { @@ -34,27 +46,9 @@ export class PaymentService { // 发出事件,支付订单创建成功 Utils.sendInnerMsg(InnerMsgCode.PayOrderCreateSucc, { orderId: orderId }); - // 打开支付页 - await PaymentOpenerFactory.create(open).open(payUrl); - - // 等待回到前台(系统浏览器策略下) - // - 如果是 inapp/minigame,可在 WebView/回跳时立即开始轮询; - // - 这里给一个通用的“等待前台”方法(可用 Cocos 的 onShow/onHide 自行接入) - await this.waitAppResumeIfNeeded(open); - - // 轮询 - const poller = new PaymentPoller(); - const data = await poller.poll(orderId, { - maxDurationMs: 2 * 60 * 1000, - startIntervalMs: 2000, - maxIntervalMs: 10000, - jitter: true, - }, (d) => console.log()); - - // 刷新订单数据 - orderData.applyQueryOrder(orderId, data); - // 返回结果 - return data; + // 分发流程 + const flow = this.flowMap[req.payType]; + return flow?.run(orderId, payUrl, open) ?? null; } /** App 回到前台后恢复未完成订单的轮询(在 onShow 时调用) */ diff --git a/assets/Scripts/chat18x/payment/WebUsdFlow.ts b/assets/Scripts/chat18x/payment/WebUsdFlow.ts new file mode 100644 index 00000000..a11b7fec --- /dev/null +++ b/assets/Scripts/chat18x/payment/WebUsdFlow.ts @@ -0,0 +1,45 @@ +/** + * web3 USD 支付流程 + * + */ +import PaymentPoller from "./PaymentPoller"; +import type { PaymentFlow } from "./PaymentFlow"; +import type proto from "db://assets/Scripts/proto/proto.pb.js"; +import { type OpenStrategy } from "./PaymentOpener"; +import { DataManager, DataId } from "db://assets/Scripts/chat18x/data/DataManager"; +import { OrderData } from "db://assets/Scripts/chat18x/data/OrderData"; + +export class WebUsdFlow implements PaymentFlow { + constructor(private delayMs: number = 5000) {} + + async run(orderId: string, _payUrl: string, _open: OpenStrategy): Promise { + // 延时 + await this.delay(this.delayMs); + // 开始轮询 + const data = await this.pollOrder(orderId); + // 刷新订单数据 + const orderData = DataManager.I.getDataById(DataId.Order); + orderData.applyQueryOrder(orderId, data); + // 返回结果 + return data; + } + + async resume(orderId: string, _payUrl: string): Promise { + // 直接轮询(也可以选择先 delay 一下再 poll,看业务需求) + return this.pollOrder(orderId); + } + + private async pollOrder(orderId: string) { + const poller = new PaymentPoller(); + return poller.poll(orderId, { + maxDurationMs: 2 * 60 * 1000, + startIntervalMs: 2000, + maxIntervalMs: 10000, + jitter: true, + }, (d) => console.log()); + } + + private delay(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)); + } +} diff --git a/assets/Scripts/chat18x/payment/WebUsdFlow.ts.meta b/assets/Scripts/chat18x/payment/WebUsdFlow.ts.meta new file mode 100644 index 00000000..03475a28 --- /dev/null +++ b/assets/Scripts/chat18x/payment/WebUsdFlow.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "87ddca36-23cb-411d-bbe9-3bd948ec5490", + "files": [], + "subMetas": {}, + "userData": {} +}