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.
- package/api/src/index.ts +2 -1
- package/api/src/libs/audit.ts +4 -1
- package/api/src/libs/context.ts +48 -0
- package/api/src/libs/invoice.ts +2 -2
- package/api/src/libs/middleware.ts +39 -1
- package/api/src/queues/checkout-session.ts +15 -0
- package/api/src/queues/event.ts +13 -4
- package/api/src/queues/invoice.ts +21 -3
- package/api/src/queues/payment.ts +3 -0
- package/api/src/queues/refund.ts +3 -0
- package/api/src/queues/usage-record.ts +4 -0
- package/api/src/queues/webhook.ts +9 -0
- package/api/src/routes/checkout-sessions.ts +40 -2
- package/api/src/routes/donations.ts +5 -1
- package/api/src/routes/events.ts +9 -4
- package/api/src/routes/invoices.ts +24 -24
- package/api/src/routes/payment-links.ts +40 -20
- package/api/src/routes/prices.ts +17 -4
- package/api/src/routes/products.ts +21 -2
- package/api/src/routes/refunds.ts +20 -3
- package/api/src/routes/subscription-items.ts +39 -2
- package/api/src/routes/subscriptions.ts +36 -4
- package/api/src/routes/usage-records.ts +29 -0
- package/api/src/store/models/event.ts +1 -0
- package/blocklet.yml +1 -1
- package/package.json +4 -4
- package/src/components/webhook/attempts.tsx +122 -3
|
@@ -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('
|
|
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
|
-
|
|
339
|
-
|
|
340
|
-
|
|
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
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
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
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
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
|
-
|
|
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
|
});
|
package/api/src/routes/prices.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
350
|
-
|
|
351
|
-
|
|
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('
|
|
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
|
-
|
|
247
|
-
|
|
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('
|
|
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
|
|
package/blocklet.yml
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "payment-kit",
|
|
3
|
-
"version": "1.15.
|
|
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.
|
|
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.
|
|
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": "
|
|
163
|
+
"gitHead": "94862642b9c4f0f753a47e8c68d9b70315d8f008"
|
|
164
164
|
}
|