Add ZarinPal sandbox payments for buying coins (config-driven merchant)
- ZarinpalService (request/verify) + /api/coins/pay/request (JWT) and /api/coins/pay/callback (verify → credit via ProfileService.BuyCoins → redirect back with ?pay=success); merchant id from config (sandbox default) - Client buyCoins (live) returns the StartPay redirect URL; BuyCoinsScreen redirects; page.tsx handles the ?pay return (notify + refresh) - Verified: sandbox request returns a real StartPay URL - Documented Cafe Bazaar (Poolakey) / Myket IAB as the required store payment path Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -47,6 +47,28 @@ export default function Page() {
|
||||
|
||||
useEffect(() => {
|
||||
init();
|
||||
|
||||
// ZarinPal payment return (?pay=success&coins= / ?pay=failed)
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const pay = params.get("pay");
|
||||
if (pay) {
|
||||
if (pay === "success") {
|
||||
const coins = params.get("coins");
|
||||
pushNotification({
|
||||
kind: "system",
|
||||
titleFa: "پرداخت موفق",
|
||||
titleEn: "Payment successful",
|
||||
bodyFa: coins ? `${coins} سکه به حساب شما اضافه شد` : undefined,
|
||||
bodyEn: coins ? `${coins} coins added` : undefined,
|
||||
icon: "💰",
|
||||
});
|
||||
useSessionStore.getState().refreshProfile();
|
||||
} else {
|
||||
pushNotification({ kind: "system", titleFa: "پرداخت ناموفق بود", titleEn: "Payment failed", icon: "⚠️" });
|
||||
}
|
||||
window.history.replaceState({}, "", window.location.pathname);
|
||||
}
|
||||
|
||||
useUIStore.getState().initHistory();
|
||||
useNotifStore.getState().init();
|
||||
// surface a daily-reward notification if it's available
|
||||
|
||||
Reference in New Issue
Block a user