@carlonicora/nextjs-jsonapi 1.15.0 → 1.16.0
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/{ApiResponseInterface-B4QdWh-y.d.mts → ApiResponseInterface-BvWIeLkq.d.ts} +2 -1
- package/dist/{ApiResponseInterface-QLDnxLA9.d.ts → ApiResponseInterface-CAbw0sv7.d.mts} +2 -1
- package/dist/{BlockNoteEditor-ITJLAOXC.mjs → BlockNoteEditor-HFX7Z5BQ.mjs} +5 -5
- package/dist/{BlockNoteEditor-FGXYUAWI.js → BlockNoteEditor-MBFDWP7X.js} +15 -15
- package/dist/{BlockNoteEditor-FGXYUAWI.js.map → BlockNoteEditor-MBFDWP7X.js.map} +1 -1
- package/dist/JsonApiRequest-45CLE65I.js +24 -0
- package/dist/{JsonApiRequest-FXZCYIER.js.map → JsonApiRequest-45CLE65I.js.map} +1 -1
- package/dist/{JsonApiRequest-HFWXMKMA.mjs → JsonApiRequest-6IPS3DZJ.mjs} +2 -2
- package/dist/{chunk-C6QXZGL7.js → chunk-2AZLCF6D.js} +1617 -158
- package/dist/chunk-2AZLCF6D.js.map +1 -0
- package/dist/{chunk-WAFOKMKT.mjs → chunk-5RAUCUAA.mjs} +3722 -396
- package/dist/chunk-5RAUCUAA.mjs.map +1 -0
- package/dist/{chunk-TGBXBUWM.mjs → chunk-BCKYJQ3K.mjs} +8 -1
- package/dist/chunk-BCKYJQ3K.mjs.map +1 -0
- package/dist/{chunk-JGVXZS7M.mjs → chunk-BCQSE3EU.mjs} +1588 -129
- package/dist/chunk-BCQSE3EU.mjs.map +1 -0
- package/dist/{chunk-FPZPD4JI.js → chunk-GPGJNTHP.js} +17 -10
- package/dist/chunk-GPGJNTHP.js.map +1 -0
- package/dist/{chunk-PK5DRSUD.js → chunk-ONB2DAIV.js} +4090 -764
- package/dist/chunk-ONB2DAIV.js.map +1 -0
- package/dist/{chunk-SJIVGCNM.mjs → chunk-POKIJ56Q.mjs} +7 -2
- package/dist/chunk-POKIJ56Q.mjs.map +1 -0
- package/dist/{chunk-6YD42BP6.js → chunk-R5QSSISB.js} +14 -9
- package/dist/chunk-R5QSSISB.js.map +1 -0
- package/dist/client/index.d.mts +5 -5
- package/dist/client/index.d.ts +5 -5
- package/dist/client/index.js +7 -5
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +6 -4
- package/dist/components/index.d.mts +253 -9
- package/dist/components/index.d.ts +253 -9
- package/dist/components/index.js +83 -5
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +82 -4
- package/dist/{config-eceYM5kN.d.ts → config-CWsTwnsK.d.mts} +7 -2
- package/dist/{config-C5tGGrYf.d.mts → config-DEaUbBqR.d.ts} +7 -2
- package/dist/{content.interface-TB2MfJGs.d.ts → content.interface-D_4b4RQt.d.ts} +1 -1
- package/dist/{content.interface-CxBBC7ec.d.mts → content.interface-Dk4UZcJM.d.mts} +1 -1
- package/dist/contexts/index.d.mts +2 -2
- package/dist/contexts/index.d.ts +2 -2
- package/dist/contexts/index.js +5 -5
- package/dist/contexts/index.mjs +4 -4
- package/dist/core/index.d.mts +521 -18
- package/dist/core/index.d.ts +521 -18
- package/dist/core/index.js +53 -3
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +52 -2
- package/dist/index.d.mts +7 -7
- package/dist/index.d.ts +7 -7
- package/dist/index.js +56 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +55 -3
- package/dist/{notification.interface-lG6UpTpt.d.mts → notification.interface-BllkURRm.d.mts} +1 -2
- package/dist/{notification.interface-lG6UpTpt.d.ts → notification.interface-BllkURRm.d.ts} +1 -2
- package/dist/{s3.service-DP_hsssD.d.mts → s3.service-BEfGqho0.d.ts} +20 -2
- package/dist/{s3.service-Dq-PTUNa.d.ts → s3.service-DIQRYe93.d.mts} +20 -2
- package/dist/scripts/generate-web-module/generator.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/generator.js +66 -0
- package/dist/scripts/generate-web-module/generator.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/index.d.ts +8 -0
- package/dist/scripts/generate-web-module/templates/index.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/index.js +18 -1
- package/dist/scripts/generate-web-module/templates/index.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/project/bootstrapper.template.d.ts +7 -0
- package/dist/scripts/generate-web-module/templates/project/bootstrapper.template.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/templates/project/bootstrapper.template.js +141 -0
- package/dist/scripts/generate-web-module/templates/project/bootstrapper.template.js.map +1 -0
- package/dist/scripts/generate-web-module/templates/project/env.template.d.ts +7 -0
- package/dist/scripts/generate-web-module/templates/project/env.template.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/templates/project/env.template.js +110 -0
- package/dist/scripts/generate-web-module/templates/project/env.template.js.map +1 -0
- package/dist/scripts/generate-web-module/templates/project/main-layout.template.d.ts +7 -0
- package/dist/scripts/generate-web-module/templates/project/main-layout.template.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/templates/project/main-layout.template.js +101 -0
- package/dist/scripts/generate-web-module/templates/project/main-layout.template.js.map +1 -0
- package/dist/scripts/generate-web-module/templates/project/middleware-env.template.d.ts +7 -0
- package/dist/scripts/generate-web-module/templates/project/middleware-env.template.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/templates/project/middleware-env.template.js +66 -0
- package/dist/scripts/generate-web-module/templates/project/middleware-env.template.js.map +1 -0
- package/dist/scripts/generate-web-module/templates/project/settings-container.template.d.ts +7 -0
- package/dist/scripts/generate-web-module/templates/project/settings-container.template.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/templates/project/settings-container.template.js +257 -0
- package/dist/scripts/generate-web-module/templates/project/settings-container.template.js.map +1 -0
- package/dist/scripts/generate-web-module/templates/project/settings-context.template.d.ts +7 -0
- package/dist/scripts/generate-web-module/templates/project/settings-context.template.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/templates/project/settings-context.template.js +124 -0
- package/dist/scripts/generate-web-module/templates/project/settings-context.template.js.map +1 -0
- package/dist/scripts/generate-web-module/templates/project/settings-module-page.template.d.ts +7 -0
- package/dist/scripts/generate-web-module/templates/project/settings-module-page.template.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/templates/project/settings-module-page.template.js +78 -0
- package/dist/scripts/generate-web-module/templates/project/settings-module-page.template.js.map +1 -0
- package/dist/scripts/generate-web-module/templates/project/settings-page.template.d.ts +7 -0
- package/dist/scripts/generate-web-module/templates/project/settings-page.template.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/templates/project/settings-page.template.js +75 -0
- package/dist/scripts/generate-web-module/templates/project/settings-page.template.js.map +1 -0
- package/dist/scripts/generate-web-module/types/template-data.interface.d.ts +1 -1
- package/dist/scripts/generate-web-module/types/template-data.interface.d.ts.map +1 -1
- package/dist/server/index.d.mts +4 -4
- package/dist/server/index.d.ts +4 -4
- package/dist/server/index.js +12 -12
- package/dist/server/index.mjs +2 -2
- package/dist/stripe-subscription.interface-C63L6hVg.d.mts +226 -0
- package/dist/stripe-subscription.interface-CUvNDvw5.d.ts +226 -0
- package/dist/{useSocket-Bua6MwLi.d.mts → useSocket-BpenBR2z.d.mts} +1 -1
- package/dist/{useSocket-D5dhUp4m.d.ts → useSocket-D-QYA0Sr.d.ts} +1 -1
- package/package.json +9 -1
- package/scripts/generate-web-module/generator.ts +83 -0
- package/scripts/generate-web-module/templates/index.ts +10 -0
- package/scripts/generate-web-module/templates/project/bootstrapper.template.ts +108 -0
- package/scripts/generate-web-module/templates/project/env.template.ts +77 -0
- package/scripts/generate-web-module/templates/project/main-layout.template.tsx +68 -0
- package/scripts/generate-web-module/templates/project/middleware-env.template.ts +33 -0
- package/scripts/generate-web-module/templates/project/settings-container.template.tsx +224 -0
- package/scripts/generate-web-module/templates/project/settings-context.template.tsx +91 -0
- package/scripts/generate-web-module/templates/project/settings-module-page.template.tsx +45 -0
- package/scripts/generate-web-module/templates/project/settings-page.template.tsx +42 -0
- package/scripts/generate-web-module/types/template-data.interface.ts +1 -1
- package/src/client/config.ts +9 -0
- package/src/components/index.ts +7 -0
- package/src/core/abstracts/AbstractService.ts +104 -0
- package/src/core/endpoint/EndpointCreator.ts +7 -4
- package/src/core/index.ts +12 -4
- package/src/core/interfaces/ApiResponseInterface.ts +1 -0
- package/src/core/registry/ModuleRegistry.ts +11 -2
- package/src/core/utils/translateResponse.ts +17 -0
- package/src/features/billing/components/cards/BillingUsageSummaryCard.tsx +97 -0
- package/src/features/billing/components/cards/CustomerInfoCard.tsx +112 -0
- package/src/features/billing/components/cards/InvoicesSummaryCard.tsx +114 -0
- package/src/features/billing/components/cards/PaymentMethodSummaryCard.tsx +119 -0
- package/src/features/billing/components/cards/SubscriptionSummaryCard.tsx +146 -0
- package/src/features/billing/components/cards/index.ts +5 -0
- package/src/features/billing/components/containers/BillingDashboardContainer.tsx +427 -0
- package/src/features/billing/components/containers/index.ts +1 -0
- package/src/features/billing/components/index.ts +6 -0
- package/src/features/billing/components/modals/BillingDetailModal.tsx +36 -0
- package/src/features/billing/components/modals/index.ts +1 -0
- package/src/features/billing/components/providers/StripeProvider.tsx +48 -0
- package/src/features/billing/components/providers/index.ts +1 -0
- package/src/features/billing/components/utils/currency.ts +49 -0
- package/src/features/billing/components/utils/date.ts +21 -0
- package/src/features/billing/components/utils/index.ts +2 -0
- package/src/features/billing/components/widgets/BillingAlertBanner.tsx +63 -0
- package/src/features/billing/components/widgets/index.ts +1 -0
- package/src/features/billing/data/Billing.ts +17 -0
- package/src/features/billing/data/billing.service.ts +58 -0
- package/src/features/billing/data/index.ts +5 -0
- package/src/features/billing/index.ts +3 -0
- package/src/features/billing/modules/billing.module.ts +9 -0
- package/src/features/billing/modules/index.ts +1 -0
- package/src/features/billing/stripe-customer/components/containers/PaymentMethodsContainer.tsx +79 -0
- package/src/features/billing/stripe-customer/components/containers/index.ts +1 -0
- package/src/features/billing/stripe-customer/components/details/PaymentMethodCard.tsx +151 -0
- package/src/features/billing/stripe-customer/components/details/index.ts +1 -0
- package/src/features/billing/stripe-customer/components/forms/PaymentMethodEditor.tsx +186 -0
- package/src/features/billing/stripe-customer/components/forms/index.ts +1 -0
- package/src/features/billing/stripe-customer/components/index.ts +4 -0
- package/src/features/billing/stripe-customer/components/lists/PaymentMethodsList.tsx +19 -0
- package/src/features/billing/stripe-customer/components/lists/index.ts +1 -0
- package/src/features/billing/stripe-customer/data/index.ts +5 -0
- package/src/features/billing/stripe-customer/data/payment-method.interface.ts +27 -0
- package/src/features/billing/stripe-customer/data/payment-method.ts +119 -0
- package/src/features/billing/stripe-customer/data/stripe-customer.interface.ts +16 -0
- package/src/features/billing/stripe-customer/data/stripe-customer.service.ts +128 -0
- package/src/features/billing/stripe-customer/data/stripe-customer.ts +71 -0
- package/src/features/billing/stripe-customer/index.ts +3 -0
- package/src/features/billing/stripe-customer/stripe-customer.module.ts +9 -0
- package/src/features/billing/stripe-customer/stripe-payment-method.module.ts +9 -0
- package/src/features/billing/stripe-invoice/components/containers/InvoicesContainer.tsx +66 -0
- package/src/features/billing/stripe-invoice/components/containers/index.ts +1 -0
- package/src/features/billing/stripe-invoice/components/details/InvoiceDetails.tsx +172 -0
- package/src/features/billing/stripe-invoice/components/details/index.ts +1 -0
- package/src/features/billing/stripe-invoice/components/index.ts +4 -0
- package/src/features/billing/stripe-invoice/components/lists/InvoicesList.tsx +84 -0
- package/src/features/billing/stripe-invoice/components/lists/index.ts +1 -0
- package/src/features/billing/stripe-invoice/components/widgets/InvoiceStatusBadge.tsx +41 -0
- package/src/features/billing/stripe-invoice/components/widgets/index.ts +1 -0
- package/src/features/billing/stripe-invoice/data/index.ts +3 -0
- package/src/features/billing/stripe-invoice/data/stripe-invoice.interface.ts +65 -0
- package/src/features/billing/stripe-invoice/data/stripe-invoice.service.ts +64 -0
- package/src/features/billing/stripe-invoice/data/stripe-invoice.ts +177 -0
- package/src/features/billing/stripe-invoice/index.ts +2 -0
- package/src/features/billing/stripe-invoice/stripe-invoice.module.ts +9 -0
- package/src/features/billing/stripe-price/components/forms/PriceEditor.tsx +304 -0
- package/src/features/billing/stripe-price/components/forms/index.ts +1 -0
- package/src/features/billing/stripe-price/components/index.ts +2 -0
- package/src/features/billing/stripe-price/components/lists/PricesList.tsx +283 -0
- package/src/features/billing/stripe-price/components/lists/index.ts +1 -0
- package/src/features/billing/stripe-price/data/index.ts +3 -0
- package/src/features/billing/stripe-price/data/stripe-price.interface.ts +48 -0
- package/src/features/billing/stripe-price/data/stripe-price.service.ts +123 -0
- package/src/features/billing/stripe-price/data/stripe-price.ts +156 -0
- package/src/features/billing/stripe-price/index.ts +2 -0
- package/src/features/billing/stripe-price/stripe-price.module.ts +9 -0
- package/src/features/billing/stripe-product/components/containers/ProductsAdminContainer.tsx +86 -0
- package/src/features/billing/stripe-product/components/containers/index.ts +1 -0
- package/src/features/billing/stripe-product/components/forms/ProductEditor.tsx +100 -0
- package/src/features/billing/stripe-product/components/forms/index.ts +1 -0
- package/src/features/billing/stripe-product/components/index.ts +3 -0
- package/src/features/billing/stripe-product/components/lists/ProductsList.tsx +206 -0
- package/src/features/billing/stripe-product/components/lists/index.ts +1 -0
- package/src/features/billing/stripe-product/data/index.ts +3 -0
- package/src/features/billing/stripe-product/data/stripe-product.interface.ts +18 -0
- package/src/features/billing/stripe-product/data/stripe-product.service.ts +112 -0
- package/src/features/billing/stripe-product/data/stripe-product.ts +74 -0
- package/src/features/billing/stripe-product/index.ts +2 -0
- package/src/features/billing/stripe-product/stripe-product.module.ts +9 -0
- package/src/features/billing/stripe-subscription/components/containers/SubscriptionsContainer.tsx +304 -0
- package/src/features/billing/stripe-subscription/components/containers/index.ts +1 -0
- package/src/features/billing/stripe-subscription/components/details/SubscriptionDetails.tsx +223 -0
- package/src/features/billing/stripe-subscription/components/details/index.ts +1 -0
- package/src/features/billing/stripe-subscription/components/forms/CancelSubscriptionDialog.tsx +116 -0
- package/src/features/billing/stripe-subscription/components/forms/SubscriptionEditor.tsx +331 -0
- package/src/features/billing/stripe-subscription/components/forms/index.ts +2 -0
- package/src/features/billing/stripe-subscription/components/index.ts +5 -0
- package/src/features/billing/stripe-subscription/components/lists/SubscriptionsList.tsx +104 -0
- package/src/features/billing/stripe-subscription/components/lists/index.ts +1 -0
- package/src/features/billing/stripe-subscription/components/widgets/PricingCard.tsx +95 -0
- package/src/features/billing/stripe-subscription/components/widgets/PricingCardsGrid.tsx +110 -0
- package/src/features/billing/stripe-subscription/components/widgets/ProrationPreview.tsx +41 -0
- package/src/features/billing/stripe-subscription/components/widgets/SubscriptionStatusBadge.tsx +60 -0
- package/src/features/billing/stripe-subscription/components/widgets/index.ts +4 -0
- package/src/features/billing/stripe-subscription/data/index.ts +3 -0
- package/src/features/billing/stripe-subscription/data/stripe-subscription.interface.ts +66 -0
- package/src/features/billing/stripe-subscription/data/stripe-subscription.service.ts +193 -0
- package/src/features/billing/stripe-subscription/data/stripe-subscription.ts +135 -0
- package/src/features/billing/stripe-subscription/hooks/index.ts +1 -0
- package/src/features/billing/stripe-subscription/hooks/useConfirmSubscriptionPayment.ts +111 -0
- package/src/features/billing/stripe-subscription/index.ts +5 -0
- package/src/features/billing/stripe-subscription/stripe-subscription.module.ts +9 -0
- package/src/features/billing/stripe-usage/components/containers/UsageContainer.tsx +109 -0
- package/src/features/billing/stripe-usage/components/containers/index.ts +1 -0
- package/src/features/billing/stripe-usage/components/details/UsageSummaryCard.tsx +90 -0
- package/src/features/billing/stripe-usage/components/details/index.ts +1 -0
- package/src/features/billing/stripe-usage/components/index.ts +4 -0
- package/src/features/billing/stripe-usage/components/lists/UsageHistoryTable.tsx +72 -0
- package/src/features/billing/stripe-usage/components/lists/index.ts +1 -0
- package/src/features/billing/stripe-usage/components/widgets/UsageSummaryCards.tsx +19 -0
- package/src/features/billing/stripe-usage/components/widgets/index.ts +1 -0
- package/src/features/billing/stripe-usage/data/index.ts +3 -0
- package/src/features/billing/stripe-usage/data/stripe-usage.interface.ts +55 -0
- package/src/features/billing/stripe-usage/data/stripe-usage.service.ts +129 -0
- package/src/features/billing/stripe-usage/data/stripe-usage.ts +70 -0
- package/src/features/billing/stripe-usage/index.ts +2 -0
- package/src/features/billing/stripe-usage/stripe-usage.module.ts +9 -0
- package/src/features/company/components/forms/CompanyEditor.tsx +2 -2
- package/src/features/company/contexts/CompanyContext.tsx +2 -2
- package/src/features/feature/components/forms/FormFeatures.tsx +13 -106
- package/src/features/feature/data/feature.interface.ts +1 -1
- package/src/features/feature/data/feature.ts +4 -4
- package/src/features/index.ts +7 -0
- package/src/features/module/data/module.interface.ts +0 -1
- package/src/features/module/data/module.ts +0 -6
- package/src/features/user/components/lists/ContributorsList.tsx +2 -2
- package/src/features/user/components/widgets/UserAvatar.tsx +1 -1
- package/src/index.ts +1 -1
- package/src/shadcnui/custom/link.tsx +16 -6
- package/src/utils/blocknote-diff.util.ts +2 -1
- package/src/utils/blocknote-word-diff-renderer.util.ts +8 -7
- package/dist/AuthComponent-hxOPs9o8.d.mts +0 -11
- package/dist/AuthComponent-hxOPs9o8.d.ts +0 -11
- package/dist/JsonApiRequest-FXZCYIER.js +0 -24
- package/dist/chunk-6YD42BP6.js.map +0 -1
- package/dist/chunk-C6QXZGL7.js.map +0 -1
- package/dist/chunk-FPZPD4JI.js.map +0 -1
- package/dist/chunk-JGVXZS7M.mjs.map +0 -1
- package/dist/chunk-PK5DRSUD.js.map +0 -1
- package/dist/chunk-SJIVGCNM.mjs.map +0 -1
- package/dist/chunk-TGBXBUWM.mjs.map +0 -1
- package/dist/chunk-WAFOKMKT.mjs.map +0 -1
- /package/dist/{BlockNoteEditor-ITJLAOXC.mjs.map → BlockNoteEditor-HFX7Z5BQ.mjs.map} +0 -0
- /package/dist/{JsonApiRequest-HFWXMKMA.mjs.map → JsonApiRequest-6IPS3DZJ.mjs.map} +0 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { AbstractService, EndpointCreator, HttpMethod, Modules, NextRef, PreviousRef } from "../../../core";
|
|
2
|
+
|
|
3
|
+
// Import from new sub-modules for backwards compatibility re-exports
|
|
4
|
+
import { MeterInterface, MeterSummaryInterface } from "../stripe-usage/data/stripe-usage.interface";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Legacy billing service - only contains meter methods
|
|
8
|
+
* @deprecated Use StripeUsageService for meter methods, StripeInvoiceService for invoices,
|
|
9
|
+
* StripeCustomerService for payment methods
|
|
10
|
+
*/
|
|
11
|
+
export class BillingService extends AbstractService {
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// Meter Methods (kept here for backwards compatibility)
|
|
14
|
+
// ============================================================================
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* List all available usage meters
|
|
18
|
+
* @deprecated Use StripeUsageService.listMeters() instead
|
|
19
|
+
*/
|
|
20
|
+
static async listMeters(params?: { next?: NextRef; prev?: PreviousRef }): Promise<MeterInterface[]> {
|
|
21
|
+
const endpoint = new EndpointCreator({
|
|
22
|
+
endpoint: Modules.StripeUsage,
|
|
23
|
+
childEndpoint: "meters",
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
return this.callApi({
|
|
27
|
+
type: Modules.StripeUsage,
|
|
28
|
+
method: HttpMethod.GET,
|
|
29
|
+
endpoint: endpoint.generate(),
|
|
30
|
+
next: params?.next,
|
|
31
|
+
previous: params?.prev,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Get meter summaries for a specific time period
|
|
37
|
+
* @deprecated Use StripeUsageService.getMeterSummaries() instead
|
|
38
|
+
*/
|
|
39
|
+
static async getMeterSummaries(params: {
|
|
40
|
+
meterId: string;
|
|
41
|
+
startTime: Date;
|
|
42
|
+
endTime: Date;
|
|
43
|
+
}): Promise<MeterSummaryInterface[]> {
|
|
44
|
+
const endpoint = new EndpointCreator({
|
|
45
|
+
endpoint: Modules.StripeUsage,
|
|
46
|
+
childEndpoint: `meters/${params.meterId}/summaries`,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
endpoint.addAdditionalParam("startTime", params.startTime.toISOString());
|
|
50
|
+
endpoint.addAdditionalParam("endTime", params.endTime.toISOString());
|
|
51
|
+
|
|
52
|
+
return this.callApi({
|
|
53
|
+
type: Modules.StripeUsage,
|
|
54
|
+
method: HttpMethod.GET,
|
|
55
|
+
endpoint: endpoint.generate(),
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ModuleFactory } from "../../../permissions";
|
|
2
|
+
import { Billing } from "../data/Billing";
|
|
3
|
+
|
|
4
|
+
export const BillingModule = (factory: ModuleFactory) =>
|
|
5
|
+
factory({
|
|
6
|
+
name: "billing",
|
|
7
|
+
model: Billing,
|
|
8
|
+
moduleId: "3266b307-5a9a-46f9-b78d-631f672f8735",
|
|
9
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { BillingModule } from "./billing.module";
|
package/src/features/billing/stripe-customer/components/containers/PaymentMethodsContainer.tsx
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { CreditCard } from "lucide-react";
|
|
4
|
+
import { useEffect, useState } from "react";
|
|
5
|
+
import { Button } from "../../../../../shadcnui";
|
|
6
|
+
import { PaymentMethodInterface, StripeCustomerService } from "../../data";
|
|
7
|
+
import { PaymentMethodEditor } from "../forms/PaymentMethodEditor";
|
|
8
|
+
import { PaymentMethodsList } from "../lists/PaymentMethodsList";
|
|
9
|
+
|
|
10
|
+
export function PaymentMethodsContainer() {
|
|
11
|
+
const [paymentMethods, setPaymentMethods] = useState<PaymentMethodInterface[]>([]);
|
|
12
|
+
const [loading, setLoading] = useState<boolean>(true);
|
|
13
|
+
const [showAddPaymentMethod, setShowAddPaymentMethod] = useState<boolean>(false);
|
|
14
|
+
|
|
15
|
+
const loadPaymentMethods = async () => {
|
|
16
|
+
setLoading(true);
|
|
17
|
+
try {
|
|
18
|
+
const fetchedPaymentMethods = await StripeCustomerService.listPaymentMethods();
|
|
19
|
+
setPaymentMethods(fetchedPaymentMethods);
|
|
20
|
+
} catch (error) {
|
|
21
|
+
console.error("[PaymentMethodsContainer] Failed to load payment methods:", error);
|
|
22
|
+
} finally {
|
|
23
|
+
setLoading(false);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
loadPaymentMethods();
|
|
29
|
+
}, []);
|
|
30
|
+
|
|
31
|
+
if (loading) {
|
|
32
|
+
return (
|
|
33
|
+
<div className="flex h-64 items-center justify-center">
|
|
34
|
+
<p className="text-muted-foreground">Loading payment methods...</p>
|
|
35
|
+
</div>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<div className="flex w-full flex-col gap-y-6">
|
|
41
|
+
{/* Header */}
|
|
42
|
+
<div className="flex items-center justify-between">
|
|
43
|
+
<div className="flex items-center gap-x-3">
|
|
44
|
+
<CreditCard className="h-8 w-8" />
|
|
45
|
+
<h1 className="text-3xl font-bold">Payment Methods</h1>
|
|
46
|
+
</div>
|
|
47
|
+
<Button onClick={() => setShowAddPaymentMethod(true)}>Add Payment Method</Button>
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
{/* Empty State */}
|
|
51
|
+
{paymentMethods.length === 0 && (
|
|
52
|
+
<div className="flex flex-col items-center justify-center gap-y-4 rounded-lg border-2 border-dashed border-gray-300 bg-muted/50 p-12">
|
|
53
|
+
<CreditCard className="h-16 w-16 text-muted-foreground" />
|
|
54
|
+
<div className="text-center">
|
|
55
|
+
<h3 className="mb-2 text-xl font-semibold">No payment methods</h3>
|
|
56
|
+
<p className="mb-4 text-muted-foreground">
|
|
57
|
+
Add a payment method to enable subscriptions and secure checkout.
|
|
58
|
+
</p>
|
|
59
|
+
<Button onClick={() => setShowAddPaymentMethod(true)}>Add Your First Card</Button>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
)}
|
|
63
|
+
|
|
64
|
+
{/* Payment Methods List */}
|
|
65
|
+
{paymentMethods.length > 0 && (
|
|
66
|
+
<PaymentMethodsList paymentMethods={paymentMethods} onUpdate={loadPaymentMethods} />
|
|
67
|
+
)}
|
|
68
|
+
|
|
69
|
+
{/* Add Payment Method Modal */}
|
|
70
|
+
{showAddPaymentMethod && (
|
|
71
|
+
<PaymentMethodEditor
|
|
72
|
+
open={showAddPaymentMethod}
|
|
73
|
+
onOpenChange={setShowAddPaymentMethod}
|
|
74
|
+
onSuccess={loadPaymentMethods}
|
|
75
|
+
/>
|
|
76
|
+
)}
|
|
77
|
+
</div>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./PaymentMethodsContainer";
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { MoreVertical } from "lucide-react";
|
|
4
|
+
import { useEffect, useState } from "react";
|
|
5
|
+
import {
|
|
6
|
+
AlertDialog,
|
|
7
|
+
AlertDialogAction,
|
|
8
|
+
AlertDialogCancel,
|
|
9
|
+
AlertDialogContent,
|
|
10
|
+
AlertDialogDescription,
|
|
11
|
+
AlertDialogFooter,
|
|
12
|
+
AlertDialogHeader,
|
|
13
|
+
AlertDialogTitle,
|
|
14
|
+
Badge,
|
|
15
|
+
Button,
|
|
16
|
+
Card,
|
|
17
|
+
CardContent,
|
|
18
|
+
CardHeader,
|
|
19
|
+
DropdownMenu,
|
|
20
|
+
DropdownMenuContent,
|
|
21
|
+
DropdownMenuItem,
|
|
22
|
+
DropdownMenuTrigger,
|
|
23
|
+
} from "../../../../../shadcnui";
|
|
24
|
+
import { PaymentMethodInterface, StripeCustomerInterface, StripeCustomerService } from "../../data";
|
|
25
|
+
|
|
26
|
+
type PaymentMethodCardProps = {
|
|
27
|
+
paymentMethod: PaymentMethodInterface;
|
|
28
|
+
onUpdate: () => void;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// Card brand icons mapping
|
|
32
|
+
const brandIcons: Record<string, string> = {
|
|
33
|
+
visa: "💳",
|
|
34
|
+
mastercard: "💳",
|
|
35
|
+
amex: "💳",
|
|
36
|
+
discover: "💳",
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export function PaymentMethodCard({ paymentMethod, onUpdate }: PaymentMethodCardProps) {
|
|
40
|
+
const [loading, setLoading] = useState<boolean>(false);
|
|
41
|
+
const [customer, setCustomer] = useState<StripeCustomerInterface | null>(null);
|
|
42
|
+
const [showRemoveDialog, setShowRemoveDialog] = useState<boolean>(false);
|
|
43
|
+
|
|
44
|
+
// Load customer to check default payment method
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
const loadCustomer = async () => {
|
|
47
|
+
try {
|
|
48
|
+
const fetchedCustomer = await StripeCustomerService.getCustomer();
|
|
49
|
+
setCustomer(fetchedCustomer);
|
|
50
|
+
} catch (error) {
|
|
51
|
+
console.error("[PaymentMethodCard] Failed to load customer:", error);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
loadCustomer();
|
|
56
|
+
}, []);
|
|
57
|
+
|
|
58
|
+
const isDefault = customer?.defaultPaymentMethodId === paymentMethod.id;
|
|
59
|
+
const brand = paymentMethod.card?.brand || "card";
|
|
60
|
+
const last4 = paymentMethod.card?.last4 || "****";
|
|
61
|
+
const expMonth = paymentMethod.card?.expMonth || 0;
|
|
62
|
+
const expYear = paymentMethod.card?.expYear || 0;
|
|
63
|
+
const brandIcon = brandIcons[brand.toLowerCase()] || "💳";
|
|
64
|
+
|
|
65
|
+
const handleSetDefault = async () => {
|
|
66
|
+
setLoading(true);
|
|
67
|
+
try {
|
|
68
|
+
await StripeCustomerService.setDefaultPaymentMethod({ paymentMethodId: paymentMethod.id });
|
|
69
|
+
onUpdate();
|
|
70
|
+
} catch (error) {
|
|
71
|
+
console.error("[PaymentMethodCard] Failed to set as default:", error);
|
|
72
|
+
} finally {
|
|
73
|
+
setLoading(false);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const handleRemove = async () => {
|
|
78
|
+
setLoading(true);
|
|
79
|
+
try {
|
|
80
|
+
await StripeCustomerService.removePaymentMethod({ paymentMethodId: paymentMethod.id });
|
|
81
|
+
setShowRemoveDialog(false);
|
|
82
|
+
onUpdate();
|
|
83
|
+
} catch (error) {
|
|
84
|
+
console.error("[PaymentMethodCard] Failed to remove:", error);
|
|
85
|
+
setLoading(false);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
return (
|
|
90
|
+
<>
|
|
91
|
+
<Card className="relative">
|
|
92
|
+
{/* Default Badge */}
|
|
93
|
+
{isDefault && (
|
|
94
|
+
<Badge className="absolute right-2 top-2 bg-green-100 text-green-800 hover:bg-green-100">Default</Badge>
|
|
95
|
+
)}
|
|
96
|
+
|
|
97
|
+
<CardHeader className="flex flex-row items-center justify-between pb-2">
|
|
98
|
+
<div className="flex items-center gap-x-2">
|
|
99
|
+
<span className="text-2xl">{brandIcon}</span>
|
|
100
|
+
<span className="text-sm font-medium capitalize">{brand}</span>
|
|
101
|
+
</div>
|
|
102
|
+
<DropdownMenu>
|
|
103
|
+
<DropdownMenuTrigger asChild>
|
|
104
|
+
<Button variant="ghost" size="sm" disabled={loading} className="h-8 w-8 p-0">
|
|
105
|
+
<MoreVertical className="h-4 w-4" />
|
|
106
|
+
</Button>
|
|
107
|
+
</DropdownMenuTrigger>
|
|
108
|
+
<DropdownMenuContent align="end">
|
|
109
|
+
{!isDefault && (
|
|
110
|
+
<DropdownMenuItem onClick={handleSetDefault} disabled={loading}>
|
|
111
|
+
Set as Default
|
|
112
|
+
</DropdownMenuItem>
|
|
113
|
+
)}
|
|
114
|
+
<DropdownMenuItem onClick={() => setShowRemoveDialog(true)} disabled={loading} className="text-red-600">
|
|
115
|
+
Remove
|
|
116
|
+
</DropdownMenuItem>
|
|
117
|
+
</DropdownMenuContent>
|
|
118
|
+
</DropdownMenu>
|
|
119
|
+
</CardHeader>
|
|
120
|
+
|
|
121
|
+
<CardContent>
|
|
122
|
+
<div className="flex flex-col gap-y-1">
|
|
123
|
+
<p className="text-lg font-semibold">•••• {last4}</p>
|
|
124
|
+
<p className="text-sm text-muted-foreground">
|
|
125
|
+
Expires {String(expMonth).padStart(2, "0")}/{expYear}
|
|
126
|
+
</p>
|
|
127
|
+
</div>
|
|
128
|
+
</CardContent>
|
|
129
|
+
</Card>
|
|
130
|
+
|
|
131
|
+
{/* Remove Confirmation Dialog */}
|
|
132
|
+
<AlertDialog open={showRemoveDialog} onOpenChange={setShowRemoveDialog}>
|
|
133
|
+
<AlertDialogContent>
|
|
134
|
+
<AlertDialogHeader>
|
|
135
|
+
<AlertDialogTitle>Remove Payment Method</AlertDialogTitle>
|
|
136
|
+
<AlertDialogDescription>
|
|
137
|
+
Are you sure you want to remove this payment method? This action cannot be undone.
|
|
138
|
+
{isDefault && " This is your default payment method."}
|
|
139
|
+
</AlertDialogDescription>
|
|
140
|
+
</AlertDialogHeader>
|
|
141
|
+
<AlertDialogFooter>
|
|
142
|
+
<AlertDialogCancel disabled={loading}>Cancel</AlertDialogCancel>
|
|
143
|
+
<AlertDialogAction onClick={handleRemove} disabled={loading} className="bg-red-600 hover:bg-red-700">
|
|
144
|
+
{loading ? "Removing..." : "Remove"}
|
|
145
|
+
</AlertDialogAction>
|
|
146
|
+
</AlertDialogFooter>
|
|
147
|
+
</AlertDialogContent>
|
|
148
|
+
</AlertDialog>
|
|
149
|
+
</>
|
|
150
|
+
);
|
|
151
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./PaymentMethodCard";
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { CardElement, useElements, useStripe } from "@stripe/react-stripe-js";
|
|
4
|
+
import { useEffect, useState } from "react";
|
|
5
|
+
import {
|
|
6
|
+
Alert,
|
|
7
|
+
AlertDescription,
|
|
8
|
+
Button,
|
|
9
|
+
Checkbox,
|
|
10
|
+
Dialog,
|
|
11
|
+
DialogContent,
|
|
12
|
+
DialogDescription,
|
|
13
|
+
DialogHeader,
|
|
14
|
+
DialogTitle,
|
|
15
|
+
Label,
|
|
16
|
+
} from "../../../../../shadcnui";
|
|
17
|
+
import { StripeCustomerService } from "../../data";
|
|
18
|
+
|
|
19
|
+
type PaymentMethodEditorProps = {
|
|
20
|
+
open: boolean;
|
|
21
|
+
onOpenChange: (open: boolean) => void;
|
|
22
|
+
onSuccess: () => void;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export function PaymentMethodEditor({ open, onOpenChange, onSuccess }: PaymentMethodEditorProps) {
|
|
26
|
+
const stripe = useStripe();
|
|
27
|
+
const elements = useElements();
|
|
28
|
+
|
|
29
|
+
const [setupIntent, setSetupIntent] = useState<{ clientSecret: string } | null>(null);
|
|
30
|
+
const [loading, setLoading] = useState<boolean>(true);
|
|
31
|
+
const [isSubmitting, setIsSubmitting] = useState<boolean>(false);
|
|
32
|
+
const [error, setError] = useState<string | null>(null);
|
|
33
|
+
const [setAsDefault, setSetAsDefault] = useState<boolean>(true);
|
|
34
|
+
|
|
35
|
+
// Fetch setup intent on component mount
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
const fetchSetupIntent = async () => {
|
|
38
|
+
setLoading(true);
|
|
39
|
+
try {
|
|
40
|
+
const intent = await StripeCustomerService.createSetupIntent();
|
|
41
|
+
setSetupIntent(intent);
|
|
42
|
+
} catch (err) {
|
|
43
|
+
console.error("[PaymentMethodEditor] Failed to create setup intent:", err);
|
|
44
|
+
setError("Failed to initialize payment form. Please try again.");
|
|
45
|
+
} finally {
|
|
46
|
+
setLoading(false);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
if (open) {
|
|
51
|
+
fetchSetupIntent();
|
|
52
|
+
}
|
|
53
|
+
}, [open]);
|
|
54
|
+
|
|
55
|
+
const handleSubmit = async (e: React.FormEvent) => {
|
|
56
|
+
e.preventDefault();
|
|
57
|
+
|
|
58
|
+
if (!stripe || !elements || !setupIntent) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
setIsSubmitting(true);
|
|
63
|
+
setError(null);
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
const cardElement = elements.getElement(CardElement);
|
|
67
|
+
if (!cardElement) {
|
|
68
|
+
throw new Error("Card element not found");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Confirm card setup with Stripe
|
|
72
|
+
const { error: stripeError, setupIntent: confirmedSetupIntent } = await stripe.confirmCardSetup(
|
|
73
|
+
setupIntent.clientSecret,
|
|
74
|
+
{
|
|
75
|
+
payment_method: {
|
|
76
|
+
card: cardElement,
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
if (stripeError) {
|
|
82
|
+
console.error("[PaymentMethodEditor] Stripe error:", stripeError);
|
|
83
|
+
setError(stripeError.message || "Failed to add payment method. Please check your card details.");
|
|
84
|
+
setIsSubmitting(false);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Set as default if checkbox is checked
|
|
89
|
+
if (setAsDefault && confirmedSetupIntent?.payment_method) {
|
|
90
|
+
await StripeCustomerService.setDefaultPaymentMethod({
|
|
91
|
+
paymentMethodId:
|
|
92
|
+
typeof confirmedSetupIntent.payment_method === "string"
|
|
93
|
+
? confirmedSetupIntent.payment_method
|
|
94
|
+
: confirmedSetupIntent.payment_method.id,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
onSuccess();
|
|
99
|
+
onOpenChange(false);
|
|
100
|
+
} catch (err: any) {
|
|
101
|
+
console.error("[PaymentMethodEditor] Error:", err);
|
|
102
|
+
setError(err.message || "An unexpected error occurred. Please try again.");
|
|
103
|
+
} finally {
|
|
104
|
+
setIsSubmitting(false);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
return (
|
|
109
|
+
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
110
|
+
<DialogContent className="max-w-md">
|
|
111
|
+
<DialogHeader>
|
|
112
|
+
<DialogTitle>Add Payment Method</DialogTitle>
|
|
113
|
+
<DialogDescription>
|
|
114
|
+
Add a new payment method to your account. Your card information is securely processed by Stripe.
|
|
115
|
+
</DialogDescription>
|
|
116
|
+
</DialogHeader>
|
|
117
|
+
|
|
118
|
+
{loading && (
|
|
119
|
+
<div className="flex items-center justify-center py-8">
|
|
120
|
+
<p className="text-muted-foreground">Loading payment form...</p>
|
|
121
|
+
</div>
|
|
122
|
+
)}
|
|
123
|
+
|
|
124
|
+
{!loading && setupIntent && (
|
|
125
|
+
<form onSubmit={handleSubmit} className="flex flex-col gap-y-4">
|
|
126
|
+
{/* Card Element */}
|
|
127
|
+
<div className="rounded-md border border-gray-300 p-3">
|
|
128
|
+
<CardElement
|
|
129
|
+
options={{
|
|
130
|
+
style: {
|
|
131
|
+
base: {
|
|
132
|
+
fontSize: "16px",
|
|
133
|
+
color: "#424770",
|
|
134
|
+
"::placeholder": {
|
|
135
|
+
color: "#aab7c4",
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
invalid: {
|
|
139
|
+
color: "#9e2146",
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
}}
|
|
143
|
+
/>
|
|
144
|
+
</div>
|
|
145
|
+
|
|
146
|
+
{/* Set as Default Checkbox */}
|
|
147
|
+
<div className="flex items-center gap-x-2">
|
|
148
|
+
<Checkbox
|
|
149
|
+
id="setAsDefault"
|
|
150
|
+
checked={setAsDefault}
|
|
151
|
+
onCheckedChange={(checked) => setSetAsDefault(!!checked)}
|
|
152
|
+
/>
|
|
153
|
+
<Label htmlFor="setAsDefault" className="text-sm font-normal">
|
|
154
|
+
Set as default payment method
|
|
155
|
+
</Label>
|
|
156
|
+
</div>
|
|
157
|
+
|
|
158
|
+
{/* Error Alert */}
|
|
159
|
+
{error && (
|
|
160
|
+
<Alert variant="destructive" className="bg-red-50 border-red-200">
|
|
161
|
+
<AlertDescription>{error}</AlertDescription>
|
|
162
|
+
</Alert>
|
|
163
|
+
)}
|
|
164
|
+
|
|
165
|
+
{/* Action Buttons */}
|
|
166
|
+
<div className="flex justify-end gap-x-2">
|
|
167
|
+
<Button type="button" variant="outline" onClick={() => onOpenChange(false)} disabled={isSubmitting}>
|
|
168
|
+
Cancel
|
|
169
|
+
</Button>
|
|
170
|
+
<Button type="submit" disabled={!stripe || isSubmitting}>
|
|
171
|
+
{isSubmitting ? "Processing..." : "Add Card"}
|
|
172
|
+
</Button>
|
|
173
|
+
</div>
|
|
174
|
+
</form>
|
|
175
|
+
)}
|
|
176
|
+
|
|
177
|
+
{/* Error State */}
|
|
178
|
+
{!loading && !setupIntent && error && (
|
|
179
|
+
<Alert variant="destructive" className="bg-red-50 border-red-200">
|
|
180
|
+
<AlertDescription>{error}</AlertDescription>
|
|
181
|
+
</Alert>
|
|
182
|
+
)}
|
|
183
|
+
</DialogContent>
|
|
184
|
+
</Dialog>
|
|
185
|
+
);
|
|
186
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./PaymentMethodEditor";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { PaymentMethodInterface } from "../../data";
|
|
4
|
+
import { PaymentMethodCard } from "../details/PaymentMethodCard";
|
|
5
|
+
|
|
6
|
+
type PaymentMethodsListProps = {
|
|
7
|
+
paymentMethods: PaymentMethodInterface[];
|
|
8
|
+
onUpdate: () => void;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export function PaymentMethodsList({ paymentMethods, onUpdate }: PaymentMethodsListProps) {
|
|
12
|
+
return (
|
|
13
|
+
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
|
|
14
|
+
{paymentMethods.map((paymentMethod) => (
|
|
15
|
+
<PaymentMethodCard key={paymentMethod.id} paymentMethod={paymentMethod} onUpdate={onUpdate} />
|
|
16
|
+
))}
|
|
17
|
+
</div>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./PaymentMethodsList";
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Payment Method Interfaces
|
|
3
|
+
// ============================================================================
|
|
4
|
+
|
|
5
|
+
export interface PaymentMethodInterface {
|
|
6
|
+
id: string;
|
|
7
|
+
type: string;
|
|
8
|
+
card?: {
|
|
9
|
+
brand: string;
|
|
10
|
+
last4: string;
|
|
11
|
+
expMonth: number;
|
|
12
|
+
expYear: number;
|
|
13
|
+
};
|
|
14
|
+
billingDetails?: {
|
|
15
|
+
name?: string;
|
|
16
|
+
email?: string;
|
|
17
|
+
phone?: string;
|
|
18
|
+
address?: {
|
|
19
|
+
city?: string;
|
|
20
|
+
country?: string;
|
|
21
|
+
line1?: string;
|
|
22
|
+
line2?: string;
|
|
23
|
+
postalCode?: string;
|
|
24
|
+
state?: string;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
}
|