fix(payments): reuse checkout attempts and show pending status
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useNavigate, useParams } from "@/lib/router";
|
||||
import { api } from "@/lib/api";
|
||||
import type * as Types from "@/lib/types";
|
||||
@@ -76,6 +76,8 @@ export default function EventDetail({ initialEvent = null }: EventDetailProps) {
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
const [alreadyRegistered, setAlreadyRegistered] = useState(false);
|
||||
const [nowTs, setNowTs] = useState(() => Date.now());
|
||||
const checkoutInProgressRef = useRef(false);
|
||||
const checkoutIdempotencyKeyRef = useRef<string | null>(null);
|
||||
|
||||
const basePrice = Number(event?.price ?? 0);
|
||||
const isFree = useMemo(() => basePrice <= 0, [basePrice]);
|
||||
@@ -163,6 +165,9 @@ export default function EventDetail({ initialEvent = null }: EventDetailProps) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (checkoutInProgressRef.current) return;
|
||||
checkoutInProgressRef.current = true;
|
||||
|
||||
try {
|
||||
setSubmitting(true);
|
||||
const reg = await api.registerForEvent(event.id, coupon);
|
||||
@@ -185,9 +190,10 @@ export default function EventDetail({ initialEvent = null }: EventDetailProps) {
|
||||
event_id: event.id,
|
||||
description: `پرداخت رویداد: ${event.title}`,
|
||||
discount_code: (coupon ?? "").trim() || null,
|
||||
idempotency_key: checkoutIdempotencyKeyRef.current ??= crypto.randomUUID(),
|
||||
});
|
||||
|
||||
if (!result?.start_pay_url || Number(result.amount) === 0) {
|
||||
if (Number(result?.amount ?? 0) === 0) {
|
||||
window.sessionStorage.setItem(
|
||||
"payment:last",
|
||||
buildPaymentSnapshot(event, eventThumb, {
|
||||
@@ -200,6 +206,20 @@ export default function EventDetail({ initialEvent = null }: EventDetailProps) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.status === "failed" || result.status === "canceled") {
|
||||
checkoutIdempotencyKeyRef.current = null;
|
||||
setOpen(false);
|
||||
navigate(`/payments/result?status=${result.status}&event_id=${event.id}&payment_id=${result.payment_id ?? ""}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!result.start_pay_url) {
|
||||
setOpen(false);
|
||||
const resultStatus = result.status === "paid" ? "success" : "pending";
|
||||
navigate(`/payments/result?status=${resultStatus}&event_id=${event.id}&payment_id=${result.payment_id ?? ""}`);
|
||||
return;
|
||||
}
|
||||
|
||||
window.sessionStorage.setItem(
|
||||
"payment:last",
|
||||
buildPaymentSnapshot(event, eventThumb, {
|
||||
@@ -223,6 +243,7 @@ export default function EventDetail({ initialEvent = null }: EventDetailProps) {
|
||||
});
|
||||
} finally {
|
||||
setSubmitting(false);
|
||||
checkoutInProgressRef.current = false;
|
||||
setOpen(false);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user