payment-kit 1.15.21 → 1.15.23

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.
@@ -194,6 +194,7 @@ router.post('/', auth, async (req, res) => {
194
194
  try {
195
195
  const { error } = PaymentLinkCreateSchema.validate(req.body);
196
196
  if (error) {
197
+ logger.warn('Payment link create request invalid', { error: error.message, body: req.body });
197
198
  res.status(400).json({ error: `Payment link create request invalid: ${error.message}` });
198
199
  return;
199
200
  }
@@ -204,9 +205,10 @@ router.post('/', auth, async (req, res) => {
204
205
  currency_id: req.body.currency_id || req.currency.id,
205
206
  metadata: formatMetadata(req.body.metadata),
206
207
  });
208
+ logger.info('Payment link created successfully', { id: result.id, user: req.user?.did });
207
209
  res.json(result);
208
210
  } catch (err) {
209
- logger.error('create payment link error', err);
211
+ logger.error('Create payment link error', { error: err.message, stack: err.stack, body: req.body });
210
212
  res.status(400).json({ error: err.message });
211
213
  }
212
214
  });
@@ -321,23 +323,33 @@ const PaymentLinkUpdateSchema = Joi.object({
321
323
  router.put('/:id', auth, async (req, res) => {
322
324
  const { error } = PaymentLinkUpdateSchema.validate(req.body);
323
325
  if (error) {
326
+ logger.warn('Payment link update request invalid', { error: error.message, id: req.params.id, body: req.body });
324
327
  return res.status(400).json({ error: `Payment link update request invalid: ${error.message}` });
325
328
  }
326
329
  const doc = await PaymentLink.findByPk(req.params.id);
327
330
 
328
331
  if (!doc) {
332
+ logger.warn('Payment link not found for update', { id: req.params.id });
329
333
  return res.status(404).json({ error: 'payment link not found' });
330
334
  }
331
335
  if (doc.active === false) {
336
+ logger.warn('Attempt to update archived payment link', { id: req.params.id });
332
337
  return res.status(403).json({ error: 'payment link archived' });
333
338
  }
334
- // if (doc.locked) {
335
- // return res.status(403).json({ error: 'payment link locked' });
336
- // }
337
339
 
338
- await doc.update(formatBeforeSave(Object.assign({}, doc.dataValues, req.body)));
339
-
340
- res.json(doc);
340
+ try {
341
+ await doc.update(formatBeforeSave(Object.assign({}, doc.dataValues, req.body)));
342
+ logger.info('Payment link updated successfully', { id: req.params.id, user: req.user?.did });
343
+ res.json(doc);
344
+ } catch (err) {
345
+ logger.error('Update payment link error', {
346
+ error: err.message,
347
+ stack: err.stack,
348
+ id: req.params.id,
349
+ body: req.body,
350
+ });
351
+ res.status(500).json({ error: 'Failed to update payment link' });
352
+ }
341
353
  });
342
354
 
343
355
  // archive
@@ -345,19 +357,23 @@ router.put('/:id/archive', auth, async (req, res) => {
345
357
  const doc = await PaymentLink.findByPk(req.params.id);
346
358
 
347
359
  if (!doc) {
360
+ logger.warn('Payment link not found for archiving', { id: req.params.id });
348
361
  return res.status(404).json({ error: 'payment link not found' });
349
362
  }
350
363
 
351
364
  if (doc.active === false) {
365
+ logger.warn('Attempt to archive already archived payment link', { id: req.params.id });
352
366
  return res.status(403).json({ error: 'payment link already archived' });
353
367
  }
354
368
 
355
- // if (doc.locked) {
356
- // return res.status(403).json({ error: 'payment link locked' });
357
- // }
358
-
359
- await doc.update({ active: false });
360
- return res.json(doc);
369
+ try {
370
+ await doc.update({ active: false });
371
+ logger.info('Payment link archived successfully', { id: req.params.id, user: req.user?.did });
372
+ return res.json(doc);
373
+ } catch (err) {
374
+ logger.error('Archive payment link error', { error: err.message, stack: err.stack, id: req.params.id });
375
+ return res.status(500).json({ error: 'Failed to archive payment link' });
376
+ }
361
377
  });
362
378
 
363
379
  // delete
@@ -372,12 +388,14 @@ router.delete('/:id', auth, async (req, res) => {
372
388
  return res.status(403).json({ error: 'payment link archived' });
373
389
  }
374
390
 
375
- // if (doc.locked) {
376
- // return res.status(403).json({ error: 'payment link locked' });
377
- // }
378
-
379
- await doc.destroy();
380
- return res.json(doc);
391
+ try {
392
+ await doc.destroy();
393
+ logger.info('Payment link deleted successfully', { id: req.params.id, user: req.user?.did });
394
+ return res.json(doc);
395
+ } catch (err) {
396
+ logger.error('Delete payment link error', { error: err.message, stack: err.stack, id: req.params.id });
397
+ return res.status(500).json({ error: 'Failed to delete payment link' });
398
+ }
381
399
  });
382
400
 
383
401
  router.post('/stash', auth, async (req, res) => {
@@ -393,12 +411,14 @@ router.post('/stash', auth, async (req, res) => {
393
411
  let doc = await PaymentLink.findByPk(raw.id);
394
412
  if (doc) {
395
413
  await doc.update({ ...formatBeforeSave(req.body), livemode: raw.livemode });
414
+ logger.info('Stashed payment link updated', { id: raw.id, user: req.user?.did });
396
415
  } else {
397
416
  doc = await PaymentLink.create(raw as PaymentLink);
417
+ logger.info('New stashed payment link created', { id: raw.id, user: req.user?.did });
398
418
  }
399
419
  res.json(doc);
400
420
  } catch (err) {
401
- console.error(err);
421
+ logger.error('Stash payment link error', { error: err.message, stack: err.stack, body: req.body });
402
422
  res.status(500).json({ error: err.message });
403
423
  }
404
424
  });
@@ -217,9 +217,10 @@ router.post('/', auth, async (req, res) => {
217
217
  quantity_sold: 0,
218
218
  });
219
219
 
220
+ logger.info(`Price created: ${result?.id}`, { priceId: result?.id, requestedBy: req.user?.did });
220
221
  res.json(result);
221
222
  } catch (err) {
222
- console.error(err);
223
+ logger.error('Error creating price', { error: err.message, request: req.body });
223
224
  res.status(400).json({ error: err.message });
224
225
  }
225
226
  });
