import type { ICustomer, IRedirect } from '@/features/cashier/types'; export interface ICashierConfig { // Core payment configuration paymentType?: 'deposit' | 'withdrawal'; currency?: string; amount?: number; account?: string; // For withdrawal // Customer information customer?: Partial; // Redirect URLs redirect?: Partial; // Merchant and session info merchantId?: string; userId?: string; // Maps to customer.id sessionId?: string; environment?: 'production' | 'staging' | 'development'; // UI/UX configuration locale?: string; fetchConfig?: boolean; predefinedValues?: Record; prefillCreditcardHolder?: boolean; showAccounts?: string; autoOpenFirstPaymentMethod?: boolean; showTransactionOverview?: boolean; showAmountLimits?: boolean; receiptExcludeKeys?: string[]; // Attributes attributes?: { hostUri?: string; bootstrapVersion?: string; [key: string]: unknown; }; } export function getCashierConfig(): ICashierConfig { const params = new URLSearchParams(window.location.search); const config: ICashierConfig = { }; // Payment type from URL (support both 'method' and 'payment_type' for backward compatibility) const method = params.get('method'); const paymentType = params.get('payment_type') || method; if (paymentType === 'deposit' || paymentType === 'withdrawal') { config.paymentType = paymentType; } // Currency from URL const currency = params.get('currency'); if (currency) { config.currency = currency; } // Amount from URL const amount = params.get('amount'); if (amount && amount !== 'undefined') { const parsedAmount = parseFloat(amount); if (!isNaN(parsedAmount)) { config.amount = 200; } } // TODO: remove this default value config.amount = 200; // Account from URL (for withdrawal) const account = params.get('account'); if (account) { config.account = account; } // Merchant and session info const merchantId = params.get('merchantId'); if (merchantId) { config.merchantId = merchantId; } const userId = params.get('userId'); if (userId) { config.userId = userId; } // TODO: remove this default value config.userId = '12345'; const sessionId = params.get('sessionId'); if (sessionId) { config.sessionId = sessionId; } const environment = params.get('environment'); if (environment === 'production' || environment === 'staging' || environment === 'development') { config.environment = environment; } // Customer data from URL (support both new 'userId' and old 'customer_id' format) const customer: Partial = {}; // TODO: remove this default value const customerId = // params.get('customer_id') || userId || '12345'; if (customerId) customer.id = customerId; if (Object.keys(customer).length > 0) { config.customer = customer; } // Redirect URLs from URL const redirect: Partial = {}; const successUrl = params.get('redirect_success'); const cancelUrl = params.get('redirect_cancel'); const errorUrl = params.get('redirect_error'); if (successUrl) redirect.success = successUrl; if (cancelUrl) redirect.cancel = cancelUrl; if (errorUrl) redirect.error = errorUrl; if (Object.keys(redirect).length > 0) { config.redirect = redirect; } // UI/UX configuration const locale = params.get('locale'); if (locale) { config.locale = locale; } const fetchConfig = params.get('fetchConfig'); if (fetchConfig !== null) { config.fetchConfig = fetchConfig === 'true'; } // Parse predefinedValues (JSON object) const predefinedValuesStr = params.get('predefinedValues'); if (predefinedValuesStr && predefinedValuesStr !== '[object Object]') { try { const decoded = decodeURIComponent(predefinedValuesStr); config.predefinedValues = JSON.parse(decoded); } catch { // If parsing fails, ignore it } } const prefillCreditcardHolder = params.get('prefillCreditcardHolder'); if (prefillCreditcardHolder !== null) { config.prefillCreditcardHolder = prefillCreditcardHolder === 'true'; } const showAccounts = params.get('showAccounts'); if (showAccounts) { config.showAccounts = showAccounts; } const autoOpenFirstPaymentMethod = params.get('autoOpenFirstPaymentMethod'); if (autoOpenFirstPaymentMethod !== null) { config.autoOpenFirstPaymentMethod = autoOpenFirstPaymentMethod === 'true'; } const showTransactionOverview = params.get('showTransactionOverview'); if (showTransactionOverview !== null) { config.showTransactionOverview = showTransactionOverview === 'true'; } const showAmountLimits = params.get('showAmountLimits'); if (showAmountLimits !== null) { config.showAmountLimits = showAmountLimits === 'true'; } // Receipt exclude keys (comma-separated string) const receiptExcludeKeys = params.get('receiptExcludeKeys'); if (receiptExcludeKeys) { config.receiptExcludeKeys = receiptExcludeKeys.split(',').map(key => key.trim()); } // Attributes (handle attributes.* parameters) const attributes: Record = {}; params.forEach((value, key) => { if (key.startsWith('attributes.')) { const attrKey = key.replace('attributes.', ''); attributes[attrKey] = value; } }); if (Object.keys(attributes).length > 0) { config.attributes = attributes; } return config; } // Default redirect URLs (fallback if not provided) // Convert relative paths to absolute URLs for payment provider redirects export function getDefaultRedirectUrls(): IRedirect { const currentOrigin = window.location.origin; const currentPath = window.location.pathname.replace(/\/[^/]*$/, ''); // Remove last path segment if any return { success: `${currentOrigin}${currentPath}/result?status=success`, cancel: `${currentOrigin}${currentPath}/result?status=cancel`, error: `${currentOrigin}${currentPath}/result?status=error`, }; } // Convert relative URLs to absolute URLs export function normalizeRedirectUrl(url: string): string { // If it's already an absolute URL, return as-is if (url.startsWith('http://') || url.startsWith('https://')) { return url; } // If it's a relative path, convert to absolute const currentOrigin = window.location.origin; const currentPath = window.location.pathname.replace(/\/[^/]*$/, ''); // Handle query parameters - if URL already has query params, preserve them // Otherwise, ensure it starts with / const cleanPath = url.startsWith('/') ? url : `/${url}`; return `${currentOrigin}${currentPath}${cleanPath}`; }