payment-kit 1.13.15
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/.eslintrc.js +15 -0
- package/README.md +3 -0
- package/api/dev.ts +6 -0
- package/api/hooks/pre-start.js +12 -0
- package/api/src/hooks/pre-start.ts +21 -0
- package/api/src/index.ts +92 -0
- package/api/src/jobs/event.ts +72 -0
- package/api/src/jobs/invoice.ts +148 -0
- package/api/src/jobs/payment.ts +208 -0
- package/api/src/jobs/subscription.ts +301 -0
- package/api/src/jobs/webhook.ts +113 -0
- package/api/src/libs/audit.ts +73 -0
- package/api/src/libs/auth.ts +40 -0
- package/api/src/libs/chain/arcblock.ts +13 -0
- package/api/src/libs/dayjs.ts +17 -0
- package/api/src/libs/env.ts +5 -0
- package/api/src/libs/hooks.ts +42 -0
- package/api/src/libs/logger.ts +27 -0
- package/api/src/libs/middleware.ts +12 -0
- package/api/src/libs/payment.ts +53 -0
- package/api/src/libs/queue/index.ts +263 -0
- package/api/src/libs/queue/store.ts +47 -0
- package/api/src/libs/security.ts +95 -0
- package/api/src/libs/session.ts +164 -0
- package/api/src/libs/util.ts +93 -0
- package/api/src/locales/en.ts +3 -0
- package/api/src/locales/index.ts +37 -0
- package/api/src/locales/zh.ts +3 -0
- package/api/src/routes/checkout-sessions.ts +536 -0
- package/api/src/routes/connect/collect.ts +109 -0
- package/api/src/routes/connect/pay.ts +116 -0
- package/api/src/routes/connect/setup.ts +121 -0
- package/api/src/routes/connect/shared.ts +410 -0
- package/api/src/routes/connect/subscribe.ts +128 -0
- package/api/src/routes/customers.ts +70 -0
- package/api/src/routes/events.ts +76 -0
- package/api/src/routes/index.ts +59 -0
- package/api/src/routes/invoices.ts +126 -0
- package/api/src/routes/payment-currencies.ts +38 -0
- package/api/src/routes/payment-intents.ts +122 -0
- package/api/src/routes/payment-links.ts +221 -0
- package/api/src/routes/payment-methods.ts +39 -0
- package/api/src/routes/prices.ts +134 -0
- package/api/src/routes/products.ts +191 -0
- package/api/src/routes/settings.ts +33 -0
- package/api/src/routes/subscription-items.ts +148 -0
- package/api/src/routes/subscriptions.ts +254 -0
- package/api/src/routes/usage-records.ts +120 -0
- package/api/src/routes/webhook-attempts.ts +57 -0
- package/api/src/routes/webhook-endpoints.ts +105 -0
- package/api/src/store/migrate.ts +16 -0
- package/api/src/store/migrations/20230905-genesis.ts +52 -0
- package/api/src/store/migrations/20230911-seeding.ts +145 -0
- package/api/src/store/models/checkout-session.ts +395 -0
- package/api/src/store/models/coupon.ts +137 -0
- package/api/src/store/models/customer.ts +199 -0
- package/api/src/store/models/discount.ts +116 -0
- package/api/src/store/models/event.ts +111 -0
- package/api/src/store/models/index.ts +165 -0
- package/api/src/store/models/invoice-item.ts +185 -0
- package/api/src/store/models/invoice.ts +492 -0
- package/api/src/store/models/job.ts +75 -0
- package/api/src/store/models/payment-currency.ts +139 -0
- package/api/src/store/models/payment-intent.ts +282 -0
- package/api/src/store/models/payment-link.ts +219 -0
- package/api/src/store/models/payment-method.ts +169 -0
- package/api/src/store/models/price.ts +266 -0
- package/api/src/store/models/product.ts +162 -0
- package/api/src/store/models/promotion-code.ts +112 -0
- package/api/src/store/models/setup-intent.ts +206 -0
- package/api/src/store/models/subscription-item.ts +103 -0
- package/api/src/store/models/subscription-schedule.ts +157 -0
- package/api/src/store/models/subscription.ts +307 -0
- package/api/src/store/models/types.ts +406 -0
- package/api/src/store/models/usage-record.ts +132 -0
- package/api/src/store/models/webhook-attempt.ts +96 -0
- package/api/src/store/models/webhook-endpoint.ts +96 -0
- package/api/src/store/sequelize.ts +15 -0
- package/api/third.d.ts +28 -0
- package/blocklet.md +3 -0
- package/blocklet.yml +89 -0
- package/index.html +14 -0
- package/logo.png +0 -0
- package/package.json +133 -0
- package/public/.gitkeep +0 -0
- package/screenshots/.gitkeep +0 -0
- package/screenshots/1-subscription.png +0 -0
- package/screenshots/2-customer-1.png +0 -0
- package/screenshots/3-customer-2.png +0 -0
- package/screenshots/4-admin-3.png +0 -0
- package/screenshots/5-admin-4.png +0 -0
- package/scripts/build-clean.js +6 -0
- package/scripts/bump-version.mjs +35 -0
- package/src/app.tsx +68 -0
- package/src/components/actions.tsx +85 -0
- package/src/components/blockchain/tx.tsx +29 -0
- package/src/components/checkout/amount.tsx +24 -0
- package/src/components/checkout/error.tsx +30 -0
- package/src/components/checkout/footer.tsx +12 -0
- package/src/components/checkout/form/address.tsx +38 -0
- package/src/components/checkout/form/index.tsx +295 -0
- package/src/components/checkout/header.tsx +23 -0
- package/src/components/checkout/pay.tsx +222 -0
- package/src/components/checkout/product-card.tsx +56 -0
- package/src/components/checkout/product-item.tsx +37 -0
- package/src/components/checkout/skeleton/overview.tsx +21 -0
- package/src/components/checkout/skeleton/payment.tsx +35 -0
- package/src/components/checkout/success.tsx +183 -0
- package/src/components/checkout/summary.tsx +34 -0
- package/src/components/collapse.tsx +50 -0
- package/src/components/confirm.tsx +55 -0
- package/src/components/copyable.tsx +38 -0
- package/src/components/currency.tsx +15 -0
- package/src/components/customer/actions.tsx +73 -0
- package/src/components/data.tsx +20 -0
- package/src/components/drawer-form.tsx +77 -0
- package/src/components/error-fallback.tsx +7 -0
- package/src/components/error.tsx +39 -0
- package/src/components/event/list.tsx +217 -0
- package/src/components/info-card.tsx +40 -0
- package/src/components/info-metric.tsx +35 -0
- package/src/components/info-row.tsx +28 -0
- package/src/components/input.tsx +40 -0
- package/src/components/invoice/action.tsx +94 -0
- package/src/components/invoice/list.tsx +225 -0
- package/src/components/invoice/table.tsx +110 -0
- package/src/components/layout.tsx +70 -0
- package/src/components/livemode.tsx +23 -0
- package/src/components/metadata/editor.tsx +57 -0
- package/src/components/metadata/form.tsx +45 -0
- package/src/components/payment-intent/actions.tsx +81 -0
- package/src/components/payment-intent/list.tsx +204 -0
- package/src/components/payment-link/actions.tsx +114 -0
- package/src/components/payment-link/after-pay.tsx +87 -0
- package/src/components/payment-link/before-pay.tsx +175 -0
- package/src/components/payment-link/item.tsx +135 -0
- package/src/components/payment-link/product-select.tsx +66 -0
- package/src/components/payment-link/rename.tsx +64 -0
- package/src/components/portal/invoice/list.tsx +110 -0
- package/src/components/portal/subscription/cancel.tsx +83 -0
- package/src/components/portal/subscription/list.tsx +232 -0
- package/src/components/price/actions.tsx +21 -0
- package/src/components/price/form.tsx +292 -0
- package/src/components/product/actions.tsx +125 -0
- package/src/components/product/add-price.tsx +59 -0
- package/src/components/product/create.tsx +97 -0
- package/src/components/product/edit-price.tsx +75 -0
- package/src/components/product/edit.tsx +67 -0
- package/src/components/product/features.tsx +32 -0
- package/src/components/product/form.tsx +76 -0
- package/src/components/relative-time.tsx +41 -0
- package/src/components/section/header.tsx +29 -0
- package/src/components/status.tsx +12 -0
- package/src/components/subscription/actions/cancel.tsx +66 -0
- package/src/components/subscription/actions/index.tsx +172 -0
- package/src/components/subscription/actions/pause.tsx +83 -0
- package/src/components/subscription/items/actions.tsx +31 -0
- package/src/components/subscription/items/index.tsx +107 -0
- package/src/components/subscription/list.tsx +200 -0
- package/src/components/switch.tsx +48 -0
- package/src/components/table.tsx +66 -0
- package/src/components/uploader.tsx +81 -0
- package/src/components/webhook/attempts.tsx +149 -0
- package/src/contexts/products.tsx +42 -0
- package/src/contexts/session.ts +10 -0
- package/src/contexts/settings.tsx +54 -0
- package/src/env.d.ts +17 -0
- package/src/global.css +97 -0
- package/src/hooks/mobile.ts +15 -0
- package/src/index.tsx +6 -0
- package/src/libs/api.ts +19 -0
- package/src/libs/dayjs.ts +17 -0
- package/src/libs/util.ts +474 -0
- package/src/locales/en.tsx +395 -0
- package/src/locales/index.tsx +8 -0
- package/src/locales/zh.tsx +389 -0
- package/src/pages/admin/billing/index.tsx +56 -0
- package/src/pages/admin/billing/invoices/detail.tsx +215 -0
- package/src/pages/admin/billing/invoices/index.tsx +5 -0
- package/src/pages/admin/billing/subscriptions/detail.tsx +237 -0
- package/src/pages/admin/billing/subscriptions/index.tsx +5 -0
- package/src/pages/admin/customers/customers/detail.tsx +209 -0
- package/src/pages/admin/customers/customers/index.tsx +109 -0
- package/src/pages/admin/customers/index.tsx +47 -0
- package/src/pages/admin/developers/events/detail.tsx +77 -0
- package/src/pages/admin/developers/events/index.tsx +5 -0
- package/src/pages/admin/developers/index.tsx +60 -0
- package/src/pages/admin/developers/logs.tsx +3 -0
- package/src/pages/admin/developers/overview.tsx +3 -0
- package/src/pages/admin/developers/webhooks/detail.tsx +109 -0
- package/src/pages/admin/developers/webhooks/index.tsx +102 -0
- package/src/pages/admin/index.tsx +120 -0
- package/src/pages/admin/overview.tsx +3 -0
- package/src/pages/admin/payments/index.tsx +65 -0
- package/src/pages/admin/payments/intents/detail.tsx +205 -0
- package/src/pages/admin/payments/intents/index.tsx +5 -0
- package/src/pages/admin/payments/links/create.tsx +141 -0
- package/src/pages/admin/payments/links/detail.tsx +318 -0
- package/src/pages/admin/payments/links/index.tsx +167 -0
- package/src/pages/admin/products/coupons/index.tsx +3 -0
- package/src/pages/admin/products/index.tsx +81 -0
- package/src/pages/admin/products/prices/actions.tsx +151 -0
- package/src/pages/admin/products/prices/detail.tsx +203 -0
- package/src/pages/admin/products/prices/list.tsx +95 -0
- package/src/pages/admin/products/pricing-tables.tsx +3 -0
- package/src/pages/admin/products/products/create.tsx +105 -0
- package/src/pages/admin/products/products/detail.tsx +246 -0
- package/src/pages/admin/products/products/index.tsx +154 -0
- package/src/pages/admin/settings/branding.tsx +3 -0
- package/src/pages/admin/settings/business.tsx +3 -0
- package/src/pages/admin/settings/index.tsx +47 -0
- package/src/pages/admin/settings/payment-methods.tsx +80 -0
- package/src/pages/checkout/index.tsx +38 -0
- package/src/pages/checkout/pay.tsx +89 -0
- package/src/pages/customer/index.tsx +93 -0
- package/src/pages/customer/invoice.tsx +147 -0
- package/src/pages/home.tsx +9 -0
- package/tsconfig.api.json +9 -0
- package/tsconfig.eslint.json +7 -0
- package/tsconfig.json +99 -0
- package/tsconfig.types.json +11 -0
- package/vite.config.ts +19 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { fromTokenToUnit } from '@ocap/util';
|
|
2
|
+
import Sequelize from 'sequelize';
|
|
3
|
+
|
|
4
|
+
import { createIdGenerator } from '../../libs/util';
|
|
5
|
+
import type { Migration } from '../migrate';
|
|
6
|
+
|
|
7
|
+
const genPaymentMethodId = createIdGenerator('pm', 24);
|
|
8
|
+
const genPaymentCurrencyId = createIdGenerator('pc', 12);
|
|
9
|
+
|
|
10
|
+
const abtId = genPaymentCurrencyId();
|
|
11
|
+
const tbaId = genPaymentCurrencyId();
|
|
12
|
+
const mainId = genPaymentMethodId();
|
|
13
|
+
const betaId = genPaymentMethodId();
|
|
14
|
+
const now = new Date();
|
|
15
|
+
|
|
16
|
+
const logo = 'https://new.arcblock.io/.well-known/service/blocklet/logo?imageFilter=resize&w=80';
|
|
17
|
+
|
|
18
|
+
const paymentCurrencies = [
|
|
19
|
+
{
|
|
20
|
+
id: abtId,
|
|
21
|
+
active: true,
|
|
22
|
+
livemode: true,
|
|
23
|
+
locked: true,
|
|
24
|
+
is_base_currency: true,
|
|
25
|
+
payment_method_id: mainId,
|
|
26
|
+
name: 'Native ABT',
|
|
27
|
+
description: 'ABT on ArcBlock main chain',
|
|
28
|
+
logo,
|
|
29
|
+
symbol: 'ABT',
|
|
30
|
+
decimal: 18,
|
|
31
|
+
minimum_payment_amount: fromTokenToUnit(0.1, 18).toString(), // 0.1 token
|
|
32
|
+
maximum_payment_amount: fromTokenToUnit(100000000, 18).toString(), // 0.1 billion
|
|
33
|
+
contract: 'z35nNRvYxBoHitx9yZ5ATS88psfShzPPBLxYD',
|
|
34
|
+
metadata: {},
|
|
35
|
+
created_at: now,
|
|
36
|
+
updated_at: now,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: tbaId,
|
|
40
|
+
active: true,
|
|
41
|
+
livemode: false,
|
|
42
|
+
locked: true,
|
|
43
|
+
is_base_currency: true,
|
|
44
|
+
payment_method_id: betaId,
|
|
45
|
+
name: 'Test ABT',
|
|
46
|
+
description: 'ABT on ArcBlock beta chain',
|
|
47
|
+
logo,
|
|
48
|
+
symbol: 'TBA',
|
|
49
|
+
decimal: 18,
|
|
50
|
+
minimum_payment_amount: fromTokenToUnit(0.1, 18).toString(), // 0.1 token
|
|
51
|
+
maximum_payment_amount: fromTokenToUnit(100000000, 18).toString(), // 0.1 billion
|
|
52
|
+
contract: 'z35n6UoHSi9MED4uaQy6ozFgKPaZj2UKrurBG',
|
|
53
|
+
metadata: {},
|
|
54
|
+
created_at: now,
|
|
55
|
+
updated_at: now,
|
|
56
|
+
},
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
const paymentMethods = [
|
|
60
|
+
{
|
|
61
|
+
id: mainId,
|
|
62
|
+
active: true,
|
|
63
|
+
livemode: true,
|
|
64
|
+
locked: true,
|
|
65
|
+
type: 'arcblock',
|
|
66
|
+
name: 'ArcBlock Main',
|
|
67
|
+
description: 'Process payments with tokens on ArcBlock main chain',
|
|
68
|
+
logo,
|
|
69
|
+
default_currency_id: abtId,
|
|
70
|
+
confirmation: {
|
|
71
|
+
type: 'immediate',
|
|
72
|
+
},
|
|
73
|
+
settings: {
|
|
74
|
+
arcblock: {
|
|
75
|
+
chain_id: 'main',
|
|
76
|
+
api_host: 'https://main.abtnetwork.io/api/',
|
|
77
|
+
explorer_host: 'https://main.abtnetwork.io/explorer/',
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
features: {
|
|
81
|
+
recurring: true,
|
|
82
|
+
refund: true,
|
|
83
|
+
dispute: true,
|
|
84
|
+
},
|
|
85
|
+
metadata: {},
|
|
86
|
+
created_at: now,
|
|
87
|
+
updated_at: now,
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
id: betaId,
|
|
91
|
+
active: true,
|
|
92
|
+
livemode: false,
|
|
93
|
+
locked: true,
|
|
94
|
+
type: 'arcblock',
|
|
95
|
+
name: 'ArcBlock Beta',
|
|
96
|
+
description: 'Process payments with tokens on ArcBlock beta chain, just for test purpose',
|
|
97
|
+
logo,
|
|
98
|
+
default_currency_id: tbaId,
|
|
99
|
+
confirmation: {
|
|
100
|
+
type: 'immediate',
|
|
101
|
+
},
|
|
102
|
+
settings: {
|
|
103
|
+
arcblock: {
|
|
104
|
+
chain_id: 'beta',
|
|
105
|
+
api_host: 'https://beta.abtnetwork.io/api/',
|
|
106
|
+
explorer_host: 'https://beta.abtnetwork.io/explorer/',
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
features: {
|
|
110
|
+
recurring: true,
|
|
111
|
+
refund: true,
|
|
112
|
+
dispute: true,
|
|
113
|
+
},
|
|
114
|
+
metadata: {},
|
|
115
|
+
created_at: now,
|
|
116
|
+
updated_at: now,
|
|
117
|
+
},
|
|
118
|
+
];
|
|
119
|
+
|
|
120
|
+
export const up: Migration = async ({ context: queryInterface }) => {
|
|
121
|
+
await queryInterface.bulkInsert(
|
|
122
|
+
'payment_methods',
|
|
123
|
+
paymentMethods,
|
|
124
|
+
{},
|
|
125
|
+
{
|
|
126
|
+
confirmation: { type: new Sequelize.JSON() },
|
|
127
|
+
settings: { type: new Sequelize.JSON() },
|
|
128
|
+
features: { type: new Sequelize.JSON() },
|
|
129
|
+
metadata: { type: new Sequelize.JSON() },
|
|
130
|
+
}
|
|
131
|
+
);
|
|
132
|
+
await queryInterface.bulkInsert(
|
|
133
|
+
'payment_currencies',
|
|
134
|
+
paymentCurrencies,
|
|
135
|
+
{},
|
|
136
|
+
{
|
|
137
|
+
metadata: { type: new Sequelize.JSON() },
|
|
138
|
+
}
|
|
139
|
+
);
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
export const down: Migration = async ({ context: queryInterface }) => {
|
|
143
|
+
await queryInterface.bulkDelete('payment_methods', {});
|
|
144
|
+
await queryInterface.bulkDelete('payment_currencies', {});
|
|
145
|
+
};
|
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/lines-between-class-members */
|
|
2
|
+
/* eslint-disable @typescript-eslint/indent */
|
|
3
|
+
import {
|
|
4
|
+
CreationOptional,
|
|
5
|
+
DataTypes,
|
|
6
|
+
FindOptions,
|
|
7
|
+
InferAttributes,
|
|
8
|
+
InferCreationAttributes,
|
|
9
|
+
Model,
|
|
10
|
+
Op,
|
|
11
|
+
} from 'sequelize';
|
|
12
|
+
import type { LiteralUnion } from 'type-fest';
|
|
13
|
+
|
|
14
|
+
import { createStatusEvent } from '../../libs/audit';
|
|
15
|
+
import { createIdGenerator } from '../../libs/util';
|
|
16
|
+
import type { CurrencyConversion, CustomField, CustomerDetail, InvoiceData, LineItem } from './types';
|
|
17
|
+
|
|
18
|
+
const nextId = createIdGenerator('cs', 58);
|
|
19
|
+
|
|
20
|
+
// @link https://stripe.com/docs/api/checkout/sessions
|
|
21
|
+
// eslint-disable-next-line prettier/prettier
|
|
22
|
+
export class CheckoutSession extends Model<InferAttributes<CheckoutSession>, InferCreationAttributes<CheckoutSession>> {
|
|
23
|
+
// Unique identifier for the object.
|
|
24
|
+
declare id: CreationOptional<string>;
|
|
25
|
+
declare livemode: boolean;
|
|
26
|
+
declare client_reference_id?: string;
|
|
27
|
+
|
|
28
|
+
// ID of the payment currency
|
|
29
|
+
declare currency_id: string;
|
|
30
|
+
|
|
31
|
+
// ID of the invoice created by the Checkout Session, if it exists.
|
|
32
|
+
declare invoice_id?: string;
|
|
33
|
+
|
|
34
|
+
// The ID of the Payment Link that created this Session.
|
|
35
|
+
declare payment_link_id?: string;
|
|
36
|
+
|
|
37
|
+
// The ID of the subscription for Checkout Sessions in subscription mode.
|
|
38
|
+
declare subscription_id?: string;
|
|
39
|
+
|
|
40
|
+
// The ID of the original expired Checkout Session that triggered the recovery flow.
|
|
41
|
+
declare recovered_from?: string;
|
|
42
|
+
|
|
43
|
+
// The ID of the PaymentIntent for Checkout Sessions in payment mode.
|
|
44
|
+
declare payment_intent_id?: string;
|
|
45
|
+
|
|
46
|
+
// The ID of the SetupIntent for Checkout Sessions in setup mode.
|
|
47
|
+
declare setup_intent_id?: string;
|
|
48
|
+
|
|
49
|
+
// Pass subscription if the Checkout Session includes at least one recurring item.
|
|
50
|
+
declare mode: LiteralUnion<'payment' | 'setup' | 'subscription', string>;
|
|
51
|
+
|
|
52
|
+
declare status: LiteralUnion<'complete' | 'open' | 'expired', string>;
|
|
53
|
+
declare payment_status: LiteralUnion<'paid' | 'unpaid' | 'no_payment_required', string>;
|
|
54
|
+
|
|
55
|
+
declare line_items: LineItem[];
|
|
56
|
+
|
|
57
|
+
// Total of all items before discounts or taxes are applied.
|
|
58
|
+
declare amount_subtotal: string;
|
|
59
|
+
// Total of all items after discounts and taxes are applied.
|
|
60
|
+
declare amount_total: string;
|
|
61
|
+
// Tax and discount details for the computed total amount.
|
|
62
|
+
declare total_details?: {
|
|
63
|
+
amount_discount?: string;
|
|
64
|
+
amount_shipping?: string;
|
|
65
|
+
amount_tax?: string;
|
|
66
|
+
breakdown?: {
|
|
67
|
+
discounts?: {
|
|
68
|
+
amount?: string;
|
|
69
|
+
discount?: string;
|
|
70
|
+
}[];
|
|
71
|
+
taxes?: {
|
|
72
|
+
amount?: string;
|
|
73
|
+
rate?: string;
|
|
74
|
+
}[];
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
declare url?: string;
|
|
79
|
+
declare cancel_url?: string;
|
|
80
|
+
declare success_url?: string;
|
|
81
|
+
|
|
82
|
+
declare currency_conversion?: CurrencyConversion;
|
|
83
|
+
|
|
84
|
+
// customer_email field on creation is stored here?
|
|
85
|
+
declare customer_details?: CustomerDetail;
|
|
86
|
+
declare customer_creation: LiteralUnion<'if_required' | 'always', string>;
|
|
87
|
+
declare customer_update?: {
|
|
88
|
+
address: LiteralUnion<'auto' | 'never', string>;
|
|
89
|
+
name: LiteralUnion<'auto' | 'never', string>;
|
|
90
|
+
shipping: LiteralUnion<'auto' | 'never', string>;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
// When set, provides configuration for actions to take if this Checkout Session expires
|
|
94
|
+
declare after_expiration?: {
|
|
95
|
+
recovery: {
|
|
96
|
+
enabled: boolean;
|
|
97
|
+
allow_promotion_codes?: boolean;
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
declare allow_promotion_codes?: boolean;
|
|
102
|
+
|
|
103
|
+
declare consent_collection?: {
|
|
104
|
+
promotions?: LiteralUnion<'auto' | 'none', string>;
|
|
105
|
+
terms_of_service?: LiteralUnion<'required' | 'none', string>;
|
|
106
|
+
};
|
|
107
|
+
declare consent?: {
|
|
108
|
+
promotions?: LiteralUnion<'opt_in', string>;
|
|
109
|
+
terms_of_service?: LiteralUnion<'accepted', string>;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
declare custom_fields?: CustomField[];
|
|
113
|
+
declare custom_text?: {
|
|
114
|
+
shipping_address?: string;
|
|
115
|
+
submit?: string;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
// By default, this value is 24 hours from creation.
|
|
119
|
+
declare expires_at: number;
|
|
120
|
+
|
|
121
|
+
// Generate a post-purchase Invoice for one-time payments.
|
|
122
|
+
declare invoice_creation?: {
|
|
123
|
+
enabled: boolean;
|
|
124
|
+
invoice_data?: InvoiceData;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
// The list of payment method types that customers can use
|
|
128
|
+
declare payment_method_types?: string[];
|
|
129
|
+
|
|
130
|
+
// Controls phone number collection settings during checkout.
|
|
131
|
+
declare phone_number_collection?: {
|
|
132
|
+
enabled: boolean;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
// Describes the type of transaction being performed in order to customize relevant text
|
|
136
|
+
declare submit_type: LiteralUnion<'auto' | 'book' | 'donate' | 'pay', string>;
|
|
137
|
+
|
|
138
|
+
declare metadata?: Record<string, any>;
|
|
139
|
+
|
|
140
|
+
// Configuration for collecting the customer’s billing address.
|
|
141
|
+
declare billing_address_collection?: LiteralUnion<'auto' | 'required', string>;
|
|
142
|
+
|
|
143
|
+
// When creating a subscription, the specified configuration data will be used.
|
|
144
|
+
declare subscription_data?: {
|
|
145
|
+
description: string;
|
|
146
|
+
trial_period_days: number;
|
|
147
|
+
billing_cycle_anchor?: number;
|
|
148
|
+
metadata?: Record<string, any>;
|
|
149
|
+
proration_behavior?: LiteralUnion<'create_prorations' | 'none', string>;
|
|
150
|
+
trial_end?: number;
|
|
151
|
+
trial_settings?: {
|
|
152
|
+
end_behavior: {
|
|
153
|
+
missing_payment_method: LiteralUnion<'cancel' | 'pause' | 'create_invoice', string>;
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
// 3rd party payment tx hash
|
|
159
|
+
declare payment_details?: {
|
|
160
|
+
tx_hash?: string;
|
|
161
|
+
payer?: string;
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
// FIXME: Only exist on creation
|
|
165
|
+
// declare discounts?: {
|
|
166
|
+
// coupon?: string;
|
|
167
|
+
// promotion_code?: string;
|
|
168
|
+
// };
|
|
169
|
+
// A subset of parameters to be passed to PaymentIntent creation for Checkout Sessions in payment mode.
|
|
170
|
+
// declare payment_intent_data?: any;
|
|
171
|
+
|
|
172
|
+
// TODO: following fields not supported yet
|
|
173
|
+
// automatic_tax
|
|
174
|
+
// locale --> auto selected
|
|
175
|
+
// payment_method_collection // FIXME:
|
|
176
|
+
// payment_method_options
|
|
177
|
+
// setup_intent_data
|
|
178
|
+
// shipping_address_collection
|
|
179
|
+
// shipping_options
|
|
180
|
+
// tax_id_collection
|
|
181
|
+
// shipping_cost
|
|
182
|
+
// shipping_details
|
|
183
|
+
// shipping_options
|
|
184
|
+
|
|
185
|
+
declare created_at: CreationOptional<Date>;
|
|
186
|
+
declare created_via: LiteralUnion<'api' | 'dashboard' | 'portal', string>;
|
|
187
|
+
declare updated_at: CreationOptional<Date>;
|
|
188
|
+
|
|
189
|
+
public static readonly GENESIS_ATTRIBUTES = {
|
|
190
|
+
id: {
|
|
191
|
+
type: DataTypes.STRING(64),
|
|
192
|
+
primaryKey: true,
|
|
193
|
+
allowNull: false,
|
|
194
|
+
defaultValue: nextId,
|
|
195
|
+
},
|
|
196
|
+
livemode: {
|
|
197
|
+
type: DataTypes.BOOLEAN,
|
|
198
|
+
allowNull: false,
|
|
199
|
+
},
|
|
200
|
+
client_reference_id: {
|
|
201
|
+
type: DataTypes.STRING(128),
|
|
202
|
+
allowNull: true,
|
|
203
|
+
},
|
|
204
|
+
currency_id: {
|
|
205
|
+
type: DataTypes.STRING(15),
|
|
206
|
+
allowNull: false,
|
|
207
|
+
},
|
|
208
|
+
invoice_id: {
|
|
209
|
+
type: DataTypes.STRING(30),
|
|
210
|
+
allowNull: true,
|
|
211
|
+
},
|
|
212
|
+
payment_link_id: {
|
|
213
|
+
type: DataTypes.STRING(30),
|
|
214
|
+
allowNull: true,
|
|
215
|
+
},
|
|
216
|
+
subscription_id: {
|
|
217
|
+
type: DataTypes.STRING(30),
|
|
218
|
+
allowNull: true,
|
|
219
|
+
},
|
|
220
|
+
recovered_from: {
|
|
221
|
+
type: DataTypes.STRING(30),
|
|
222
|
+
allowNull: true,
|
|
223
|
+
},
|
|
224
|
+
payment_intent_id: {
|
|
225
|
+
type: DataTypes.STRING(30),
|
|
226
|
+
allowNull: true,
|
|
227
|
+
},
|
|
228
|
+
mode: {
|
|
229
|
+
type: DataTypes.ENUM('payment', 'setup', 'subscription'),
|
|
230
|
+
},
|
|
231
|
+
status: {
|
|
232
|
+
type: DataTypes.ENUM('complete', 'open', 'expired'),
|
|
233
|
+
},
|
|
234
|
+
payment_status: {
|
|
235
|
+
type: DataTypes.ENUM('paid', 'unpaid', 'no_payment_required'),
|
|
236
|
+
},
|
|
237
|
+
line_items: {
|
|
238
|
+
type: DataTypes.JSON,
|
|
239
|
+
allowNull: false,
|
|
240
|
+
},
|
|
241
|
+
amount_subtotal: {
|
|
242
|
+
type: DataTypes.STRING(32),
|
|
243
|
+
allowNull: false,
|
|
244
|
+
},
|
|
245
|
+
amount_total: {
|
|
246
|
+
type: DataTypes.STRING(32),
|
|
247
|
+
allowNull: false,
|
|
248
|
+
},
|
|
249
|
+
total_details: {
|
|
250
|
+
type: DataTypes.JSON,
|
|
251
|
+
allowNull: false,
|
|
252
|
+
},
|
|
253
|
+
url: {
|
|
254
|
+
type: DataTypes.STRING(512),
|
|
255
|
+
allowNull: true,
|
|
256
|
+
},
|
|
257
|
+
cancel_url: {
|
|
258
|
+
type: DataTypes.STRING(512),
|
|
259
|
+
allowNull: true,
|
|
260
|
+
},
|
|
261
|
+
success_url: {
|
|
262
|
+
type: DataTypes.STRING(512),
|
|
263
|
+
allowNull: true,
|
|
264
|
+
},
|
|
265
|
+
currency_conversion: {
|
|
266
|
+
type: DataTypes.JSON,
|
|
267
|
+
allowNull: true,
|
|
268
|
+
},
|
|
269
|
+
after_expiration: {
|
|
270
|
+
type: DataTypes.JSON,
|
|
271
|
+
allowNull: true,
|
|
272
|
+
},
|
|
273
|
+
allow_promotion_codes: {
|
|
274
|
+
type: DataTypes.BOOLEAN,
|
|
275
|
+
defaultValue: false,
|
|
276
|
+
},
|
|
277
|
+
consent_collection: {
|
|
278
|
+
type: DataTypes.JSON,
|
|
279
|
+
allowNull: true,
|
|
280
|
+
},
|
|
281
|
+
consent: {
|
|
282
|
+
type: DataTypes.JSON,
|
|
283
|
+
allowNull: true,
|
|
284
|
+
},
|
|
285
|
+
custom_fields: {
|
|
286
|
+
type: DataTypes.JSON,
|
|
287
|
+
defaultValue: [],
|
|
288
|
+
},
|
|
289
|
+
custom_text: {
|
|
290
|
+
type: DataTypes.JSON,
|
|
291
|
+
allowNull: true,
|
|
292
|
+
},
|
|
293
|
+
customer_creation: {
|
|
294
|
+
type: DataTypes.ENUM('if_required', 'always'),
|
|
295
|
+
allowNull: false,
|
|
296
|
+
},
|
|
297
|
+
customer_update: {
|
|
298
|
+
type: DataTypes.JSON,
|
|
299
|
+
defaultValue: {
|
|
300
|
+
address: 'never',
|
|
301
|
+
name: 'never',
|
|
302
|
+
shipping: 'never',
|
|
303
|
+
},
|
|
304
|
+
},
|
|
305
|
+
expires_at: {
|
|
306
|
+
type: DataTypes.INTEGER,
|
|
307
|
+
allowNull: true,
|
|
308
|
+
},
|
|
309
|
+
invoice_creation: {
|
|
310
|
+
type: DataTypes.JSON,
|
|
311
|
+
allowNull: true,
|
|
312
|
+
},
|
|
313
|
+
payment_method_types: {
|
|
314
|
+
type: DataTypes.JSON,
|
|
315
|
+
defaultValue: [],
|
|
316
|
+
},
|
|
317
|
+
phone_number_collection: {
|
|
318
|
+
type: DataTypes.JSON,
|
|
319
|
+
allowNull: true,
|
|
320
|
+
},
|
|
321
|
+
billing_address_collection: {
|
|
322
|
+
type: DataTypes.ENUM('auto', 'required'),
|
|
323
|
+
defaultValue: 'auto',
|
|
324
|
+
allowNull: false,
|
|
325
|
+
},
|
|
326
|
+
submit_type: {
|
|
327
|
+
type: DataTypes.ENUM('auto', 'book', 'donate', 'pay'),
|
|
328
|
+
allowNull: false,
|
|
329
|
+
},
|
|
330
|
+
subscription_data: {
|
|
331
|
+
type: DataTypes.JSON,
|
|
332
|
+
allowNull: true,
|
|
333
|
+
},
|
|
334
|
+
payment_details: {
|
|
335
|
+
type: DataTypes.JSON,
|
|
336
|
+
allowNull: true,
|
|
337
|
+
},
|
|
338
|
+
metadata: {
|
|
339
|
+
type: DataTypes.JSON,
|
|
340
|
+
allowNull: true,
|
|
341
|
+
},
|
|
342
|
+
created_at: {
|
|
343
|
+
type: DataTypes.DATE,
|
|
344
|
+
defaultValue: DataTypes.NOW,
|
|
345
|
+
allowNull: false,
|
|
346
|
+
},
|
|
347
|
+
created_via: {
|
|
348
|
+
type: DataTypes.ENUM('api', 'dashboard', 'portal'),
|
|
349
|
+
},
|
|
350
|
+
updated_at: {
|
|
351
|
+
type: DataTypes.DATE,
|
|
352
|
+
defaultValue: DataTypes.NOW,
|
|
353
|
+
allowNull: false,
|
|
354
|
+
},
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
public static initialize(sequelize: any) {
|
|
358
|
+
this.init(CheckoutSession.GENESIS_ATTRIBUTES, {
|
|
359
|
+
sequelize,
|
|
360
|
+
modelName: 'CheckoutSession',
|
|
361
|
+
tableName: 'checkout_sessions',
|
|
362
|
+
createdAt: 'created_at',
|
|
363
|
+
updatedAt: 'updated_at',
|
|
364
|
+
hooks: {
|
|
365
|
+
afterUpdate: (model: CheckoutSession, options) => {
|
|
366
|
+
createStatusEvent(
|
|
367
|
+
'CheckoutSession',
|
|
368
|
+
'checkout.session',
|
|
369
|
+
{ complete: 'completed', expired: 'expired' },
|
|
370
|
+
model,
|
|
371
|
+
options
|
|
372
|
+
).catch(console.error);
|
|
373
|
+
},
|
|
374
|
+
},
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// FIXME:
|
|
379
|
+
public static associate(models: any) {
|
|
380
|
+
this.hasOne(models.PaymentCurrency, {
|
|
381
|
+
sourceKey: 'currency_id',
|
|
382
|
+
foreignKey: 'id',
|
|
383
|
+
as: 'currency',
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
public static findByPkOrClientRefId(id: string, options: FindOptions<CheckoutSession> = {}) {
|
|
388
|
+
return this.findOne({
|
|
389
|
+
where: { [Op.or]: [{ id }, { client_reference_id: id }] },
|
|
390
|
+
...options,
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
export type TCheckoutSession = InferAttributes<CheckoutSession>;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/lines-between-class-members */
|
|
2
|
+
import { CreationOptional, DataTypes, InferAttributes, InferCreationAttributes, Model } from 'sequelize';
|
|
3
|
+
import type { LiteralUnion } from 'type-fest';
|
|
4
|
+
|
|
5
|
+
import { createCodeGenerator } from '../../libs/util';
|
|
6
|
+
|
|
7
|
+
const nextId = createCodeGenerator('', 8);
|
|
8
|
+
|
|
9
|
+
// eslint-disable-next-line prettier/prettier
|
|
10
|
+
export class Coupon extends Model<InferAttributes<Coupon>, InferCreationAttributes<Coupon>> {
|
|
11
|
+
declare id: CreationOptional<string>;
|
|
12
|
+
declare livemode: boolean;
|
|
13
|
+
|
|
14
|
+
declare amount_off: string;
|
|
15
|
+
declare percent_off: number;
|
|
16
|
+
|
|
17
|
+
declare currency_id: string;
|
|
18
|
+
|
|
19
|
+
declare duration: LiteralUnion<'forever' | 'once' | 'repeating', string>;
|
|
20
|
+
|
|
21
|
+
declare duration_in_months: number;
|
|
22
|
+
|
|
23
|
+
declare name: string;
|
|
24
|
+
|
|
25
|
+
declare metadata: Record<string, any>;
|
|
26
|
+
|
|
27
|
+
declare applies_to?: {
|
|
28
|
+
products: string[];
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
declare currency_options?: Record<string, number>;
|
|
32
|
+
|
|
33
|
+
declare max_redemptions?: number;
|
|
34
|
+
|
|
35
|
+
declare redeem_by?: Date;
|
|
36
|
+
|
|
37
|
+
declare times_redeemed?: number;
|
|
38
|
+
|
|
39
|
+
declare valid?: boolean;
|
|
40
|
+
|
|
41
|
+
declare created_at: CreationOptional<Date>;
|
|
42
|
+
declare updated_at: CreationOptional<Date>;
|
|
43
|
+
|
|
44
|
+
public static readonly GENESIS_ATTRIBUTES = {
|
|
45
|
+
id: {
|
|
46
|
+
type: DataTypes.STRING(15),
|
|
47
|
+
primaryKey: true,
|
|
48
|
+
allowNull: false,
|
|
49
|
+
defaultValue: nextId,
|
|
50
|
+
},
|
|
51
|
+
livemode: {
|
|
52
|
+
type: DataTypes.BOOLEAN,
|
|
53
|
+
allowNull: false,
|
|
54
|
+
},
|
|
55
|
+
amount_off: {
|
|
56
|
+
type: DataTypes.STRING(32),
|
|
57
|
+
defaultValue: '0',
|
|
58
|
+
},
|
|
59
|
+
percent_off: {
|
|
60
|
+
type: DataTypes.INTEGER,
|
|
61
|
+
defaultValue: 0,
|
|
62
|
+
},
|
|
63
|
+
currency_id: {
|
|
64
|
+
type: DataTypes.STRING(15),
|
|
65
|
+
allowNull: false,
|
|
66
|
+
},
|
|
67
|
+
duration: {
|
|
68
|
+
type: DataTypes.ENUM('forever', 'once', 'repeating'),
|
|
69
|
+
},
|
|
70
|
+
duration_in_months: {
|
|
71
|
+
type: DataTypes.INTEGER,
|
|
72
|
+
allowNull: false,
|
|
73
|
+
},
|
|
74
|
+
name: {
|
|
75
|
+
type: DataTypes.STRING(64),
|
|
76
|
+
allowNull: false,
|
|
77
|
+
},
|
|
78
|
+
applies_to: {
|
|
79
|
+
type: DataTypes.JSON,
|
|
80
|
+
allowNull: true,
|
|
81
|
+
},
|
|
82
|
+
currency_options: {
|
|
83
|
+
type: DataTypes.JSON,
|
|
84
|
+
defaultValue: {},
|
|
85
|
+
},
|
|
86
|
+
max_redemptions: {
|
|
87
|
+
type: DataTypes.INTEGER,
|
|
88
|
+
allowNull: true,
|
|
89
|
+
},
|
|
90
|
+
redeem_by: {
|
|
91
|
+
type: DataTypes.DATE,
|
|
92
|
+
allowNull: true,
|
|
93
|
+
},
|
|
94
|
+
times_redeemed: {
|
|
95
|
+
type: DataTypes.INTEGER,
|
|
96
|
+
defaultValue: 0,
|
|
97
|
+
},
|
|
98
|
+
valid: {
|
|
99
|
+
type: DataTypes.BOOLEAN,
|
|
100
|
+
defaultValue: false,
|
|
101
|
+
},
|
|
102
|
+
metadata: {
|
|
103
|
+
type: DataTypes.JSON,
|
|
104
|
+
allowNull: true,
|
|
105
|
+
},
|
|
106
|
+
created_at: {
|
|
107
|
+
type: DataTypes.DATE,
|
|
108
|
+
defaultValue: DataTypes.NOW,
|
|
109
|
+
allowNull: false,
|
|
110
|
+
},
|
|
111
|
+
updated_at: {
|
|
112
|
+
type: DataTypes.DATE,
|
|
113
|
+
defaultValue: DataTypes.NOW,
|
|
114
|
+
allowNull: false,
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
public static initialize(sequelize: any) {
|
|
119
|
+
this.init(Coupon.GENESIS_ATTRIBUTES, {
|
|
120
|
+
sequelize,
|
|
121
|
+
modelName: 'Coupon',
|
|
122
|
+
tableName: 'coupons',
|
|
123
|
+
createdAt: 'created_at',
|
|
124
|
+
updatedAt: 'updated_at',
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
public static associate(models: any) {
|
|
129
|
+
this.hasOne(models.PaymentCurrency, {
|
|
130
|
+
sourceKey: 'currency_id',
|
|
131
|
+
foreignKey: 'id',
|
|
132
|
+
as: 'currency',
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export type TCoupon = InferAttributes<Coupon>;
|