feat(payment): implement first recharge offer functionality and UI updates

This commit is contained in:
2026-07-02 14:39:09 +08:00
parent 7b35fd18c5
commit d4de1370e8
20 changed files with 607 additions and 50 deletions
@@ -145,6 +145,52 @@ describe("paymentMachine", () => {
actor.stop();
});
it("keeps first recharge offer metadata from the plans response", async () => {
const actor = createActor(
paymentMachine.provide({
actors: {
loadCachedPlans: fromPromise<PaymentPlansResponse | null>(
async () => null,
),
refreshPlans: fromPromise(async () =>
PaymentPlansResponse.from({
isFirstRecharge: true,
firstRechargeOffer: {
enabled: true,
type: "first_recharge_half_price",
discountPercent: 50,
},
plans: [
{
...monthlyPlan,
amountCents: 995,
originalAmountCents: 1990,
isFirstRechargeOffer: true,
firstRechargeDiscountPercent: 50,
promotionType: "first_recharge_half_price",
},
],
}),
),
},
}),
).start();
actor.send({ type: "PaymentInit" });
await waitFor(actor, (snapshot) => snapshot.matches("ready"));
const context = actor.getSnapshot().context;
expect(context.isFirstRecharge).toBe(true);
expect(context.firstRechargeOffer?.discountPercent).toBe(50);
expect(context.plans[0]).toMatchObject({
amountCents: 995,
originalAmountCents: 1990,
isFirstRechargeOffer: true,
});
actor.stop();
});
it("hydrates cached plans before refreshing with network plans", async () => {
let resolveRefresh!: (value: PaymentPlansResponse) => void;
const refreshPlansPromise = new Promise<PaymentPlansResponse>((resolve) => {