@@ -346,9 +347,14 @@ router.put('/:id', auth, async (req, res) => {
346
347
  }
347
348
  }
348
349
 
349
- await doc.update(Price.formatBeforeSave(updates));
350
-
351
- return res.json(await getExpandedPrice(req.params.id as string));
350
+ try {
351
+ await doc.update(Price.formatBeforeSave(updates));
352
+ logger.info(`Price updated: ${req.params.id}`, { priceId: req.params.id, updates, requestedBy: req.user?.did });
353
+ return res.json(await getExpandedPrice(req.params.id as string));
354
+ } catch (err) {
355
+ logger.error('Error updating price', { error: err.message, request: req.body });
356
+ return res.status(400).json({ error: err.message });
357
+ }
352
358
  });
353
359
 
354
360
  // archive
@@ -369,6 +375,7 @@ router.put('/:id/archive', auth, async (req, res) => {
369
375
 
370
376
  await price.update({ active: false });
371
377
 
378
+ logger.info(`Price archived: ${req.params.id}`, { priceId: req.params.id, requestedBy: req.user?.did });
372
379
  return res.json(await getExpandedPrice(req.params.id as string));
373
380
  });
374
381
 
@@ -431,6 +438,12 @@ router.put('/:id/inventory', auth, async (req, res) => {
431
438
  }
432
439
  await price.increment('quantity_sold', { by: req.body.quantity });
433
440
  }
