refactor(payment): remove vip status flow
This commit is contained in:
@@ -96,8 +96,7 @@ export function SubscriptionCheckoutButton({
|
|||||||
|
|
||||||
const isLoading =
|
const isLoading =
|
||||||
payment.isCreatingOrder ||
|
payment.isCreatingOrder ||
|
||||||
payment.isPollingOrder ||
|
payment.isPollingOrder;
|
||||||
payment.isCheckingVipStatus;
|
|
||||||
const label = payment.isPollingOrder
|
const label = payment.isPollingOrder
|
||||||
? "Processing payment..."
|
? "Processing payment..."
|
||||||
: payment.isCreatingOrder
|
: payment.isCreatingOrder
|
||||||
|
|||||||
@@ -57,11 +57,8 @@ export function SubscriptionScreen({
|
|||||||
const refreshedPaidOrderRef = useRef<string | null>(null);
|
const refreshedPaidOrderRef = useRef<string | null>(null);
|
||||||
const resumedPendingOrderRef = useRef<string | null>(null);
|
const resumedPendingOrderRef = useRef<string | null>(null);
|
||||||
const successDialogShownOrderRef = useRef<string | null>(null);
|
const successDialogShownOrderRef = useRef<string | null>(null);
|
||||||
const syncedVipOrderRef = useRef<string | null>(null);
|
|
||||||
const [showPaymentSuccessDialog, setShowPaymentSuccessDialog] =
|
const [showPaymentSuccessDialog, setShowPaymentSuccessDialog] =
|
||||||
useState(false);
|
useState(false);
|
||||||
const [pendingChatReturnAfterVipSync, setPendingChatReturnAfterVipSync] =
|
|
||||||
useState(false);
|
|
||||||
const isVipSubscription = subscriptionType === "vip";
|
const isVipSubscription = subscriptionType === "vip";
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -77,35 +74,6 @@ export function SubscriptionScreen({
|
|||||||
userDispatch({ type: "UserFetch" });
|
userDispatch({ type: "UserFetch" });
|
||||||
}, [payment.currentOrderId, payment.isPaid, userDispatch]);
|
}, [payment.currentOrderId, payment.isPaid, userDispatch]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const currentUser = user.currentUser;
|
|
||||||
const canMarkVipSynced =
|
|
||||||
subscriptionType === "vip" &&
|
|
||||||
payment.isPaid &&
|
|
||||||
payment.currentOrderId &&
|
|
||||||
payment.vipStatus?.isVip === true &&
|
|
||||||
currentUser &&
|
|
||||||
currentUser.isVip !== true;
|
|
||||||
if (!canMarkVipSynced) return;
|
|
||||||
if (syncedVipOrderRef.current === payment.currentOrderId) return;
|
|
||||||
|
|
||||||
syncedVipOrderRef.current = payment.currentOrderId;
|
|
||||||
userDispatch({
|
|
||||||
type: "UserUpdate",
|
|
||||||
user: {
|
|
||||||
...currentUser,
|
|
||||||
isVip: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}, [
|
|
||||||
payment.currentOrderId,
|
|
||||||
payment.isPaid,
|
|
||||||
payment.vipStatus?.isVip,
|
|
||||||
subscriptionType,
|
|
||||||
user.currentUser,
|
|
||||||
userDispatch,
|
|
||||||
]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!payment.isPaid || !payment.currentOrderId) return;
|
if (!payment.isPaid || !payment.currentOrderId) return;
|
||||||
if (successDialogShownOrderRef.current === payment.currentOrderId) return;
|
if (successDialogShownOrderRef.current === payment.currentOrderId) return;
|
||||||
@@ -200,8 +168,7 @@ export function SubscriptionScreen({
|
|||||||
: plans.find((plan) => plan.id === payment.selectedPlanId)) ?? null;
|
: plans.find((plan) => plan.id === payment.selectedPlanId)) ?? null;
|
||||||
const isPaymentBusy =
|
const isPaymentBusy =
|
||||||
payment.isCreatingOrder ||
|
payment.isCreatingOrder ||
|
||||||
payment.isPollingOrder ||
|
payment.isPollingOrder;
|
||||||
payment.isCheckingVipStatus;
|
|
||||||
const canActivate =
|
const canActivate =
|
||||||
selectedPlan !== null && payment.agreed && !isPaymentBusy;
|
selectedPlan !== null && payment.agreed && !isPaymentBusy;
|
||||||
|
|
||||||
@@ -217,7 +184,6 @@ export function SubscriptionScreen({
|
|||||||
: "Choose a subscription plan";
|
: "Choose a subscription plan";
|
||||||
|
|
||||||
const finishPaymentSuccessClose = () => {
|
const finishPaymentSuccessClose = () => {
|
||||||
setPendingChatReturnAfterVipSync(false);
|
|
||||||
setShowPaymentSuccessDialog(false);
|
setShowPaymentSuccessDialog(false);
|
||||||
paymentDispatch({ type: "PaymentReset" });
|
paymentDispatch({ type: "PaymentReset" });
|
||||||
if (returnTo === "chat") {
|
if (returnTo === "chat") {
|
||||||
@@ -226,44 +192,9 @@ export function SubscriptionScreen({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handlePaymentSuccessClose = () => {
|
const handlePaymentSuccessClose = () => {
|
||||||
const shouldWaitForVipSync =
|
|
||||||
returnTo === "chat" &&
|
|
||||||
subscriptionType === "vip" &&
|
|
||||||
user.currentUser?.isVip !== true;
|
|
||||||
|
|
||||||
if (shouldWaitForVipSync) {
|
|
||||||
setPendingChatReturnAfterVipSync(true);
|
|
||||||
if (payment.vipStatus?.isVip === true && user.currentUser) {
|
|
||||||
userDispatch({
|
|
||||||
type: "UserUpdate",
|
|
||||||
user: {
|
|
||||||
...user.currentUser,
|
|
||||||
isVip: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
userDispatch({ type: "UserFetch" });
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
finishPaymentSuccessClose();
|
finishPaymentSuccessClose();
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!pendingChatReturnAfterVipSync) return;
|
|
||||||
if (subscriptionType === "vip" && user.currentUser?.isVip !== true) return;
|
|
||||||
|
|
||||||
const timer = window.setTimeout(() => {
|
|
||||||
finishPaymentSuccessClose();
|
|
||||||
}, 0);
|
|
||||||
|
|
||||||
return () => window.clearTimeout(timer);
|
|
||||||
// `finishPaymentSuccessClose` intentionally stays local to this component;
|
|
||||||
// this effect is gated by pendingChatReturnAfterVipSync to avoid repeated closes.
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, [pendingChatReturnAfterVipSync, subscriptionType, user.currentUser?.isVip]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isVipSubscription) {
|
if (isVipSubscription) {
|
||||||
const firstVipPlanId = vipOfferPlans[0]?.id ?? "";
|
const firstVipPlanId = vipOfferPlans[0]?.id ?? "";
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import {
|
|||||||
type PayChannel,
|
type PayChannel,
|
||||||
PaymentOrderStatusResponse,
|
PaymentOrderStatusResponse,
|
||||||
PaymentPlansResponse,
|
PaymentPlansResponse,
|
||||||
PaymentVipStatusResponse,
|
|
||||||
} from "@/data/dto/payment";
|
} from "@/data/dto/payment";
|
||||||
import { paymentMachine } from "@/stores/payment/payment-machine";
|
import { paymentMachine } from "@/stores/payment/payment-machine";
|
||||||
|
|
||||||
@@ -94,12 +93,6 @@ function createTestPaymentMachine(
|
|||||||
planId: "vip_monthly",
|
planId: "vip_monthly",
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
loadVipStatus: fromPromise(async () =>
|
|
||||||
PaymentVipStatusResponse.from({
|
|
||||||
isVip: true,
|
|
||||||
vipExpiresAt: "2026-07-25T00:00:00.000Z",
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -163,7 +156,6 @@ describe("paymentMachine", () => {
|
|||||||
expect(context.currentOrderId).toBe("pay_test_001");
|
expect(context.currentOrderId).toBe("pay_test_001");
|
||||||
expect(context.orderStatus).toBe("paid");
|
expect(context.orderStatus).toBe("paid");
|
||||||
expect(context.launchNonce).toBe(1);
|
expect(context.launchNonce).toBe(1);
|
||||||
expect(context.vipStatus?.isVip).toBe(true);
|
|
||||||
|
|
||||||
actor.stop();
|
actor.stop();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -28,13 +28,11 @@ export interface PaymentContextState {
|
|||||||
currentOrderId: string | null;
|
currentOrderId: string | null;
|
||||||
payParams: Record<string, unknown> | null;
|
payParams: Record<string, unknown> | null;
|
||||||
orderStatus: MachineContext["orderStatus"];
|
orderStatus: MachineContext["orderStatus"];
|
||||||
vipStatus: MachineContext["vipStatus"];
|
|
||||||
errorMessage: string | null;
|
errorMessage: string | null;
|
||||||
launchNonce: number;
|
launchNonce: number;
|
||||||
isLoadingPlans: boolean;
|
isLoadingPlans: boolean;
|
||||||
isCreatingOrder: boolean;
|
isCreatingOrder: boolean;
|
||||||
isPollingOrder: boolean;
|
isPollingOrder: boolean;
|
||||||
isCheckingVipStatus: boolean;
|
|
||||||
isPaid: boolean;
|
isPaid: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,14 +57,12 @@ export function PaymentProvider({ children }: PaymentProviderProps) {
|
|||||||
currentOrderId: state.context.currentOrderId,
|
currentOrderId: state.context.currentOrderId,
|
||||||
payParams: state.context.payParams,
|
payParams: state.context.payParams,
|
||||||
orderStatus: state.context.orderStatus,
|
orderStatus: state.context.orderStatus,
|
||||||
vipStatus: state.context.vipStatus,
|
|
||||||
errorMessage: state.context.errorMessage,
|
errorMessage: state.context.errorMessage,
|
||||||
launchNonce: state.context.launchNonce,
|
launchNonce: state.context.launchNonce,
|
||||||
isLoadingPlans: state.matches("loadingPlans"),
|
isLoadingPlans: state.matches("loadingPlans"),
|
||||||
isCreatingOrder: state.matches("creatingOrder"),
|
isCreatingOrder: state.matches("creatingOrder"),
|
||||||
isPollingOrder:
|
isPollingOrder:
|
||||||
state.matches("pollingOrder") || state.matches("waitingForPayment"),
|
state.matches("pollingOrder") || state.matches("waitingForPayment"),
|
||||||
isCheckingVipStatus: state.matches("checkingVipStatus"),
|
|
||||||
isPaid: state.matches("paid"),
|
isPaid: state.matches("paid"),
|
||||||
}),
|
}),
|
||||||
[state],
|
[state],
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ export type PaymentEvent =
|
|||||||
| { type: "PaymentAgreementChanged"; agreed: boolean }
|
| { type: "PaymentAgreementChanged"; agreed: boolean }
|
||||||
| { type: "PaymentCreateOrderSubmitted" }
|
| { type: "PaymentCreateOrderSubmitted" }
|
||||||
| { type: "PaymentReturned"; orderId: string }
|
| { type: "PaymentReturned"; orderId: string }
|
||||||
| { type: "PaymentRefreshVipStatus" }
|
|
||||||
| { type: "PaymentLaunchFailed"; errorMessage: string }
|
| { type: "PaymentLaunchFailed"; errorMessage: string }
|
||||||
| { type: "PaymentErrorCleared" }
|
| { type: "PaymentErrorCleared" }
|
||||||
| { type: "PaymentReset" };
|
| { type: "PaymentReset" };
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import {
|
|||||||
PayChannel,
|
PayChannel,
|
||||||
PaymentOrderStatusResponse,
|
PaymentOrderStatusResponse,
|
||||||
PaymentPlansResponse,
|
PaymentPlansResponse,
|
||||||
PaymentVipStatusResponse,
|
|
||||||
} from "@/data/dto/payment";
|
} from "@/data/dto/payment";
|
||||||
import { paymentRepository } from "@/data/repositories/payment_repository";
|
import { paymentRepository } from "@/data/repositories/payment_repository";
|
||||||
import type { IPaymentRepository } from "@/data/repositories/interfaces";
|
import type { IPaymentRepository } from "@/data/repositories/interfaces";
|
||||||
@@ -45,10 +44,3 @@ export const pollPaymentOrderStatusActor = fromPromise<
|
|||||||
if (Result.isErr(result)) throw result.error;
|
if (Result.isErr(result)) throw result.error;
|
||||||
return result.data;
|
return result.data;
|
||||||
});
|
});
|
||||||
|
|
||||||
export const loadPaymentVipStatusActor =
|
|
||||||
fromPromise<PaymentVipStatusResponse>(async () => {
|
|
||||||
const result = await paymentRepo.getVipStatus();
|
|
||||||
if (Result.isErr(result)) throw result.error;
|
|
||||||
return result.data;
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import type { PaymentPlan } from "@/data/dto/payment";
|
||||||
|
|
||||||
|
import type { PaymentState } from "./payment-state";
|
||||||
|
|
||||||
|
export function toPaymentErrorMessage(error: unknown): string {
|
||||||
|
return error instanceof Error ? error.message : String(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function defaultAutoRenewForPlan(planId: string): boolean {
|
||||||
|
return (
|
||||||
|
!planId.includes("lifetime") &&
|
||||||
|
!planId.startsWith("dol_") &&
|
||||||
|
!planId.startsWith("points_") &&
|
||||||
|
!planId.startsWith("credit_")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDefaultPlanId(plans: readonly PaymentPlan[]): string {
|
||||||
|
return (
|
||||||
|
plans.find((plan) => plan.planId === "vip_monthly")?.planId ??
|
||||||
|
plans.find((plan) => plan.orderType.startsWith("vip_"))?.planId ??
|
||||||
|
plans[0]?.planId ??
|
||||||
|
""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resetOrderState(): Partial<PaymentState> {
|
||||||
|
return {
|
||||||
|
currentOrderId: null,
|
||||||
|
payParams: null,
|
||||||
|
orderStatus: null,
|
||||||
|
errorMessage: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -3,16 +3,19 @@
|
|||||||
*/
|
*/
|
||||||
import { assign, setup } from "xstate";
|
import { assign, setup } from "xstate";
|
||||||
|
|
||||||
import type { PaymentPlan } from "@/data/dto/payment";
|
|
||||||
|
|
||||||
import type { PaymentEvent } from "./payment-events";
|
import type { PaymentEvent } from "./payment-events";
|
||||||
import { initialState, type PaymentState } from "./payment-state";
|
import { initialState, type PaymentState } from "./payment-state";
|
||||||
import {
|
import {
|
||||||
createPaymentOrderActor,
|
createPaymentOrderActor,
|
||||||
loadPaymentPlansActor,
|
loadPaymentPlansActor,
|
||||||
loadPaymentVipStatusActor,
|
|
||||||
pollPaymentOrderStatusActor,
|
pollPaymentOrderStatusActor,
|
||||||
} from "./payment-machine.actors";
|
} from "./payment-machine.actors";
|
||||||
|
import {
|
||||||
|
defaultAutoRenewForPlan,
|
||||||
|
getDefaultPlanId,
|
||||||
|
resetOrderState,
|
||||||
|
toPaymentErrorMessage,
|
||||||
|
} from "./payment-machine.helpers";
|
||||||
|
|
||||||
export type { PaymentEvent } from "./payment-events";
|
export type { PaymentEvent } from "./payment-events";
|
||||||
export type { PaymentState } from "./payment-state";
|
export type { PaymentState } from "./payment-state";
|
||||||
@@ -20,37 +23,6 @@ export { initialState } from "./payment-state";
|
|||||||
|
|
||||||
const POLL_DELAY_MS = 4000;
|
const POLL_DELAY_MS = 4000;
|
||||||
|
|
||||||
function toErrorMessage(error: unknown): string {
|
|
||||||
return error instanceof Error ? error.message : String(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
function defaultAutoRenewForPlan(planId: string): boolean {
|
|
||||||
return (
|
|
||||||
!planId.includes("lifetime") &&
|
|
||||||
!planId.startsWith("dol_") &&
|
|
||||||
!planId.startsWith("points_") &&
|
|
||||||
!planId.startsWith("credit_")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getDefaultPlanId(plans: readonly PaymentPlan[]): string {
|
|
||||||
return (
|
|
||||||
plans.find((plan) => plan.planId === "vip_monthly")?.planId ??
|
|
||||||
plans.find((plan) => plan.orderType.startsWith("vip_"))?.planId ??
|
|
||||||
plans[0]?.planId ??
|
|
||||||
""
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function resetOrderState() {
|
|
||||||
return {
|
|
||||||
currentOrderId: null,
|
|
||||||
payParams: null,
|
|
||||||
orderStatus: null,
|
|
||||||
errorMessage: null,
|
|
||||||
} satisfies Partial<PaymentState>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const paymentMachine = setup({
|
export const paymentMachine = setup({
|
||||||
types: {
|
types: {
|
||||||
context: {} as PaymentState,
|
context: {} as PaymentState,
|
||||||
@@ -60,7 +32,6 @@ export const paymentMachine = setup({
|
|||||||
loadPlans: loadPaymentPlansActor,
|
loadPlans: loadPaymentPlansActor,
|
||||||
createOrder: createPaymentOrderActor,
|
createOrder: createPaymentOrderActor,
|
||||||
pollOrderStatus: pollPaymentOrderStatusActor,
|
pollOrderStatus: pollPaymentOrderStatusActor,
|
||||||
loadVipStatus: loadPaymentVipStatusActor,
|
|
||||||
},
|
},
|
||||||
}).createMachine({
|
}).createMachine({
|
||||||
/** @xstate-layout N4IgpgJg5mDOIC5QAcCGBPAtmAdgFwGIAFDbfAGVQFccBjACwDFUBLAG0gG0AGAXURQB7WCzwtBOASAAeiACwAmADQh0iAIwA2bnIB0CuQE5j67t20AOBQF9rKtFlx5dLCB2KknASRyie-JBBkYVFxSUDZBAVDPUMFdQs5dXUAVk0Adk0AZhSUlTUEdUMLXXV0w00LCyzzc00U23tPfBc3MA9HfAAlMAAzACc4egA1FmQAZTxUPCpYfylgkTEJKUjo2PjE5LTMnLzVRBTq3R1iuRTdzWz0xqDm5zZBVAgWHCgiNlQcWAIICTAXDgAG6CADWAIcZAeTxebw+X1gCFeINo0zC-nmgUWoRWEQ0WQsKV0lXSSQuFk0MUM6XyiAs6l0RmMxXSWS0FIUNjsd060Oer3en2+BDA-X6gn6umQnzwvQlmCl910j35cKFiORglRyxwGL4CxCOtW+MJxIspNS6QpVJpB0KpMZKTZBiSWXiMQst0hTl0g2e6A6UJ8fn1WMNYWNhRShiyujOCiq5yOSXUtKihm4jOilTkbKO6Ru3O9LT9EADJF58Jw4zAHFoeC4oaESwjeMKhlMunS3BqCiycm4VviWTTpnSCn02iycSdigMmi9StL5fuFYAwvQvjhaxuvjAIJjmzjwqBIgkrPoe9wFNxUhk5HI09TNLoauOMtxzRYO4ZF7zfWA-qBk4ACCVB4IIPTbgA7rubyNgER5Gm256xpocjVDkCgXNoCiaGmVSZjkSRJOhqTRlyTT-suwH4CBUCDGAUJwfuh5BOGuKnhoVREnhuTxCkWg4WmVp6AOphaEUKScvUf5QgBQEVsxfoNgA8v0ECiuMVAAEaYKIDYHk27EtpxMiIJyRRxuY6iKPScQ1I+drJOOXbqFh6RHLeTpyT6NFKU4a4qWA6maf02l6QZXDqIhJnHpGCQJG5FLnBUeHlPhdqVCUD5WhmpJVDGnpFkugFlrReA9AMQyjBMUwzHMxnYshXGFEYmZ8YJGbnOkWjKHa-aZnEFRWPEZR9b5JZlSuvIAKJihKa4cKggxGbFzWtq1RTqBOBjFISBYKFamRphRjIxJkTrXmkySTc4tAqQKoWir8-yAiC4KKv+D2AWIbzPf0SLAlqaISHq60cSe5lRCRr47VkGQUgS2SjtGeiksyn6JvSDQld9j3-RpL2iuKkrStMcr9Aqxb3QTUAA0DKKg7qfBsRtZlrGSxJpNwHb0vehijm+XYjfUD7xBhxVUfJwRsGwT1E-0r3bu9YIQkqsvy4TYWMyDOrgwaplQ2sMRxpsKY7NkuRptksYpEYiQI9GKTXoW0s+prCthcrAKap9NNSoIcte6KuvauirMxYb8VtusZsJBbGRW-sBTuTojJyJU1xuuh0Z3YHwfay9fwq376v-p7ReA5q4dg6zCgQ0bkZx3ECfbEnexPjUjKsjGmimAOWT9vnlf04rIoLWTMqU9TGtB1rY86zXzMG2GTex6brdbHeuzW85Y3nVkrIWNwgnJHh+fQawf1QIwEoBfgFU9LAYB4GzkORhSmZWjtO3GAO9QLBPj7K+DM-dM4fmqFLHk8kr6hDeHffoD9CDSFgPVAEqBegNn6AACgHGYAAlAQAOcCb6IOQe-derUjB6G-KfeoToMhD3OARC81JpxH2pNEGMbsYE+gYGAWgoIBS1UmNMWYPtVb+yVAIoRIixhiIamHFerMmofzbF-Ls9J4jcIAUcESHYTjTnoaYMwpJeEB1kcIt4oj6oSJLr7YG0jvr0EEdYqAtjxEamBrXFmvBOBRzXjHVqmif46P-uYfRdpM4MgyCNbYFQcgWJka4uRNiFF2J+CTCUUpp7yi+vJKx8i6peOUfrVRjdgnQ1Cdov+MRIlAKysUE4hIYw6ASPbWy+cinpJKQ1CepNckU3yZY1J7jPFKOXuU-xgSkKbWqdoLRv9dENNOvbYkboT45mSJSEerAIBPzgK-ShVSzwEiJCSMkVpKRGFtAUAshg4y2VPkUXMHZPJ7NcIc6qsARgZK8Sclq0MOwvk6kcXIMRNg2zkOkXQ4KYzYU5N2Ps+deisA4Ac5BQVfohUVhFfSeBDKAvmWc00lzLTWluaOB8jyCz9gTAyjsaRUXosgBVeapMlqAVWsSjmJoLnmiuZS6ko46i6ApL1OlGZsLXhZewNlyDn7HLUVQ6G7kyWCopTckVzk+ripvL2aogDoi2G5DgQQml4BYnuNHIFkQAC0mUCj2qJMyN17qMyn3zq4DgtqSXcVdZsPMmdFAJBHHaC4sL3JskMNGdp05fx43kiqWEgoER+r5YUMotKEiVHtrsQko5PKlAyjGfsmF7z52XBm42GhqQMm7L2TkVhpyslHGUWMw5BLlBPrkVk3S6YAxrc3fusKeE5DiZ61Mzk0hEhzmkct15eaUT4S0UeQ6gl2vkP1VON49BulJGYG6R7L7XwFOQm1m7-UIE0HhOG84Bx7quE6xAMQXyjp0e+bQPZuljOKYo2Yw62z9xKPUW95hEnfkaQUfu762naLiKyDInyIBAa2jeF8v9rzfmMAJHddIeylAATZKSJI5UYrQ2qvsRIew7JqIlKoQs70dqSCfbC34CymusEAA */
|
/** @xstate-layout N4IgpgJg5mDOIC5QAcCGBPAtmAdgFwGIAFDbfAGVQFccBjACwDFUBLAG0gG0AGAXURQB7WCzwtBOASAAeiACwAmADQh0iAIwA2bnIB0CuQE5j67t20AOBQF9rKtFlx5dLCB2KknASRyie-JBBkYVFxSUDZBAVDPUMFdQs5dXUAVk0Adk0AZhSUlTUEdUMLXXV0w00LCyzzc00U23tPfBc3MA9HfAAlMAAzACc4egA1FmQAZTxUPCpYfylgkTEJKUjo2PjE5LTMnLzVRBTq3R1iuRTdzWz0xqDm5zZBVAgWHCgiNlQcWAIICTAXDgAG6CADWAIcZAeTxebw+X1gCFeINo0zC-nmgUWoRWEQ0WQsKV0lXSSQuFk0MUM6XyiAs6l0RmMxXSWS0FIUNjsd060Oer3en2+BDA-X6gn6umQnzwvQlmCl910j35cKFiORglRyxwGL4CxCOtW+MJxIspNS6QpVJpB0KpMZKTZBiSWXiMQst0hTl0g2e6A6UJ8fn1WMNYWNhRShiyujOCiq5yOSXUtKihm4jOilTkbKO6Ru3O9LT9EADJF58Jw4zAHFoeC4oaESwjeMKhlMunS3BqCiycm4VviWTTpnSCn02iycSdigMmi9StL5fuFYAwvQvjhaxuvjAIJjmzjwqBIgkrPoe9wFNxUhk5HI09TNLoauOMtxzRYO4ZF7zfWA-qBk4ACCVB4IIPTbgA7rubyNgER5Gm256xpocjVDkCgXNoCiaGmVSZjkSRJOhqTRlyTT-suwH4CBUCDGAUJwfuh5BOGuKnhoVREnhuTxCkWg4WmVp6AOphaEUKScvUf5QgBQEVsxfoNgA8v0ECiuMVAAEaYKIDYHk27EtpxMiIJyRRxuY6iKPScQ1I+drJOOXbqFh6RHLeTpyT6NFKU4a4qWA6maf02l6QZXDqIhJnHpGCQJG5FLnBUeHlPhdqVCUD5WhmpJVDGnpFkugFlrReA9AMQyjBMUwzHMxnYshXGFEYmZ8YJGbnOkWjKHa-aZnEFRWPEZR9b5JZlSuvIAKJihKa4cKggxGbFzWtq1RTqBOBjFISBYKFamRphRjIxJkTrXmkySTc4tAqQKoWir8-yAiC4KKv+D2AWIbzPf0SLAlqaISHq60cSe5lRCRr47VkGQUgS2SjtGeiksyn6JvSDQld9j3-RpL2iuKkrStMcr9Aqxb3QTUAA0DKKg7qfBsRtZlrGSxJpNwHb0vehijm+XYjfUD7xBhxVUfJwRsGwT1E-0r3bu9YIQkqsvy4TYWMyDOrgwaplQ2sMRxpsKY7NkuRptksYpEYiQI9GKTXoW0s+prCthcrAKap9NNSoIcte6KuvauirMxYb8VtusZsJBbGRW-sBTuTojJyJU1xuuh0Z3YHwfay9fwq376v-p7ReA5q4dg6zCgQ0bkZx3ECfbEnexPjUjKsjGmimAOWT9vnlf04rIoLWTMqU9TGtB1rY86zXzMG2GTex6brdbHeuzW85Y3nVkrIWNwgnJHh+fQawf1QIwEoBfgFU9LAYB4GzkORhSmZWjtO3GAO9QLBPj7K+DM-dM4fmqFLHk8kr6hDeHffoD9CDSFgPVAEqBegNn6AACgHGYAAlAQAOcCb6IOQe-derUjB6G-KfeoToMhD3OARC81JpxH2pNEGMbsYE+gYGAWgoIBS1UmNMWYPtVb+yVAIoRIixhiIamHFerMmofzbF-Ls9J4jcIAUcESHYTjTnoaYMwpJeEB1kcIt4oj6oSJLr7YG0jvr0EEdYqAtjxEamBrXFmvBOBRzXjHVqmif46P-uYfRdpM4MgyCNbYFQcgWJka4uRNiFF2J+CTCUUpp7yi+vJKx8i6peOUfrVRjdgnQ1Cdov+MRIlAKysUE4hIYw6ASPbWy+cinpJKQ1CepNckU3yZY1J7jPFKOXuU-xgSkKbWqdoLRv9dENNOvbYkboT45mSJSEerAIBPzgK-ShVSzwEiJCSMkVpKRGFtAUAshg4y2VPkUXMHZPJ7NcIc6qsARgZK8Sclq0MOwvk6kcXIMRNg2zkOkXQ4KYzYU5N2Ps+deisA4Ac5BQVfohUVhFfSeBDKAvmWc00lzLTWluaOB8jyCz9gTAyjsaRUXosgBVeapMlqAVWsSjmJoLnmiuZS6ko46i6ApL1OlGZsLXhZewNlyDn7HLUVQ6G7kyWCopTckVzk+ripvL2aogDoi2G5DgQQml4BYnuNHIFkQAC0mUCj2qJMyN17qMyn3zq4DgtqSXcVdZsPMmdFAJBHHaC4sL3JskMNGdp05fx43kiqWEgoER+r5YUMotKEiVHtrsQko5PKlAyjGfsmF7z52XBm42GhqQMm7L2TkVhpyslHGUWMw5BLlBPrkVk3S6YAxrc3fusKeE5DiZ61Mzk0hEhzmkct15eaUT4S0UeQ6gl2vkP1VON49BulJGYG6R7L7XwFOQm1m7-UIE0HhOG84Bx7quE6xAMQXyjp0e+bQPZuljOKYo2Yw62z9xKPUW95hEnfkaQUfu762naLiKyDInyIBAa2jeF8v9rzfmMAJHddIeylAATZKSJI5UYrQ2qvsRIew7JqIlKoQs70dqSCfbC34CymusEAA */
|
||||||
@@ -71,7 +42,6 @@ export const paymentMachine = setup({
|
|||||||
idle: {
|
idle: {
|
||||||
on: {
|
on: {
|
||||||
PaymentInit: "loadingPlans",
|
PaymentInit: "loadingPlans",
|
||||||
PaymentRefreshVipStatus: "checkingVipStatus",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -95,7 +65,7 @@ export const paymentMachine = setup({
|
|||||||
onError: {
|
onError: {
|
||||||
target: "ready",
|
target: "ready",
|
||||||
actions: assign(({ event }) => ({
|
actions: assign(({ event }) => ({
|
||||||
errorMessage: toErrorMessage(event.error),
|
errorMessage: toPaymentErrorMessage(event.error),
|
||||||
})),
|
})),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -143,7 +113,6 @@ export const paymentMachine = setup({
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
PaymentRefreshVipStatus: "checkingVipStatus",
|
|
||||||
PaymentErrorCleared: {
|
PaymentErrorCleared: {
|
||||||
actions: assign({ errorMessage: null }),
|
actions: assign({ errorMessage: null }),
|
||||||
},
|
},
|
||||||
@@ -171,7 +140,7 @@ export const paymentMachine = setup({
|
|||||||
onError: {
|
onError: {
|
||||||
target: "failed",
|
target: "failed",
|
||||||
actions: assign(({ event }) => ({
|
actions: assign(({ event }) => ({
|
||||||
errorMessage: toErrorMessage(event.error),
|
errorMessage: toPaymentErrorMessage(event.error),
|
||||||
})),
|
})),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -186,7 +155,7 @@ export const paymentMachine = setup({
|
|||||||
onDone: [
|
onDone: [
|
||||||
{
|
{
|
||||||
guard: ({ event }) => event.output.status === "paid",
|
guard: ({ event }) => event.output.status === "paid",
|
||||||
target: "checkingVipStatus",
|
target: "paid",
|
||||||
actions: assign(({ event }) => ({
|
actions: assign(({ event }) => ({
|
||||||
orderStatus: event.output.status,
|
orderStatus: event.output.status,
|
||||||
errorMessage: null,
|
errorMessage: null,
|
||||||
@@ -211,7 +180,7 @@ export const paymentMachine = setup({
|
|||||||
onError: {
|
onError: {
|
||||||
target: "failed",
|
target: "failed",
|
||||||
actions: assign(({ event }) => ({
|
actions: assign(({ event }) => ({
|
||||||
errorMessage: toErrorMessage(event.error),
|
errorMessage: toPaymentErrorMessage(event.error),
|
||||||
})),
|
})),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -235,44 +204,6 @@ export const paymentMachine = setup({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
checkingVipStatus: {
|
|
||||||
invoke: {
|
|
||||||
src: "loadVipStatus",
|
|
||||||
onDone: [
|
|
||||||
{
|
|
||||||
guard: ({ context }) => context.orderStatus === "paid",
|
|
||||||
target: "paid",
|
|
||||||
actions: assign(({ event }) => ({
|
|
||||||
vipStatus: event.output,
|
|
||||||
errorMessage: null,
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
target: "ready",
|
|
||||||
actions: assign(({ event }) => ({
|
|
||||||
vipStatus: event.output,
|
|
||||||
errorMessage: null,
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
onError: [
|
|
||||||
{
|
|
||||||
guard: ({ context }) => context.orderStatus === "paid",
|
|
||||||
target: "paid",
|
|
||||||
actions: assign(({ event }) => ({
|
|
||||||
errorMessage: toErrorMessage(event.error),
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
target: "ready",
|
|
||||||
actions: assign(({ event }) => ({
|
|
||||||
errorMessage: toErrorMessage(event.error),
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
paid: {
|
paid: {
|
||||||
on: {
|
on: {
|
||||||
PaymentPlanSelected: {
|
PaymentPlanSelected: {
|
||||||
@@ -310,7 +241,6 @@ export const paymentMachine = setup({
|
|||||||
target: "ready",
|
target: "ready",
|
||||||
actions: assign(resetOrderState),
|
actions: assign(resetOrderState),
|
||||||
},
|
},
|
||||||
PaymentRefreshVipStatus: "checkingVipStatus",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import type {
|
|||||||
PayChannel,
|
PayChannel,
|
||||||
PaymentOrderStatus,
|
PaymentOrderStatus,
|
||||||
PaymentPlan,
|
PaymentPlan,
|
||||||
PaymentVipStatusResponse,
|
|
||||||
} from "@/data/dto/payment";
|
} from "@/data/dto/payment";
|
||||||
|
|
||||||
export interface PaymentState {
|
export interface PaymentState {
|
||||||
@@ -17,7 +16,6 @@ export interface PaymentState {
|
|||||||
currentOrderId: string | null;
|
currentOrderId: string | null;
|
||||||
payParams: Record<string, unknown> | null;
|
payParams: Record<string, unknown> | null;
|
||||||
orderStatus: PaymentOrderStatus | null;
|
orderStatus: PaymentOrderStatus | null;
|
||||||
vipStatus: PaymentVipStatusResponse | null;
|
|
||||||
errorMessage: string | null;
|
errorMessage: string | null;
|
||||||
launchNonce: number;
|
launchNonce: number;
|
||||||
}
|
}
|
||||||
@@ -31,7 +29,6 @@ export const initialState: PaymentState = {
|
|||||||
currentOrderId: null,
|
currentOrderId: null,
|
||||||
payParams: null,
|
payParams: null,
|
||||||
orderStatus: null,
|
orderStatus: null,
|
||||||
vipStatus: null,
|
|
||||||
errorMessage: null,
|
errorMessage: null,
|
||||||
launchNonce: 0,
|
launchNonce: 0,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user