payment-kit 1.26.4 → 1.27.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/api/src/libs/payment.ts +113 -22
- package/api/src/libs/queue/index.ts +20 -9
- package/api/src/libs/queue/store.ts +11 -7
- package/api/src/libs/reference-cache.ts +115 -0
- package/api/src/queues/auto-recharge.ts +68 -21
- package/api/src/queues/credit-consume.ts +835 -206
- package/api/src/routes/checkout-sessions.ts +78 -1
- package/api/src/routes/customers.ts +15 -3
- package/api/src/routes/donations.ts +4 -4
- package/api/src/routes/index.ts +37 -8
- package/api/src/routes/invoices.ts +14 -3
- package/api/src/routes/meter-events.ts +41 -15
- package/api/src/routes/payment-links.ts +2 -2
- package/api/src/routes/prices.ts +1 -1
- package/api/src/routes/pricing-table.ts +3 -2
- package/api/src/routes/products.ts +2 -2
- package/api/src/routes/subscription-items.ts +12 -3
- package/api/src/routes/subscriptions.ts +27 -9
- package/api/src/store/migrations/20260306-checkout-session-indexes.ts +23 -0
- package/api/src/store/models/checkout-session.ts +3 -2
- package/api/src/store/models/coupon.ts +9 -6
- package/api/src/store/models/credit-grant.ts +4 -1
- package/api/src/store/models/credit-transaction.ts +3 -2
- package/api/src/store/models/customer.ts +9 -6
- package/api/src/store/models/exchange-rate-provider.ts +9 -6
- package/api/src/store/models/invoice.ts +3 -2
- package/api/src/store/models/meter-event.ts +6 -4
- package/api/src/store/models/meter.ts +9 -6
- package/api/src/store/models/payment-intent.ts +9 -6
- package/api/src/store/models/payment-link.ts +9 -6
- package/api/src/store/models/payout.ts +3 -2
- package/api/src/store/models/price.ts +9 -6
- package/api/src/store/models/pricing-table.ts +9 -6
- package/api/src/store/models/product.ts +9 -6
- package/api/src/store/models/promotion-code.ts +9 -6
- package/api/src/store/models/refund.ts +9 -6
- package/api/src/store/models/setup-intent.ts +6 -4
- package/api/src/store/sequelize.ts +8 -3
- package/api/tests/queues/credit-consume-batch.spec.ts +438 -0
- package/api/tests/queues/credit-consume.spec.ts +505 -0
- package/api/third.d.ts +1 -1
- package/blocklet.yml +1 -1
- package/package.json +8 -7
- package/scripts/benchmark-seed.js +247 -0
- package/src/components/customer/credit-overview.tsx +31 -42
- package/src/components/invoice-pdf/template.tsx +5 -4
- package/src/components/payment-link/actions.tsx +45 -0
- package/src/components/payment-link/before-pay.tsx +24 -0
- package/src/components/subscription/payment-method-info.tsx +23 -6
- package/src/components/subscription/portal/actions.tsx +2 -0
- package/src/locales/en.tsx +11 -0
- package/src/locales/zh.tsx +10 -0
- package/src/pages/admin/products/links/detail.tsx +8 -0
- package/src/pages/customer/subscription/detail.tsx +21 -18
|
@@ -99,12 +99,15 @@ export class ExchangeRateProvider extends Model<
|
|
|
99
99
|
createdAt: 'created_at',
|
|
100
100
|
updatedAt: 'updated_at',
|
|
101
101
|
hooks: {
|
|
102
|
-
afterCreate: (model: ExchangeRateProvider, options) =>
|
|
103
|
-
createEvent('ExchangeRateProvider', 'exchange_rate_provider.created', model, options).catch(console.error)
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
102
|
+
afterCreate: (model: ExchangeRateProvider, options) => {
|
|
103
|
+
createEvent('ExchangeRateProvider', 'exchange_rate_provider.created', model, options).catch(console.error);
|
|
104
|
+
},
|
|
105
|
+
afterUpdate: (model: ExchangeRateProvider, options) => {
|
|
106
|
+
createEvent('ExchangeRateProvider', 'exchange_rate_provider.updated', model, options).catch(console.error);
|
|
107
|
+
},
|
|
108
|
+
afterDestroy: (model: ExchangeRateProvider, options) => {
|
|
109
|
+
createEvent('ExchangeRateProvider', 'exchange_rate_provider.deleted', model, options).catch(console.error);
|
|
110
|
+
},
|
|
108
111
|
},
|
|
109
112
|
}
|
|
110
113
|
);
|
|
@@ -491,8 +491,9 @@ export class Invoice extends Model<InferAttributes<Invoice>, InferCreationAttrib
|
|
|
491
491
|
options
|
|
492
492
|
).catch(console.error);
|
|
493
493
|
},
|
|
494
|
-
afterDestroy: (model: Invoice, options) =>
|
|
495
|
-
createEvent('Invoice', 'invoice.deleted', model, options).catch(console.error)
|
|
494
|
+
afterDestroy: (model: Invoice, options) => {
|
|
495
|
+
createEvent('Invoice', 'invoice.deleted', model, options).catch(console.error);
|
|
496
|
+
},
|
|
496
497
|
},
|
|
497
498
|
}
|
|
498
499
|
);
|
|
@@ -233,8 +233,9 @@ export class MeterEvent extends Model<InferAttributes<MeterEvent>, InferCreation
|
|
|
233
233
|
updatedAt: 'updated_at',
|
|
234
234
|
indexes: [{ fields: ['identifier'], unique: true }, { fields: ['status'] }, { fields: ['event_name'] }],
|
|
235
235
|
hooks: {
|
|
236
|
-
afterCreate: (model: MeterEvent, options) =>
|
|
237
|
-
createEvent('MeterEvent', 'billing.meter_event.created', model, options).catch(console.error)
|
|
236
|
+
afterCreate: (model: MeterEvent, options) => {
|
|
237
|
+
createEvent('MeterEvent', 'billing.meter_event.created', model, options).catch(console.error);
|
|
238
|
+
},
|
|
238
239
|
},
|
|
239
240
|
}
|
|
240
241
|
);
|
|
@@ -260,10 +261,11 @@ export class MeterEvent extends Model<InferAttributes<MeterEvent>, InferCreation
|
|
|
260
261
|
|
|
261
262
|
// 检查事件是否已存在(防重复)
|
|
262
263
|
public static async isEventExists(identifier: string): Promise<boolean> {
|
|
263
|
-
const
|
|
264
|
+
const event = await this.findOne({
|
|
264
265
|
where: { identifier },
|
|
266
|
+
attributes: ['id'],
|
|
265
267
|
});
|
|
266
|
-
return
|
|
268
|
+
return !!event;
|
|
267
269
|
}
|
|
268
270
|
|
|
269
271
|
// 获取事件统计
|
|
@@ -123,12 +123,15 @@ export class Meter extends Model<InferAttributes<Meter>, InferCreationAttributes
|
|
|
123
123
|
updatedAt: 'updated_at',
|
|
124
124
|
indexes: [{ fields: ['event_name'] }, { fields: ['currency_id'] }],
|
|
125
125
|
hooks: {
|
|
126
|
-
afterCreate: (model: Meter, options) =>
|
|
127
|
-
createEvent('Meter', 'meter.created', model, options).catch(console.error)
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
126
|
+
afterCreate: (model: Meter, options) => {
|
|
127
|
+
createEvent('Meter', 'meter.created', model, options).catch(console.error);
|
|
128
|
+
},
|
|
129
|
+
afterUpdate: (model: Meter, options) => {
|
|
130
|
+
createEvent('Meter', 'meter.updated', model, options).catch(console.error);
|
|
131
|
+
},
|
|
132
|
+
afterDestroy: (model: Meter, options) => {
|
|
133
|
+
createEvent('Meter', 'meter.deleted', model, options).catch(console.error);
|
|
134
|
+
},
|
|
132
135
|
},
|
|
133
136
|
});
|
|
134
137
|
}
|
|
@@ -257,9 +257,10 @@ export class PaymentIntent extends Model<InferAttributes<PaymentIntent>, InferCr
|
|
|
257
257
|
createdAt: 'created_at',
|
|
258
258
|
updatedAt: 'updated_at',
|
|
259
259
|
hooks: {
|
|
260
|
-
afterCreate: (model: PaymentIntent, options) =>
|
|
261
|
-
createEvent('PaymentIntent', 'payment_intent.created', model, options).catch(console.error)
|
|
262
|
-
|
|
260
|
+
afterCreate: (model: PaymentIntent, options) => {
|
|
261
|
+
createEvent('PaymentIntent', 'payment_intent.created', model, options).catch(console.error);
|
|
262
|
+
},
|
|
263
|
+
afterUpdate: (model: PaymentIntent, options) => {
|
|
263
264
|
createStatusEvent(
|
|
264
265
|
'PaymentIntent',
|
|
265
266
|
'payment_intent',
|
|
@@ -271,9 +272,11 @@ export class PaymentIntent extends Model<InferAttributes<PaymentIntent>, InferCr
|
|
|
271
272
|
},
|
|
272
273
|
model,
|
|
273
274
|
options
|
|
274
|
-
)
|
|
275
|
-
|
|
276
|
-
|
|
275
|
+
).catch(console.error);
|
|
276
|
+
},
|
|
277
|
+
afterDestroy: (model: PaymentIntent, options) => {
|
|
278
|
+
createEvent('PaymentIntent', 'payment_intent.deleted', model, options).catch(console.error);
|
|
279
|
+
},
|
|
277
280
|
},
|
|
278
281
|
}
|
|
279
282
|
);
|
|
@@ -239,12 +239,15 @@ export class PaymentLink extends Model<InferAttributes<PaymentLink>, InferCreati
|
|
|
239
239
|
createdAt: 'created_at',
|
|
240
240
|
updatedAt: 'updated_at',
|
|
241
241
|
hooks: {
|
|
242
|
-
afterCreate: (model: PaymentLink, options) =>
|
|
243
|
-
createEvent('PaymentLink', 'payment_link.created', model, options).catch(console.error)
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
242
|
+
afterCreate: (model: PaymentLink, options) => {
|
|
243
|
+
createEvent('PaymentLink', 'payment_link.created', model, options).catch(console.error);
|
|
244
|
+
},
|
|
245
|
+
afterUpdate: (model: PaymentLink, options) => {
|
|
246
|
+
createEvent('PaymentLink', 'payment_link.updated', model, options).catch(console.error);
|
|
247
|
+
},
|
|
248
|
+
afterDestroy: (model: PaymentLink, options) => {
|
|
249
|
+
createEvent('PaymentLink', 'payment_link.deleted', model, options).catch(console.error);
|
|
250
|
+
},
|
|
248
251
|
},
|
|
249
252
|
}
|
|
250
253
|
);
|
|
@@ -196,14 +196,15 @@ export class Payout extends Model<InferAttributes<Payout>, InferCreationAttribut
|
|
|
196
196
|
createEvent('Payout', 'payout.paid', model, options).catch(console.error);
|
|
197
197
|
}
|
|
198
198
|
},
|
|
199
|
-
afterUpdate: (model: Payout, options) =>
|
|
199
|
+
afterUpdate: (model: Payout, options) => {
|
|
200
200
|
createStatusEvent(
|
|
201
201
|
'Payout',
|
|
202
202
|
'payout',
|
|
203
203
|
{ canceled: 'canceled', failed: 'failed', paid: 'paid' },
|
|
204
204
|
model,
|
|
205
205
|
options
|
|
206
|
-
)
|
|
206
|
+
).catch(console.error);
|
|
207
|
+
},
|
|
207
208
|
},
|
|
208
209
|
}
|
|
209
210
|
);
|
|
@@ -249,12 +249,15 @@ export class Price extends Model<InferAttributes<Price>, InferCreationAttributes
|
|
|
249
249
|
createdAt: 'created_at',
|
|
250
250
|
updatedAt: 'updated_at',
|
|
251
251
|
hooks: {
|
|
252
|
-
afterCreate: (model: Price, options) =>
|
|
253
|
-
createEvent('Price', 'price.created', model, options).catch(console.error)
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
252
|
+
afterCreate: (model: Price, options) => {
|
|
253
|
+
createEvent('Price', 'price.created', model, options).catch(console.error);
|
|
254
|
+
},
|
|
255
|
+
afterUpdate: (model: Price, options) => {
|
|
256
|
+
createEvent('Price', 'price.updated', model, options).catch(console.error);
|
|
257
|
+
},
|
|
258
|
+
afterDestroy: (model: Price, options) => {
|
|
259
|
+
createEvent('Price', 'price.deleted', model, options).catch(console.error);
|
|
260
|
+
},
|
|
258
261
|
},
|
|
259
262
|
}
|
|
260
263
|
);
|
|
@@ -91,12 +91,15 @@ export class PricingTable extends Model<InferAttributes<PricingTable>, InferCrea
|
|
|
91
91
|
createdAt: 'created_at',
|
|
92
92
|
updatedAt: 'updated_at',
|
|
93
93
|
hooks: {
|
|
94
|
-
afterCreate: (model: PricingTable, options) =>
|
|
95
|
-
createEvent('PricingTable', 'pricing_table.created', model, options).catch(console.error)
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
94
|
+
afterCreate: (model: PricingTable, options) => {
|
|
95
|
+
createEvent('PricingTable', 'pricing_table.created', model, options).catch(console.error);
|
|
96
|
+
},
|
|
97
|
+
afterUpdate: (model: PricingTable, options) => {
|
|
98
|
+
createEvent('PricingTable', 'pricing_table.updated', model, options).catch(console.error);
|
|
99
|
+
},
|
|
100
|
+
afterDestroy: (model: PricingTable, options) => {
|
|
101
|
+
createEvent('PricingTable', 'pricing_table.deleted', model, options).catch(console.error);
|
|
102
|
+
},
|
|
100
103
|
},
|
|
101
104
|
});
|
|
102
105
|
}
|
|
@@ -170,12 +170,15 @@ export class Product extends Model<InferAttributes<Product>, InferCreationAttrib
|
|
|
170
170
|
createdAt: 'created_at',
|
|
171
171
|
updatedAt: 'updated_at',
|
|
172
172
|
hooks: {
|
|
173
|
-
afterCreate: (model: Product, options) =>
|
|
174
|
-
createEvent('Product', 'product.created', model, options).catch(console.error)
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
173
|
+
afterCreate: (model: Product, options) => {
|
|
174
|
+
createEvent('Product', 'product.created', model, options).catch(console.error);
|
|
175
|
+
},
|
|
176
|
+
afterUpdate: (model: Product, options) => {
|
|
177
|
+
createEvent('Product', 'product.updated', model, options).catch(console.error);
|
|
178
|
+
},
|
|
179
|
+
afterDestroy: (model: Product, options) => {
|
|
180
|
+
createEvent('Product', 'product.deleted', model, options).catch(console.error);
|
|
181
|
+
},
|
|
179
182
|
},
|
|
180
183
|
}
|
|
181
184
|
);
|
|
@@ -156,12 +156,15 @@ export class PromotionCode extends Model<InferAttributes<PromotionCode>, InferCr
|
|
|
156
156
|
createdAt: 'created_at',
|
|
157
157
|
updatedAt: 'updated_at',
|
|
158
158
|
hooks: {
|
|
159
|
-
afterCreate: (model: PromotionCode, options) =>
|
|
160
|
-
createEvent('PromotionCode', 'promotion_code.created', model, options).catch(console.error)
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
159
|
+
afterCreate: (model: PromotionCode, options) => {
|
|
160
|
+
createEvent('PromotionCode', 'promotion_code.created', model, options).catch(console.error);
|
|
161
|
+
},
|
|
162
|
+
afterUpdate: (model: PromotionCode, options) => {
|
|
163
|
+
createEvent('PromotionCode', 'promotion_code.updated', model, options).catch(console.error);
|
|
164
|
+
},
|
|
165
|
+
afterDestroy: (model: PromotionCode, options) => {
|
|
166
|
+
createEvent('PromotionCode', 'promotion_code.deleted', model, options).catch(console.error);
|
|
167
|
+
},
|
|
165
168
|
},
|
|
166
169
|
}
|
|
167
170
|
);
|
|
@@ -200,18 +200,21 @@ export class Refund extends Model<InferAttributes<Refund>, InferCreationAttribut
|
|
|
200
200
|
createdAt: 'created_at',
|
|
201
201
|
updatedAt: 'updated_at',
|
|
202
202
|
hooks: {
|
|
203
|
-
afterCreate: (model: Refund, options) =>
|
|
204
|
-
createEvent('Refund', 'refund.created', model, options).catch(console.error)
|
|
205
|
-
|
|
203
|
+
afterCreate: (model: Refund, options) => {
|
|
204
|
+
createEvent('Refund', 'refund.created', model, options).catch(console.error);
|
|
205
|
+
},
|
|
206
|
+
afterUpdate: (model: Refund, options) => {
|
|
206
207
|
createStatusEvent(
|
|
207
208
|
'Refund',
|
|
208
209
|
'refund',
|
|
209
210
|
{ canceled: 'canceled', processing: 'processing', succeeded: 'succeeded' },
|
|
210
211
|
model,
|
|
211
212
|
options
|
|
212
|
-
)
|
|
213
|
-
|
|
214
|
-
|
|
213
|
+
).catch(console.error);
|
|
214
|
+
},
|
|
215
|
+
afterDestroy: (model: Refund, options) => {
|
|
216
|
+
createEvent('Refund', 'refund.deleted', model, options).catch(console.error);
|
|
217
|
+
},
|
|
215
218
|
},
|
|
216
219
|
}
|
|
217
220
|
);
|
|
@@ -163,9 +163,10 @@ export class SetupIntent extends Model<InferAttributes<SetupIntent>, InferCreati
|
|
|
163
163
|
createdAt: 'created_at',
|
|
164
164
|
updatedAt: 'updated_at',
|
|
165
165
|
hooks: {
|
|
166
|
-
afterCreate: (model: SetupIntent, options) =>
|
|
167
|
-
createEvent('SetupIntent', 'setup_intent.created', model, options).catch(console.error)
|
|
168
|
-
|
|
166
|
+
afterCreate: (model: SetupIntent, options) => {
|
|
167
|
+
createEvent('SetupIntent', 'setup_intent.created', model, options).catch(console.error);
|
|
168
|
+
},
|
|
169
|
+
afterUpdate: (model: SetupIntent, options) => {
|
|
169
170
|
createStatusEvent(
|
|
170
171
|
'SetupIntent',
|
|
171
172
|
'setup_intent',
|
|
@@ -176,7 +177,8 @@ export class SetupIntent extends Model<InferAttributes<SetupIntent>, InferCreati
|
|
|
176
177
|
},
|
|
177
178
|
model,
|
|
178
179
|
options
|
|
179
|
-
)
|
|
180
|
+
).catch(console.error);
|
|
181
|
+
},
|
|
180
182
|
},
|
|
181
183
|
});
|
|
182
184
|
}
|
|
@@ -26,6 +26,11 @@ export const sequelize = new Sequelize({
|
|
|
26
26
|
},
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
// SQLite PRAGMAs — run once at startup on the single reused connection.
|
|
30
|
+
// Note: SQLite in Sequelize reuses a cached connection (connection-manager.js:43-44),
|
|
31
|
+
// so these fire-and-forget calls reliably apply to all subsequent queries.
|
|
32
|
+
sequelize.query('PRAGMA journal_mode = WAL');
|
|
33
|
+
sequelize.query('PRAGMA synchronous = NORMAL');
|
|
34
|
+
sequelize.query('PRAGMA journal_size_limit = 67108864');
|
|
35
|
+
sequelize.query('PRAGMA busy_timeout = 5000');
|
|
36
|
+
sequelize.query('PRAGMA cache_size = -16000'); // 16MB page cache (default ~2MB)
|