payment-kit 1.22.31 → 1.23.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.
Files changed (35) hide show
  1. package/api/src/index.ts +4 -0
  2. package/api/src/integrations/arcblock/token.ts +599 -0
  3. package/api/src/libs/credit-grant.ts +7 -6
  4. package/api/src/queues/credit-consume.ts +29 -4
  5. package/api/src/queues/credit-grant.ts +245 -50
  6. package/api/src/queues/credit-reconciliation.ts +253 -0
  7. package/api/src/queues/refund.ts +263 -30
  8. package/api/src/queues/token-transfer.ts +331 -0
  9. package/api/src/routes/checkout-sessions.ts +1 -1
  10. package/api/src/routes/credit-grants.ts +27 -7
  11. package/api/src/routes/credit-tokens.ts +38 -0
  12. package/api/src/routes/index.ts +2 -0
  13. package/api/src/routes/meter-events.ts +1 -1
  14. package/api/src/routes/meters.ts +32 -10
  15. package/api/src/routes/payment-currencies.ts +103 -0
  16. package/api/src/routes/products.ts +2 -2
  17. package/api/src/routes/settings.ts +4 -3
  18. package/api/src/store/migrations/20251120-add-token-config-to-currencies.ts +20 -0
  19. package/api/src/store/migrations/20251204-add-chain-fields.ts +74 -0
  20. package/api/src/store/models/credit-grant.ts +57 -10
  21. package/api/src/store/models/credit-transaction.ts +18 -1
  22. package/api/src/store/models/meter-event.ts +48 -25
  23. package/api/src/store/models/payment-currency.ts +31 -4
  24. package/api/src/store/models/refund.ts +12 -2
  25. package/api/src/store/models/types.ts +48 -0
  26. package/api/third.d.ts +2 -0
  27. package/blocklet.yml +1 -1
  28. package/package.json +7 -6
  29. package/src/components/customer/credit-overview.tsx +1 -1
  30. package/src/components/meter/form.tsx +191 -18
  31. package/src/components/price/form.tsx +49 -37
  32. package/src/locales/en.tsx +24 -0
  33. package/src/locales/zh.tsx +26 -0
  34. package/src/pages/admin/billing/meters/create.tsx +42 -13
  35. package/src/pages/admin/billing/meters/detail.tsx +56 -5
@@ -0,0 +1,20 @@
1
+ import { DataTypes } from 'sequelize';
2
+ import { safeApplyColumnChanges, type Migration } from '../migrate';
3
+
4
+ export const up: Migration = async ({ context }) => {
5
+ await safeApplyColumnChanges(context, {
6
+ payment_currencies: [
7
+ {
8
+ name: 'token_config',
9
+ field: {
10
+ type: DataTypes.JSON,
11
+ allowNull: true,
12
+ },
13
+ },
14
+ ],
15
+ });
16
+ };
17
+
18
+ export const down: Migration = async ({ context }) => {
19
+ await context.removeColumn('payment_currencies', 'token_config');
20
+ };
@@ -0,0 +1,74 @@
1
+ import { DataTypes } from 'sequelize';
2
+ import { createIndexIfNotExists, safeApplyColumnChanges, type Migration } from '../migrate';
3
+
4
+ export const up: Migration = async ({ context }) => {
5
+ // Add new columns to credit_transactions table
6
+ await safeApplyColumnChanges(context, {
7
+ credit_transactions: [
8
+ {
9
+ name: 'transfer_status',
10
+ field: {
11
+ type: DataTypes.ENUM('pending', 'completed', 'failed'),
12
+ allowNull: true,
13
+ },
14
+ },
15
+ {
16
+ name: 'transfer_hash',
17
+ field: {
18
+ type: DataTypes.STRING(255),
19
+ allowNull: true,
20
+ },
21
+ },
22
+ ],
23
+ });
24
+
25
+ // Add new columns to credit_grants table for on-chain operations
26
+ await safeApplyColumnChanges(context, {
27
+ credit_grants: [
28
+ {
29
+ name: 'chain_status',
30
+ field: {
31
+ type: DataTypes.ENUM(
32
+ 'mint_pending',
33
+ 'mint_completed',
34
+ 'mint_failed',
35
+ 'burn_pending',
36
+ 'burn_completed',
37
+ 'burn_failed'
38
+ ),
39
+ allowNull: true,
40
+ },
41
+ },
42
+ {
43
+ name: 'chain_detail',
44
+ field: {
45
+ type: DataTypes.JSON,
46
+ allowNull: true,
47
+ },
48
+ },
49
+ ],
50
+ });
51
+
52
+ // Add indexes for efficient querying
53
+ await createIndexIfNotExists(
54
+ context,
55
+ 'credit_transactions',
56
+ ['transfer_status'],
57
+ 'idx_credit_transactions_transfer_status'
58
+ );
59
+ await createIndexIfNotExists(context, 'credit_grants', ['chain_status'], 'idx_credit_grants_chain_status');
60
+ };
61
+
62
+ export const down: Migration = async ({ context }) => {
63
+ // Remove indexes
64
+ await context.removeIndex('credit_transactions', 'idx_credit_transactions_transfer_status');
65
+ await context.removeIndex('credit_grants', 'idx_credit_grants_chain_status');
66
+
67
+ // Remove columns from credit_transactions
68
+ await context.removeColumn('credit_transactions', 'transfer_hash');
69
+ await context.removeColumn('credit_transactions', 'transfer_status');
70
+
71
+ // Remove columns from credit_grants
72
+ await context.removeColumn('credit_grants', 'chain_detail');
73
+ await context.removeColumn('credit_grants', 'chain_status');
74
+ };
@@ -6,9 +6,10 @@ import type { LiteralUnion } from 'type-fest';
6
6
  import { createEvent } from '../../libs/audit';
