diff --git a/modules/rcart/components/folk-payment-page.ts b/modules/rcart/components/folk-payment-page.ts
index 6fba6ea..2ffc4ff 100644
--- a/modules/rcart/components/folk-payment-page.ts
+++ b/modules/rcart/components/folk-payment-page.ts
@@ -137,14 +137,15 @@ class FolkPaymentPage extends HTMLElement {
// ── Card tab: Transak ──
- private async startTransak() {
+ private async startCardPayment() {
if (!this.cardEmail) return;
this.cardLoading = true;
this.render();
try {
const effectiveAmount = this.getEffectiveAmount();
- const res = await fetch(`${this.getApiBase()}/api/payments/${this.paymentId}/transak-session`, {
+ // Use the unified card-session endpoint (picks MoonPay or Transak server-side)
+ const res = await fetch(`${this.getApiBase()}/api/payments/${this.paymentId}/card-session`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: this.cardEmail, ...(effectiveAmount ? { amount: effectiveAmount } : {}) }),
@@ -152,16 +153,17 @@ class FolkPaymentPage extends HTMLElement {
const data = await res.json();
if (!res.ok) throw new Error(data.error || 'Failed to create session');
- this.transakEnv = data.env || 'PRODUCTION';
this.transakUrl = data.widgetUrl;
+ this.transakEnv = data.env || 'sandbox';
+ const provider = data.provider || 'transak';
- // Listen for Transak postMessage events
- window.addEventListener('message', this.handleTransakMessage);
+ // Listen for postMessage events from both MoonPay and Transak
+ window.addEventListener('message', this.handlePaymentMessage);
- // Transak blocks iframes (X-Frame-Options: sameorigin) — always use popup
+ // Open in popup (both providers block iframes)
this.transakPopup = window.open(
data.widgetUrl,
- 'transak-payment',
+ 'card-payment',
'width=450,height=700,scrollbars=yes,resizable=yes',
);
// Poll for popup close (user cancelled)
@@ -178,12 +180,18 @@ class FolkPaymentPage extends HTMLElement {
this.render();
}
- private handleTransakMessage = (e: MessageEvent) => {
- if (!e.data?.event_id) return;
- if (e.data.event_id === 'TRANSAK_ORDER_SUCCESSFUL' || e.data.event_id === 'TRANSAK_ORDER_COMPLETED') {
+ private handlePaymentMessage = (e: MessageEvent) => {
+ // Transak events
+ if (e.data?.event_id === 'TRANSAK_ORDER_SUCCESSFUL' || e.data?.event_id === 'TRANSAK_ORDER_COMPLETED') {
const orderId = e.data.data?.id || e.data.data?.orderId;
this.updatePaymentStatus('paid', 'transak', null, orderId);
- window.removeEventListener('message', this.handleTransakMessage);
+ window.removeEventListener('message', this.handlePaymentMessage);
+ }
+ // MoonPay events
+ if (e.data?.type === 'moonpay_onTransactionCompleted' || e.data?.type === 'MOONPAY_TRANSACTION_COMPLETED') {
+ const txId = e.data.data?.id || e.data.transactionId;
+ this.updatePaymentStatus('paid', 'moonpay', null, txId);
+ window.removeEventListener('message', this.handlePaymentMessage);
}
};
@@ -574,7 +582,7 @@ class FolkPaymentPage extends HTMLElement {
`;
}
@@ -585,7 +593,7 @@ class FolkPaymentPage extends HTMLElement {
-