441
+ logger.info(`Price inventory updated: ${req.params.id}`, {
442
+ priceId: req.params.id,
443
+ action: req.body.action,
444
+ quantity: req.body.quantity,
445
+ requestedBy: req.user?.did,
446
+ });
434
447
  return res.json(await getExpandedPrice(req.params.id as string));
435
448
  } catch (err) {
436
449
  logger.error('update price inventory error', err);
@@ -161,6 +161,12 @@ router.post('/', auth, async (req, res) => {
161
161
  currency_id: req.currency.id,
162
162
  metadata: formatMetadata(req.body.metadata),
163
163
  });
164
+ logger.info('Product and prices created', {
165
+ productId: result.id,
166
+ name: result.name,
167
+ priceCount: result.prices.length,
168
+ requestedBy: req.user?.did,
169
+ });
164
170
  res.json(result);
165
171
  } catch (err) {
166
172
  logger.error('create product error', err);
@@ -300,7 +306,11 @@ router.put('/:id', auth, async (req, res) => {
300
306
  updates.metadata = formatMetadata(updates.metadata);
301
307
  }
302
308
  await product.update(updates);
303
-
309
+ logger.info('Product updated', {
310
+ productId: product.id,
311
+ updatedFields: Object.keys(updates),
312
+ requestedBy: req.user?.did,
313
+ });
304
314
  return res.json(await Product.expand(req.params.id as string));
305
315
  });
306
316
 
@@ -346,7 +356,10 @@ router.delete('/:id', auth, async (req, res) => {
346
356
 
347
357
  await product.destroy();
348
358
  await Price.destroy({ where: { product_id: product.id } });
349
-
359
+ logger.info('Product and associated prices deleted', {
360
+ productId: product.id,
361
+ requestedBy: req.user?.did,
362
+ });
350
363
  return res.json(product);
351
364
  } catch (err) {
352
365
  logger.error('delete product error', err);
@@ -415,6 +428,12 @@ router.post('/batch-price-update', auth, async (req, res) => {
415
428
  })
416
429
  );
417
430
 
431
+ logger.info('Batch price update completed', {
432
+ updatedCount: updated.length,
433
+ dryRun,
434
+ factor,
435
+ requestedBy: req.user?.did,
436
+ });
418
437
  return res.json(updated);
419
438
  } catch (err) {
420
439
  logger.error('batch price update error', err);
@@ -169,10 +169,16 @@ router.post('/', authAdmin, async (req, res) => {
169
169
  ...req.params,
170
170
  ...req.body,
171
171
  result: item.toJSON(),
172
+ requestedBy: req.user?.did,
172
173
  });
173
174
  res.json(item);
174
175
  } catch (err) {
175
- logger.error('create refund error', err);
176
+ logger.error('Create refund failed', {
177
+ error: err.message,
178
+ stack: err.stack,
179
+ requestBody: req.body,
180
+ requestedBy: req.user?.did,
181
+ });
176
182
  res.status(400).json({ error: err.message });
177
183
  }
178
184
  });
@@ -241,10 +247,21 @@ router.put('/:id', authAdmin, async (req, res) => {
241
247
  }
242
248
 
243
249
  await doc.update(raw);
250
+ logger.info('Refund updated', {
251
+ refundId: doc.id,
252
+ updatedFields: Object.keys(raw),
253
+ requestedBy: req.user?.did,
254
+ });
244
255
  res.json(doc);
245
256
  } catch (err) {
246
- console.error(err);
247
- res.json(null);
257
+ logger.error('Update refund failed', {
258
+ refundId: req.params.id,
259
+ error: err.message,
260
+ stack: err.stack,
261
+ requestBody: req.body,
262
+ requestedBy: req.user?.did,
263
+ });
264
+ res.status(500).json({ error: 'Internal server error' });
248
265
  }
249
266
  });
250
267
 
