@burdenoff/microfe-billing 2026.913.1 → 2026.914.1

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.
Files changed (43) hide show
  1. package/dist/billing/BillingAdminRoutes.js +84 -71
  2. package/dist/billing/BillingAdminRoutes.js.map +1 -1
  3. package/dist/billing/modules/billing/hooks/useRefunds.js.map +1 -1
  4. package/dist/billing/modules/billing/pages/PaymentMethodsPage.js +90 -87
  5. package/dist/billing/modules/billing/pages/PaymentMethodsPage.js.map +1 -1
  6. package/dist/billing/modules/billing/pages/RefundIssueLogsPage.js +97 -58
  7. package/dist/billing/modules/billing/pages/RefundIssueLogsPage.js.map +1 -1
  8. package/dist/billing/modules/checkout/components/OrderSummary.js +22 -19
  9. package/dist/billing/modules/checkout/components/OrderSummary.js.map +1 -1
  10. package/dist/billing/modules/checkout/components/RazorpayPaymentButton.js.map +1 -1
  11. package/dist/billing/modules/checkout/hooks/useCheckout.js +174 -157
  12. package/dist/billing/modules/checkout/hooks/useCheckout.js.map +1 -1
  13. package/dist/billing/modules/checkout/pages/CheckoutPage.js +189 -182
  14. package/dist/billing/modules/checkout/pages/CheckoutPage.js.map +1 -1
  15. package/dist/billing/modules/credits/pages/CreditWithdrawalPage.js +293 -274
  16. package/dist/billing/modules/credits/pages/CreditWithdrawalPage.js.map +1 -1
  17. package/dist/billing/modules/dashboard/components/AddPaymentMethodModal.js +140 -250
  18. package/dist/billing/modules/dashboard/components/AddPaymentMethodModal.js.map +1 -1
  19. package/dist/billing/modules/earnings/api.js +79 -42
  20. package/dist/billing/modules/earnings/api.js.map +1 -1
  21. package/dist/billing/modules/earnings/index.js +4 -3
  22. package/dist/billing/modules/earnings/pages/DeveloperRevenueAdminPage.js +103 -310
  23. package/dist/billing/modules/earnings/pages/DeveloperRevenueAdminPage.js.map +1 -1
  24. package/dist/billing/modules/earnings/pages/DeveloperRevenueOrgDetailPage.js +545 -0
  25. package/dist/billing/modules/earnings/pages/DeveloperRevenueOrgDetailPage.js.map +1 -0
  26. package/dist/billing/modules/earnings/pages/PayoutAdminPage.js +246 -196
  27. package/dist/billing/modules/earnings/pages/PayoutAdminPage.js.map +1 -1
  28. package/dist/billing/modules/subscriptions/hooks/useSubscriptions.js +44 -28
  29. package/dist/billing/modules/subscriptions/hooks/useSubscriptions.js.map +1 -1
  30. package/dist/billing/modules/subscriptions/pages/SubscriptionDetailPage.js +317 -270
  31. package/dist/billing/modules/subscriptions/pages/SubscriptionDetailPage.js.map +1 -1
  32. package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js +153 -150
  33. package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js.map +1 -1
  34. package/dist/billing/modules/subscriptions/pages/UpgradeSubscriptionPage.js +1 -1
  35. package/dist/billing/modules/subscriptions/pages/UpgradeSubscriptionPage.js.map +1 -1
  36. package/dist/billing/modules/usage/hooks/useUsage.js +74 -48
  37. package/dist/billing/modules/usage/hooks/useUsage.js.map +1 -1
  38. package/dist/generated/global-operations.js +220 -183
  39. package/dist/generated/global-operations.js.map +1 -1
  40. package/dist/generated/global-types.js.map +1 -1
  41. package/dist/node_modules/sonner/dist/index.js +163 -0
  42. package/dist/node_modules/sonner/dist/index.js.map +1 -0
  43. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"AddPaymentMethodModal.js","names":[],"sources":["../../../../../src/billing/modules/dashboard/components/AddPaymentMethodModal.tsx"],"sourcesContent":["/**\n * Add Payment Method Modal Component\n * Modal for adding a new payment method via Stripe or Razorpay SDKs\n */\n\nimport { type FC, useState, useCallback, useEffect, useRef } from 'react';\nimport { X, CreditCard, Loader2, AlertCircle, CheckCircle2 } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { usePaymentProviderConfig, useDashboardMutations } from '../hooks';\nimport { PaymentProviderPreference } from '../../../shared/types';\nimport { getStripeCardElementStyle } from '../../../shared/utils';\n\n// Stripe types (loaded dynamically)\ndeclare global {\n interface Window {\n Stripe?: (key: string) => StripeInstance;\n Razorpay?: new (options: RazorpayOptions) => RazorpayInstance;\n }\n}\n\ninterface StripeInstance {\n elements: () => StripeElements;\n createPaymentMethod: (options: {\n type: 'card';\n card: StripeCardElement;\n billing_details?: { name?: string };\n }) => Promise<{\n paymentMethod?: {\n id: string;\n card?: { brand: string; last4: string; exp_month: number; exp_year: number };\n };\n error?: { message: string };\n }>;\n confirmCardSetup: (\n clientSecret: string,\n options?: {\n payment_method?: {\n card: StripeCardElement;\n billing_details?: { name?: string };\n };\n }\n ) => Promise<{\n setupIntent?: {\n id: string;\n status: string;\n payment_method?: string;\n };\n error?: { message: string };\n }>;\n}\n\ninterface StripeElements {\n create: (type: 'card', options?: object) => StripeCardElement;\n}\n\ninterface StripeCardElement {\n mount: (element: HTMLElement | string) => void;\n unmount: () => void;\n on: (\n event: string,\n handler: (event: { complete: boolean; error?: { message: string } }) => void\n ) => void;\n destroy: () => void;\n}\n\ninterface RazorpayOptions {\n key: string;\n amount: number;\n currency: string;\n order_id: string;\n customer_id?: string;\n name: string;\n description: string;\n method?: 'card' | 'upi' | 'netbanking' | 'wallet' | 'emi' | 'cardless_emi';\n handler: (response: RazorpayResponse) => void;\n modal?: { ondismiss?: () => void };\n prefill?: { name?: string; email?: string; contact?: string };\n notes?: Record<string, string>;\n config?: {\n display?: {\n hide?: Array<{ method: string }>;\n preferences?: {\n show_default_blocks?: boolean;\n };\n };\n };\n}\n\ninterface RazorpayInstance {\n open: () => void;\n close: () => void;\n}\n\ninterface RazorpayResponse {\n razorpay_payment_id: string;\n razorpay_token?: string;\n}\n\ninterface AddPaymentMethodModalProps {\n isOpen: boolean;\n onClose: () => void;\n billingAccountId: string;\n currency: string; // e.g., 'INR', 'USD'\n country?: string; // e.g., 'IN', 'US' - from billing address\n onSuccess?: () => void;\n}\n\ntype ModalStep = 'select-provider' | 'add-card' | 'processing' | 'success';\n\n// Load external script dynamically\nconst loadScript = (src: string, id: string): Promise<void> => {\n return new Promise((resolve, reject) => {\n if (document.getElementById(id)) {\n resolve();\n return;\n }\n const script = document.createElement('script');\n script.id = id;\n script.src = src;\n script.async = true;\n script.onload = () => resolve();\n script.onerror = () => reject(new Error(`Failed to load ${src}`));\n document.head.appendChild(script);\n });\n};\n\nexport const AddPaymentMethodModal: FC<AddPaymentMethodModalProps> = ({\n isOpen,\n onClose,\n billingAccountId,\n currency,\n country,\n onSuccess,\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 modalRef = useRef<HTMLDivElement>(null);\n const cardElementRef = useRef<HTMLDivElement>(null);\n const stripeCardElementRef = useRef<StripeCardElement | null>(null);\n const stripeRef = useRef<StripeInstance | null>(null);\n\n // Only fetch payment provider config when modal is open\n const {\n stripeEnabled,\n stripePublishableKey,\n razorpayEnabled,\n isLoading: isLoadingConfig,\n } = usePaymentProviderConfig(!isOpen);\n const { isAddingPaymentMethod, verifyPaymentMethod } = useDashboardMutations();\n\n // Determine which providers to show based on currency and country\n // Razorpay: India only (INR currency OR IN country)\n // Stripe: International (non-INR OR non-IN country)\n const isIndianAccount = currency?.toUpperCase() === 'INR' || country?.toUpperCase() === 'IN';\n const showRazorpay = razorpayEnabled && isIndianAccount;\n const showStripe = stripeEnabled && !isIndianAccount;\n\n const [step, setStep] = useState<ModalStep>('select-provider');\n const [selectedProvider, setSelectedProvider] = useState<'stripe' | 'razorpay' | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [isProcessing, setIsProcessing] = useState(false);\n const [isLoadingSdk, setIsLoadingSdk] = useState(false);\n const [cardholderName, setCardholderName] = useState('');\n const [setAsDefault, setSetAsDefault] = useState(true);\n const [isCardComplete, setIsCardComplete] = useState(false);\n\n // Must be declared before the effects that reference it\n const handleSelectProvider = useCallback((provider: 'stripe' | 'razorpay') => {\n setSelectedProvider(provider);\n setStep('add-card');\n setError(null);\n }, []);\n\n // Reset state when modal opens/closes\n useEffect(() => {\n if (isOpen) {\n setStep('select-provider');\n setSelectedProvider(null);\n setError(null);\n setCardholderName('');\n setSetAsDefault(true);\n setIsCardComplete(false);\n } else {\n // Cleanup Stripe element when modal closes\n if (stripeCardElementRef.current) {\n stripeCardElementRef.current.destroy();\n stripeCardElementRef.current = null;\n }\n }\n }, [isOpen]);\n\n // Auto-select provider when only one is available (skip the select-provider screen)\n useEffect(() => {\n if (step !== 'select-provider' || isLoadingConfig) return;\n if (showStripe && !showRazorpay) {\n handleSelectProvider('stripe');\n } else if (showRazorpay && !showStripe) {\n handleSelectProvider('razorpay');\n }\n }, [step, isLoadingConfig, showStripe, showRazorpay, handleSelectProvider]);\n\n // Initialize Stripe when provider is selected\n useEffect(() => {\n if (step !== 'add-card' || selectedProvider !== 'stripe') return;\n\n // Show error if config loaded but key is missing\n if (!stripePublishableKey && !isLoadingConfig) {\n setError('Stripe is not configured. Please contact support.');\n return;\n }\n\n if (!stripePublishableKey) return;\n\n const initStripe = async () => {\n setIsLoadingSdk(true);\n try {\n await loadScript('https://js.stripe.com/v3/', 'stripe-js');\n\n if (!window.Stripe) {\n throw new Error('Stripe SDK failed to load');\n }\n\n const stripe = window.Stripe(stripePublishableKey);\n stripeRef.current = stripe;\n\n // Wait for the card element container to be mounted in the DOM\n let attempts = 0;\n while (!cardElementRef.current && attempts < 50) {\n await new Promise((resolve) => setTimeout(resolve, 100));\n attempts++;\n }\n\n if (!cardElementRef.current) {\n throw new Error('Card element container not found after 5 seconds');\n }\n\n if (stripeCardElementRef.current) {\n return;\n }\n\n const elements = stripe.elements();\n const cardElement = elements.create('card', {\n style: getStripeCardElementStyle('system-ui, -apple-system, sans-serif'),\n });\n\n cardElement.mount(cardElementRef.current);\n stripeCardElementRef.current = cardElement;\n\n cardElement.on('change', (event) => {\n setIsCardComplete(event.complete);\n if (event.error) {\n setError(event.error.message);\n } else {\n setError(null);\n }\n });\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load Stripe');\n } finally {\n setIsLoadingSdk(false);\n }\n };\n\n initStripe();\n\n return () => {\n if (stripeCardElementRef.current) {\n try {\n stripeCardElementRef.current.destroy();\n stripeCardElementRef.current = null;\n } catch {\n // Stripe element may already be detached during modal teardown.\n }\n }\n };\n }, [step, selectedProvider, stripePublishableKey, isLoadingConfig]);\n\n // Handle escape key\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && isOpen && !isProcessing) {\n onClose();\n }\n };\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [isOpen, isProcessing, onClose]);\n\n const handleStripeSubmit = useCallback(async () => {\n if (!stripeRef.current || !stripeCardElementRef.current) {\n setError('Stripe not initialized');\n return;\n }\n\n if (!cardholderName.trim()) {\n setError('Please enter the cardholder name');\n return;\n }\n\n setIsProcessing(true);\n setError(null);\n\n try {\n // Step 1: Call backend to create SetupIntent and get client secret\n const verificationResult = await verifyPaymentMethod({\n billingAccountId,\n currency: 'USD',\n provider: PaymentProviderPreference.STRIPE,\n setAsDefault,\n });\n\n if (!verificationResult.clientSecret) {\n throw new Error('Failed to initiate card verification');\n }\n\n // Step 2: Confirm card setup using the client secret (no charge)\n const { setupIntent, error: stripeError } = await stripeRef.current.confirmCardSetup(\n verificationResult.clientSecret,\n {\n payment_method: {\n card: stripeCardElementRef.current,\n billing_details: { name: cardholderName },\n },\n }\n );\n\n if (stripeError) {\n throw new Error(stripeError.message);\n }\n\n if (setupIntent?.status !== 'succeeded') {\n throw new Error('Card verification failed');\n }\n\n // Step 3: Show success (webhook will save the payment method)\n setStep('success');\n\n // Wait for webhook to process (2 seconds) before refetching\n await new Promise((resolve) => setTimeout(resolve, 2000));\n onSuccess?.();\n\n // Show success message briefly before closing\n setTimeout(() => {\n onClose();\n }, 500);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to add payment method');\n setIsProcessing(false);\n }\n }, [cardholderName, setAsDefault, billingAccountId, verifyPaymentMethod, onSuccess, onClose]);\n\n const handleRazorpaySubmit = useCallback(async () => {\n setIsProcessing(true);\n setError(null);\n\n try {\n // Load Razorpay SDK\n setIsLoadingSdk(true);\n try {\n await loadScript('https://checkout.razorpay.com/v1/checkout.js', 'razorpay-sdk');\n } catch {\n setError('Failed to load Razorpay SDK');\n setIsProcessing(false);\n setIsLoadingSdk(false);\n return;\n }\n setIsLoadingSdk(false);\n\n // Initiate ₹1 verification payment\n const verificationResult = await verifyPaymentMethod({\n billingAccountId,\n currency: 'INR',\n provider: PaymentProviderPreference.RAZORPAY,\n setAsDefault,\n });\n\n if (\n !verificationResult.success ||\n !verificationResult.orderId ||\n !verificationResult.razorpayKeyId\n ) {\n setError(verificationResult.error || 'Failed to initiate verification');\n setIsProcessing(false);\n return;\n }\n\n // Open Razorpay checkout with ALL payment methods\n if (!window.Razorpay) {\n setError('Razorpay SDK not loaded');\n setIsProcessing(false);\n return;\n }\n\n const options = {\n key: verificationResult.razorpayKeyId,\n amount: (verificationResult.amount ?? 0) * 100, // Convert to paise\n currency: verificationResult.currency.toUpperCase(),\n order_id: verificationResult.orderId,\n customer_id: verificationResult.razorpayCustomerId, // Link to customer for saving\n name: 'Add Payment Method',\n description: `₹${verificationResult.amount} verification charge (refundable)`,\n prefill: {\n name: verificationResult.prefillName,\n email: verificationResult.prefillEmail,\n contact: verificationResult.prefillContact,\n },\n notes: {\n purchaseType: 'PAYMENT_METHOD_VERIFICATION',\n default_method: setAsDefault.toString(),\n },\n handler: async () => {\n // Payment successful - payment method will be saved via webhook\n setStep('success');\n\n // Wait for webhook to process (2 seconds) before refetching\n await new Promise((resolve) => setTimeout(resolve, 2000));\n onSuccess?.();\n\n // Show success message briefly before closing\n setTimeout(() => {\n onClose();\n }, 500);\n },\n modal: {\n ondismiss: () => {\n setIsProcessing(false);\n setError('Payment cancelled');\n },\n },\n };\n\n const rzp = new window.Razorpay(options);\n rzp.open();\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to add payment method');\n setIsProcessing(false);\n }\n }, [setAsDefault, billingAccountId, verifyPaymentMethod, onSuccess, onClose]);\n\n const handleSubmit = useCallback(() => {\n if (selectedProvider === 'stripe') {\n handleStripeSubmit();\n } else if (selectedProvider === 'razorpay') {\n handleRazorpaySubmit();\n }\n }, [selectedProvider, handleStripeSubmit, handleRazorpaySubmit]);\n\n if (!isOpen) return null;\n\n return (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"modal-title\"\n >\n {/* Backdrop */}\n <div\n className=\"absolute inset-0 bg-bg-overlay backdrop-blur-sm\"\n onClick={!isProcessing ? onClose : undefined}\n aria-hidden=\"true\"\n />\n\n {/* Modal */}\n <div\n ref={modalRef}\n className=\"relative w-full max-w-md max-h-[90vh] mx-4 bg-bg-surface border border-border-seam rounded-card shadow-[var(--shadow-elevation-4)] flex flex-col\"\n >\n {/* Header */}\n <header className=\"flex items-center justify-between p-4 border-b border-border-subtle flex-shrink-0\">\n <div className=\"flex items-center gap-3\">\n <div className=\"size-10 rounded-lg bg-[var(--color-accent-soft)] flex items-center justify-center\">\n <CreditCard className=\"size-5 text-text-link\" />\n </div>\n <div>\n <h2 id=\"modal-title\" className=\"text-lg font-semibold text-text-primary\">\n {step === 'success' ? 'Payment Method Added' : 'Add Payment Method'}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {step === 'select-provider' && 'Choose a payment provider'}\n {step === 'add-card' &&\n (selectedProvider === 'stripe'\n ? 'Add card via Stripe'\n : 'Add payment method with ₹1 verification')}\n {step === 'processing' && 'Processing...'}\n {step === 'success' && 'Your payment method has been saved'}\n </p>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n disabled={isProcessing}\n className=\"p-2 rounded-button hover:bg-bg-sunken text-text-secondary hover:text-text-primary transition-colors disabled:opacity-50\"\n aria-label=\"Close modal\"\n >\n <X className=\"size-5\" />\n </button>\n </header>\n\n {/* Content */}\n <div className=\"p-4 overflow-y-auto flex-1\">\n {isLoadingConfig ? (\n <div className=\"flex items-center justify-center py-8\">\n <Loader2 className=\"size-6 animate-spin text-text-secondary\" />\n </div>\n ) : step === 'select-provider' ? (\n <div className=\"space-y-3\">\n {showStripe && (\n <button\n type=\"button\"\n onClick={() => handleSelectProvider('stripe')}\n className=\"w-full flex items-center gap-4 p-4 border border-border-subtle rounded-lg hover:border-border-strong hover:bg-[var(--color-accent-soft)] transition-colors text-left\"\n >\n <div className=\"size-12 rounded-lg bg-accent-violet-subtle flex items-center justify-center\">\n <CreditCard className=\"size-6 text-accent-violet\" />\n </div>\n <div>\n <p className=\"font-medium text-text-primary\">Stripe</p>\n <p className=\"text-sm text-text-secondary\">Cards, Apple Pay, Google Pay</p>\n </div>\n </button>\n )}\n {showRazorpay && (\n <button\n type=\"button\"\n onClick={() => handleSelectProvider('razorpay')}\n className=\"w-full flex items-center gap-4 p-4 border border-border-subtle rounded-lg hover:border-border-strong hover:bg-[var(--color-accent-soft)] transition-colors text-left\"\n >\n <div className=\"size-12 rounded-lg bg-status-info-bg-subtle flex items-center justify-center\">\n <CreditCard className=\"size-6 text-accent-blue\" />\n </div>\n <div>\n <p className=\"font-medium text-text-primary\">Razorpay</p>\n <p className=\"text-sm text-text-secondary\">UPI, Netbanking, Cards</p>\n </div>\n </button>\n )}\n {!showStripe && !showRazorpay && (\n <div className=\"flex flex-col items-center py-8 text-center\">\n <AlertCircle className=\"size-12 text-status-warning-text mb-3\" />\n <p className=\"font-medium text-text-primary\">\n {tr('billing.overview.noPaymentProviders', 'No Payment Providers Available')}\n </p>\n <p className=\"text-sm text-text-secondary mt-1\">\n {isIndianAccount\n ? 'Razorpay is not configured for Indian accounts. Please contact support.'\n : 'Stripe is not configured for international accounts. Please contact support.'}\n </p>\n </div>\n )}\n </div>\n ) : step === 'add-card' ? (\n <div className=\"space-y-4\">\n {/* Error Message */}\n {error && (\n <div className=\"flex items-center gap-2 p-3 rounded-lg bg-status-error-bg-subtle border border-status-error-border text-status-error-text\">\n <AlertCircle className=\"size-4 flex-shrink-0\" />\n <p className=\"text-sm\">{error}</p>\n </div>\n )}\n\n {/* Cardholder Name - only for Stripe */}\n {selectedProvider === 'stripe' && (\n <div className=\"space-y-1.5\">\n <label\n htmlFor=\"cardholderName\"\n className=\"block text-sm font-medium text-text-primary\"\n >\n Cardholder Name\n </label>\n <input\n type=\"text\"\n id=\"cardholderName\"\n value={cardholderName}\n onChange={(e) => setCardholderName(e.target.value)}\n className=\"w-full px-3 py-2 border border-border-default rounded-input bg-bg-surface text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-border-strong\"\n placeholder=\"John Doe\"\n disabled={isProcessing}\n />\n </div>\n )}\n\n {/* Stripe Card Element */}\n {selectedProvider === 'stripe' && (\n <div className=\"space-y-1.5\">\n <label className=\"block text-sm font-medium text-text-primary\">\n {tr('billing.overview.cardDetails', 'Card Details')}\n </label>\n <div className=\"relative\">\n <div\n ref={cardElementRef}\n className=\"p-3 border border-border-default rounded-lg bg-bg-surface min-h-[56px]\"\n />\n {isLoadingSdk && (\n <div className=\"absolute inset-0 flex items-center justify-center bg-bg-overlay rounded-lg\">\n <Loader2 className=\"size-5 animate-spin text-text-secondary\" />\n <span className=\"ml-2 text-sm text-text-secondary\">Loading Stripe…</span>\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* Razorpay - Verification Info */}\n {selectedProvider === 'razorpay' && (\n <div className=\"p-3 border border-border-subtle rounded-lg bg-status-info-bg-subtle\">\n <p className=\"text-sm text-status-info-text\">\n <strong>Verification Process:</strong> A ₹1 charge will be made to verify your\n payment method. This amount will be refunded immediately after verification.\n </p>\n </div>\n )}\n\n {/* Set as default */}\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={setAsDefault}\n onChange={(e) => setSetAsDefault(e.target.checked)}\n className=\"size-4 rounded border-border-default text-text-link focus:ring-[var(--color-focus-ring)]\"\n disabled={isProcessing}\n />\n <span className=\"text-sm text-text-primary\">\n {tr('billing.overview.setAsDefault', 'Set as default payment method')}\n </span>\n </label>\n\n {/* Provider badge */}\n <div className=\"flex items-center gap-2 pt-2 border-t border-border-subtle\">\n <span className=\"text-xs text-text-secondary\">Secured by</span>\n <span\n className={`inline-flex items-center px-2 py-0.5 rounded text-xs font-medium ${\n selectedProvider === 'stripe'\n ? 'bg-accent-violet-subtle text-accent-violet'\n : 'bg-status-info-bg-subtle text-status-info-text'\n }`}\n >\n {selectedProvider === 'stripe' ? 'Stripe' : 'Razorpay'}\n </span>\n </div>\n </div>\n ) : (\n /* Success state */\n <div className=\"flex flex-col items-center py-8 text-center\">\n <div className=\"size-16 rounded-full bg-status-success-bg-subtle flex items-center justify-center mb-4\">\n <CheckCircle2 className=\"size-8 text-status-success-text\" />\n </div>\n <p className=\"font-medium text-text-primary\">\n {tr('billing.overview.paymentMethodAdded', 'Payment method added successfully!')}\n </p>\n <p className=\"text-sm text-text-secondary mt-1\">\n Your payment method has been securely saved.\n </p>\n </div>\n )}\n </div>\n\n {/* Footer */}\n {step !== 'success' && (\n <footer className=\"flex items-center justify-between gap-3 p-4 border-t border-border-subtle bg-bg-sunken rounded-b-lg flex-shrink-0\">\n {step === 'add-card' && showStripe && showRazorpay ? (\n <button\n type=\"button\"\n onClick={() => {\n setStep('select-provider');\n setSelectedProvider(null);\n setError(null);\n // Cleanup Stripe element\n if (stripeCardElementRef.current) {\n stripeCardElementRef.current.destroy();\n stripeCardElementRef.current = null;\n }\n }}\n disabled={isProcessing}\n className=\"px-4 py-2 text-sm font-medium text-text-primary hover:text-text-link transition-colors disabled:opacity-50\"\n >\n Back\n </button>\n ) : (\n <div />\n )}\n <div className=\"flex items-center gap-3\">\n <button\n type=\"button\"\n onClick={onClose}\n disabled={isProcessing}\n className=\"px-4 py-2 text-sm font-medium text-text-primary border border-border-subtle rounded-lg hover:bg-bg-sunken transition-colors disabled:opacity-50\"\n >\n Cancel\n </button>\n {step === 'add-card' && (\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={\n isProcessing ||\n isAddingPaymentMethod ||\n isLoadingSdk ||\n (selectedProvider === 'stripe' && !isCardComplete)\n }\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-action-primary-text bg-action-primary-bg rounded-lg hover:bg-action-primary-bgHover transition-colors disabled:opacity-50\"\n >\n {isProcessing || isAddingPaymentMethod ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n {selectedProvider === 'razorpay' ? 'Processing...' : 'Saving...'}\n </>\n ) : isLoadingSdk ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n Loading…\n </>\n ) : selectedProvider === 'stripe' ? (\n 'Add Card'\n ) : (\n 'Add Payment Method (₹1)'\n )}\n </button>\n )}\n </div>\n </footer>\n )}\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"AddPaymentMethodModal.js","names":[],"sources":["../../../../../src/billing/modules/dashboard/components/AddPaymentMethodModal.tsx"],"sourcesContent":["/**\n * Add Payment Method Modal Component\n * Modal for adding a new payment method via Stripe or Razorpay SDKs\n */\n\nimport { type FC, useState, useCallback, useEffect, useRef } from 'react';\nimport { X, CreditCard, Loader2, AlertCircle, CheckCircle2 } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { usePaymentProviderConfig, useDashboardMutations } from '../hooks';\nimport { PaymentProviderPreference } from '../../../shared/types';\nimport { getStripeCardElementStyle } from '../../../shared/utils';\n\n// Stripe types (loaded dynamically)\ndeclare global {\n interface Window {\n Stripe?: (key: string) => StripeInstance;\n }\n}\n\ninterface StripeInstance {\n elements: () => StripeElements;\n createPaymentMethod: (options: {\n type: 'card';\n card: StripeCardElement;\n billing_details?: { name?: string };\n }) => Promise<{\n paymentMethod?: {\n id: string;\n card?: { brand: string; last4: string; exp_month: number; exp_year: number };\n };\n error?: { message: string };\n }>;\n confirmCardSetup: (\n clientSecret: string,\n options?: {\n payment_method?: {\n card: StripeCardElement;\n billing_details?: { name?: string };\n };\n }\n ) => Promise<{\n setupIntent?: {\n id: string;\n status: string;\n payment_method?: string;\n };\n error?: { message: string };\n }>;\n}\n\ninterface StripeElements {\n create: (type: 'card', options?: object) => StripeCardElement;\n}\n\ninterface StripeCardElement {\n mount: (element: HTMLElement | string) => void;\n unmount: () => void;\n on: (\n event: string,\n handler: (event: { complete: boolean; error?: { message: string } }) => void\n ) => void;\n destroy: () => void;\n}\n\ninterface AddPaymentMethodModalProps {\n isOpen: boolean;\n onClose: () => void;\n billingAccountId: string;\n currency: string; // e.g., 'INR', 'USD'\n country?: string; // e.g., 'IN', 'US' - from billing address\n onSuccess?: () => void;\n}\n\ntype ModalStep = 'select-provider' | 'add-card' | 'processing' | 'success';\n\n// Load external script dynamically\nconst loadScript = (src: string, id: string): Promise<void> => {\n return new Promise((resolve, reject) => {\n if (document.getElementById(id)) {\n resolve();\n return;\n }\n const script = document.createElement('script');\n script.id = id;\n script.src = src;\n script.async = true;\n script.onload = () => resolve();\n script.onerror = () => reject(new Error(`Failed to load ${src}`));\n document.head.appendChild(script);\n });\n};\n\nexport const AddPaymentMethodModal: FC<AddPaymentMethodModalProps> = ({\n isOpen,\n onClose,\n billingAccountId,\n onSuccess,\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 modalRef = useRef<HTMLDivElement>(null);\n const cardElementRef = useRef<HTMLDivElement>(null);\n const stripeCardElementRef = useRef<StripeCardElement | null>(null);\n const stripeRef = useRef<StripeInstance | null>(null);\n\n // Only fetch payment provider config when modal is open\n const {\n stripeEnabled,\n stripePublishableKey,\n isLoading: isLoadingConfig,\n } = usePaymentProviderConfig(!isOpen);\n const { isAddingPaymentMethod, verifyPaymentMethod } = useDashboardMutations();\n\n // Standalone \"add a card without purchasing anything\" is only offered via\n // Stripe's SetupIntent flow (a genuine $0 card verification). Razorpay has\n // no equivalent zero-charge save: their Checkout.js widget only remembers a\n // card as a side effect of a real payment (customer_id + remember_customer),\n // and our backend's Razorpay \"attach payment method\" call is a documented\n // no-op stub. Offering it here previously meant charging (and refunding) a\n // real ₹1 for a save that didn't actually do anything durable — Razorpay's\n // own remember-card behavior already works during real checkout regardless.\n // Stripe is offered to every account regardless of country/currency, same\n // as checkout itself does (PaymentProviderSelector gates Stripe purely on\n // `stripeEnabled`, never on billing country) — see BOFF-7192 follow-up for\n // a real Razorpay saved-card implementation (Tokens API + Recurring\n // Payments) to close the gap for accounts that only pay via Razorpay.\n const showStripe = stripeEnabled;\n\n const [step, setStep] = useState<ModalStep>('select-provider');\n const [selectedProvider, setSelectedProvider] = useState<'stripe' | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [isProcessing, setIsProcessing] = useState(false);\n const [isLoadingSdk, setIsLoadingSdk] = useState(false);\n const [cardholderName, setCardholderName] = useState('');\n const [setAsDefault, setSetAsDefault] = useState(true);\n const [isCardComplete, setIsCardComplete] = useState(false);\n\n // Must be declared before the effects that reference it\n const handleSelectProvider = useCallback((provider: 'stripe') => {\n setSelectedProvider(provider);\n setStep('add-card');\n setError(null);\n }, []);\n\n // Reset state when modal opens/closes\n useEffect(() => {\n if (isOpen) {\n setStep('select-provider');\n setSelectedProvider(null);\n setError(null);\n setCardholderName('');\n setSetAsDefault(true);\n setIsCardComplete(false);\n } else {\n // Cleanup Stripe element when modal closes\n if (stripeCardElementRef.current) {\n stripeCardElementRef.current.destroy();\n stripeCardElementRef.current = null;\n }\n }\n }, [isOpen]);\n\n // Stripe is the only provider this modal ever offers, so skip straight to\n // the card form when it's available (no provider-selection screen needed).\n useEffect(() => {\n if (step !== 'select-provider' || isLoadingConfig) return;\n if (showStripe) {\n handleSelectProvider('stripe');\n }\n }, [step, isLoadingConfig, showStripe, handleSelectProvider]);\n\n // Initialize Stripe when provider is selected\n useEffect(() => {\n if (step !== 'add-card' || selectedProvider !== 'stripe') return;\n\n // Show error if config loaded but key is missing\n if (!stripePublishableKey && !isLoadingConfig) {\n setError('Stripe is not configured. Please contact support.');\n return;\n }\n\n if (!stripePublishableKey) return;\n\n const initStripe = async () => {\n setIsLoadingSdk(true);\n try {\n await loadScript('https://js.stripe.com/v3/', 'stripe-js');\n\n if (!window.Stripe) {\n throw new Error('Stripe SDK failed to load');\n }\n\n const stripe = window.Stripe(stripePublishableKey);\n stripeRef.current = stripe;\n\n // Wait for the card element container to be mounted in the DOM\n let attempts = 0;\n while (!cardElementRef.current && attempts < 50) {\n await new Promise((resolve) => setTimeout(resolve, 100));\n attempts++;\n }\n\n if (!cardElementRef.current) {\n throw new Error('Card element container not found after 5 seconds');\n }\n\n if (stripeCardElementRef.current) {\n return;\n }\n\n const elements = stripe.elements();\n const cardElement = elements.create('card', {\n style: getStripeCardElementStyle('system-ui, -apple-system, sans-serif'),\n });\n\n cardElement.mount(cardElementRef.current);\n stripeCardElementRef.current = cardElement;\n\n cardElement.on('change', (event) => {\n setIsCardComplete(event.complete);\n if (event.error) {\n setError(event.error.message);\n } else {\n setError(null);\n }\n });\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load Stripe');\n } finally {\n setIsLoadingSdk(false);\n }\n };\n\n initStripe();\n\n return () => {\n if (stripeCardElementRef.current) {\n try {\n stripeCardElementRef.current.destroy();\n stripeCardElementRef.current = null;\n } catch {\n // Stripe element may already be detached during modal teardown.\n }\n }\n };\n }, [step, selectedProvider, stripePublishableKey, isLoadingConfig]);\n\n // Handle escape key\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && isOpen && !isProcessing) {\n onClose();\n }\n };\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [isOpen, isProcessing, onClose]);\n\n const handleStripeSubmit = useCallback(async () => {\n if (!stripeRef.current || !stripeCardElementRef.current) {\n setError('Stripe not initialized');\n return;\n }\n\n if (!cardholderName.trim()) {\n setError('Please enter the cardholder name');\n return;\n }\n\n setIsProcessing(true);\n setError(null);\n\n try {\n // Step 1: Call backend to create SetupIntent and get client secret\n const verificationResult = await verifyPaymentMethod({\n billingAccountId,\n currency: 'USD',\n provider: PaymentProviderPreference.STRIPE,\n setAsDefault,\n });\n\n if (!verificationResult.clientSecret) {\n throw new Error('Failed to initiate card verification');\n }\n\n // Step 2: Confirm card setup using the client secret (no charge)\n const { setupIntent, error: stripeError } = await stripeRef.current.confirmCardSetup(\n verificationResult.clientSecret,\n {\n payment_method: {\n card: stripeCardElementRef.current,\n billing_details: { name: cardholderName },\n },\n }\n );\n\n if (stripeError) {\n throw new Error(stripeError.message);\n }\n\n if (setupIntent?.status !== 'succeeded') {\n throw new Error('Card verification failed');\n }\n\n // Step 3: Show success (webhook will save the payment method)\n setStep('success');\n\n // Wait for webhook to process (2 seconds) before refetching\n await new Promise((resolve) => setTimeout(resolve, 2000));\n onSuccess?.();\n\n // Show success message briefly before closing\n setTimeout(() => {\n onClose();\n }, 500);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to add payment method');\n setIsProcessing(false);\n }\n }, [cardholderName, setAsDefault, billingAccountId, verifyPaymentMethod, onSuccess, onClose]);\n\n const handleSubmit = useCallback(() => {\n if (selectedProvider === 'stripe') {\n handleStripeSubmit();\n }\n }, [selectedProvider, handleStripeSubmit]);\n\n if (!isOpen) return null;\n\n return (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"modal-title\"\n >\n {/* Backdrop */}\n <div\n className=\"absolute inset-0 bg-bg-overlay backdrop-blur-sm\"\n onClick={!isProcessing ? onClose : undefined}\n aria-hidden=\"true\"\n />\n\n {/* Modal */}\n <div\n ref={modalRef}\n className=\"relative w-full max-w-md max-h-[90vh] mx-4 bg-bg-surface border border-border-seam rounded-card shadow-[var(--shadow-elevation-4)] flex flex-col\"\n >\n {/* Header */}\n <header className=\"flex items-center justify-between p-4 border-b border-border-subtle flex-shrink-0\">\n <div className=\"flex items-center gap-3\">\n <div className=\"size-10 rounded-lg bg-[var(--color-accent-soft)] flex items-center justify-center\">\n <CreditCard className=\"size-5 text-text-link\" />\n </div>\n <div>\n <h2 id=\"modal-title\" className=\"text-lg font-semibold text-text-primary\">\n {step === 'success' ? 'Payment Method Added' : 'Add Payment Method'}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {step === 'select-provider' &&\n (showStripe ? 'Add card via Stripe' : 'Standalone card save unavailable')}\n {step === 'add-card' && 'Add card via Stripe'}\n {step === 'processing' && 'Processing...'}\n {step === 'success' && 'Your payment method has been saved'}\n </p>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n disabled={isProcessing}\n className=\"p-2 rounded-button hover:bg-bg-sunken text-text-secondary hover:text-text-primary transition-colors disabled:opacity-50\"\n aria-label=\"Close modal\"\n >\n <X className=\"size-5\" />\n </button>\n </header>\n\n {/* Content */}\n <div className=\"p-4 overflow-y-auto flex-1\">\n {isLoadingConfig ? (\n <div className=\"flex items-center justify-center py-8\">\n <Loader2 className=\"size-6 animate-spin text-text-secondary\" />\n </div>\n ) : step === 'select-provider' ? (\n <div className=\"space-y-3\">\n {showStripe ? (\n <div className=\"flex items-center justify-center py-8\">\n <Loader2 className=\"size-6 animate-spin text-text-secondary\" />\n </div>\n ) : (\n <div className=\"flex flex-col items-center py-8 text-center\">\n <AlertCircle className=\"size-12 text-status-warning-text mb-3\" />\n <p className=\"font-medium text-text-primary\">\n {tr('billing.overview.noPaymentProviders', 'No Payment Providers Available')}\n </p>\n <p className=\"text-sm text-text-secondary mt-1\">\n Card saving isn&apos;t configured for this account yet. Please contact support.\n </p>\n </div>\n )}\n </div>\n ) : step === 'add-card' ? (\n <div className=\"space-y-4\">\n {/* Error Message */}\n {error && (\n <div className=\"flex items-center gap-2 p-3 rounded-lg bg-status-error-bg-subtle border border-status-error-border text-status-error-text\">\n <AlertCircle className=\"size-4 flex-shrink-0\" />\n <p className=\"text-sm\">{error}</p>\n </div>\n )}\n\n {/* Cardholder Name - only for Stripe */}\n {selectedProvider === 'stripe' && (\n <div className=\"space-y-1.5\">\n <label\n htmlFor=\"cardholderName\"\n className=\"block text-sm font-medium text-text-primary\"\n >\n Cardholder Name\n </label>\n <input\n type=\"text\"\n id=\"cardholderName\"\n value={cardholderName}\n onChange={(e) => setCardholderName(e.target.value)}\n className=\"w-full px-3 py-2 border border-border-default rounded-input bg-bg-surface text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-border-strong\"\n placeholder=\"John Doe\"\n disabled={isProcessing}\n />\n </div>\n )}\n\n {/* Stripe Card Element */}\n {selectedProvider === 'stripe' && (\n <div className=\"space-y-1.5\">\n <label className=\"block text-sm font-medium text-text-primary\">\n {tr('billing.overview.cardDetails', 'Card Details')}\n </label>\n <div className=\"relative\">\n <div\n ref={cardElementRef}\n className=\"p-3 border border-border-default rounded-lg bg-bg-surface min-h-[56px]\"\n />\n {isLoadingSdk && (\n <div className=\"absolute inset-0 flex items-center justify-center bg-bg-overlay rounded-lg\">\n <Loader2 className=\"size-5 animate-spin text-text-secondary\" />\n <span className=\"ml-2 text-sm text-text-secondary\">Loading Stripe…</span>\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* Set as default */}\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={setAsDefault}\n onChange={(e) => setSetAsDefault(e.target.checked)}\n className=\"size-4 rounded border-border-default text-text-link focus:ring-[var(--color-focus-ring)]\"\n disabled={isProcessing}\n />\n <span className=\"text-sm text-text-primary\">\n {tr('billing.overview.setAsDefault', 'Set as default payment method')}\n </span>\n </label>\n\n {/* Provider badge */}\n <div className=\"flex items-center gap-2 pt-2 border-t border-border-subtle\">\n <span className=\"text-xs text-text-secondary\">Secured by</span>\n <span className=\"inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-accent-violet-subtle text-accent-violet\">\n Stripe\n </span>\n </div>\n </div>\n ) : (\n /* Success state */\n <div className=\"flex flex-col items-center py-8 text-center\">\n <div className=\"size-16 rounded-full bg-status-success-bg-subtle flex items-center justify-center mb-4\">\n <CheckCircle2 className=\"size-8 text-status-success-text\" />\n </div>\n <p className=\"font-medium text-text-primary\">\n {tr('billing.overview.paymentMethodAdded', 'Payment method added successfully!')}\n </p>\n <p className=\"text-sm text-text-secondary mt-1\">\n Your payment method has been securely saved.\n </p>\n </div>\n )}\n </div>\n\n {/* Footer */}\n {step !== 'success' && (\n <footer className=\"flex items-center justify-between gap-3 p-4 border-t border-border-subtle bg-bg-sunken rounded-b-lg flex-shrink-0\">\n <div />\n <div className=\"flex items-center gap-3\">\n <button\n type=\"button\"\n onClick={onClose}\n disabled={isProcessing}\n className=\"px-4 py-2 text-sm font-medium text-text-primary border border-border-subtle rounded-lg hover:bg-bg-sunken transition-colors disabled:opacity-50\"\n >\n Cancel\n </button>\n {step === 'add-card' && (\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={\n isProcessing || isAddingPaymentMethod || isLoadingSdk || !isCardComplete\n }\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-action-primary-text bg-action-primary-bg rounded-lg hover:bg-action-primary-bgHover transition-colors disabled:opacity-50\"\n >\n {isProcessing || isAddingPaymentMethod ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n Saving...\n </>\n ) : isLoadingSdk ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n Loading…\n </>\n ) : (\n 'Add Card'\n )}\n </button>\n )}\n </div>\n </footer>\n )}\n </div>\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;AA4EA,IAAM,KAAc,GAAa,MACxB,IAAI,SAAS,GAAS,MAAW;CACtC,IAAI,SAAS,eAAe,CAAE,GAAG;EAC/B,EAAQ;EACR;CACF;CACA,IAAM,IAAS,SAAS,cAAc,QAAQ;CAM9C,AALA,EAAO,KAAK,GACZ,EAAO,MAAM,GACb,EAAO,QAAQ,IACf,EAAO,eAAe,EAAQ,GAC9B,EAAO,gBAAgB,EAAO,gBAAI,MAAM,kBAAkB,GAAK,CAAC,GAChE,SAAS,KAAK,YAAY,CAAM;AAClC,CAAC,GAGU,KAAyD,EACpE,WACA,YACA,qBACA,mBACI;CACJ,IAAM,EAAE,SAAM,EAAQ,GAChB,KAAM,GAAa,MAA6B;EACpD,IAAM,IAAa,EAAE,CAAG;EACxB,OAAO,MAAe,IAAM,IAAW;CACzC,GACM,IAAW,EAAuB,IAAI,GACtC,IAAiB,EAAuB,IAAI,GAC5C,IAAuB,EAAiC,IAAI,GAC5D,IAAY,EAA8B,IAAI,GAG9C,EACJ,kBACA,yBACA,WAAW,MACT,EAAyB,CAAC,CAAM,GAC9B,EAAE,0BAAuB,2BAAwB,EAAsB,GAevE,IAAa,GAEb,CAAC,GAAM,KAAW,EAAoB,iBAAiB,GACvD,CAAC,GAAkB,KAAuB,EAA0B,IAAI,GACxE,CAAC,GAAO,KAAY,EAAwB,IAAI,GAChD,CAAC,GAAc,KAAmB,EAAS,EAAK,GAChD,CAAC,GAAc,KAAmB,EAAS,EAAK,GAChD,CAAC,GAAgB,KAAqB,EAAS,EAAE,GACjD,CAAC,GAAc,KAAmB,EAAS,EAAI,GAC/C,CAAC,GAAgB,KAAqB,EAAS,EAAK,GAGpD,IAAuB,GAAa,MAAuB;EAG/D,AAFA,EAAoB,CAAQ,GAC5B,EAAQ,UAAU,GAClB,EAAS,IAAI;CACf,GAAG,CAAC,CAAC;CA0GL,AAvGA,QAAgB;EACd,AAAI,KACF,EAAQ,iBAAiB,GACzB,EAAoB,IAAI,GACxB,EAAS,IAAI,GACb,EAAkB,EAAE,GACpB,EAAgB,EAAI,GACpB,EAAkB,EAAK,KAGvB,AAEE,EAAqB,aADrB,EAAqB,QAAQ,QAAQ,GACN;CAGrC,GAAG,CAAC,CAAM,CAAC,GAIX,QAAgB;EACV,MAAS,qBAAqB,KAC9B,KACF,EAAqB,QAAQ;CAEjC,GAAG;EAAC;EAAM;EAAiB;EAAY;CAAoB,CAAC,GAG5D,QAAgB;EACV,YAAS,cAAc,MAAqB,WAGhD;OAAI,CAAC,KAAwB,CAAC,GAAiB;IAC7C,EAAS,mDAAmD;IAC5D;GACF;GAwDA,OAtDK,MAoDL,YAlD+B;IAC7B,EAAgB,EAAI;IACpB,IAAI;KAGF,IAFA,MAAM,EAAW,6BAA6B,WAAW,GAErD,CAAC,OAAO,QACV,MAAU,MAAM,2BAA2B;KAG7C,IAAM,IAAS,OAAO,OAAO,CAAoB;KACjD,EAAU,UAAU;KAGpB,IAAI,IAAW;KACf,OAAO,CAAC,EAAe,WAAW,IAAW,KAE3C,AADA,MAAM,IAAI,SAAS,MAAY,WAAW,GAAS,GAAG,CAAC,GACvD;KAGF,IAAI,CAAC,EAAe,SAClB,MAAU,MAAM,kDAAkD;KAGpE,IAAI,EAAqB,SACvB;KAIF,IAAM,IADW,EAAO,SACJ,EAAS,OAAO,QAAQ,EAC1C,OAAO,EAA0B,sCAAsC,EACzE,CAAC;KAKD,AAHA,EAAY,MAAM,EAAe,OAAO,GACxC,EAAqB,UAAU,GAE/B,EAAY,GAAG,WAAW,MAAU;MAElC,AADA,EAAkB,EAAM,QAAQ,GAC5B,EAAM,QACR,EAAS,EAAM,MAAM,OAAO,IAE5B,EAAS,IAAI;KAEjB,CAAC;IACH,SAAS,GAAK;KACZ,EAAS,aAAe,QAAQ,EAAI,UAAU,uBAAuB;IACvE,UAAU;KACR,EAAgB,EAAK;IACvB;GACF,GAEW,SAEE;IACX,IAAI,EAAqB,SACvB,IAAI;KAEF,AADA,EAAqB,QAAQ,QAAQ,GACrC,EAAqB,UAAU;IACjC,QAAQ,CAER;GAEJ,KA/D2B;EAF3B;CAkEF,GAAG;EAAC;EAAM;EAAkB;EAAsB;CAAe,CAAC,GAGlE,QAAgB;EACd,IAAM,KAAiB,MAAqB;GAC1C,AAAI,EAAE,QAAQ,YAAY,KAAU,CAAC,KACnC,EAAQ;EAEZ;EAEA,OADA,SAAS,iBAAiB,WAAW,CAAa,SACrC,SAAS,oBAAoB,WAAW,CAAa;CACpE,GAAG;EAAC;EAAQ;EAAc;CAAO,CAAC;CAElC,IAAM,IAAqB,EAAY,YAAY;EACjD,IAAI,CAAC,EAAU,WAAW,CAAC,EAAqB,SAAS;GACvD,EAAS,wBAAwB;GACjC;EACF;EAEA,IAAI,CAAC,EAAe,KAAK,GAAG;GAC1B,EAAS,kCAAkC;GAC3C;EACF;EAGA,AADA,EAAgB,EAAI,GACpB,EAAS,IAAI;EAEb,IAAI;GAEF,IAAM,IAAqB,MAAM,EAAoB;IACnD;IACA,UAAU;IACV,UAAU,EAA0B;IACpC;GACF,CAAC;GAED,IAAI,CAAC,EAAmB,cACtB,MAAU,MAAM,sCAAsC;GAIxD,IAAM,EAAE,gBAAa,OAAO,MAAgB,MAAM,EAAU,QAAQ,iBAClE,EAAmB,cACnB,EACE,gBAAgB;IACd,MAAM,EAAqB;IAC3B,iBAAiB,EAAE,MAAM,EAAe;GAC1C,EACF,CACF;GAEA,IAAI,GACF,MAAU,MAAM,EAAY,OAAO;GAGrC,IAAI,GAAa,WAAW,aAC1B,MAAU,MAAM,0BAA0B;GAW5C,AAPA,EAAQ,SAAS,GAGjB,MAAM,IAAI,SAAS,MAAY,WAAW,GAAS,GAAI,CAAC,GACxD,IAAY,GAGZ,iBAAiB;IACf,EAAQ;GACV,GAAG,GAAG;EACR,SAAS,GAAK;GAEZ,AADA,EAAS,aAAe,QAAQ,EAAI,UAAU,8BAA8B,GAC5E,EAAgB,EAAK;EACvB;CACF,GAAG;EAAC;EAAgB;EAAc;EAAkB;EAAqB;EAAW;CAAO,CAAC,GAEtF,IAAe,QAAkB;EACrC,AAAI,MAAqB,YACvB,EAAmB;CAEvB,GAAG,CAAC,GAAkB,CAAkB,CAAC;CAIzC,OAFK,IAGH,kBAAC,OAAD;EACE,WAAU;EACV,MAAK;EACL,cAAW;EACX,mBAAgB;YAJlB,CAOE,kBAAC,OAAD;GACE,WAAU;GACV,SAAU,IAAyB,KAAA,IAAV;GACzB,eAAY;EACb,CAAA,GAGD,kBAAC,OAAD;GACE,KAAK;GACL,WAAU;aAFZ;IAKE,kBAAC,UAAD;KAAQ,WAAU;eAAlB,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,GAAD,EAAY,WAAU,wBAAyB,CAAA;MAC5C,CAAA,GACL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;OAAI,IAAG;OAAc,WAAU;iBAC5B,MAAS,YAAY,yBAAyB;MAC7C,CAAA,GACJ,kBAAC,KAAD;OAAG,WAAU;iBAAb;QACG,MAAS,sBACP,IAAa,wBAAwB;QACvC,MAAS,cAAc;QACvB,MAAS,gBAAgB;QACzB,MAAS,aAAa;OACtB;QACA,EAAA,CAAA,CACF;SACL,kBAAC,UAAD;MACE,MAAK;MACL,SAAS;MACT,UAAU;MACV,WAAU;MACV,cAAW;gBAEX,kBAAC,GAAD,EAAG,WAAU,SAAU,CAAA;KACjB,CAAA,CACF;;IAGR,kBAAC,OAAD;KAAK,WAAU;eACZ,IACC,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,GAAD,EAAS,WAAU,0CAA2C,CAAA;KAC3D,CAAA,IACH,MAAS,oBACX,kBAAC,OAAD;MAAK,WAAU;gBACZ,IACC,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,GAAD,EAAS,WAAU,0CAA2C,CAAA;MAC3D,CAAA,IAEL,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,GAAD,EAAa,WAAU,wCAAyC,CAAA;QAChE,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAG,uCAAuC,gCAAgC;QAC1E,CAAA;QACH,kBAAC,KAAD;SAAG,WAAU;mBAAmC;QAE7C,CAAA;OACA;;KAEJ,CAAA,IACH,MAAS,aACX,kBAAC,OAAD;MAAK,WAAU;gBAAf;OAEG,KACC,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD,EAAa,WAAU,uBAAwB,CAAA,GAC/C,kBAAC,KAAD;SAAG,WAAU;mBAAW;QAAS,CAAA,CAC9B;;OAIN,MAAqB,YACpB,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,SAAD;SACE,SAAQ;SACR,WAAU;mBACX;QAEM,CAAA,GACP,kBAAC,SAAD;SACE,MAAK;SACL,IAAG;SACH,OAAO;SACP,WAAW,MAAM,EAAkB,EAAE,OAAO,KAAK;SACjD,WAAU;SACV,aAAY;SACZ,UAAU;QACX,CAAA,CACE;;OAIN,MAAqB,YACpB,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,SAAD;SAAO,WAAU;mBACd,EAAG,gCAAgC,cAAc;QAC7C,CAAA,GACP,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,OAAD;UACE,KAAK;UACL,WAAU;SACX,CAAA,GACA,KACC,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,GAAD,EAAS,WAAU,0CAA2C,CAAA,GAC9D,kBAAC,QAAD;WAAM,WAAU;qBAAmC;UAAqB,CAAA,CACrE;WAEJ;UACF;;OAIP,kBAAC,SAAD;QAAO,WAAU;kBAAjB,CACE,kBAAC,SAAD;SACE,MAAK;SACL,SAAS;SACT,WAAW,MAAM,EAAgB,EAAE,OAAO,OAAO;SACjD,WAAU;SACV,UAAU;QACX,CAAA,GACD,kBAAC,QAAD;SAAM,WAAU;mBACb,EAAG,iCAAiC,+BAA+B;QAChE,CAAA,CACD;;OAGP,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,QAAD;SAAM,WAAU;mBAA8B;QAAgB,CAAA,GAC9D,kBAAC,QAAD;SAAM,WAAU;mBAA8G;QAExH,CAAA,CACH;;MACF;UAGL,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,OAAD;QAAK,WAAU;kBACb,kBAAC,GAAD,EAAc,WAAU,kCAAmC,CAAA;OACxD,CAAA;OACL,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAG,uCAAuC,oCAAoC;OAC9E,CAAA;OACH,kBAAC,KAAD;QAAG,WAAU;kBAAmC;OAE7C,CAAA;MACA;;IAEJ,CAAA;IAGJ,MAAS,aACR,kBAAC,UAAD;KAAQ,WAAU;eAAlB,CACE,kBAAC,OAAD,CAAM,CAAA,GACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,UAAD;OACE,MAAK;OACL,SAAS;OACT,UAAU;OACV,WAAU;iBACX;MAEO,CAAA,GACP,MAAS,cACR,kBAAC,UAAD;OACE,MAAK;OACL,SAAS;OACT,UACE,KAAgB,KAAyB,KAAgB,CAAC;OAE5D,WAAU;iBAET,KAAgB,IACf,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD,EAAS,WAAU,sBAAuB,CAAA,GAAC,WAE3C,EAAA,CAAA,IACA,IACF,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD,EAAS,WAAU,sBAAuB,CAAA,GAAC,UAE3C,EAAA,CAAA,IAEF;MAEI,CAAA,CAEP;OACC;;GAEP;IACF;MA9Ma;AAgNtB"}
@@ -1,12 +1,12 @@
1
1
  import { gatewayGraphqlRequest as e } from "../../shared/utils/gatewayGraphql.js";
2
2
  import { directBillingGraphqlRequest as t } from "../../shared/utils/directBillingGraphql.js";
3
3
  import "../../shared/utils/index.js";
4
- import { AddPayoutAccountDocument as n, AdminDeveloperRevenueOrgDetailDocument as r, AdminDeveloperRevenueOrgsDocument as i, AdminPayoutRequestsDocument as a, AdminPayoutSummaryDocument as o, ApprovePayoutRequestDocument as s, ArchivePayoutAccountDocument as c, BillingDeveloperPortalRevenueDocument as l, MarkPayoutPaidDocument as u, MyEarningsEntriesDocument as d, MyEarningsSummaryDocument as f, MyPayoutAccountsDocument as p, MyPayoutRequestsDocument as m, RejectPayoutRequestDocument as h, RetrySaleCreditSyncDocument as g, SetDefaultPayoutAccountDocument as _, UpdatePayoutAccountDocument as v } from "../../../generated/global-operations.js";
4
+ import { AddPayoutAccountDocument as n, AdminDeveloperRevenueOrgDetailDocument as r, AdminDeveloperRevenueOrgDocument as i, AdminDeveloperRevenueOrgMonthlyDocument as a, AdminDeveloperRevenueOrgsDocument as o, AdminPayoutRequestsDocument as s, AdminPayoutSummaryDocument as c, ApprovePayoutRequestDocument as l, ArchivePayoutAccountDocument as u, BillingDeveloperPortalRevenueDocument as d, GetCostOfCreditsDocument as f, GetCreditBalanceByTypeDocument as p, MarkPayoutPaidDocument as m, MyEarningsEntriesDocument as h, MyEarningsSummaryDocument as g, MyPayoutAccountsDocument as _, MyPayoutRequestsDocument as v, RejectPayoutRequestDocument as y, RetrySaleCreditSyncDocument as b, SetDefaultPayoutAccountDocument as x, UpdatePayoutAccountDocument as S } from "../../../generated/global-operations.js";
5
5
  //#region src/billing/modules/earnings/api.ts
6
- async function y(t, n) {
6
+ async function C(t, n) {
7
7
  let r = await e({
8
8
  ...n,
9
- query: l,
9
+ query: d,
10
10
  variables: { organizationId: t }
11
11
  });
12
12
  return {
@@ -15,140 +15,177 @@ async function y(t, n) {
15
15
  payouts: r.developerOrgPayouts.edges.map((e) => e.node)
16
16
  };
17
17
  }
18
- async function b(e, n) {
18
+ async function w(e, n) {
19
19
  return (await t({
20
20
  ...n,
21
- query: f,
21
+ query: g,
22
22
  variables: { billingAccountId: e }
23
23
  })).myEarningsSummary;
24
24
  }
25
- async function x(e, n) {
25
+ async function T(e, n) {
26
26
  return (await t({
27
27
  ...n,
28
- query: d,
28
+ query: h,
29
29
  variables: { billingAccountId: e }
30
30
  })).myEarningsEntries.items;
31
31
  }
32
- async function S(e, n) {
32
+ async function E(e, n) {
33
33
  return (await t({
34
34
  ...n,
35
- query: p,
35
+ query: _,
36
36
  variables: { billingAccountId: e }
37
37
  })).myPayoutAccounts;
38
38
  }
39
- async function C(e, n) {
39
+ async function D(e, n) {
40
40
  return (await t({
41
41
  ...n,
42
- query: m,
42
+ query: v,
43
43
  variables: { billingAccountId: e }
44
44
  })).myPayoutRequests.items;
45
45
  }
46
- async function w(e, r) {
46
+ async function O(e, r) {
47
47
  await t({
48
48
  ...r,
49
49
  query: n,
50
50
  variables: { input: e }
51
51
  });
52
52
  }
53
- async function T(e, n, r) {
53
+ async function k(e, n, r) {
54
54
  await t({
55
55
  ...r,
56
- query: v,
56
+ query: S,
57
57
  variables: {
58
58
  id: e,
59
59
  input: n
60
60
  }
61
61
  });
62
62
  }
63
- async function E(e, n) {
63
+ async function A(e, n) {
64
64
  await t({
65
65
  ...n,
66
- query: _,
66
+ query: x,
67
67
  variables: { id: e }
68
68
  });
69
69
  }
70
- async function D(e, n) {
70
+ async function j(e, n) {
71
71
  await t({
72
72
  ...n,
73
- query: c,
73
+ query: u,
74
74
  variables: { id: e }
75
75
  });
76
76
  }
77
- async function O(e, t) {
77
+ async function M(e, t) {
78
78
  throw Error("Payout request not yet implemented");
79
79
  }
80
- async function k(e) {
80
+ async function N(e) {
81
81
  return (await t({
82
82
  ...e,
83
- query: o
83
+ query: c
84
84
  })).adminPayoutSummary;
85
85
  }
86
- async function A(e, n = {}) {
86
+ async function P(e, n = {}) {
87
87
  return (await t({
88
88
  ...e,
89
- query: a,
89
+ query: s,
90
90
  variables: {
91
91
  limit: n.limit ?? 50,
92
- offset: n.offset ?? 0
92
+ offset: n.offset ?? 0,
93
+ filter: n.filter
93
94
  }
94
95
  })).adminPayoutRequests;
95
96
  }
96
- async function j(t) {
97
+ async function F(t) {
97
98
  return (await e({
98
99
  ...t,
99
- query: i
100
+ query: o
100
101
  })).developerOrganizations.edges.map((e) => e.node);
101
102
  }
102
- async function M(t, n) {
103
- let i = await e({
103
+ async function I(t, n) {
104
+ return (await e({
105
+ ...n,
106
+ query: i,
107
+ variables: { organizationId: t }
108
+ })).developerOrganization;
109
+ }
110
+ async function L(t, n, i = {}) {
111
+ let a = await e({
104
112
  ...n,
105
113
  query: r,
106
114
  variables: {
107
115
  organizationId: t,
108
116
  period: "monthly",
109
- salesLimit: 20,
110
- salesOffset: 0
117
+ salesLimit: 50,
118
+ salesOffset: 0,
119
+ startDate: i.startDate,
120
+ endDate: i.endDate
111
121
  }
112
122
  });
113
123
  return {
114
- summary: i.developerOrgRevenueSummary,
124
+ summary: a.developerOrgRevenueSummary,
115
125
  unpaidSales: {
116
- totalCount: i.developerOrgSales.totalCount,
117
- items: i.developerOrgSales.edges.map((e) => e.node)
126
+ totalCount: a.developerOrgSales.totalCount,
127
+ items: a.developerOrgSales.edges.map((e) => e.node)
118
128
  }
119
129
  };
120
130
  }
121
- async function N(t, n) {
131
+ async function R(e, n, r) {
132
+ return (await t({
133
+ ...r,
134
+ query: f,
135
+ variables: {
136
+ creditAmount: e,
137
+ currency: n
138
+ }
139
+ })).getCostOfCredits.amount;
140
+ }
141
+ async function z(t, n, r = 12) {
122
142
  return (await e({
123
143
  ...n,
124
- query: g,
144
+ query: a,
145
+ variables: {
146
+ organizationId: t,
147
+ months: r
148
+ }
149
+ })).developerOrgMonthlyRevenue;
150
+ }
151
+ async function B(e, n) {
152
+ return (await t({
153
+ ...n,
154
+ query: p,
155
+ variables: { billingAccountId: e }
156
+ })).getCreditBalanceByType;
157
+ }
158
+ async function V(t, n) {
159
+ return (await e({
160
+ ...n,
161
+ query: b,
125
162
  variables: { saleId: t }
126
163
  })).retrySaleCreditSync;
127
164
  }
128
- async function P(e, n, r) {
165
+ async function H(e, n, r) {
129
166
  await t({
130
167
  ...r,
131
- query: s,
168
+ query: l,
132
169
  variables: {
133
170
  id: e,
134
171
  notes: n
135
172
  }
136
173
  });
137
174
  }
138
- async function F(e, n, r) {
175
+ async function U(e, n, r) {
139
176
  await t({
140
177
  ...r,
141
- query: h,
178
+ query: y,
142
179
  variables: {
143
180
  id: e,
144
181
  reason: n
145
182
  }
146
183
  });
147
184
  }
148
- async function I(e, n, r, i) {
185
+ async function W(e, n, r, i) {
149
186
  await t({
150
187
  ...i,
151
- query: u,
188
+ query: m,
152
189
  variables: {
153
190
  id: e,
154
191
  externalReference: n,
@@ -157,6 +194,6 @@ async function I(e, n, r, i) {
157
194
  });
158
195
  }
159
196
  //#endregion
160
- export { w as addPayoutAccount, P as approvePayoutRequest, D as archivePayoutAccount, M as fetchAdminDeveloperRevenueOrgDetail, j as fetchAdminDeveloperRevenueOrgs, A as fetchAdminPayoutRequests, k as fetchAdminPayoutSummary, y as fetchDeveloperPortalRevenueDashboard, x as fetchEarningsEntries, b as fetchEarningsSummary, S as fetchPayoutAccounts, C as fetchPayoutRequests, I as markPayoutPaid, F as rejectPayoutRequest, O as requestPayout, N as retrySaleCreditSync, E as setDefaultPayoutAccount, T as updatePayoutAccount };
197
+ export { O as addPayoutAccount, H as approvePayoutRequest, j as archivePayoutAccount, I as fetchAdminDeveloperRevenueOrg, L as fetchAdminDeveloperRevenueOrgDetail, z as fetchAdminDeveloperRevenueOrgMonthly, F as fetchAdminDeveloperRevenueOrgs, P as fetchAdminPayoutRequests, N as fetchAdminPayoutSummary, B as fetchBillingAccountCreditBalance, R as fetchCreditCost, C as fetchDeveloperPortalRevenueDashboard, T as fetchEarningsEntries, w as fetchEarningsSummary, E as fetchPayoutAccounts, D as fetchPayoutRequests, W as markPayoutPaid, U as rejectPayoutRequest, M as requestPayout, V as retrySaleCreditSync, A as setDefaultPayoutAccount, k as updatePayoutAccount };
161
198
 
162
199
  //# sourceMappingURL=api.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","names":[],"sources":["../../../../src/billing/modules/earnings/api.ts"],"sourcesContent":["import { directBillingGraphqlRequest } from '../../shared/utils';\nimport { gatewayGraphqlRequest } from '../../shared/utils/gatewayGraphql';\nimport {\n AddPayoutAccountDocument,\n AdminDeveloperRevenueOrgDetailDocument,\n AdminDeveloperRevenueOrgsDocument,\n AdminPayoutRequestsDocument,\n AdminPayoutSummaryDocument,\n ApprovePayoutRequestDocument,\n ArchivePayoutAccountDocument,\n BillingDeveloperPortalRevenueDocument,\n MarkPayoutPaidDocument,\n MyEarningsEntriesDocument,\n MyEarningsSummaryDocument,\n MyPayoutAccountsDocument,\n MyPayoutRequestsDocument,\n ProcessPayoutRequestDocument,\n RejectPayoutRequestDocument,\n RetrySaleCreditSyncDocument,\n SetDefaultPayoutAccountDocument,\n UpdatePayoutAccountDocument,\n} from '../../../generated/global-operations';\n\nexport interface EarningsSummary {\n totalLifetimeAmount: number;\n availableAmount: number;\n reservedAmount: number;\n paidAmount: number;\n pendingAmount: number;\n moneyAmount: number;\n creditsAmount: number;\n categoryBreakdown?: Array<{\n category: 'AFFILIATE' | 'STORE' | 'OTHER';\n amount: number;\n count: number;\n }>;\n}\n\nexport interface EarningsEntry {\n id: string;\n sourceCategory: 'AFFILIATE' | 'STORE' | 'OTHER';\n sourceSubcategory?: string | null;\n description?: string | null;\n unitType: 'MONEY' | 'CREDITS';\n amount: number;\n currency: string;\n status: 'AVAILABLE' | 'RESERVED' | 'PAID' | 'REVERSED';\n createdAt: string;\n}\n\nexport interface PayoutAccount {\n id: string;\n label: string;\n type: 'BANK_ACCOUNT' | 'UPI' | 'WALLET';\n providerPreference: 'AUTO' | 'STRIPE' | 'RAZORPAY' | 'MANUAL';\n status: 'PENDING_VERIFICATION' | 'ACTIVE' | 'FAILED_VERIFICATION' | 'ARCHIVED';\n displayName?: string | null;\n accountLast4?: string | null;\n country?: string | null;\n currency: string;\n isDefault: boolean;\n accountDetails?: Record<string, unknown> | null;\n}\n\nexport interface PayoutRequest {\n id: string;\n billingAccountId?: string | null;\n requesterUserId?: string | null;\n requestedAmount: number;\n approvedAmount?: number | null;\n currency: string;\n provider: 'AUTO' | 'STRIPE' | 'RAZORPAY' | 'MANUAL';\n status: 'REQUESTED' | 'APPROVED' | 'REJECTED' | 'PROCESSING' | 'PAID' | 'FAILED' | 'CANCELED';\n externalReference?: string | null;\n failureReason?: string | null;\n internalNotes?: string | null;\n userNotes?: string | null;\n createdAt: string;\n processedAt?: string | null;\n paidAt?: string | null;\n payoutAccount?: PayoutAccount | null;\n}\n\nexport interface PayoutAdminSummary {\n totalRequestedAmount: number;\n totalProcessingAmount: number;\n totalPaidAmount: number;\n pendingCount: number;\n failedCount: number;\n statusBreakdown?: Array<{ status: string; count: number; totalAmount: number }>;\n providerBreakdown?: Array<{ provider: string; count: number; totalAmount: number }>;\n}\n\nexport interface AdminPayoutRequestsPage {\n items: PayoutRequest[];\n totalCount: number;\n hasMore: boolean;\n}\n\nexport interface DeveloperPortalRevenueSummary {\n totalGrossRevenue: number;\n totalNetRevenue: number;\n totalPlatformFees: number;\n totalRefunds: number;\n totalRefundsCount: number;\n totalSales: number;\n pendingBalance: number;\n nextPayoutDate?: string | null;\n nextPayoutAmount?: number | null;\n}\n\nexport interface DeveloperPortalRevenueSale {\n id: string;\n grossAmount: number;\n netAmount: number;\n currency: string;\n pricingModel: string;\n status: string;\n billingCreditSyncStatus?: string | null;\n billingCreditSyncError?: string | null;\n billingCreditSyncedAt?: string | null;\n purchasedAt: string;\n application?: {\n id: string;\n name: string;\n slug: string;\n } | null;\n}\n\nexport interface DeveloperPortalRevenuePayout {\n id: string;\n periodLabel?: string | null;\n netAmount: number;\n currency: string;\n status: string;\n scheduledAt?: string | null;\n completedAt?: string | null;\n}\n\nexport interface DeveloperPortalRevenueDashboard {\n summary: DeveloperPortalRevenueSummary | null;\n sales: DeveloperPortalRevenueSale[];\n payouts: DeveloperPortalRevenuePayout[];\n}\n\nexport interface AdminDeveloperRevenueOrg {\n id: string;\n name: string;\n slug: string;\n billingAccountId?: string | null;\n isVerified: boolean;\n totalApps: number;\n publishedApps: number;\n totalInstalls: number;\n activeInstalls: number;\n averageRating?: number | null;\n totalRevenue: number;\n totalPlatformFees: number;\n totalPayouts: number;\n pendingBalance: number;\n lifetimeRevenue: number;\n platformFeeRate: number;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface AdminDeveloperRevenueOrgDetail {\n summary: DeveloperPortalRevenueSummary | null;\n unpaidSales: {\n totalCount: number;\n items: DeveloperPortalRevenueSale[];\n };\n}\n\ninterface GatewayContext {\n apiGatewayUrl?: string;\n authToken?: string;\n orgId?: string;\n}\n\nexport async function fetchDeveloperPortalRevenueDashboard(\n organizationId: string,\n context: GatewayContext\n): Promise<DeveloperPortalRevenueDashboard> {\n type RevenueQueryResult = {\n developerOrgRevenueSummary: DeveloperPortalRevenueSummary | null;\n developerOrgSales: { edges: Array<{ node: DeveloperPortalRevenueSale }> };\n developerOrgPayouts: { edges: Array<{ node: DeveloperPortalRevenuePayout }> };\n };\n\n const data = await gatewayGraphqlRequest<RevenueQueryResult, { organizationId: string }>({\n ...context,\n query: BillingDeveloperPortalRevenueDocument,\n variables: { organizationId },\n });\n\n return {\n summary: data.developerOrgRevenueSummary,\n sales: data.developerOrgSales.edges.map((edge) => edge.node),\n payouts: data.developerOrgPayouts.edges.map((edge) => edge.node),\n };\n}\n\nexport async function fetchEarningsSummary(billingAccountId: string, context: GatewayContext) {\n const data = await directBillingGraphqlRequest<\n {\n myEarningsSummary: EarningsSummary;\n },\n { billingAccountId: string }\n >({\n ...context,\n query: MyEarningsSummaryDocument,\n variables: { billingAccountId },\n });\n\n return data.myEarningsSummary;\n}\n\nexport async function fetchEarningsEntries(billingAccountId: string, context: GatewayContext) {\n const data = await directBillingGraphqlRequest<\n {\n myEarningsEntries: { items: EarningsEntry[] };\n },\n { billingAccountId: string }\n >({\n ...context,\n query: MyEarningsEntriesDocument,\n variables: { billingAccountId },\n });\n\n return data.myEarningsEntries.items;\n}\n\nexport async function fetchPayoutAccounts(billingAccountId: string, context: GatewayContext) {\n const data = await directBillingGraphqlRequest<\n {\n myPayoutAccounts: PayoutAccount[];\n },\n { billingAccountId: string }\n >({\n ...context,\n query: MyPayoutAccountsDocument,\n variables: { billingAccountId },\n });\n\n return data.myPayoutAccounts;\n}\n\nexport async function fetchPayoutRequests(billingAccountId: string, context: GatewayContext) {\n const data = await directBillingGraphqlRequest<\n {\n myPayoutRequests: { items: PayoutRequest[] };\n },\n { billingAccountId: string }\n >({\n ...context,\n query: MyPayoutRequestsDocument,\n variables: { billingAccountId },\n });\n\n return data.myPayoutRequests.items;\n}\n\nexport async function addPayoutAccount(input: Record<string, unknown>, context: GatewayContext) {\n await directBillingGraphqlRequest<\n {\n addPayoutAccount: { id: string };\n },\n { input: Record<string, unknown> }\n >({\n ...context,\n query: AddPayoutAccountDocument,\n variables: { input },\n });\n}\n\nexport async function updatePayoutAccount(\n id: string,\n input: Record<string, unknown>,\n context: GatewayContext\n) {\n await directBillingGraphqlRequest<\n { updatePayoutAccount: { id: string } },\n { id: string; input: Record<string, unknown> }\n >({\n ...context,\n query: UpdatePayoutAccountDocument,\n variables: { id, input },\n });\n}\n\nexport async function setDefaultPayoutAccount(id: string, context: GatewayContext) {\n await directBillingGraphqlRequest<{ setDefaultPayoutAccount: { id: string } }, { id: string }>({\n ...context,\n query: SetDefaultPayoutAccountDocument,\n variables: { id },\n });\n}\n\nexport async function archivePayoutAccount(id: string, context: GatewayContext) {\n await directBillingGraphqlRequest<{ archivePayoutAccount: boolean }, { id: string }>({\n ...context,\n query: ArchivePayoutAccountDocument,\n variables: { id },\n });\n}\n\nexport async function requestPayout(_input: Record<string, unknown>, _context: GatewayContext) {\n throw new Error('Payout request not yet implemented');\n}\n\nexport async function fetchAdminPayoutSummary(context: GatewayContext) {\n const data = await directBillingGraphqlRequest<{\n adminPayoutSummary: PayoutAdminSummary;\n }>({\n ...context,\n query: AdminPayoutSummaryDocument,\n });\n\n return data.adminPayoutSummary;\n}\n\nexport async function fetchAdminPayoutRequests(\n context: GatewayContext,\n pagination: { limit?: number; offset?: number } = {}\n) {\n const data = await directBillingGraphqlRequest<\n {\n adminPayoutRequests: AdminPayoutRequestsPage;\n },\n {\n limit: number;\n offset: number;\n }\n >({\n ...context,\n query: AdminPayoutRequestsDocument,\n variables: {\n limit: pagination.limit ?? 50,\n offset: pagination.offset ?? 0,\n },\n });\n\n return data.adminPayoutRequests;\n}\n\nexport async function fetchAdminDeveloperRevenueOrgs(context: GatewayContext) {\n const data = await gatewayGraphqlRequest<{\n developerOrganizations: {\n edges: Array<{ node: AdminDeveloperRevenueOrg }>;\n };\n }>({\n ...context,\n query: AdminDeveloperRevenueOrgsDocument,\n });\n\n return data.developerOrganizations.edges.map((edge) => edge.node);\n}\n\nexport async function fetchAdminDeveloperRevenueOrgDetail(\n organizationId: string,\n context: GatewayContext\n) {\n const data = await gatewayGraphqlRequest<\n {\n developerOrgRevenueSummary: DeveloperPortalRevenueSummary | null;\n developerOrgSales: { totalCount: number; edges: Array<{ node: DeveloperPortalRevenueSale }> };\n },\n {\n organizationId: string;\n period: string;\n salesLimit: number;\n salesOffset: number;\n }\n >({\n ...context,\n query: AdminDeveloperRevenueOrgDetailDocument,\n variables: {\n organizationId,\n period: 'monthly',\n salesLimit: 20,\n salesOffset: 0,\n },\n });\n\n return {\n summary: data.developerOrgRevenueSummary,\n unpaidSales: {\n totalCount: data.developerOrgSales.totalCount,\n items: data.developerOrgSales.edges.map((edge) => edge.node),\n },\n } satisfies AdminDeveloperRevenueOrgDetail;\n}\n\nexport async function retrySaleCreditSync(saleId: string, context: GatewayContext) {\n const data = await gatewayGraphqlRequest<\n {\n retrySaleCreditSync: Pick<\n DeveloperPortalRevenueSale,\n 'id' | 'billingCreditSyncStatus' | 'billingCreditSyncError' | 'billingCreditSyncedAt'\n >;\n },\n { saleId: string }\n >({\n ...context,\n query: RetrySaleCreditSyncDocument,\n variables: { saleId },\n });\n\n return data.retrySaleCreditSync;\n}\n\nexport async function approvePayoutRequest(\n id: string,\n notes: string | null,\n context: GatewayContext\n) {\n await directBillingGraphqlRequest<\n {\n approvePayoutRequest: { id: string };\n },\n { id: string; notes: string | null }\n >({\n ...context,\n query: ApprovePayoutRequestDocument,\n variables: { id, notes },\n });\n}\n\nexport async function rejectPayoutRequest(id: string, reason: string, context: GatewayContext) {\n await directBillingGraphqlRequest<\n {\n rejectPayoutRequest: { id: string };\n },\n { id: string; reason: string }\n >({\n ...context,\n query: RejectPayoutRequestDocument,\n variables: { id, reason },\n });\n}\n\nexport async function processPayoutRequest(id: string, context: GatewayContext) {\n await directBillingGraphqlRequest<\n {\n processPayoutRequest: { id: string };\n },\n { id: string }\n >({\n ...context,\n query: ProcessPayoutRequestDocument,\n variables: { id },\n });\n}\n\nexport async function markPayoutPaid(\n id: string,\n externalReference: string | null,\n notes: string | null,\n context: GatewayContext\n) {\n await directBillingGraphqlRequest<\n { markPayoutPaid: { id: string } },\n { id: string; externalReference: string | null; notes: string | null }\n >({\n ...context,\n query: MarkPayoutPaidDocument,\n variables: { id, externalReference, notes },\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"api.js","names":[],"sources":["../../../../src/billing/modules/earnings/api.ts"],"sourcesContent":["import { directBillingGraphqlRequest } from '../../shared/utils';\nimport { gatewayGraphqlRequest } from '../../shared/utils/gatewayGraphql';\nimport {\n AddPayoutAccountDocument,\n AdminDeveloperRevenueOrgDetailDocument,\n AdminDeveloperRevenueOrgDocument,\n AdminDeveloperRevenueOrgMonthlyDocument,\n AdminDeveloperRevenueOrgsDocument,\n AdminPayoutRequestsDocument,\n AdminPayoutSummaryDocument,\n ApprovePayoutRequestDocument,\n ArchivePayoutAccountDocument,\n BillingDeveloperPortalRevenueDocument,\n GetCostOfCreditsDocument,\n GetCreditBalanceByTypeDocument,\n MarkPayoutPaidDocument,\n MyEarningsEntriesDocument,\n MyEarningsSummaryDocument,\n MyPayoutAccountsDocument,\n MyPayoutRequestsDocument,\n ProcessPayoutRequestDocument,\n RejectPayoutRequestDocument,\n RetrySaleCreditSyncDocument,\n SetDefaultPayoutAccountDocument,\n UpdatePayoutAccountDocument,\n} from '../../../generated/global-operations';\n\nexport interface EarningsSummary {\n totalLifetimeAmount: number;\n availableAmount: number;\n reservedAmount: number;\n paidAmount: number;\n pendingAmount: number;\n moneyAmount: number;\n creditsAmount: number;\n categoryBreakdown?: Array<{\n category: 'AFFILIATE' | 'STORE' | 'OTHER';\n amount: number;\n count: number;\n }>;\n}\n\nexport interface EarningsEntry {\n id: string;\n sourceCategory: 'AFFILIATE' | 'STORE' | 'OTHER';\n sourceSubcategory?: string | null;\n description?: string | null;\n unitType: 'MONEY' | 'CREDITS';\n amount: number;\n currency: string;\n status: 'AVAILABLE' | 'RESERVED' | 'PAID' | 'REVERSED';\n createdAt: string;\n}\n\nexport interface PayoutAccount {\n id: string;\n label: string;\n type: 'BANK_ACCOUNT' | 'UPI' | 'WALLET';\n providerPreference: 'AUTO' | 'STRIPE' | 'RAZORPAY' | 'MANUAL';\n status: 'PENDING_VERIFICATION' | 'ACTIVE' | 'FAILED_VERIFICATION' | 'ARCHIVED';\n displayName?: string | null;\n accountLast4?: string | null;\n country?: string | null;\n currency: string;\n isDefault: boolean;\n accountDetails?: Record<string, unknown> | null;\n}\n\nexport interface PayoutRequest {\n id: string;\n billingAccountId?: string | null;\n requesterUserId?: string | null;\n requestedAmount: number;\n approvedAmount?: number | null;\n currency: string;\n provider: 'AUTO' | 'STRIPE' | 'RAZORPAY' | 'MANUAL';\n status: 'REQUESTED' | 'APPROVED' | 'REJECTED' | 'PROCESSING' | 'PAID' | 'FAILED' | 'CANCELED';\n /** See PayoutRequestKind on the backend — what approving this request actually does. */\n requestKind: 'CREDIT_CONVERSION' | 'CASH_PAYOUT';\n externalReference?: string | null;\n failureReason?: string | null;\n internalNotes?: string | null;\n userNotes?: string | null;\n createdAt: string;\n processedAt?: string | null;\n paidAt?: string | null;\n payoutAccount?: PayoutAccount | null;\n}\n\nexport interface PayoutAdminSummary {\n totalRequestedAmount: number;\n totalProcessingAmount: number;\n totalPaidAmount: number;\n pendingCount: number;\n failedCount: number;\n statusBreakdown?: Array<{ status: string; count: number; totalAmount: number }>;\n providerBreakdown?: Array<{ provider: string; count: number; totalAmount: number }>;\n}\n\nexport interface AdminPayoutRequestsPage {\n items: PayoutRequest[];\n totalCount: number;\n hasMore: boolean;\n}\n\nexport interface PayoutRequestFilter {\n billingAccountId?: string;\n provider?: PayoutRequest['provider'];\n status?: PayoutRequest['status'];\n startDate?: string;\n endDate?: string;\n}\n\nexport interface CreditBalanceByType {\n purchased: number;\n earned: number;\n granted: number;\n withdrawable: number;\n total: number;\n}\n\nexport interface DeveloperOrgMonthlyRevenuePoint {\n month: string;\n grossRevenue: number;\n platformFees: number;\n netRevenue: number;\n refunds: number;\n salesCount: number;\n}\n\nexport interface DeveloperPortalRevenueSummary {\n totalGrossRevenue: number;\n totalNetRevenue: number;\n totalPlatformFees: number;\n totalRefunds: number;\n totalRefundsCount: number;\n totalSales: number;\n pendingBalance: number;\n nextPayoutDate?: string | null;\n nextPayoutAmount?: number | null;\n}\n\nexport interface DeveloperPortalRevenueSale {\n id: string;\n grossAmount: number;\n netAmount: number;\n currency: string;\n pricingModel: string;\n status: string;\n billingCreditSyncStatus?: string | null;\n billingCreditSyncError?: string | null;\n billingCreditSyncedAt?: string | null;\n purchasedAt: string;\n application?: {\n id: string;\n name: string;\n slug: string;\n } | null;\n}\n\nexport interface DeveloperPortalRevenuePayout {\n id: string;\n periodLabel?: string | null;\n netAmount: number;\n currency: string;\n status: string;\n scheduledAt?: string | null;\n completedAt?: string | null;\n}\n\nexport interface DeveloperPortalRevenueDashboard {\n summary: DeveloperPortalRevenueSummary | null;\n sales: DeveloperPortalRevenueSale[];\n payouts: DeveloperPortalRevenuePayout[];\n}\n\nexport interface AdminDeveloperRevenueOrg {\n id: string;\n name: string;\n slug: string;\n billingAccountId?: string | null;\n isVerified: boolean;\n totalApps: number;\n publishedApps: number;\n totalInstalls: number;\n activeInstalls: number;\n averageRating?: number | null;\n totalRevenue: number;\n totalPlatformFees: number;\n totalPayouts: number;\n pendingBalance: number;\n lifetimeRevenue: number;\n platformFeeRate: number;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface AdminDeveloperRevenueOrgDetail {\n summary: DeveloperPortalRevenueSummary | null;\n unpaidSales: {\n totalCount: number;\n items: DeveloperPortalRevenueSale[];\n };\n}\n\ninterface GatewayContext {\n apiGatewayUrl?: string;\n authToken?: string;\n orgId?: string;\n}\n\nexport async function fetchDeveloperPortalRevenueDashboard(\n organizationId: string,\n context: GatewayContext\n): Promise<DeveloperPortalRevenueDashboard> {\n type RevenueQueryResult = {\n developerOrgRevenueSummary: DeveloperPortalRevenueSummary | null;\n developerOrgSales: { edges: Array<{ node: DeveloperPortalRevenueSale }> };\n developerOrgPayouts: { edges: Array<{ node: DeveloperPortalRevenuePayout }> };\n };\n\n const data = await gatewayGraphqlRequest<RevenueQueryResult, { organizationId: string }>({\n ...context,\n query: BillingDeveloperPortalRevenueDocument,\n variables: { organizationId },\n });\n\n return {\n summary: data.developerOrgRevenueSummary,\n sales: data.developerOrgSales.edges.map((edge) => edge.node),\n payouts: data.developerOrgPayouts.edges.map((edge) => edge.node),\n };\n}\n\nexport async function fetchEarningsSummary(billingAccountId: string, context: GatewayContext) {\n const data = await directBillingGraphqlRequest<\n {\n myEarningsSummary: EarningsSummary;\n },\n { billingAccountId: string }\n >({\n ...context,\n query: MyEarningsSummaryDocument,\n variables: { billingAccountId },\n });\n\n return data.myEarningsSummary;\n}\n\nexport async function fetchEarningsEntries(billingAccountId: string, context: GatewayContext) {\n const data = await directBillingGraphqlRequest<\n {\n myEarningsEntries: { items: EarningsEntry[] };\n },\n { billingAccountId: string }\n >({\n ...context,\n query: MyEarningsEntriesDocument,\n variables: { billingAccountId },\n });\n\n return data.myEarningsEntries.items;\n}\n\nexport async function fetchPayoutAccounts(billingAccountId: string, context: GatewayContext) {\n const data = await directBillingGraphqlRequest<\n {\n myPayoutAccounts: PayoutAccount[];\n },\n { billingAccountId: string }\n >({\n ...context,\n query: MyPayoutAccountsDocument,\n variables: { billingAccountId },\n });\n\n return data.myPayoutAccounts;\n}\n\nexport async function fetchPayoutRequests(billingAccountId: string, context: GatewayContext) {\n const data = await directBillingGraphqlRequest<\n {\n myPayoutRequests: { items: PayoutRequest[] };\n },\n { billingAccountId: string }\n >({\n ...context,\n query: MyPayoutRequestsDocument,\n variables: { billingAccountId },\n });\n\n return data.myPayoutRequests.items;\n}\n\nexport async function addPayoutAccount(input: Record<string, unknown>, context: GatewayContext) {\n await directBillingGraphqlRequest<\n {\n addPayoutAccount: { id: string };\n },\n { input: Record<string, unknown> }\n >({\n ...context,\n query: AddPayoutAccountDocument,\n variables: { input },\n });\n}\n\nexport async function updatePayoutAccount(\n id: string,\n input: Record<string, unknown>,\n context: GatewayContext\n) {\n await directBillingGraphqlRequest<\n { updatePayoutAccount: { id: string } },\n { id: string; input: Record<string, unknown> }\n >({\n ...context,\n query: UpdatePayoutAccountDocument,\n variables: { id, input },\n });\n}\n\nexport async function setDefaultPayoutAccount(id: string, context: GatewayContext) {\n await directBillingGraphqlRequest<{ setDefaultPayoutAccount: { id: string } }, { id: string }>({\n ...context,\n query: SetDefaultPayoutAccountDocument,\n variables: { id },\n });\n}\n\nexport async function archivePayoutAccount(id: string, context: GatewayContext) {\n await directBillingGraphqlRequest<{ archivePayoutAccount: boolean }, { id: string }>({\n ...context,\n query: ArchivePayoutAccountDocument,\n variables: { id },\n });\n}\n\nexport async function requestPayout(_input: Record<string, unknown>, _context: GatewayContext) {\n throw new Error('Payout request not yet implemented');\n}\n\nexport async function fetchAdminPayoutSummary(context: GatewayContext) {\n const data = await directBillingGraphqlRequest<{\n adminPayoutSummary: PayoutAdminSummary;\n }>({\n ...context,\n query: AdminPayoutSummaryDocument,\n });\n\n return data.adminPayoutSummary;\n}\n\nexport async function fetchAdminPayoutRequests(\n context: GatewayContext,\n pagination: { limit?: number; offset?: number; filter?: PayoutRequestFilter } = {}\n) {\n const data = await directBillingGraphqlRequest<\n {\n adminPayoutRequests: AdminPayoutRequestsPage;\n },\n {\n limit: number;\n offset: number;\n filter?: PayoutRequestFilter;\n }\n >({\n ...context,\n query: AdminPayoutRequestsDocument,\n variables: {\n limit: pagination.limit ?? 50,\n offset: pagination.offset ?? 0,\n filter: pagination.filter,\n },\n });\n\n return data.adminPayoutRequests;\n}\n\nexport async function fetchAdminDeveloperRevenueOrgs(context: GatewayContext) {\n const data = await gatewayGraphqlRequest<{\n developerOrganizations: {\n edges: Array<{ node: AdminDeveloperRevenueOrg }>;\n };\n }>({\n ...context,\n query: AdminDeveloperRevenueOrgsDocument,\n });\n\n return data.developerOrganizations.edges.map((edge) => edge.node);\n}\n\nexport async function fetchAdminDeveloperRevenueOrg(\n organizationId: string,\n context: GatewayContext\n) {\n const data = await gatewayGraphqlRequest<\n { developerOrganization: AdminDeveloperRevenueOrg | null },\n { organizationId: string }\n >({\n ...context,\n query: AdminDeveloperRevenueOrgDocument,\n variables: { organizationId },\n });\n\n return data.developerOrganization;\n}\n\nexport async function fetchAdminDeveloperRevenueOrgDetail(\n organizationId: string,\n context: GatewayContext,\n range: { startDate?: string; endDate?: string } = {}\n) {\n const data = await gatewayGraphqlRequest<\n {\n developerOrgRevenueSummary: DeveloperPortalRevenueSummary | null;\n developerOrgSales: { totalCount: number; edges: Array<{ node: DeveloperPortalRevenueSale }> };\n },\n {\n organizationId: string;\n period: string;\n salesLimit: number;\n salesOffset: number;\n startDate?: string;\n endDate?: string;\n }\n >({\n ...context,\n query: AdminDeveloperRevenueOrgDetailDocument,\n variables: {\n organizationId,\n period: 'monthly',\n salesLimit: 50,\n salesOffset: 0,\n startDate: range.startDate,\n endDate: range.endDate,\n },\n });\n\n return {\n summary: data.developerOrgRevenueSummary,\n unpaidSales: {\n totalCount: data.developerOrgSales.totalCount,\n items: data.developerOrgSales.edges.map((edge) => edge.node),\n },\n } satisfies AdminDeveloperRevenueOrgDetail;\n}\n\n/**\n * Estimated fiat cost of a raw credit amount at the current global credit\n * rate (1 credit = $0.01 by default). Credit-balance figures from\n * getCreditBalanceByType are raw credit units, NOT currency — never format\n * them with formatCurrency directly.\n */\nexport async function fetchCreditCost(\n creditAmount: number,\n currency: string,\n context: GatewayContext\n) {\n const data = await directBillingGraphqlRequest<\n { getCostOfCredits: { amount: number } },\n { creditAmount: number; currency: string }\n >({\n ...context,\n query: GetCostOfCreditsDocument,\n variables: { creditAmount, currency },\n });\n\n return data.getCostOfCredits.amount;\n}\n\nexport async function fetchAdminDeveloperRevenueOrgMonthly(\n organizationId: string,\n context: GatewayContext,\n months = 12\n) {\n const data = await gatewayGraphqlRequest<\n { developerOrgMonthlyRevenue: DeveloperOrgMonthlyRevenuePoint[] },\n { organizationId: string; months: number }\n >({\n ...context,\n query: AdminDeveloperRevenueOrgMonthlyDocument,\n variables: { organizationId, months },\n });\n\n return data.developerOrgMonthlyRevenue;\n}\n\n/**\n * Current credit balance for a devorg's linked billing account. Callable for\n * any billingAccountId as a billing admin — getCreditBalanceByType's\n * `scopeType: \"billing\"` RBAC bypasses org ownership for super_admin actors.\n */\nexport async function fetchBillingAccountCreditBalance(\n billingAccountId: string,\n context: GatewayContext\n) {\n const data = await directBillingGraphqlRequest<\n { getCreditBalanceByType: CreditBalanceByType },\n { billingAccountId: string }\n >({\n ...context,\n query: GetCreditBalanceByTypeDocument,\n variables: { billingAccountId },\n });\n\n return data.getCreditBalanceByType;\n}\n\nexport async function retrySaleCreditSync(saleId: string, context: GatewayContext) {\n const data = await gatewayGraphqlRequest<\n {\n retrySaleCreditSync: Pick<\n DeveloperPortalRevenueSale,\n 'id' | 'billingCreditSyncStatus' | 'billingCreditSyncError' | 'billingCreditSyncedAt'\n >;\n },\n { saleId: string }\n >({\n ...context,\n query: RetrySaleCreditSyncDocument,\n variables: { saleId },\n });\n\n return data.retrySaleCreditSync;\n}\n\nexport async function approvePayoutRequest(\n id: string,\n notes: string | null,\n context: GatewayContext\n) {\n await directBillingGraphqlRequest<\n {\n approvePayoutRequest: { id: string };\n },\n { id: string; notes: string | null }\n >({\n ...context,\n query: ApprovePayoutRequestDocument,\n variables: { id, notes },\n });\n}\n\nexport async function rejectPayoutRequest(id: string, reason: string, context: GatewayContext) {\n await directBillingGraphqlRequest<\n {\n rejectPayoutRequest: { id: string };\n },\n { id: string; reason: string }\n >({\n ...context,\n query: RejectPayoutRequestDocument,\n variables: { id, reason },\n });\n}\n\nexport async function processPayoutRequest(id: string, context: GatewayContext) {\n await directBillingGraphqlRequest<\n {\n processPayoutRequest: { id: string };\n },\n { id: string }\n >({\n ...context,\n query: ProcessPayoutRequestDocument,\n variables: { id },\n });\n}\n\nexport async function markPayoutPaid(\n id: string,\n externalReference: string | null,\n notes: string | null,\n context: GatewayContext\n) {\n await directBillingGraphqlRequest<\n { markPayoutPaid: { id: string } },\n { id: string; externalReference: string | null; notes: string | null }\n >({\n ...context,\n query: MarkPayoutPaidDocument,\n variables: { id, externalReference, notes },\n });\n}\n"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { EarningsPage as e } from "./pages/EarningsPage.js";
2
2
  import { DeveloperRevenueAdminPage as t } from "./pages/DeveloperRevenueAdminPage.js";
3
- import { PayoutsPage as n } from "./pages/PayoutsPage.js";
4
- import { PayoutAdminPage as r } from "./pages/PayoutAdminPage.js";
5
- export { t as DeveloperRevenueAdminPage, e as EarningsPage, r as PayoutAdminPage, n as PayoutsPage };
3
+ import { DeveloperRevenueOrgDetailPage as n } from "./pages/DeveloperRevenueOrgDetailPage.js";
4
+ import { PayoutsPage as r } from "./pages/PayoutsPage.js";
5
+ import { PayoutAdminPage as i } from "./pages/PayoutAdminPage.js";
6
+ export { t as DeveloperRevenueAdminPage, n as DeveloperRevenueOrgDetailPage, e as EarningsPage, i as PayoutAdminPage, r as PayoutsPage };