payment-kit 1.20.17 → 1.20.19

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.
@@ -47,7 +47,8 @@ export class VendorFulfillmentService {
47
47
  currency_id: string;
48
48
  customer_did: string;
49
49
  },
50
- vendorConfig: any
50
+ vendorConfig: any,
51
+ sharedContext?: any // Pass bindDomainCap and other shared data between vendors
51
52
  ): Promise<VendorFulfillmentResult> {
52
53
  try {
53
54
  const vendor = await ProductVendor.findByPk(vendorConfig.vendor_id);
@@ -87,7 +88,11 @@ export class VendorFulfillmentService {
87
88
  },
88
89
  deliveryParams: {
89
90
  blockletMetaUrl: vendor.metadata?.blockletMetaUrl,
90
- customParams: vendorConfig.custom_params,
91
+ customParams: {
92
+ ...vendorConfig.custom_params,
93
+ // Merge shared context (bindDomainCap from didnames-adapter)
94
+ ...(sharedContext || {}),
95
+ },
91
96
  },
92
97
  });
93
98
 
@@ -24,11 +24,172 @@ interface CoordinatorJob {
24
24
 
25
25
  const MAX_FULFILLMENT_TIMEOUT = 300000;
26
26
 
27
+ // Helper function to get order info for coordinated fulfillment
28
+ async function getCoordinatedOrderInfo(checkoutSessionId: string) {
29
+ const checkoutSession = await CheckoutSession.findByPk(checkoutSessionId);
30
+
31
+ if (!checkoutSession) {
32
+ throw new Error('CheckoutSession or Invoice not found');
33
+ }
34
+
35
+ return {
36
+ checkoutSessionId,
37
+ amount_total: checkoutSession.amount_total,
38
+ customer_id: checkoutSession.customer_id || '',
39
+ invoiceId: checkoutSession.invoice_id || '',
40
+ currency_id: checkoutSession.currency_id,
41
+ customer_did: checkoutSession.customer_did || '',
42
+ };
43
+ }
44
+
45
+ async function handleCoordinatedFulfillment(job: any): Promise<void> {
46
+ const { checkoutSessionId, invoiceId, didnamesVendorConfig, launcherVendorConfig, context } = job;
47
+
48
+ try {
49
+ logger.info('Starting coordinated fulfillment', {
50
+ checkoutSessionId,
51
+ didnamesVendorId: didnamesVendorConfig.vendor_id,
52
+ launcherVendorId: launcherVendorConfig.vendor_id,
53
+ });
54
+
55
+ const orderInfo = await getCoordinatedOrderInfo(checkoutSessionId);
56
+ if (!orderInfo) {
57
+ throw new Error('Order info not found');
58
+ }
59
+
60
+ // Step 1: Execute didnames fulfillment to generate bindDomainCap
61
+ logger.info('Step 1: Executing didnames fulfillment', { checkoutSessionId });
62
+ const didnamesResult = await VendorFulfillmentService.fulfillSingleVendorOrder(
63
+ orderInfo,
64
+ didnamesVendorConfig,
65
+ context
66
+ );
67
+
68
+ if (didnamesResult.status === 'failed') {
69
+ throw new Error(`Didnames fulfillment failed: ${didnamesResult.errorMessage}`);
70
+ }
71
+
72
+ // Extract bindDomainCap from didnames result
73
+ const bindCapData = didnamesResult.orderDetails?.customParams || {};
74
+ const { domain, sessionId, bindDomainCap, nftDid } = bindCapData;
75
+
76
+ if (!bindDomainCap || !domain || !sessionId) {
77
+ logger.warn('Missing bindDomainCap data from didnames adapter', {
78
+ checkoutSessionId,
79
+ hasBindCap: !!bindDomainCap,
80
+ hasDomain: !!domain,
81
+ hasSessionId: !!sessionId,
82
+ });
83
+ }
84
+
85
+ // Update didnames vendor status
86
+ await updateVendorFulfillmentStatus(
87
+ checkoutSessionId,
88
+ invoiceId,
89
+ didnamesVendorConfig.vendor_id,
90
+ didnamesResult.status === 'completed' ? 'completed' : 'sent',
91
+ {
92
+ orderId: didnamesResult.orderId,
93
+ commissionAmount: didnamesResult.commissionAmount,
94
+ serviceUrl: didnamesResult.serviceUrl,
95
+ }
96
+ );
97
+
98
+ // Step 2: Execute launcher fulfillment with bindDomainCap
99
+ logger.info('Step 2: Executing launcher fulfillment with bindDomainCap', {
100
+ checkoutSessionId,
101
+ hasBindCapData: !!bindDomainCap,
102
+ });
103
+
104
+ const launcherResult = await VendorFulfillmentService.fulfillSingleVendorOrder(orderInfo, launcherVendorConfig, {
105
+ ...context,
106
+ domain,
107
+ sessionId,
108
+ bindDomainCap,
109
+ domainNftDid: nftDid,
110
+ });
111
+
112
+ // Update launcher vendor status
113
+ await updateVendorFulfillmentStatus(
114
+ checkoutSessionId,
115
+ invoiceId,
116
+ launcherVendorConfig.vendor_id,
117
+ launcherResult.status === 'completed' ? 'completed' : 'sent',
118
+ {
119
+ orderId: launcherResult.orderId,
120
+ commissionAmount: launcherResult.commissionAmount,
121
+ serviceUrl: launcherResult.serviceUrl,
122
+ }
123
+ );
124
+
125
+ logger.info('Coordinated fulfillment completed successfully', {
126
+ checkoutSessionId,
127
+ didnamesStatus: didnamesResult.status,
128
+ launcherStatus: launcherResult.status,
129
+ });
130
+
131
+ // Check if all vendors are completed to trigger commission
132
+ await triggerCommissionProcess(checkoutSessionId, invoiceId);
133
+ } catch (error: any) {
134
+ logger.error('Coordinated fulfillment failed', {
135
+ checkoutSessionId,
136
+ error: error.message,
137
+ });
138
+
139
+ // Mark both vendors as failed
140
+ await updateVendorFulfillmentStatus(checkoutSessionId, invoiceId, didnamesVendorConfig.vendor_id, 'failed', {
141
+ lastError: error.message,
142
+ });
143
+
144
+ await updateVendorFulfillmentStatus(checkoutSessionId, invoiceId, launcherVendorConfig.vendor_id, 'failed', {
145
+ lastError: error.message,
146
+ });
147
+
148
+ throw error;
149
+ }
150
+ }
151
+
27
152
  export const fulfillmentCoordinatorQueue = createQueue({
28
153
  name: 'fulfillment-coordinator',
29
154
  onJob: handleFulfillmentCoordination,
30
155
  });
31
156
 
157
+ export const coordinatedFulfillmentQueue = createQueue({
158
+ name: 'coordinated-fulfillment',
159
+ onJob: handleCoordinatedFulfillment,
160
+ options: {
161
+ concurrency: 1,
162
+ maxRetries: 3,
163
+ enableScheduledJob: true,
164
+ },
165
+ });
166
+
167
+ export const startCoordinatedFulfillmentQueue = () => {
168
+ logger.debug('startCoordinatedFulfillmentQueue');
169
+ return Promise.resolve();
170
+ };
171
+
172
+ // Add event listener for coordinated fulfillment
173
+ events.on('vendor.fulfillment.coordinated', async (id, job) => {
174
+ try {
175
+ const exist = await coordinatedFulfillmentQueue.get(id);
176
+ if (!exist) {
177
+ logger.info('Adding coordinated fulfillment job to queue', { id, checkoutSessionId: job.checkoutSessionId });
178
+ coordinatedFulfillmentQueue.push({
179
+ id,
180
+ job,
181
+ });
182
+ } else {
183
+ logger.info('Coordinated fulfillment job already exists, skipping', { id });
184
+ }
185
+ } catch (error: any) {
186
+ logger.error('Failed to handle coordinated fulfillment queue event', {
187
+ id,
188
+ error: error.message,
189
+ });
190
+ }
191
+ });
192
+
32
193
  export async function startVendorFulfillment(checkoutSessionId: string, invoiceId: string): Promise<void> {
33
194
  try {
34
195
  logger.info('Starting vendor fulfillment process', {
@@ -60,17 +221,42 @@ export async function startVendorFulfillment(checkoutSessionId: string, invoiceI
60
221
 
61
222
  await updateVendorInfo(checkoutSessionId, initialVendorInfo);
62
223
 
63
- // Trigger a separate vendor-fulfillment queue for each vendor
64
- for (const vendorConfig of vendorConfigs) {
65
- const vendorFulfillmentJobId = `vendor-fulfillment-${checkoutSessionId}-${vendorConfig.vendor_id}`;
224
+ // Check if we need coordinated fulfillment (didnames + launcher)
225
+ const didnamesVendor = vendorConfigs.find((v) => v.vendor_type === 'didnames');
226
+ const launcherVendor = vendorConfigs.find((v) => v.vendor_type === 'launcher');
227
+
228
+ if (didnamesVendor && launcherVendor) {
229
+ // Coordinated fulfillment: didnames first, then launcher with bindDomainCap
230
+ logger.info('Starting coordinated domain binding fulfillment', {
231
+ checkoutSessionId,
232
+ didnamesVendorId: didnamesVendor.vendor_id,
233
+ launcherVendorId: launcherVendor.vendor_id,
234
+ });
66
235
 
67
- events.emit('vendor.fulfillment.queued', vendorFulfillmentJobId, {
236
+ const coordinatedJobId = `coordinated-fulfillment-${checkoutSessionId}`;
237
+ events.emit('vendor.fulfillment.coordinated', coordinatedJobId, {
68
238
  checkoutSessionId,
69
239
  invoiceId,
70
- vendorId: vendorConfig.vendor_id,
71
- vendorConfig,
240
+ didnamesVendorConfig: didnamesVendor,
241
+ launcherVendorConfig: launcherVendor,
72
242
  retryOnError: true,
73
243
  });
244
+ } else {
245
+ // Regular parallel fulfillment for other vendors
246
+ for (const vendorConfig of vendorConfigs) {
247
+ const vendorFulfillmentJobId = `vendor-fulfillment-${checkoutSessionId}-${vendorConfig.vendor_id}`;
248
+
249
+ events.emit('vendor.fulfillment.queued', vendorFulfillmentJobId, {
250
+ checkoutSessionId,
251
+ invoiceId,
252
+ vendorId: vendorConfig.vendor_id,
253
+ vendorConfig,
254
+ retryOnError: true,
255
+ context: {
256
+ subdomain: `docsmith-${Date.now()}`,
257
+ },
258
+ });
259
+ }
74
260
  }
75
261
 
76
262
  logger.info('Vendor fulfillment process has been triggered', {
@@ -294,7 +480,7 @@ async function updateSingleVendorInfo(
294
480
  logger.error('updateVendorInfo - Update failed', {
295
481
  checkoutSessionId,
296
482
  vendorId,
297
- error: error.message,
483
+ error,
298
484
  });
299
485
  throw error;
300
486
  } finally {
@@ -1,9 +1,8 @@
1
1
  import { getUrl } from '@blocklet/sdk/lib/component';
2
2
  import { Router } from 'express';
3
3
  import Joi from 'joi';
4
+ import { middleware } from '@blocklet/payment-vendor';
4
5
 
5
- import { Auth as VendorAuth, middleware } from '@blocklet/payment-vendor';
6
- import { joinURL } from 'ufo';
7
6
  import { MetadataSchema } from '../libs/api';
8
7
  import { wallet } from '../libs/auth';
9
8
  import dayjs from '../libs/dayjs';
@@ -11,37 +10,37 @@ import logger from '../libs/logger';
11
10
  import { authenticate } from '../libs/security';
12
11
  import { formatToShortUrl } from '../libs/url';
13
12
  import { getBlockletJson } from '../libs/util';
13
+ import { VendorFulfillmentService } from '../libs/vendor-util/fulfillment';
14
14
  import { CheckoutSession, Invoice, Subscription } from '../store/models';
15
15
  import { ProductVendor } from '../store/models/product-vendor';
16
16
 
17
+ const VENDOR_DID = {
18
+ launcher: 'z8iZkFBbrVQxZHvcWWB3Sa2TrfGmSeFz9MSU7',
19
+ didnames: 'z2qaGosS3rZ7m5ttP3Nd4V4qczR9TryTcRV4p',
20
+ };
21
+
17
22
  const authAdmin = authenticate<CheckoutSession>({ component: true, roles: ['owner', 'admin'] });
18
23
  const loginAuth = authenticate<CheckoutSession>({ component: true, ensureLogin: true, mine: true });
19
24
 
20
25
  const createVendorSchema = Joi.object({
21
26
  vendor_key: Joi.string().max(50).required(),
22
- vendor_type: Joi.string().valid('launcher').default('launcher'),
27
+ vendor_type: Joi.string().valid('launcher', 'didnames').default('launcher'),
23
28
  name: Joi.string().max(255).required(),
24
29
  description: Joi.string().max(1000).allow('').optional(),
25
30
  app_url: Joi.string().uri().max(512).required(),
26
31
  app_pid: Joi.string().max(255).allow('').optional(),
27
32
  app_logo: Joi.string().max(512).allow('').optional(),
28
- vendor_did: Joi.string()
29
- .pattern(/^(did:abt:)?[1-9A-HJ-NP-Za-km-z]{37}$/)
30
- .required(),
31
33
  status: Joi.string().valid('active', 'inactive').default('active'),
32
34
  metadata: MetadataSchema,
33
35
  }).unknown(false);
34
36
 
35
37
  const updateVendorSchema = Joi.object({
36
- vendor_type: Joi.string().valid('launcher').optional(),
38
+ vendor_type: Joi.string().valid('launcher', 'didnames').optional(),
37
39
  name: Joi.string().max(255).optional(),
38
40
  description: Joi.string().max(1000).allow('').optional(),
39
41
  app_url: Joi.string().uri().max(512).optional(),
40
42
  app_pid: Joi.string().max(255).allow('').optional(),
41
43
  app_logo: Joi.string().max(512).allow('').optional(),
42
- vendor_did: Joi.string()
43
- .pattern(/^(did:abt:)?[1-9A-HJ-NP-Za-km-z]{37}$/)
44
- .required(),
45
44
  status: Joi.string().valid('active', 'inactive').optional(),
46
45
  metadata: MetadataSchema,
47
46
  }).unknown(true);
@@ -115,7 +114,7 @@ async function getAllVendors(_req: any, res: any) {
115
114
  }
116
115
  }
117
116
 
118
- async function getVendorById(req: any, res: any) {
117
+ async function getVendorInfo(req: any, res: any) {
119
118
  try {
120
119
  const vendor = await ProductVendor.findByPk(req.params.id);
121
120
  if (!vendor) {
@@ -144,17 +143,19 @@ async function createVendor(req: any, res: any) {
144
143
 
145
144
  const {
146
145
  vendor_key: vendorKey,
147
- vendor_type: vendorType,
146
+ vendor_type: type,
148
147
  name,
149
148
  description,
150
149
  app_url: appUrl,
151
- vendor_did: vendorDid,
152
150
  metadata,
153
151
  app_pid: appPid,
154
152
  app_logo: appLogo,
155
153
  status,
156
154
  } = value;
157
155
 
156
+ const vendorType = (type || 'launcher') as 'launcher' | 'didnames';
157
+ const vendorDid = VENDOR_DID[vendorType];
158
+
158
159
  const existingVendor = await ProductVendor.findOne({
159
160
  where: { vendor_key: vendorKey },
160
161
  });
@@ -164,18 +165,25 @@ async function createVendor(req: any, res: any) {
164
165
 
165
166
  const blockletJson = await getBlockletJson(appUrl);
166
167
 
168
+ const mountPoint =
169
+ blockletJson?.componentMountPoints?.find((item: any) => item.did === vendorDid)?.mountPoint || '/';
170
+
167
171
  const vendor = await ProductVendor.create({
168
172
  vendor_key: vendorKey,
169
- vendor_type: vendorType || 'launcher',
173
+ vendor_type: vendorType,
170
174
  name,
171
175
  description,
172
176
  app_url: appUrl,
173
- vendor_did: vendorDid?.replace('did:abt:', '').trim(),
177
+ vendor_did: vendorDid,
174
178
  status: status || 'active',
175
179
  app_pid: appPid,
176
180
  app_logo: appLogo,
177
- metadata: metadata || {},
181
+ metadata: {
182
+ ...metadata,
183
+ mountPoint,
184
+ },
178
185
  extends: {
186
+ mountPoint,
179
187
  appId: blockletJson?.appId,
180
188
  appPk: blockletJson?.appPk,
181
189
  },
@@ -208,19 +216,24 @@ async function updateVendor(req: any, res: any) {
208
216
  }
209
217
 
210
218
  const {
211
- vendor_type: vendorType,
219
+ vendor_type: type,
212
220
  name,
213
221
  description,
214
222
  app_url: appUrl,
215
- vendor_did: vendorDid,
216
223
  status,
217
224
  metadata,
218
225
  app_pid: appPid,
219
226
  app_logo: appLogo,
220
227
  } = value;
221
228
 
229
+ const vendorType = (type || 'launcher') as 'launcher' | 'didnames';
230
+ const vendorDid = VENDOR_DID[vendorType];
231
+
222
232
  const blockletJson = await getBlockletJson(appUrl);
223
233
 
234
+ const mountPoint =
235
+ blockletJson?.componentMountPoints?.find((item: any) => item.did === vendorDid)?.mountPoint || '/';
236
+
224
237
  if (req.body.vendorKey && req.body.vendorKey !== vendor.vendor_key) {
225
238
  const existingVendor = await ProductVendor.findOne({
226
239
  where: { vendor_key: req.body.vendorKey },
@@ -236,11 +249,15 @@ async function updateVendor(req: any, res: any) {
236
249
  app_url: appUrl,
237
250
  vendor_did: vendorDid,
238
251
  status,
239
- metadata,
252
+ metadata: {
253
+ ...metadata,
254
+ mountPoint,
255
+ },
240
256
  app_pid: appPid,
241
257
  app_logo: appLogo,
242
258
  vendor_key: req.body.vendor_key,
243
259
  extends: {
260
+ mountPoint,
244
261
  appId: blockletJson?.appId,
245
262
  appPk: blockletJson?.appPk,
246
263
  },
@@ -295,57 +312,40 @@ async function testVendorConnection(req: any, res: any) {
295
312
  }
296
313
  }
297
314
 
298
- async function getVendorStatusByVendorId(vendorId: string, orderId: string, isDetail = false) {
315
+ const getVendorById = async (vendorId: string, orderId: string) => {
316
+ if (!vendorId || !orderId) {
317
+ throw new Error(`vendorId or orderId is required, vendorId: ${vendorId}, orderId: ${orderId}`);
318
+ }
319
+
320
+ const vendor = await ProductVendor.findByPk(vendorId);
321
+ if (!vendor) {
322
+ throw new Error(`vendor not found, vendorId: ${vendorId}`);
323
+ }
324
+
325
+ const vendorAdapter = await VendorFulfillmentService.getVendorAdapter(vendor.vendor_key);
326
+
327
+ const data = await vendorAdapter.getOrder(vendor, orderId);
328
+
329
+ return data;
330
+ };
331
+
332
+ async function getVendorStatusById(vendorId: string, orderId: string) {
299
333
  if (!vendorId || !orderId) {
300
- return {};
334
+ throw new Error(`vendorId or orderId is required, vendorId: ${vendorId}, orderId: ${orderId}`);
301
335
  }
302
336
 
303
337
  const vendor = await ProductVendor.findByPk(vendorId);
304
- const url = vendor?.app_url
305
- ? joinURL(
306
- vendor.app_url,
307
- vendor.metadata?.mountPoint || '',
308
- '/api/vendor/',
309
- isDetail ? 'orders' : 'status',
310
- orderId
311
- )
312
- : null;
313
-
314
- const { headers } = VendorAuth.signRequestWithHeaders({});
315
- const name = vendor?.name;
316
- const key = vendor?.vendor_key;
317
-
318
- return url
319
- ? fetch(url, { headers })
320
- .then(async (r) => {
321
- const data = await r.json();
322
-
323
- if (!data.dashboardUrl) {
324
- return {
325
- ...data,
326
- name,
327
- key,
328
- };
329
- }
330
- const validUntil = dayjs().add(20, 'minutes').format('YYYY-MM-DDTHH:mm:ss+00:00');
331
- const maxVisits = 5;
332
-
333
- const homeUrl = await formatToShortUrl({ url: data.homeUrl, maxVisits, validUntil });
334
- const dashboardUrl = await formatToShortUrl({ url: data.dashboardUrl, maxVisits, validUntil });
335
-
336
- return {
337
- ...data,
338
- name,
339
- key,
340
- homeUrl,
341
- dashboardUrl,
342
- };
343
- })
344
- .catch((e) => ({ error: e.message }))
345
- : null;
338
+
339
+ if (!vendor) {
340
+ throw new Error(`vendor not found, vendorId: ${vendorId}`);
341
+ }
342
+
343
+ const vendorAdapter = await VendorFulfillmentService.getVendorAdapter(vendor.vendor_key);
344
+
345
+ return vendorAdapter.getOrderStatus(vendor, orderId);
346
346
  }
347
347
 
348
- async function getVendorStatus(sessionId: string, isDetail = false) {
348
+ async function doRequestVendor(sessionId: string, func: (vendorId: string, orderId: string) => Promise<any>) {
349
349
  const doc = await CheckoutSession.findByPk(sessionId);
350
350
 
351
351
  if (!doc) {
@@ -377,35 +377,36 @@ async function getVendorStatus(sessionId: string, isDetail = false) {
377
377
  }
378
378
 
379
379
  const vendors = doc.vendor_info.map((item) => {
380
- return getVendorStatusByVendorId(item.vendor_id, item.order_id, isDetail).then((status) => {
381
- return {
382
- error_message: item.error_message,
383
- status: item.status,
384
- ...status,
385
- };
386
- });
380
+ return func(item.vendor_id, item.order_id);
387
381
  });
388
382
 
389
- const subscriptionId = doc.subscription_id;
390
- let shortSubscriptionUrl = '';
383
+ return {
384
+ payment_status: doc.payment_status,
385
+ session_status: doc.status,
386
+ vendors: await Promise.all(vendors),
387
+ subscriptionId: doc.subscription_id,
388
+ error: null,
389
+ };
390
+ }
391
+
392
+ async function getVendorStatus(sessionId: string) {
393
+ const result: any = await doRequestVendor(sessionId, getVendorStatusById);
391
394
 
392
- if (isDetail && subscriptionId) {
393
- const subscriptionUrl = getUrl(`/customer/subscription/${subscriptionId}`);
395
+ if (result.subscriptionId) {
396
+ const subscriptionUrl = getUrl(`/customer/subscription/${result.subscriptionId}`);
394
397
 
395
- shortSubscriptionUrl = await formatToShortUrl({
398
+ result.subscriptionUrl = await formatToShortUrl({
396
399
  url: subscriptionUrl,
397
400
  maxVisits: 5,
398
401
  validUntil: dayjs().add(20, 'minutes').format('YYYY-MM-DDTHH:mm:ss+00:00'),
399
402
  });
400
403
  }
401
404
 
402
- return {
403
- payment_status: paymentStatus,
404
- session_status: doc.status,
405
- subscriptionUrl: shortSubscriptionUrl,
406
- vendors: await Promise.all(vendors),
407
- error: null,
408
- };
405
+ return result;
406
+ }
407
+
408
+ function getVendor(sessionId: string) {
409
+ return doRequestVendor(sessionId, getVendorById);
409
410
  }
410
411
 
411
412
  async function getVendorFulfillmentStatus(req: any, res: any) {
@@ -427,7 +428,7 @@ async function getVendorFulfillmentDetail(req: any, res: any) {
427
428
  const { sessionId } = req.params;
428
429
 
429
430
  try {
430
- const detail = await getVendorStatus(sessionId, true);
431
+ const detail = await getVendor(sessionId);
431
432
  if (detail.code) {
432
433
  return res.status(detail.code).json({ error: detail.error });
433
434
  }
@@ -458,7 +459,7 @@ async function redirectToVendor(req: any, res: any) {
458
459
  return res.redirect('/404');
459
460
  }
460
461
 
461
- const detail = await getVendorStatusByVendorId(vendorId, order.order_id || '', true);
462
+ const detail = await getVendorById(vendorId, order.order_id || '');
462
463
  if (!detail) {
463
464
  logger.warn('Vendor status detail not found', {
464
465
  subscriptionId,
@@ -555,7 +556,7 @@ router.get(
555
556
  );
556
557
 
557
558
  router.get('/', getAllVendors);
558
- router.get('/:id', authAdmin, validateParams(vendorIdParamSchema), getVendorById);
559
+ router.get('/:id', authAdmin, validateParams(vendorIdParamSchema), getVendorInfo);
559
560
  router.post('/', authAdmin, createVendor);
560
561
  router.put('/:id', authAdmin, validateParams(vendorIdParamSchema), updateVendor);
561
562
  router.delete('/:id', authAdmin, validateParams(vendorIdParamSchema), deleteVendor);
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.20.17
17
+ version: 1.20.19
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.20.17",
3
+ "version": "1.20.19",
4
4
  "scripts": {
5
5
  "dev": "blocklet dev --open",
6
6
  "lint": "tsc --noEmit && eslint src api/src --ext .mjs,.js,.jsx,.ts,.tsx",
@@ -56,9 +56,9 @@
56
56
  "@blocklet/error": "^0.2.5",
57
57
  "@blocklet/js-sdk": "^1.16.52-beta-20250912-112002-e3499e9c",
58
58
  "@blocklet/logger": "^1.16.52-beta-20250912-112002-e3499e9c",
59
- "@blocklet/payment-broker-client": "1.20.17",
60
- "@blocklet/payment-react": "1.20.17",
61
- "@blocklet/payment-vendor": "1.20.17",
59
+ "@blocklet/payment-broker-client": "1.20.19",
60
+ "@blocklet/payment-react": "1.20.19",
61
+ "@blocklet/payment-vendor": "1.20.19",
62
62
  "@blocklet/sdk": "^1.16.52-beta-20250912-112002-e3499e9c",
63
63
  "@blocklet/ui-react": "^3.1.41",
64
64
  "@blocklet/uploader": "^0.2.12",
@@ -121,13 +121,14 @@
121
121
  "ufo": "^1.6.1",
122
122
  "umzug": "^3.8.2",
123
123
  "use-bus": "^2.5.2",
124
+ "uuid": "^13.0.0",
124
125
  "validator": "^13.15.15",
125
126
  "web3": "^4.16.0"
126
127
  },
127
128
  "devDependencies": {
128
129
  "@abtnode/types": "^1.16.52-beta-20250912-112002-e3499e9c",
129
130
  "@arcblock/eslint-config-ts": "^0.3.3",
130
- "@blocklet/payment-types": "1.20.17",
131
+ "@blocklet/payment-types": "1.20.19",
131
132
  "@types/cookie-parser": "^1.4.9",
132
133
  "@types/cors": "^2.8.19",
133
134
  "@types/debug": "^4.1.12",
@@ -174,5 +175,5 @@
174
175
  "parser": "typescript"
175
176
  }
176
177
  },
177
- "gitHead": "20e9d7519327cb4df0c93375ff85783303fc99d6"
178
+ "gitHead": "13703fca3eb2151623b303605df104c4a1199741"
178
179
  }
@@ -37,7 +37,7 @@ export default function VendorActions({ data, variant = 'compact', onChange }: V
37
37
  try {
38
38
  setState({ loading: true });
39
39
  const newStatus = data.status === 'active' ? 'inactive' : 'active';
40
- await api.put(`/api/vendors/${data.id}`, { status: newStatus }).then((res: any) => res.data);
40
+ await api.put(`/api/vendors/${data.id}`, { ...data, status: newStatus }).then((res: any) => res.data);
41
41
  Toast.success(t('common.saved'));
42
42
  onChange(state.action);
43
43
  } catch (err) {
@@ -1126,6 +1126,7 @@ export default flat({
1126
1126
  nameRequired: 'Vendor name is required',
1127
1127
  vendorType: 'Vendor Type',
1128
1128
  vendorTypeRequired: 'Vendor type is required',
1129
+ didnames: 'DID Names',
1129
1130
  launcher: 'Launcher',
1130
1131
  vendorKey: 'Vendor Key',
1131
1132
  vendorKeyRequired: 'Vendor key is required',
@@ -1098,7 +1098,8 @@ export default flat({
1098
1098
  nameRequired: '供应商名称是必填项',
1099
1099
  vendorType: '供应商类型',
1100
1100
  vendorTypeRequired: '供应商类型是必填项',
1101
- launcher: '启动器',
1101
+ didnames: 'DID Names',
1102
+ launcher: 'Launcher',
1102
1103
  vendorKey: '供应商标识',
1103
1104
  vendorKeyRequired: '供应商标识是必填项',
1104
1105
  vendorKeyHelp: '供应商的唯一标识符',