@@ -11,6 +11,7 @@ import { formatMetadata } from '../libs/util';
11
11
  import { Price, Product, Subscription, SubscriptionItem, UsageRecord } from '../store/models';
12
12
  import { forwardUsageRecordToStripe } from '../integrations/stripe/resource';
13
13
  import { usageRecordQueue } from '../queues/usage-record';
14
+ import logger from '../libs/logger';
14
15
 
15
16
  const router = Router();
16
17
  const auth = authenticate<SubscriptionItem>({ component: true, roles: ['owner', 'admin'] });
@@ -42,6 +43,13 @@ router.post('/', auth, async (req, res) => {
42
43
  }
43
44
 
44
45
  const doc = await SubscriptionItem.create(raw as SubscriptionItem);
46
+ logger.info('SubscriptionItem created', {
47
+ id: doc.id,
48
+ subscriptionId: doc.subscription_id,
49
+ priceId: doc.price_id,
50
+ quantity: doc.quantity,
51
+ requestedBy: req.user?.did,
52
+ });
45
53
  return res.json(doc);
46
54
  });
47
55
 
@@ -135,7 +143,12 @@ router.put('/:id', auth, async (req, res) => {
135
143
  }
136
144
 
137
145
  await doc.update(updates);
138
-
146
+ logger.info('SubscriptionItem updated', {
147
+ id: doc.id,
148
+ subscriptionId: doc.subscription_id,
149
+ updatedFields: Object.keys(updates),
150
+ requestedBy: req.user?.did,
151
+ });
139
152
  return res.json(doc);
140
153
  });
141
154
 
@@ -156,7 +169,12 @@ router.delete('/:id', auth, async (req, res) => {
156
169
  }
157
170
 
158
171
  await doc.destroy();
159
-
172
+ logger.info('SubscriptionItem deleted', {
173
+ id: doc.id,
174
+ subscriptionId: doc.subscription_id,
175
+ clearUsage: req.body.clear_usage,
176
+ requestedBy: req.user?.did,
177
+ });
160
178
  return res.json(doc);
161
179
  });
162
180
 
@@ -198,11 +216,23 @@ router.post('/:id/add-usage-quantity', auth, async (req, res) => {
198
216
  timestamp: now,
199
217
  } as UsageRecord);
200
218
 
219
+ logger.info('Usage quantity added', {
220
+ subscriptionItemId: subscriptionItem.id,
221
+ subscriptionId: subscription.id,
222
+ quantity,
223
+ timestamp: now,
224
+ requestedBy: req.user?.did,
225
+ });
226
+
201
227
  if (subscription.billing_thresholds?.amount_gte) {
202
228
  usageRecordQueue.push({
203
229
  id: `usage-${subscription.id}`,
204
230
  job: { subscriptionId: subscription.id, subscriptionItemId: subscriptionItem.id },
205
231
  });
232
+ logger.info('Usage record pushed to queue', {
233
+ subscriptionId: subscription.id,
234
+ subscriptionItemId: subscriptionItem.id,
235
+ });
206
236
  }
207
237
 
208
238
  await forwardUsageRecordToStripe(subscriptionItem, {
@@ -210,6 +240,13 @@ router.post('/:id/add-usage-quantity', auth, async (req, res) => {
210
240
  timestamp: now,
211
241
  action: 'increment',
212
242
  });
243
+ logger.info('Usage record forwarded to Stripe', {
244
+ subscriptionItemId: subscriptionItem.id,
245
+ quantity,
246
+ timestamp: now,
247
+ action: 'increment',
248
+ });
249
+
213
250
  return res.json(usageRecord);
214
251
  } catch (err) {
215
252
  console.error(err);
@@ -407,7 +407,14 @@ router.put('/:id/cancel', authPortal, async (req, res) => {
407
407
  }
408
408
  await subscription.update(updates);
409
409
  await new SubscriptionWillCanceledSchedule().reScheduleSubscriptionTasks([subscription]);
410
-
410
+ logger.info('Update subscription for cancel request successful', {
411
+ subscriptionId: subscription.id,
412
+ customerId: subscription.customer_id,
413
+ reason: req.body.reason,
414
+ cancelAt: subscription.cancel_at,
415
+ requestedBy: req.user?.did,
416
+ updates,
417
+ });
411
418
  return res.json(subscription);
412
419
  });
413
420
 
@@ -1105,7 +1112,11 @@ router.put('/:id', authPortal, async (req, res) => {
1105
1112
  }
1106
1113
  }
1107
1114
  }
