@burdenoff/microfe-billing 2026.912.1 → 2026.912.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/billing/BillingAdminRoutes.js +83 -70
- package/dist/billing/BillingAdminRoutes.js.map +1 -1
- package/dist/billing/modules/billing/hooks/index.js +1 -0
- package/dist/billing/modules/billing/hooks/useOrderCallbacks.js +41 -0
- package/dist/billing/modules/billing/hooks/useOrderCallbacks.js.map +1 -0
- package/dist/billing/modules/billing/index.js +3 -1
- package/dist/billing/modules/billing/pages/OrderCallbackLogsPage.js +427 -0
- package/dist/billing/modules/billing/pages/OrderCallbackLogsPage.js.map +1 -0
- package/dist/billing/modules/billing/pages/index.js +1 -0
- package/dist/billing/modules/checkout/components/UnifiedPaymentMethodSelector.js +1 -1
- package/dist/billing/modules/checkout/components/UnifiedPaymentMethodSelector.js.map +1 -1
- package/dist/billing/modules/checkout/pages/CheckoutPage.js +30 -31
- package/dist/billing/modules/checkout/pages/CheckoutPage.js.map +1 -1
- package/dist/generated/global-operations.js +335 -272
- package/dist/generated/global-operations.js.map +1 -1
- package/dist/generated/global-types.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UnifiedPaymentMethodSelector.js","names":[],"sources":["../../../../../src/billing/modules/checkout/components/UnifiedPaymentMethodSelector.tsx"],"sourcesContent":["/**\n * Unified Payment Method Selector\n * Combines payment providers and saved payment methods into one clear interface\n */\n\nimport { type FC, useState } from 'react';\nimport { Coins, CreditCard, Wallet, ChevronDown } from 'lucide-react';\nimport type { SavedPaymentMethod } from '../types';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\ninterface UnifiedPaymentMethodSelectorProps {\n // Saved cards\n savedPaymentMethods: SavedPaymentMethod[];\n selectedPaymentMethodId: string | null;\n onSelectSavedCard: (id: string | null) => void;\n\n // Provider selection (for new cards)\n selectedProvider: 'CREDITS' | 'STRIPE' | 'RAZORPAY' | 'AUTO';\n onSelectProvider: (provider: 'CREDITS' | 'STRIPE' | 'RAZORPAY') => void;\n\n // Provider availability\n stripeEnabled: boolean;\n razorpayEnabled: boolean;\n canPayWithCredits: boolean;\n availableCredits: number;\n totalAmount: number;\n billingCountry?: string;\n\n // Save card option\n saveCard: boolean;\n onSaveCardChange: (save: boolean) => void;\n\n // Auto-renewal (when enabled, card must be saved - checkbox hidden)\n autoRenewEnabled?: boolean;\n\n isLoading?: boolean;\n}\n\nconst getCardIcon = (type: string) => {\n if (type === 'WALLET') return <Wallet className=\"size-4\" />;\n return <CreditCard className=\"size-4\" />;\n};\n\nconst getCardDisplay = (pm: SavedPaymentMethod): string => {\n const type =\n pm.type === 'CREDIT_CARD' ? 'Credit Card' : pm.type === 'DEBIT_CARD' ? 'Debit Card' : pm.type;\n const last4 = pm.last4 ? ` •••• ${pm.last4}` : '';\n const brand = pm.brand ? ` (${pm.brand})` : '';\n return `${type}${last4}${brand}`;\n};\n\nexport const UnifiedPaymentMethodSelector: FC<UnifiedPaymentMethodSelectorProps> = ({\n savedPaymentMethods,\n selectedPaymentMethodId,\n onSelectSavedCard,\n selectedProvider,\n onSelectProvider,\n stripeEnabled,\n razorpayEnabled,\n canPayWithCredits,\n availableCredits,\n totalAmount,\n billingCountry,\n saveCard,\n onSaveCardChange,\n autoRenewEnabled = false,\n isLoading = false,\n}) => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n const [showAllSavedCards, setShowAllSavedCards] = useState(false);\n const hasEnoughCredits = availableCredits >= totalAmount;\n const isIndia = billingCountry === 'IN';\n\n // Get default card or first card for collapsible view\n const defaultSavedCard = savedPaymentMethods.find((pm) => pm.isDefault) || savedPaymentMethods[0];\n const otherSavedCards = savedPaymentMethods.filter((pm) => pm.id !== defaultSavedCard?.id);\n\n const handleSelect = (type: 'saved' | 'new', value: string) => {\n if (type === 'saved') {\n // When selecting saved card, set it and auto-determine provider\n const selectedCard = savedPaymentMethods.find((pm) => pm.id === value);\n if (selectedCard) {\n onSelectSavedCard(value);\n // Auto-set provider based on card type\n if (selectedCard.razorpayPaymentMethodId) {\n onSelectProvider('RAZORPAY');\n } else if (selectedCard.stripePaymentMethodId) {\n onSelectProvider('STRIPE');\n }\n }\n } else {\n // When selecting new card payment, clear saved card selection\n onSelectSavedCard(null);\n onSelectProvider(value as 'CREDITS' | 'STRIPE' | 'RAZORPAY');\n }\n };\n\n const isSelected = (type: 'saved' | 'new', value: string): boolean => {\n if (type === 'saved') {\n return selectedPaymentMethodId === value;\n } else {\n return !selectedPaymentMethodId && selectedProvider === value;\n }\n };\n\n return (\n <div className=\"space-y-3\">\n <h3 className=\"text-sm font-medium text-text-primary\">\n {tr('billing.checkout.paymentMethod', 'Payment Method')}\n </h3>\n\n {isLoading ? (\n <div className=\"space-y-2\">\n <div className=\"h-16 rounded-lg border border-border-subtle bg-bg-sunken animate-pulse\" />\n <div className=\"h-16 rounded-lg border border-border-subtle bg-bg-sunken animate-pulse\" />\n </div>\n ) : (\n <div className=\"space-y-2\">\n {/* Credits Option */}\n {canPayWithCredits && (\n <button\n type=\"button\"\n onClick={() => handleSelect('new', 'CREDITS')}\n disabled={!hasEnoughCredits}\n className={`\n w-full flex items-center gap-3 p-4 rounded-lg border transition-all text-left\n ${\n isSelected('new', 'CREDITS')\n ? 'border-border-strong bg-[var(--color-accent-soft)] ring-1 ring-[var(--color-focus-ring)]'\n : 'border-border-subtle hover:border-border-strong hover:bg-bg-sunken'\n }\n ${!hasEnoughCredits && 'opacity-50 cursor-not-allowed'}\n `}\n >\n <Coins\n className={`size-5 shrink-0 ${isSelected('new', 'CREDITS') ? 'text-text-link' : 'text-text-secondary'}`}\n />\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm font-medium text-text-primary\">Pay with Credits</div>\n <div className=\"text-xs text-text-secondary\">\n {hasEnoughCredits\n ? `Available: ${availableCredits.toLocaleString()} credits`\n : `Insufficient credits (need ${totalAmount.toLocaleString()})`}\n </div>\n </div>\n {hasEnoughCredits && (\n <span className=\"text-xs px-2 py-0.5 rounded bg-success/10 text-success\">\n Instant\n </span>\n )}\n </button>\n )}\n\n {/* Saved Cards Section */}\n {savedPaymentMethods.length > 0 && (\n <>\n <div className=\"text-xs font-medium text-text-secondary uppercase tracking-wide pt-2\">\n Saved Cards\n </div>\n\n {/* Default/First Card - Always Shown */}\n {defaultSavedCard && (\n <button\n type=\"button\"\n onClick={() => handleSelect('saved', defaultSavedCard.id)}\n className={`\n w-full flex items-center gap-3 p-4 rounded-lg border transition-all text-left\n ${\n isSelected('saved', defaultSavedCard.id)\n ? 'border-border-strong bg-[var(--color-accent-soft)] ring-1 ring-[var(--color-focus-ring)]'\n : 'border-border-subtle hover:border-border-strong hover:bg-bg-sunken'\n }\n `}\n >\n {getCardIcon(defaultSavedCard.type)}\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm font-medium text-text-primary\">\n {getCardDisplay(defaultSavedCard)}\n </div>\n {defaultSavedCard.expiryMonth && defaultSavedCard.expiryYear && (\n <div className=\"text-xs text-text-secondary\">\n Expires {defaultSavedCard.expiryMonth.toString().padStart(2, '0')}/\n {defaultSavedCard.expiryYear}\n </div>\n )}\n </div>\n {defaultSavedCard.isDefault && (\n <span className=\"text-xs px-2 py-0.5 rounded bg-[var(--color-accent-soft)] text-text-link\">\n Default\n </span>\n )}\n </button>\n )}\n\n {/* Other Cards - Collapsible */}\n {otherSavedCards.length > 0 && (\n <>\n {showAllSavedCards ? (\n <>\n {otherSavedCards.map((pm) => (\n <button\n key={pm.id}\n type=\"button\"\n onClick={() => handleSelect('saved', pm.id)}\n className={`\n w-full flex items-center gap-3 p-4 rounded-lg border transition-all text-left\n ${\n isSelected('saved', pm.id)\n ? 'border-border-strong bg-[var(--color-accent-soft)] ring-1 ring-[var(--color-focus-ring)]'\n : 'border-border-subtle hover:border-border-strong hover:bg-bg-sunken'\n }\n `}\n >\n {getCardIcon(pm.type)}\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm font-medium text-text-primary\">\n {getCardDisplay(pm)}\n </div>\n {pm.expiryMonth && pm.expiryYear && (\n <div className=\"text-xs text-text-secondary\">\n Expires {pm.expiryMonth.toString().padStart(2, '0')}/{pm.expiryYear}\n </div>\n )}\n </div>\n </button>\n ))}\n <button\n type=\"button\"\n onClick={() => setShowAllSavedCards(false)}\n className=\"text-xs text-text-link hover:underline flex items-center gap-1 pl-1\"\n >\n <ChevronDown className=\"size-3 rotate-180\" />\n Hide other cards\n </button>\n </>\n ) : (\n <button\n type=\"button\"\n onClick={() => setShowAllSavedCards(true)}\n className=\"text-xs text-text-link hover:underline flex items-center gap-1 pl-1\"\n >\n <ChevronDown className=\"size-3\" />\n Show {otherSavedCards.length} more card\n {otherSavedCards.length > 1 ? 's' : ''}\n </button>\n )}\n </>\n )}\n </>\n )}\n\n {/* New Card Options */}\n <div className=\"text-xs font-medium text-text-secondary uppercase tracking-wide pt-2\">\n {savedPaymentMethods.length > 0\n ? 'Or use new card'\n : canPayWithCredits\n ? 'Or pay with card'\n : 'Pay with Card'}\n </div>\n\n {/* Razorpay (India) */}\n {razorpayEnabled && isIndia && (\n <button\n type=\"button\"\n onClick={() => handleSelect('new', 'RAZORPAY')}\n className={`\n w-full flex items-center gap-3 p-4 rounded-lg border transition-all text-left\n ${\n isSelected('new', 'RAZORPAY')\n ? 'border-border-strong bg-[var(--color-accent-soft)] ring-1 ring-[var(--color-focus-ring)]'\n : 'border-border-subtle hover:border-border-strong hover:bg-bg-sunken'\n }\n `}\n >\n <CreditCard\n className={`size-5 shrink-0 ${isSelected('new', 'RAZORPAY') ? 'text-text-link' : 'text-text-secondary'}`}\n />\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm font-medium text-text-primary\">\n UPI / Cards / Netbanking\n </div>\n <div className=\"text-xs text-text-secondary\">Razorpay</div>\n </div>\n <span className=\"text-xs px-2 py-0.5 rounded bg-accent-blue-subtle text-accent-blue\">\n Recommended\n </span>\n </button>\n )}\n\n {/* Stripe (International) */}\n {stripeEnabled && (\n <button\n type=\"button\"\n onClick={() => handleSelect('new', 'STRIPE')}\n className={`\n w-full flex items-center gap-3 p-4 rounded-lg border transition-all text-left\n ${\n isSelected('new', 'STRIPE')\n ? 'border-border-strong bg-[var(--color-accent-soft)] ring-1 ring-[var(--color-focus-ring)]'\n : 'border-border-subtle hover:border-border-strong hover:bg-bg-sunken'\n }\n `}\n >\n <CreditCard\n className={`size-5 shrink-0 ${isSelected('new', 'STRIPE') ? 'text-text-link' : 'text-text-secondary'}`}\n />\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm font-medium text-text-primary\">Credit / Debit Cards</div>\n <div className=\"text-xs text-text-secondary\">Stripe - Multi-currency</div>\n </div>\n {!isIndia && (\n <span className=\"text-xs px-2 py-0.5 rounded bg-accent-blue-subtle text-accent-blue\">\n Recommended\n </span>\n )}\n </button>\n )}\n\n {/* Save Card Checkbox - Only show when using new card (not saved card, not credits) */}\n {!selectedPaymentMethodId &&\n selectedProvider !== 'CREDITS' &&\n selectedProvider !== 'AUTO' &&\n !autoRenewEnabled && (\n <div className=\"mt-4 pt-4 border-t border-border-subtle\">\n <label className=\"flex items-start gap-3 cursor-pointer group\">\n <input\n type=\"checkbox\"\n checked={saveCard}\n onChange={(e) => onSaveCardChange(e.target.checked)}\n className=\"mt-0.5 size-4 rounded border-border-subtle text-text-link focus:ring-[var(--color-focus-ring)] focus:ring-offset-0\"\n />\n <div className=\"flex-1\">\n <div className=\"text-sm font-medium text-text-primary group-hover:text-text-link transition-colors\">\n Save card for future use\n </div>\n <div className=\"text-xs text-text-secondary mt-0.5\">\n Securely save this payment method for faster checkout next time\n </div>\n </div>\n </label>\n </div>\n )}\n\n {/* Auto-renewal notice - Show when auto-renewal is enabled */}\n {!selectedPaymentMethodId &&\n selectedProvider !== 'CREDITS' &&\n selectedProvider !== 'AUTO' &&\n autoRenewEnabled && (\n <div className=\"mt-4 pt-4 border-t border-border-subtle\">\n <div className=\"flex items-start gap-2 text-xs text-text-secondary bg-bg-sunken p-3 rounded-lg\">\n <svg\n className=\"size-4 mt-0.5 flex-shrink-0\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n <div>Your payment method will be securely saved for auto-renewal</div>\n </div>\n </div>\n )}\n </div>\n )}\n </div>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"UnifiedPaymentMethodSelector.js","names":[],"sources":["../../../../../src/billing/modules/checkout/components/UnifiedPaymentMethodSelector.tsx"],"sourcesContent":["/**\n * Unified Payment Method Selector\n * Combines payment providers and saved payment methods into one clear interface\n */\n\nimport { type FC, useState } from 'react';\nimport { Coins, CreditCard, Wallet, ChevronDown } from 'lucide-react';\nimport type { SavedPaymentMethod } from '../types';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\ninterface UnifiedPaymentMethodSelectorProps {\n // Saved cards\n savedPaymentMethods: SavedPaymentMethod[];\n selectedPaymentMethodId: string | null;\n onSelectSavedCard: (id: string | null) => void;\n\n // Provider selection (for new cards)\n selectedProvider: 'CREDITS' | 'STRIPE' | 'RAZORPAY' | 'AUTO';\n onSelectProvider: (provider: 'CREDITS' | 'STRIPE' | 'RAZORPAY') => void;\n\n // Provider availability\n stripeEnabled: boolean;\n razorpayEnabled: boolean;\n canPayWithCredits: boolean;\n availableCredits: number;\n /** Credits (not a currency amount) needed to pay for this purchase —\n * comparable directly to availableCredits. Passing a raw USD/local-\n * currency total here compares two different units and silently lets\n * a purchase proceed with insufficient credits (reproduced live,\n * BOFF-7192: 800 available credits read as \"enough\" for a 2,474-credit\n * item because the prop held $24.74, not 2,474). */\n creditsRequired: number;\n billingCountry?: string;\n\n // Save card option\n saveCard: boolean;\n onSaveCardChange: (save: boolean) => void;\n\n // Auto-renewal (when enabled, card must be saved - checkbox hidden)\n autoRenewEnabled?: boolean;\n\n isLoading?: boolean;\n}\n\nconst getCardIcon = (type: string) => {\n if (type === 'WALLET') return <Wallet className=\"size-4\" />;\n return <CreditCard className=\"size-4\" />;\n};\n\nconst getCardDisplay = (pm: SavedPaymentMethod): string => {\n const type =\n pm.type === 'CREDIT_CARD' ? 'Credit Card' : pm.type === 'DEBIT_CARD' ? 'Debit Card' : pm.type;\n const last4 = pm.last4 ? ` •••• ${pm.last4}` : '';\n const brand = pm.brand ? ` (${pm.brand})` : '';\n return `${type}${last4}${brand}`;\n};\n\nexport const UnifiedPaymentMethodSelector: FC<UnifiedPaymentMethodSelectorProps> = ({\n savedPaymentMethods,\n selectedPaymentMethodId,\n onSelectSavedCard,\n selectedProvider,\n onSelectProvider,\n stripeEnabled,\n razorpayEnabled,\n canPayWithCredits,\n availableCredits,\n creditsRequired,\n billingCountry,\n saveCard,\n onSaveCardChange,\n autoRenewEnabled = false,\n isLoading = false,\n}) => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n const [showAllSavedCards, setShowAllSavedCards] = useState(false);\n const hasEnoughCredits = availableCredits >= creditsRequired;\n const isIndia = billingCountry === 'IN';\n\n // Get default card or first card for collapsible view\n const defaultSavedCard = savedPaymentMethods.find((pm) => pm.isDefault) || savedPaymentMethods[0];\n const otherSavedCards = savedPaymentMethods.filter((pm) => pm.id !== defaultSavedCard?.id);\n\n const handleSelect = (type: 'saved' | 'new', value: string) => {\n if (type === 'saved') {\n // When selecting saved card, set it and auto-determine provider\n const selectedCard = savedPaymentMethods.find((pm) => pm.id === value);\n if (selectedCard) {\n onSelectSavedCard(value);\n // Auto-set provider based on card type\n if (selectedCard.razorpayPaymentMethodId) {\n onSelectProvider('RAZORPAY');\n } else if (selectedCard.stripePaymentMethodId) {\n onSelectProvider('STRIPE');\n }\n }\n } else {\n // When selecting new card payment, clear saved card selection\n onSelectSavedCard(null);\n onSelectProvider(value as 'CREDITS' | 'STRIPE' | 'RAZORPAY');\n }\n };\n\n const isSelected = (type: 'saved' | 'new', value: string): boolean => {\n if (type === 'saved') {\n return selectedPaymentMethodId === value;\n } else {\n return !selectedPaymentMethodId && selectedProvider === value;\n }\n };\n\n return (\n <div className=\"space-y-3\">\n <h3 className=\"text-sm font-medium text-text-primary\">\n {tr('billing.checkout.paymentMethod', 'Payment Method')}\n </h3>\n\n {isLoading ? (\n <div className=\"space-y-2\">\n <div className=\"h-16 rounded-lg border border-border-subtle bg-bg-sunken animate-pulse\" />\n <div className=\"h-16 rounded-lg border border-border-subtle bg-bg-sunken animate-pulse\" />\n </div>\n ) : (\n <div className=\"space-y-2\">\n {/* Credits Option */}\n {canPayWithCredits && (\n <button\n type=\"button\"\n onClick={() => handleSelect('new', 'CREDITS')}\n disabled={!hasEnoughCredits}\n className={`\n w-full flex items-center gap-3 p-4 rounded-lg border transition-all text-left\n ${\n isSelected('new', 'CREDITS')\n ? 'border-border-strong bg-[var(--color-accent-soft)] ring-1 ring-[var(--color-focus-ring)]'\n : 'border-border-subtle hover:border-border-strong hover:bg-bg-sunken'\n }\n ${!hasEnoughCredits && 'opacity-50 cursor-not-allowed'}\n `}\n >\n <Coins\n className={`size-5 shrink-0 ${isSelected('new', 'CREDITS') ? 'text-text-link' : 'text-text-secondary'}`}\n />\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm font-medium text-text-primary\">Pay with Credits</div>\n <div className=\"text-xs text-text-secondary\">\n {hasEnoughCredits\n ? `Available: ${availableCredits.toLocaleString()} credits`\n : `Insufficient credits (need ${creditsRequired.toLocaleString()})`}\n </div>\n </div>\n {hasEnoughCredits && (\n <span className=\"text-xs px-2 py-0.5 rounded bg-success/10 text-success\">\n Instant\n </span>\n )}\n </button>\n )}\n\n {/* Saved Cards Section */}\n {savedPaymentMethods.length > 0 && (\n <>\n <div className=\"text-xs font-medium text-text-secondary uppercase tracking-wide pt-2\">\n Saved Cards\n </div>\n\n {/* Default/First Card - Always Shown */}\n {defaultSavedCard && (\n <button\n type=\"button\"\n onClick={() => handleSelect('saved', defaultSavedCard.id)}\n className={`\n w-full flex items-center gap-3 p-4 rounded-lg border transition-all text-left\n ${\n isSelected('saved', defaultSavedCard.id)\n ? 'border-border-strong bg-[var(--color-accent-soft)] ring-1 ring-[var(--color-focus-ring)]'\n : 'border-border-subtle hover:border-border-strong hover:bg-bg-sunken'\n }\n `}\n >\n {getCardIcon(defaultSavedCard.type)}\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm font-medium text-text-primary\">\n {getCardDisplay(defaultSavedCard)}\n </div>\n {defaultSavedCard.expiryMonth && defaultSavedCard.expiryYear && (\n <div className=\"text-xs text-text-secondary\">\n Expires {defaultSavedCard.expiryMonth.toString().padStart(2, '0')}/\n {defaultSavedCard.expiryYear}\n </div>\n )}\n </div>\n {defaultSavedCard.isDefault && (\n <span className=\"text-xs px-2 py-0.5 rounded bg-[var(--color-accent-soft)] text-text-link\">\n Default\n </span>\n )}\n </button>\n )}\n\n {/* Other Cards - Collapsible */}\n {otherSavedCards.length > 0 && (\n <>\n {showAllSavedCards ? (\n <>\n {otherSavedCards.map((pm) => (\n <button\n key={pm.id}\n type=\"button\"\n onClick={() => handleSelect('saved', pm.id)}\n className={`\n w-full flex items-center gap-3 p-4 rounded-lg border transition-all text-left\n ${\n isSelected('saved', pm.id)\n ? 'border-border-strong bg-[var(--color-accent-soft)] ring-1 ring-[var(--color-focus-ring)]'\n : 'border-border-subtle hover:border-border-strong hover:bg-bg-sunken'\n }\n `}\n >\n {getCardIcon(pm.type)}\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm font-medium text-text-primary\">\n {getCardDisplay(pm)}\n </div>\n {pm.expiryMonth && pm.expiryYear && (\n <div className=\"text-xs text-text-secondary\">\n Expires {pm.expiryMonth.toString().padStart(2, '0')}/{pm.expiryYear}\n </div>\n )}\n </div>\n </button>\n ))}\n <button\n type=\"button\"\n onClick={() => setShowAllSavedCards(false)}\n className=\"text-xs text-text-link hover:underline flex items-center gap-1 pl-1\"\n >\n <ChevronDown className=\"size-3 rotate-180\" />\n Hide other cards\n </button>\n </>\n ) : (\n <button\n type=\"button\"\n onClick={() => setShowAllSavedCards(true)}\n className=\"text-xs text-text-link hover:underline flex items-center gap-1 pl-1\"\n >\n <ChevronDown className=\"size-3\" />\n Show {otherSavedCards.length} more card\n {otherSavedCards.length > 1 ? 's' : ''}\n </button>\n )}\n </>\n )}\n </>\n )}\n\n {/* New Card Options */}\n <div className=\"text-xs font-medium text-text-secondary uppercase tracking-wide pt-2\">\n {savedPaymentMethods.length > 0\n ? 'Or use new card'\n : canPayWithCredits\n ? 'Or pay with card'\n : 'Pay with Card'}\n </div>\n\n {/* Razorpay (India) */}\n {razorpayEnabled && isIndia && (\n <button\n type=\"button\"\n onClick={() => handleSelect('new', 'RAZORPAY')}\n className={`\n w-full flex items-center gap-3 p-4 rounded-lg border transition-all text-left\n ${\n isSelected('new', 'RAZORPAY')\n ? 'border-border-strong bg-[var(--color-accent-soft)] ring-1 ring-[var(--color-focus-ring)]'\n : 'border-border-subtle hover:border-border-strong hover:bg-bg-sunken'\n }\n `}\n >\n <CreditCard\n className={`size-5 shrink-0 ${isSelected('new', 'RAZORPAY') ? 'text-text-link' : 'text-text-secondary'}`}\n />\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm font-medium text-text-primary\">\n UPI / Cards / Netbanking\n </div>\n <div className=\"text-xs text-text-secondary\">Razorpay</div>\n </div>\n <span className=\"text-xs px-2 py-0.5 rounded bg-accent-blue-subtle text-accent-blue\">\n Recommended\n </span>\n </button>\n )}\n\n {/* Stripe (International) */}\n {stripeEnabled && (\n <button\n type=\"button\"\n onClick={() => handleSelect('new', 'STRIPE')}\n className={`\n w-full flex items-center gap-3 p-4 rounded-lg border transition-all text-left\n ${\n isSelected('new', 'STRIPE')\n ? 'border-border-strong bg-[var(--color-accent-soft)] ring-1 ring-[var(--color-focus-ring)]'\n : 'border-border-subtle hover:border-border-strong hover:bg-bg-sunken'\n }\n `}\n >\n <CreditCard\n className={`size-5 shrink-0 ${isSelected('new', 'STRIPE') ? 'text-text-link' : 'text-text-secondary'}`}\n />\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm font-medium text-text-primary\">Credit / Debit Cards</div>\n <div className=\"text-xs text-text-secondary\">Stripe - Multi-currency</div>\n </div>\n {!isIndia && (\n <span className=\"text-xs px-2 py-0.5 rounded bg-accent-blue-subtle text-accent-blue\">\n Recommended\n </span>\n )}\n </button>\n )}\n\n {/* Save Card Checkbox - Only show when using new card (not saved card, not credits) */}\n {!selectedPaymentMethodId &&\n selectedProvider !== 'CREDITS' &&\n selectedProvider !== 'AUTO' &&\n !autoRenewEnabled && (\n <div className=\"mt-4 pt-4 border-t border-border-subtle\">\n <label className=\"flex items-start gap-3 cursor-pointer group\">\n <input\n type=\"checkbox\"\n checked={saveCard}\n onChange={(e) => onSaveCardChange(e.target.checked)}\n className=\"mt-0.5 size-4 rounded border-border-subtle text-text-link focus:ring-[var(--color-focus-ring)] focus:ring-offset-0\"\n />\n <div className=\"flex-1\">\n <div className=\"text-sm font-medium text-text-primary group-hover:text-text-link transition-colors\">\n Save card for future use\n </div>\n <div className=\"text-xs text-text-secondary mt-0.5\">\n Securely save this payment method for faster checkout next time\n </div>\n </div>\n </label>\n </div>\n )}\n\n {/* Auto-renewal notice - Show when auto-renewal is enabled */}\n {!selectedPaymentMethodId &&\n selectedProvider !== 'CREDITS' &&\n selectedProvider !== 'AUTO' &&\n autoRenewEnabled && (\n <div className=\"mt-4 pt-4 border-t border-border-subtle\">\n <div className=\"flex items-start gap-2 text-xs text-text-secondary bg-bg-sunken p-3 rounded-lg\">\n <svg\n className=\"size-4 mt-0.5 flex-shrink-0\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n <div>Your payment method will be securely saved for auto-renewal</div>\n </div>\n </div>\n )}\n </div>\n )}\n </div>\n );\n};\n"],"mappings":"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"}
|
|
@@ -200,19 +200,19 @@ var $e = () => {
|
|
|
200
200
|
kt,
|
|
201
201
|
Jt
|
|
202
202
|
]);
|
|
203
|
-
let {
|
|
203
|
+
let { billingAccount: Xt, canPayWithCredits: Zt, hasEnoughCredits: Qt, selectedCurrency: J, selectedPaymentMethodId: $t, selectedProvider: en, setCurrency: Y, setPaymentProvider: X, setSelectedPaymentMethodId: tn } = F;
|
|
204
204
|
l(() => {
|
|
205
|
-
if (!
|
|
206
|
-
let e =
|
|
205
|
+
if (!Xt?.currency || q === "IN") return;
|
|
206
|
+
let e = Xt.currency;
|
|
207
207
|
e !== "INR" && J !== e && Y(e);
|
|
208
208
|
}, [
|
|
209
209
|
q,
|
|
210
|
-
|
|
210
|
+
Xt,
|
|
211
211
|
J,
|
|
212
212
|
Y
|
|
213
213
|
]), l(() => {
|
|
214
214
|
if (!(en !== "AUTO" && en !== null)) {
|
|
215
|
-
if (
|
|
215
|
+
if (Zt && Qt) {
|
|
216
216
|
X("CREDITS"), tn(null);
|
|
217
217
|
return;
|
|
218
218
|
}
|
|
@@ -225,9 +225,8 @@ var $e = () => {
|
|
|
225
225
|
}
|
|
226
226
|
}
|
|
227
227
|
}, [
|
|
228
|
-
|
|
228
|
+
Zt,
|
|
229
229
|
Qt,
|
|
230
|
-
nn,
|
|
231
230
|
G,
|
|
232
231
|
$t,
|
|
233
232
|
en,
|
|
@@ -490,7 +489,7 @@ var $e = () => {
|
|
|
490
489
|
v?.billingAccountId,
|
|
491
490
|
b
|
|
492
491
|
]);
|
|
493
|
-
let
|
|
492
|
+
let nn = !!(v?.upgradeFromSubscriptionId || v?.downgradeFromSubscriptionId);
|
|
494
493
|
l(() => {
|
|
495
494
|
w && C && S.length === 0 && !Z && _("/addons", { replace: !0 });
|
|
496
495
|
}, [
|
|
@@ -500,11 +499,11 @@ var $e = () => {
|
|
|
500
499
|
Z,
|
|
501
500
|
_
|
|
502
501
|
]);
|
|
503
|
-
let
|
|
502
|
+
let rn = fe({
|
|
504
503
|
billingAccountId: F.billingAccount?.id,
|
|
505
504
|
purchaseType: E,
|
|
506
505
|
productId: D
|
|
507
|
-
}),
|
|
506
|
+
}), an = c(async () => {
|
|
508
507
|
if (!F.billingAccount) return;
|
|
509
508
|
let e = ht.current;
|
|
510
509
|
if (ht.current = !1, !e && !Ee(F.billingAccount)) {
|
|
@@ -589,7 +588,7 @@ var $e = () => {
|
|
|
589
588
|
g,
|
|
590
589
|
Rt,
|
|
591
590
|
Bt
|
|
592
|
-
]),
|
|
591
|
+
]), on = c((e) => {
|
|
593
592
|
y("billing.payment.succeeded", {
|
|
594
593
|
route: "/billing/checkout",
|
|
595
594
|
entityId: A?.paymentId ?? A?.orderId,
|
|
@@ -599,7 +598,7 @@ var $e = () => {
|
|
|
599
598
|
y,
|
|
600
599
|
A?.orderId,
|
|
601
600
|
A?.paymentId
|
|
602
|
-
]),
|
|
601
|
+
]), sn = c((e) => {
|
|
603
602
|
y("billing.payment.failed", {
|
|
604
603
|
route: "/billing/checkout",
|
|
605
604
|
entityId: A?.paymentId ?? A?.orderId,
|
|
@@ -610,7 +609,7 @@ var $e = () => {
|
|
|
610
609
|
y,
|
|
611
610
|
A?.orderId,
|
|
612
611
|
A?.paymentId
|
|
613
|
-
]),
|
|
612
|
+
]), cn = c((e) => {
|
|
614
613
|
F.updateItemQuantity("credits-purchase", e);
|
|
615
614
|
}, [F]);
|
|
616
615
|
if (!rt.canProcessPayment) return /* @__PURE__ */ p(t, { message: "You don't have permission to make purchases." });
|
|
@@ -618,12 +617,12 @@ var $e = () => {
|
|
|
618
617
|
purchaseType: E,
|
|
619
618
|
productId: D,
|
|
620
619
|
billingAccountId: F.billingAccount?.id,
|
|
621
|
-
nativeCheckout:
|
|
620
|
+
nativeCheckout: rn,
|
|
622
621
|
onBack: () => _("dashboard")
|
|
623
622
|
});
|
|
624
|
-
let
|
|
623
|
+
let ln = Nt || Ft && E === "PLAN" || It && E === "ADDON" && !w || w && !C;
|
|
625
624
|
if (w && C && S.length === 0 && !Z) return null;
|
|
626
|
-
let
|
|
625
|
+
let un = () => {
|
|
627
626
|
if (w) {
|
|
628
627
|
let e = F.items.length;
|
|
629
628
|
return `Purchase ${e} Add-on${e === 1 ? "" : "s"}`;
|
|
@@ -634,7 +633,7 @@ var $e = () => {
|
|
|
634
633
|
case "ADDON": return "Purchase Add-on";
|
|
635
634
|
default: return "Checkout";
|
|
636
635
|
}
|
|
637
|
-
},
|
|
636
|
+
}, dn = () => {
|
|
638
637
|
switch (E) {
|
|
639
638
|
case "CREDITS": return /* @__PURE__ */ p(Le, { className: "size-6" });
|
|
640
639
|
case "PLAN": return /* @__PURE__ */ p(Be, { className: "size-6" });
|
|
@@ -642,7 +641,7 @@ var $e = () => {
|
|
|
642
641
|
default: return /* @__PURE__ */ p(Ue, { className: "size-6" });
|
|
643
642
|
}
|
|
644
643
|
};
|
|
645
|
-
if (
|
|
644
|
+
if (ln) return /* @__PURE__ */ p("div", {
|
|
646
645
|
className: "flex items-center justify-center min-h-[400px]",
|
|
647
646
|
children: /* @__PURE__ */ m("div", {
|
|
648
647
|
className: "text-center space-y-4",
|
|
@@ -1034,8 +1033,8 @@ var $e = () => {
|
|
|
1034
1033
|
publishableKey: it || Dt?.stripePublishableKey || "",
|
|
1035
1034
|
amount: Math.round((A.total ?? F.total) * 100),
|
|
1036
1035
|
currency: A.currency || F.selectedCurrency,
|
|
1037
|
-
onSuccess:
|
|
1038
|
-
onError:
|
|
1036
|
+
onSuccess: on,
|
|
1037
|
+
onError: sn,
|
|
1039
1038
|
onCancel: () => k("select"),
|
|
1040
1039
|
isCompletingExistingPayment: !!F.selectedPaymentMethodId
|
|
1041
1040
|
})
|
|
@@ -1067,8 +1066,8 @@ var $e = () => {
|
|
|
1067
1066
|
email: A.prefillEmail,
|
|
1068
1067
|
contact: A.prefillContact
|
|
1069
1068
|
},
|
|
1070
|
-
onSuccess: (e) =>
|
|
1071
|
-
onError:
|
|
1069
|
+
onSuccess: (e) => on(e.razorpay_payment_id),
|
|
1070
|
+
onError: sn,
|
|
1072
1071
|
onCancel: () => k("select")
|
|
1073
1072
|
})]
|
|
1074
1073
|
})
|
|
@@ -1089,10 +1088,10 @@ var $e = () => {
|
|
|
1089
1088
|
className: "flex items-center gap-3 mb-6",
|
|
1090
1089
|
children: [/* @__PURE__ */ p("div", {
|
|
1091
1090
|
className: "p-2 rounded-lg bg-[var(--color-accent-soft)] text-text-link",
|
|
1092
|
-
children:
|
|
1091
|
+
children: dn()
|
|
1093
1092
|
}), /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("h1", {
|
|
1094
1093
|
className: "text-2xl font-bold text-text-primary",
|
|
1095
|
-
children:
|
|
1094
|
+
children: un()
|
|
1096
1095
|
}), /* @__PURE__ */ p("p", {
|
|
1097
1096
|
className: "text-sm text-text-secondary",
|
|
1098
1097
|
children: "Complete your purchase securely"
|
|
@@ -1163,7 +1162,7 @@ var $e = () => {
|
|
|
1163
1162
|
className: "rounded-lg border border-border-subtle bg-bg-surface p-4 sm:p-6",
|
|
1164
1163
|
children: /* @__PURE__ */ p(ye, {
|
|
1165
1164
|
value: F.items[0].quantity,
|
|
1166
|
-
onChange:
|
|
1165
|
+
onChange: cn,
|
|
1167
1166
|
costPerCredit: W,
|
|
1168
1167
|
currency: F.selectedCurrency,
|
|
1169
1168
|
disabled: qt
|
|
@@ -1176,8 +1175,8 @@ var $e = () => {
|
|
|
1176
1175
|
selectedAccountId: F.billingAccount?.id ?? null,
|
|
1177
1176
|
onSelect: F.setBillingAccount,
|
|
1178
1177
|
isLoading: Nt,
|
|
1179
|
-
disabled:
|
|
1180
|
-
disabledMessage:
|
|
1178
|
+
disabled: nn,
|
|
1179
|
+
disabledMessage: nn ? "Billing account is locked for plan changes" : void 0
|
|
1181
1180
|
}), E === "ADDON" && !T && F.billingAccount && /* @__PURE__ */ p(Se, {
|
|
1182
1181
|
subscriptions: V,
|
|
1183
1182
|
selectedSubscriptionId: F.selectedSubscriptionId,
|
|
@@ -1203,7 +1202,7 @@ var $e = () => {
|
|
|
1203
1202
|
razorpayEnabled: kt,
|
|
1204
1203
|
canPayWithCredits: F.canPayWithCredits,
|
|
1205
1204
|
availableCredits: F.availableCredits,
|
|
1206
|
-
|
|
1205
|
+
creditsRequired: F.creditsRequired,
|
|
1207
1206
|
billingCountry: q,
|
|
1208
1207
|
saveCard: F.saveCard,
|
|
1209
1208
|
onSaveCardChange: F.setSaveCard,
|
|
@@ -1379,8 +1378,8 @@ var $e = () => {
|
|
|
1379
1378
|
}),
|
|
1380
1379
|
/* @__PURE__ */ p("button", {
|
|
1381
1380
|
type: "button",
|
|
1382
|
-
onClick:
|
|
1383
|
-
disabled: F.isProcessing || !F.billingAccount || F.items.length === 0 || E === "ADDON" && !T && Wt || E === "ADDON" && !T && V.length === 0 || E === "ADDON" && !T && !F.selectedSubscriptionId || z && (!B.shippingAddressId || !B.shippingMethodId),
|
|
1381
|
+
onClick: an,
|
|
1382
|
+
disabled: F.isProcessing || !F.billingAccount || F.items.length === 0 || F.selectedProvider === "CREDITS" && !Qt || E === "ADDON" && !T && Wt || E === "ADDON" && !T && V.length === 0 || E === "ADDON" && !T && !F.selectedSubscriptionId || z && (!B.shippingAddressId || !B.shippingMethodId),
|
|
1384
1383
|
className: "w-full px-6 py-4 rounded-lg bg-action-primary-bg text-action-primary-text font-semibold\n hover:bg-action-primary-bgHover disabled:opacity-50 disabled:cursor-not-allowed\n transition-colors flex items-center justify-center gap-2",
|
|
1385
1384
|
children: F.isProcessing ? /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(ze, { className: "size-5 animate-spin" }), "Processing…"] }) : F.selectedProvider === "CREDITS" ? "Pay with Credits" : "Proceed to Payment"
|
|
1386
1385
|
}),
|
|
@@ -1397,7 +1396,7 @@ var $e = () => {
|
|
|
1397
1396
|
hasPhone: !!F.billingAccount.contactNumber?.trim(),
|
|
1398
1397
|
hasAddress: !!(F.billingAccount.billingAddresses?.[0]?.line1?.trim() && F.billingAccount.billingAddresses?.[0]?.postalCode?.trim()),
|
|
1399
1398
|
onCompleted: () => {
|
|
1400
|
-
ht.current = !0, mt(!1),
|
|
1399
|
+
ht.current = !0, mt(!1), an(), Pt().then((e) => {
|
|
1401
1400
|
let t = (e.data?.myBillingAccounts ?? []).map(Qe).find((e) => e?.id === F.billingAccount?.id);
|
|
1402
1401
|
t && F.setBillingAccount(t);
|
|
1403
1402
|
});
|