7
7
  import { createIdGenerator } from '../../libs/util';
8
8
  import dayjs from '../../libs/dayjs';
9
- import { CreditGrantApplicabilityConfig } from './types';
9
+ import { CreditGrantApplicabilityConfig, CreditGrantChainDetail, CreditGrantChainStatus } from './types';
10
10
  import logger from '../../libs/logger';
11
11
  import { PaymentCurrency, TPaymentCurrency } from './payment-currency';
12
+ import { Meter, TMeter } from './meter';
12
13
 
13
14
  const CREDIT_GRANT_STATUS_EVENTS = {
14
15
  depleted: 'depleted',
@@ -18,6 +19,7 @@ const CREDIT_GRANT_STATUS_EVENTS = {
18
19
 
19
20
  type CreditGrantSummary = {
20
21
  paymentCurrency: TPaymentCurrency;
22
+ meter?: TMeter;
21
23
  totalAmount: string;
22
24
  remainingAmount: string;
23
25
  grantCount: number;
@@ -62,6 +64,10 @@ export class CreditGrant extends Model<InferAttributes<CreditGrant>, InferCreati
62
64
  declare status: LiteralUnion<'pending' | 'granted' | 'depleted' | 'expired' | 'voided', string>;
63
65
  declare remaining_amount: string; // 剩余金额
64
66
 
67
+ // On-chain credit token operation fields
68
+ declare chain_status?: CreditGrantChainStatus;
69
+ declare chain_detail?: CreditGrantChainDetail;
70
+
65
71
  // 审计字段
66
72
  declare created_by?: string;
67
73
  declare updated_by?: string;
@@ -148,6 +154,21 @@ export class CreditGrant extends Model<InferAttributes<CreditGrant>, InferCreati
148
154
  type: DataTypes.STRING(32),
149
155
  allowNull: false,
150
156
  },
157
+ chain_status: {
158
+ type: DataTypes.ENUM(
159
+ 'mint_pending',
160
+ 'mint_completed',
161
+ 'mint_failed',
162
+ 'burn_pending',
163
+ 'burn_completed',
164
+ 'burn_failed'
165
+ ),
166
+ allowNull: true,
167
+ },
168
+ chain_detail: {
169
+ type: DataTypes.JSON,
170
+ allowNull: true,
171
+ },
151
172
  created_by: {
152
173
  type: DataTypes.STRING(40),
153
174
  allowNull: true,
@@ -267,6 +288,16 @@ export class CreditGrant extends Model<InferAttributes<CreditGrant>, InferCreati
267
288
  return true;
268
289
  }
269
290
 
291
+ // check if Credit Grant has on-chain token (mint completed)
292
+ public hasOnchainToken(): boolean {
293
+ return CreditGrant.hasOnchainToken(this);
294
+ }
295
+
296
+ // Static version that works with plain objects
297
+ public static hasOnchainToken(grant: { chain_status?: string | null }): boolean {
298
+ return grant.chain_status === 'mint_completed';
299
+ }
300
+
270
301
  public static initialize(sequelize: any) {
271
302
  this.init(this.GENESIS_ATTRIBUTES, {
272
303
  sequelize,
@@ -282,9 +313,6 @@ export class CreditGrant extends Model<InferAttributes<CreditGrant>, InferCreati
282
313
  hooks: {
283
314
  afterCreate: (model: CreditGrant, options) => {
284
315
  createEvent('CreditGrant', 'customer.credit_grant.created', model, options).catch(console.error);
285
- if (!model.effective_at || model.effective_at <= Math.floor(Date.now() / 1000)) {
286
- createEvent('CreditGrant', 'customer.credit_grant.granted', model, options).catch(console.error);
287
- }
288
316
  },
289
317
  afterUpdate: (model: CreditGrant, options) => {
290
318
  createEvent('CreditGrant', 'customer.credit_grant.updated', model, options).catch(console.error);
@@ -404,10 +432,7 @@ export class CreditGrant extends Model<InferAttributes<CreditGrant>, InferCreati
404
432
  currencyId?: string[] | string;
405
433
  priceIds?: string[];
406
434
  }): Promise<Record<string, CreditGrantSummary>> {
407
- const summary: Record<
408
- string,
409
- { paymentCurrency: TPaymentCurrency; totalAmount: string; remainingAmount: string; grantCount: number }
410
- > = {};
435
+ const summary: Record<string, CreditGrantSummary> = {};
411
436
 
412
437
  let targetCurrencyIds: string[] = [];
413
438
  if (searchCurrencyId) {
@@ -427,9 +452,28 @@ export class CreditGrant extends Model<InferAttributes<CreditGrant>, InferCreati
427
452
  targetCurrencyIds = grantsWithCurrency.map((grant: any) => grant.currency_id);
428
453
  }
429
454
 
455
+ const currencies = await PaymentCurrency.scope('withRechargeConfig').findAll({
456
+ where: {
457
+ id: {
458
+ [Op.in]: Array.from(new Set(targetCurrencyIds)),
459
+ },
460
+ },
461
+ });
462
+ const currencyMap = new Map(currencies.map((c) => [c.id, c]));
463
+
464
+ // Query meters for credit currencies
465
+ const meters = await Meter.findAll({
466
+ where: {
467
+ currency_id: {
468
+ [Op.in]: Array.from(new Set(targetCurrencyIds)),
469
+ },
470
+ },
471
+ });
472
+ const meterMap = new Map(meters.map((m) => [m.currency_id, m]));
473
+
430
474
  await Promise.all(
431
475
  targetCurrencyIds.map(async (currencyId: string) => {
432
- const paymentCurrency = await PaymentCurrency.scope('withRechargeConfig').findByPk(currencyId);
476
+ const paymentCurrency = currencyMap.get(currencyId);
433
477
  if (!paymentCurrency) {
434
478
  return null;
435
479
  }
@@ -437,6 +481,7 @@ export class CreditGrant extends Model<InferAttributes<CreditGrant>, InferCreati
437
481
  return null;
438
482
  }
439
483
 
484
+ const meter = meterMap.get(currencyId);
440
485
  const availableGrants = await this.getAvailableCreditsForCustomer(customerId, currencyId, priceIds);
441
486
 
442
487
  if (availableGrants.length > 0) {
@@ -450,8 +495,9 @@ export class CreditGrant extends Model<InferAttributes<CreditGrant>, InferCreati
450
495
  grantCount += 1;
451
496
  });
452
497
 
453
- const result = {
498
+ const result: CreditGrantSummary = {
454
499
  paymentCurrency,
500
+ meter,
455
501
  totalAmount,
456
502
  remainingAmount,
457
503
  grantCount,
@@ -462,6 +508,7 @@ export class CreditGrant extends Model<InferAttributes<CreditGrant>, InferCreati
462
508
  }
463
509
  summary[currencyId] = {
464
510
  paymentCurrency,
511
+ meter,
465
512
  totalAmount: '0',
466
513
  remainingAmount: '0',
467
514
  grantCount: 0,
@@ -29,6 +29,10 @@ export class CreditTransaction extends Model<
29
29
  declare description?: string;
30
30
  declare metadata?: Record<string, any>;
31
31
 
32
+ // Token transfer fields
33
+ declare transfer_status?: 'pending' | 'completed' | 'failed' | null;
34
+ declare transfer_hash?: string;
35
+
32
36
  declare created_at: CreationOptional<Date>;
33
37
  declare updated_at: CreationOptional<Date>;
34
38
 
@@ -88,6 +92,14 @@ export class CreditTransaction extends Model<
88
92
  type: DataTypes.JSON,
89
93
  allowNull: true,
90
94
  },
95
+ transfer_status: {
96
+ type: DataTypes.ENUM('pending', 'completed', 'failed'),
97
+ allowNull: true,
98
+ },
99
+ transfer_hash: {
100
+ type: DataTypes.STRING(255),
101
+ allowNull: true,
102
+ },
91
103
  created_at: {
92
104
  type: DataTypes.DATE,
93
105
  defaultValue: DataTypes.NOW,
@@ -107,7 +119,12 @@ export class CreditTransaction extends Model<
107
119
  tableName: 'credit_transactions',
108
120
  createdAt: 'created_at',
109
121
  updatedAt: 'updated_at',
110
- indexes: [{ fields: ['customer_id'] }, { fields: ['credit_grant_id'] }, { fields: ['source'] }],
122
+ indexes: [
123
+ { fields: ['customer_id'] },
124
+ { fields: ['credit_grant_id'] },
125
+ { fields: ['source'] },
126
+ { fields: ['transfer_status'] },
127
+ ],
111
128
  hooks: {
112
129
  afterCreate: (model: CreditTransaction, options) =>
113
130
  createEvent('CreditTransaction', 'customer.credit_transaction.created', model, options).catch(console.error),
@@ -373,27 +373,52 @@ export class MeterEvent extends Model<InferAttributes<MeterEvent>, InferCreation
373
373
  const summary: GroupedBN = {};
374
374
  const detail: GroupedStrList = {};
375
375
 
376
- await Promise.all(
377
- events.map(async (event) => {
378
- const meter = await Meter.getMeterByEventName(event.event_name);
379
- if (!meter) {
380
- return;
381
- }
382
- const paymentCurrency = await PaymentCurrency.findByPk(meter.currency_id);
383
- if (!paymentCurrency) {
384
- return;
385
- }
386
- const currencyId = meter.currency_id as string;
387
- if (searchCurrencyId && searchCurrencyId !== currencyId) {
388
- return;
389
- }
390
- if (!detail[currencyId]) {
391
- detail[currencyId] = [];
392
- }
393
- summary[currencyId] = new BN(summary[currencyId] || '0').add(new BN(event.credit_pending)).toString();
394
- detail[currencyId]!.push(event.id);
395
- })
396
- );
376
+ if (events.length === 0) {
377
+ return [summary, detail, events];
378
+ }
379
+
380
+ const eventNames = [...new Set(events.map((e) => e.event_name))];
381
+ const meters = await Meter.findAll({
382
+ where: {
383
+ event_name: {
384
+ [Op.in]: eventNames,
385
+ },
386
+ },
387
+ });
388
+ const meterMap = new Map(meters.map((m) => [m.event_name, m]));
389
+
390
+ const currencyIds = [...new Set(meters.map((m) => m.currency_id).filter((id): id is string => Boolean(id)))];
391
+ const currencies =
392
+ currencyIds.length > 0
393
+ ? await PaymentCurrency.findAll({
394
+ where: {
395
+ id: {
396
+ [Op.in]: currencyIds,
397
+ },
398
+ },
399
+ })
400
+ : [];
401
+ const currencyMap = new Map(currencies.map((c) => [c.id, c]));
402
+
403
+ events.forEach((event) => {
404
+ const meter = meterMap.get(event.event_name);
405
+ if (!meter || !meter.currency_id) {
406
+ return;
407
+ }
408
+ const paymentCurrency = currencyMap.get(meter.currency_id);
409
+ if (!paymentCurrency) {
410
+ return;
411
+ }
412
+ const currencyId = meter.currency_id as string;
413
+ if (searchCurrencyId && searchCurrencyId !== currencyId) {
414
+ return;
415
+ }
416
+ if (!detail[currencyId]) {
417
+ detail[currencyId] = [];
418
+ }
419
+ summary[currencyId] = new BN(summary[currencyId] || '0').add(new BN(event.credit_pending)).toString();
420
+ detail[currencyId]!.push(event.id);
421
+ });
397
422
 
398
423
  return [summary, detail, events];
399
424
  }
@@ -424,14 +449,12 @@ export class MeterEvent extends Model<InferAttributes<MeterEvent>, InferCreation
424
449
  if (subscriptionId) {
425
450
  where[Op.and] = where[Op.and] || [];
426
451
  where[Op.and].push(
427
- Sequelize.where(Sequelize.fn('json_extract', Sequelize.col('payload'), '$.subscription_id'), subscriptionId)
452
+ Sequelize.where(Sequelize.literal("json_extract(payload, '$.subscription_id')"), subscriptionId)
428
453
  );
429
454
  }
430
455
  if (customerId) {
431
456
  where[Op.and] = where[Op.and] || [];
432
- where[Op.and].push(
433
- Sequelize.where(Sequelize.fn('json_extract', Sequelize.col('payload'), '$.customer_id'), customerId)
434
- );
457
+ where[Op.and].push(Sequelize.where(Sequelize.literal("json_extract(payload, '$.customer_id')"), customerId));
435
458
  }
436
459
 
437
460
  return this._getPendingAmounts(where, currencyId);
@@ -46,6 +46,7 @@ export class PaymentCurrency extends Model<InferAttributes<PaymentCurrency>, Inf
46
46
  declare vault_config?: VaultConfig;
47
47
  declare type: LiteralUnion<'standard' | 'credit', string>;
48
48
  declare recharge_config?: RechargeConfig;
49
+ declare token_config?: Record<string, any> | null;
49
50
 
50
51
  public static readonly GENESIS_ATTRIBUTES = {
51
52
  id: {
@@ -144,6 +145,10 @@ export class PaymentCurrency extends Model<InferAttributes<PaymentCurrency>, Inf
144
145
  type: DataTypes.JSON,
145
146
  allowNull: true,
146
147
  },
148
+ token_config: {
149
+ type: DataTypes.JSON,
150
+ allowNull: true,
151
+ },
147
152
  },
148
153
  {
149
154
  sequelize,
@@ -210,7 +215,12 @@ export class PaymentCurrency extends Model<InferAttributes<PaymentCurrency>, Inf
210
215
  );
211
216
  return count > 0;
212
217
  }
213
- public static async createForMeter(meter: any, paymentMethodId: string) {
218
+ public static async createForMeter(
219
+ meter: any,
220
+ paymentMethodId: string,
221
+ tokenConfig?: Record<string, any>,
222
+ options?: { decimal?: number }
223
+ ) {
214
224
  const existingCurrency = await this.findOne({
215
225
  where: {
216
226
  type: 'credit',
@@ -222,6 +232,8 @@ export class PaymentCurrency extends Model<InferAttributes<PaymentCurrency>, Inf
222
232
  if (existingCurrency) {
223
233
  return existingCurrency;
224
234
  }
235
+
236
+ const decimal = options?.decimal ?? 10;
225
237
  const currency = await this.create({
226
238
  type: 'credit',
227
239
  payment_method_id: paymentMethodId,
@@ -229,8 +241,8 @@ export class PaymentCurrency extends Model<InferAttributes<PaymentCurrency>, Inf
229
241
  description: `Credit for ${meter.unit}`,
230
242
  symbol: meter.unit,
231
243
  logo: getUrl('/methods/arcblock.png'), // 默认credit图标
232
- decimal: 2,
233
- maximum_precision: 2,
244
+ decimal,
245
+ maximum_precision: decimal,
234
246
  minimum_payment_amount: '1',
235
247
  maximum_payment_amount: '100000000000',
236
248
  active: true,
@@ -242,13 +254,28 @@ export class PaymentCurrency extends Model<InferAttributes<PaymentCurrency>, Inf
242
254
  meter_event_name: meter.event_name,
243
255
  created_by_meter: true,
244
256
  },
257
+ token_config: tokenConfig,
245
258
  });
246
259
 
247
260
  return currency;
248
261
  }
249
262
 
250
263
  public isCredit(): boolean {
251
- return this.type === 'credit';
264
+ return PaymentCurrency.isCredit(this);
265
+ }
266
+
267
+ public isOnChainCredit(): boolean {
268
+ return PaymentCurrency.isOnChainCredit(this);
269
+ }
270
+
271
+ // Static version that works with plain objects
272
+ public static isCredit(currency: { type?: string | null }): boolean {
273
+ return currency.type === 'credit';
274
+ }
275
+
276
+ // Static version that works with plain objects
277
+ public static isOnChainCredit(currency: { type?: string | null; token_config?: any }): boolean {
278
+ return PaymentCurrency.isCredit(currency) && !!currency.token_config;
252
279
  }
253
280
  }
254
281
 
@@ -32,7 +32,11 @@ export class Refund extends Model<InferAttributes<Refund>, InferCreationAttribut
32
32
 
33
33
  declare metadata?: Record<string, any>;
34
34
 
35
- declare status: LiteralUnion<'pending' | 'requires_action' | 'failed' | 'canceled' | 'succeeded', string>;
35
+ // processing: refund transfer succeeded, waiting for credit burn (for onchain credit only)
36
+ declare status: LiteralUnion<
37
+ 'pending' | 'requires_action' | 'processing' | 'failed' | 'canceled' | 'succeeded',
38
+ string
39
+ >;
36
40
  declare reason?: LiteralUnion<
37
41
  'duplicate' | 'requested_by_customer' | 'requested_by_admin' | 'fraudulent' | 'expired_uncaptured_charge',
38
42
  string
@@ -199,7 +203,13 @@ export class Refund extends Model<InferAttributes<Refund>, InferCreationAttribut
199
203
  afterCreate: (model: Refund, options) =>
200
204
  createEvent('Refund', 'refund.created', model, options).catch(console.error),
201
205
  afterUpdate: (model: Refund, options) =>
202
- createStatusEvent('Refund', 'refund', { canceled: 'canceled', succeeded: 'succeeded' }, model, options),
206
+ createStatusEvent(
207
+ 'Refund',
208
+ 'refund',
209
+ { canceled: 'canceled', processing: 'processing', succeeded: 'succeeded' },
210
+ model,
211
+ options
212
+ ),
203
213
  afterDestroy: (model: Refund, options) =>
204
214
  createEvent('Refund', 'refund.deleted', model, options).catch(console.error),
205
215
  },
@@ -835,3 +835,51 @@ export type StructuredSourceDataField = {
835
835
  };
836
836
 
837
837
  export type SourceData = SimpleSourceData | StructuredSourceDataField[];
838
+
839
+ // Credit Grant on-chain operation status (combined mint, burn and transfer status)
840
+ export type CreditGrantChainStatus =
841
+ | 'mint_pending'
842
+ | 'mint_completed'
843
+ | 'mint_failed'
844
+ | 'burn_pending'
845
+ | 'burn_completed'
846
+ | 'burn_failed'
847
+ | 'transfer_completed' // for expired credits transferred to system wallet
848
+ | 'transfer_failed';
849
+
850
+ // Credit Grant chain operation details
851
+ export type CreditGrantChainDetail = {
852
+ // Mint operation details
853
+ mint?: {
854
+ hash?: string;
855
+ at?: number; // timestamp
856
+ error?: string;
857
+ failed_at?: number;
858
+ };
859
+ // Burn operation details (for expiration)
860
+ burn?: {
861
+ hash?: string;
862
+ at?: number; // timestamp
863
+ amount?: string;
864
+ error?: string;
865
+ failed_at?: number;
866
+ };
867
+ // Expired transfer operation details (for expiration - transfer to system wallet)
868
+ expired_transfer?: {
869
+ hash?: string;
870
+ at?: number; // timestamp
871
+ amount?: string;
872
+ error?: string;
873
+ failed_at?: number;
874
+ };
875
+ // Refund burn operation details
876
+ refund?: {
877
+ id?: string; // refund id
878
+ burn_hash?: string;
879
+ burned_amount?: string;
880
+ system_retained?: string; // amount retained by system (consumed portion)
881
+ burn_error?: string;
882
+ };
883
+ // Voided reason
884
+ voided_reason?: 'refund' | 'expired' | 'manual';
885
+ };
package/api/third.d.ts CHANGED
@@ -2,6 +2,8 @@ declare module 'vite-plugin-blocklet';
2
2
 
3
3
  declare module '@blocklet/sdk/service/notification';
4
4
 
5
+ declare module '@blocklet/sdk/service/blocklet';
6
+
5
7
  declare module 'express-history-api-fallback';
6
8
 
7
9
  declare module 'express-async-errors';
package/blocklet.yml CHANGED
@@ -14,7 +14,7 @@ repository:
14
14
  type: git
15
15
  url: git+https://github.com/blocklet/payment-kit.git
16
16
  specVersion: 1.2.8
17
- version: 1.22.31
17
+ version: 1.23.0
18
18
  logo: logo.png
19
19
  files:
20
20
  - dist
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "payment-kit",
3
- "version": "1.22.31",
3
+ "version": "1.23.0",
4
4
  "scripts": {
5
5
  "dev": "blocklet dev --open",
6
6
  "lint": "tsc --noEmit && eslint src api/src --ext .mjs,.js,.jsx,.ts,.tsx",
@@ -53,13 +53,14 @@
53
53
  "@arcblock/react-hooks": "^3.2.11",
54
54
  "@arcblock/ux": "^3.2.11",
55
55
  "@arcblock/validator": "^1.27.14",
56
+ "@arcblock/vc": "^1.27.14",
56
57
  "@blocklet/did-space-js": "^1.2.9",
57
58
  "@blocklet/error": "^0.3.4",
58
59
  "@blocklet/js-sdk": "^1.17.4",
59
60
  "@blocklet/logger": "^1.17.4",
60
- "@blocklet/payment-broker-client": "1.22.31",
61
- "@blocklet/payment-react": "1.22.31",
62
- "@blocklet/payment-vendor": "1.22.31",
61
+ "@blocklet/payment-broker-client": "1.23.0",
62
+ "@blocklet/payment-react": "1.23.0",
63
+ "@blocklet/payment-vendor": "1.23.0",
63
64
  "@blocklet/sdk": "^1.17.4",
64
65
  "@blocklet/ui-react": "^3.2.11",
65
66
  "@blocklet/uploader": "^0.3.14",
@@ -129,7 +130,7 @@
129
130
  "devDependencies": {
130
131
  "@abtnode/types": "^1.17.4",
131
132
  "@arcblock/eslint-config-ts": "^0.3.3",
132
- "@blocklet/payment-types": "1.22.31",
133
+ "@blocklet/payment-types": "1.23.0",
133
134
  "@types/cookie-parser": "^1.4.9",
134
135
  "@types/cors": "^2.8.19",
135
136
  "@types/debug": "^4.1.12",
@@ -176,5 +177,5 @@
176
177
  "parser": "typescript"
177
178
  }
178
179
  },
179
- "gitHead": "fc03087134d309474256b122eba125e4a01dd6c0"
180
+ "gitHead": "d791ace5b095ff78f4b7328dac8a9575e6b2e265"
180
181
  }
@@ -173,7 +173,7 @@ export default function CreditOverview({ customerId, settings, mode = 'portal' }
173
173
  pb: 2,
174
174
  }}>
175
175
  <Typography variant="h6" component="div">
176
- {currency.name}
176
+ {grantData.meter?.name || currency.name} ({currency.symbol})
177
177
  </Typography>
178
178
  {showRecharge && (
179
179
  <SplitButton