1108
-
1115
+ logger.info('Subscription updated successfully', {
1116
+ subscriptionId: subscription.id,
1117
+ updatedFields: Object.keys(updates),
1118
+ newStatus: subscription.status,
1119
+ });
1109
1120
  return res.json({ ...subscription.toJSON(), connectAction });
1110
1121
  } catch (err) {
1111
1122
  console.error(err);
@@ -1624,8 +1635,16 @@ router.delete('/:id', auth, async (req, res) => {
1624
1635
  await UsageRecord.destroy({ where: { subscription_item_id: items.map((x) => x.id) } });
1625
1636
  await SubscriptionItem.destroy({ where: { subscription_id: doc.id } });
1626
1637
  await doc.destroy();
1627
- logger.info('subscription deleted', { subscription: req.params.id });
1628
-
1638
+ logger.info('Subscription deleted successfully', {
1639
+ subscriptionId: req.params.id,
1640
+ deletedRelatedRecords: {
1641
+ invoiceItems: await InvoiceItem.count({ where: { subscription_id: doc.id } }),
1642
+ invoices: await Invoice.count({ where: { subscription_id: doc.id } }),
1643
+ usageRecords: await UsageRecord.count({ where: { subscription_item_id: items.map((x) => x.id) } }),
1644
+ subscriptionItems: items.length,
1645
+ },
1646
+ requestedBy: req.user?.did,
1647
+ });
1629
1648
  return res.json(doc);
1630
1649
  });
1631
1650
 
@@ -1691,6 +1710,12 @@ router.put('/:id/slash-stake', auth, async (req, res) => {
1691
1710
  return res.status(400).json({ error: 'Staking not found on subscription payment detail' });
1692
1711
  }
1693
1712
  try {
1713
+ logger.warn('Stake slash initiated', {
1714
+ subscriptionId: subscription.id,
1715
+ slashReason: req.body.slashReason,
1716
+ requestedBy: req.user?.did,
1717
+ });
1718
+
1694
1719
  await subscription.update({
1695
1720
  // @ts-ignore
1696
1721
  cancelation_details: {
@@ -1703,6 +1728,13 @@ router.put('/:id/slash-stake', auth, async (req, res) => {
1703
1728
  id: `slash-stake-${subscription.id}`,
1704
1729
  job: { subscriptionId: subscription.id },
1705
1730
  });
1731
+ logger.info('Stake slash scheduled successfully', {
1732
+ subscriptionId: subscription.id,
1733
+ result,
1734
+ slashReason: req.body.slashReason,
1735
+ requestedBy: req.user?.did,
1736
+ stakingAddress: address,
1737
+ });
1706
1738
  return res.json(result);
1707
1739
  } catch (err) {
1708
1740
  logger.error('subscription slash stake failed', { subscription: subscription.id, error: err });
@@ -45,17 +45,36 @@ router.post('/', auth, async (req, res) => {
45
45
  });
46
46
  if (doc) {
47
47
  if (doc.billed) {
48
+ logger.info('UsageRecord updated', {
49
+ subscriptionItemId: raw.subscription_item_id,
50
+ timestamp: raw.timestamp,
51
+ newQuantity: raw.quantity,
52
+ });
48
53
  return res.status(400).json({ error: 'UsageRecord is immutable because already billed' });
49
54
  }
50
55
  if (req.body.action === 'increment') {
51
56
  await doc.increment('quantity', { by: raw.quantity });
57
+ logger.info('UsageRecord incremented', {
58
+ subscriptionItemId: raw.subscription_item_id,
59
+ timestamp: raw.timestamp,
60
+ incrementBy: raw.quantity,
61
+ });
52
62
  } else {
53
63
  if (subscription.billing_thresholds?.amount_gte) {
64
+ logger.warn('Invalid action for subscription with billing_thresholds', {
65
+ subscriptionId: subscription.id,
66
+ action: req.body.action,
67
+ });
54
68
  return res
55
69
  .status(400)
56
70
  .json({ error: 'UsageRecord action must be `increment` for subscriptions with billing_thresholds' });
57
71
  }
58
72
  await doc.update({ quantity: raw.quantity });
73
+ logger.info('UsageRecord updated', {
74
+ subscriptionItemId: raw.subscription_item_id,
75
+ timestamp: raw.timestamp,
76
+ newQuantity: raw.quantity,
77
+ });
59
78
  }
60
79
  } else {
61
80
  raw.livemode = req.livemode;
@@ -67,6 +86,10 @@ router.post('/', auth, async (req, res) => {
67
86
  id: `usage-${subscription.id}`,
68
87
  job: { subscriptionId: subscription.id, subscriptionItemId: item.id },
69
88
  });
89
+ logger.info('UsageRecord pushed to queue', {
90
+ subscriptionId: subscription.id,
91
+ subscriptionItemId: item.id,
92
+ });
70
93
  }
71
94
 
72
95
  await forwardUsageRecordToStripe(item, {
@@ -75,6 +98,12 @@ router.post('/', auth, async (req, res) => {
75
98
  action: req.body.action,
76
99
  });
77
100
 
101
+ logger.info('UsageRecord forwarded to Stripe', {
102
+ subscriptionItemId: item.id,
103
+ quantity: Number(raw.quantity),
104
+ timestamp: raw.timestamp,
105
+ action: req.body.action,
106
+ });
78
107
  return res.json(doc);
79
108
  });
80
109
 
@@ -24,6 +24,7 @@ export class Event extends Model<InferAttributes<Event>, InferCreationAttributes
24
24
  declare request: {
25
25
  id: string;
26
26
  idempotency_key: string;
27
+ requested_by?: string;
27
28
  };
28
29
 
29
30
  // Number of webhooks that have yet to be successfully delivered
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.15.21
17
+ version: 1.15.23
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.15.21",
3
+ "version": "1.15.23",
4
4
  "scripts": {
5
5
  "dev": "blocklet dev --open",
6
6
  "eject": "vite eject",
@@ -52,7 +52,7 @@
52
52
  "@arcblock/validator": "^1.18.136",
53
53
  "@blocklet/js-sdk": "^1.16.32",
54
54
  "@blocklet/logger": "^1.16.32",
55
- "@blocklet/payment-react": "1.15.21",
55
+ "@blocklet/payment-react": "1.15.23",
56
56
  "@blocklet/sdk": "^1.16.32",
57
57
  "@blocklet/ui-react": "^2.10.51",
58
58
  "@blocklet/uploader": "^0.1.46",
@@ -118,7 +118,7 @@
118
118
  "devDependencies": {
119
119
  "@abtnode/types": "^1.16.32",
120
120
  "@arcblock/eslint-config-ts": "^0.3.3",
121
- "@blocklet/payment-types": "1.15.21",
121
+ "@blocklet/payment-types": "1.15.23",
122
122
  "@types/cookie-parser": "^1.4.7",
123
123
  "@types/cors": "^2.8.17",
124
124
  "@types/debug": "^4.1.12",
@@ -160,5 +160,5 @@
160
160
  "parser": "typescript"
161
161
  }
162
162
  },
163
- "gitHead": "b27debca52a2ea7f93a2a237053b8e171f8be3a2"
163
+ "gitHead": "94862642b9c4f0f753a47e8c68d9b70315d8f008"
164
164
  }