payment-kit 1.13.107 → 1.13.108

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.
@@ -151,7 +151,12 @@ export async function startCheckoutSessionQueue() {
151
151
  for (const item of checkoutSession.line_items) {
152
152
  const price = await Price.findByPk(item.price_id);
153
153
  if (price?.locked) {
154
- const used = await price.isUsed();
154
+ const used = await price.isUsed(false);
155
+ logger.info('Price used status recheck on expire', {
156
+ checkoutSession: checkoutSession.id,
157
+ priceId: item.price_id,
158
+ used,
159
+ });
155
160
  if (!used) {
156
161
  await price.update({ locked: false });
157
162
  logger.info('Price for checkout session unlocked on expire', {
@@ -5,6 +5,7 @@ import pick from 'lodash/pick';
5
5
  import type { WhereOptions } from 'sequelize';
6
6
 
7
7
  import { getWhereFromQuery } from '../libs/api';
8
+ import logger from '../libs/logger';
8
9
  import { authenticate } from '../libs/security';
9
10
  import { canUpsell } from '../libs/session';
10
11
  import { PaymentCurrency } from '../store/models/payment-currency';
@@ -202,6 +203,21 @@ router.get('/:id', auth, async (req, res) => {
202
203
  res.json(await getExpandedPrice(req.params.id as string));
203
204
  });
204
205
 
206
+ // get price used status
207
+ router.get('/:id/used', auth, async (req, res) => {
208
+ const price = await Price.findByPkOrLookupKey(req.params.id as string);
209
+ if (!price) {
210
+ return res.status(404).json({ error: 'Price not found' });
211
+ }
212
+
213
+ const used = await price.isUsed(true);
214
+ if (!used) {
215
+ await price.update({ locked: false });
216
+ }
217
+
218
+ return res.json({ used });
219
+ });
220
+
205
221
  router.get('/:id/upsell', auth, async (req, res) => {
206
222
  const price = await Price.findByPkOrLookupKey(req.params.id as string, {
207
223
  include: [{ model: PaymentCurrency, as: 'currency' }],
@@ -305,22 +321,27 @@ router.put('/:id/archive', auth, async (req, res) => {
305
321
 
306
322
  // delete price
307
323
  router.delete('/:id', auth, async (req, res) => {
308
- const price = await Price.findByPkOrLookupKey(req.params.id as string);
324
+ try {
325
+ const price = await Price.findByPkOrLookupKey(req.params.id as string);
309
326
 
310
- if (!price) {
311
- return res.status(404).json({ error: 'Can not delete none existing price' });
312
- }
327
+ if (!price) {
328
+ return res.status(404).json({ error: 'Can not delete none existing price' });
329
+ }
313
330
 
314
- if (price.locked) {
315
- return res.status(403).json({ error: 'Can not delete locked price' });
316
- }
331
+ if (price.locked) {
332
+ return res.status(403).json({ error: 'Can not delete locked price' });
333
+ }
317
334
 
318
- if (await price.isUsed()) {
319
- return res.status(403).json({ error: 'Can not delete price used by other resources' });
320
- }
335
+ if (await price.isUsed(true)) {
336
+ return res.status(403).json({ error: 'Can not delete price used by other resources' });
337
+ }
321
338
 
322
- await price.destroy();
323
- return res.json(price);
339
+ await price.destroy();
340
+ return res.json(price);
341
+ } catch (err) {
342
+ logger.error('delete price error', err);
343
+ return res.status(400).json({ error: err.message });
344
+ }
324
345
  });
325
346
 
326
347
  export default router;
@@ -266,7 +266,7 @@ router.delete('/:id', auth, async (req, res) => {
266
266
  return res.status(403).json({ error: 'product have prices that is locked' });
267
267
  }
268
268
  // eslint-disable-next-line no-await-in-loop
269
- if (await price.isUsed(true)) {
269
+ if (await price.isUsed(false)) {
270
270
  return res.status(403).json({ error: 'product have prices that is used by other resources' });
271
271
  }
272
272
  }
@@ -14,6 +14,7 @@ import {
14
14
  import type { LiteralUnion } from 'type-fest';
15
15
 
16
16
  import { createEvent } from '../../libs/audit';
17
+ import logger from '../../libs/logger';
17
18
  import { createIdGenerator, formatMetadata } from '../../libs/util';
18
19
  import { sequelize } from '../sequelize';
19
20
  import type { TPaymentCurrency } from './payment-currency';
@@ -373,45 +374,63 @@ export class Price extends Model<InferAttributes<Price>, InferCreationAttributes
373
374
  });
374
375
  }
375
376
 
376
- public async isUsed(skipProduct: boolean = false) {
377
+ public async isUsed(checkProduct: boolean = false) {
377
378
  const { SubscriptionItem, InvoiceItem, Product } = this.sequelize.models;
378
379
 
379
- let used = skipProduct ? false : (await Product!.count({ where: { default_price_id: this.id } })) > 0;
380
+ let used = checkProduct ? (await Product!.count({ where: { default_price_id: this.id } })) > 0 : false;
381
+ if (used) {
382
+ logger.info('Price is used as default product price', { priceId: this.id });
383
+ return true;
384
+ }
380
385
 
381
- if (!used) {
382
- // @ts-ignore
383
- used = await InvoiceItem!.isPriceUsed(this.id);
386
+ // @ts-ignore
387
+ used = await InvoiceItem!.isPriceUsed(this.id);
388
+ if (used) {
389
+ logger.info('Price is used by invoice item', { priceId: this.id });
390
+ return true;
384
391
  }
385
- if (!used) {
386
- // @ts-ignore
387
- used = await SubscriptionItem!.isPriceUsed(this.id);
392
+
393
+ // @ts-ignore
394
+ used = await SubscriptionItem!.isPriceUsed(this.id);
395
+ if (used) {
396
+ logger.info('Price is used by subscription item', { priceId: this.id });
397
+ return true;
388
398
  }
389
- if (!used) {
390
- // @ts-ignore
391
- const [{ count }] = await this.sequelize.query(
392
- `SELECT count(*) AS count FROM pricing_tables JOIN json_each(items) AS item ON json_extract(item.value, '$.price_id') = '${this.id}'`,
393
- { type: QueryTypes.SELECT }
394
- );
395
- used = count > 0;
399
+
400
+ // @ts-ignore
401
+ let [{ count }] = await this.sequelize.query(
402
+ `SELECT count(*) AS count FROM pricing_tables JOIN json_each(items) AS item ON json_extract(item.value, '$.price_id') = '${this.id}'`,
403
+ { type: QueryTypes.SELECT }
404
+ );
405
+ used = count > 0;
406
+ if (used) {
407
+ logger.info('Price is used by pricing table', { priceId: this.id });
408
+ return true;
396
409
  }
397
- if (!used) {
398
- // @ts-ignore
399
- const [{ count }] = await this.sequelize.query(
400
- `SELECT count(*) AS count FROM payment_links JOIN json_each(line_items) AS item ON json_extract(item.value, '$.price_id') = '${this.id}'`,
401
- { type: QueryTypes.SELECT }
402
- );
403
- used = count > 0;
410
+
411
+ // @ts-ignore
412
+ [{ count }] = await this.sequelize.query(
413
+ `SELECT count(*) AS count FROM payment_links JOIN json_each(line_items) AS item ON json_extract(item.value, '$.price_id') = '${this.id}'`,
414
+ { type: QueryTypes.SELECT }
415
+ );
416
+ used = count > 0;
417
+ if (used) {
418
+ logger.info('Price is used by payment link', { priceId: this.id });
419
+ return true;
404
420
  }
405
- if (!used) {
406
- // @ts-ignore
407
- const [{ count }] = await this.sequelize.query(
408
- `SELECT count(cs.id) AS count FROM checkout_sessions AS cs JOIN json_each(line_items) AS item ON json_extract(item.value, '$.price_id') = '${this.id}' WHERE cs.status != 'expired'`,
409
- { type: QueryTypes.SELECT }
410
- );
411
- used = count > 0;
421
+
422
+ // @ts-ignore
423
+ [{ count }] = await this.sequelize.query(
424
+ `SELECT count(cs.id) AS count FROM checkout_sessions AS cs JOIN json_each(line_items) AS item ON json_extract(item.value, '$.price_id') = '${this.id}' WHERE cs.status != 'expired'`,
425
+ { type: QueryTypes.SELECT }
426
+ );
427
+ used = count > 0;
428
+ if (used) {
429
+ logger.info('Price is used by active checkout session', { priceId: this.id });
430
+ return true;
412
431
  }
413
432
 
414
- return used;
433
+ return false;
415
434
  }
416
435
  }
417
436
 
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.13.107
17
+ version: 1.13.108
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.13.107",
3
+ "version": "1.13.108",
4
4
  "scripts": {
5
5
  "dev": "COMPONENT_STORE_URL=https://test.store.blocklet.dev blocklet dev",
6
6
  "eject": "vite eject",
@@ -110,7 +110,7 @@
110
110
  "@abtnode/types": "1.16.22",
111
111
  "@arcblock/eslint-config": "^0.2.4",
112
112
  "@arcblock/eslint-config-ts": "^0.2.4",
113
- "@did-pay/types": "1.13.107",
113
+ "@did-pay/types": "1.13.108",
114
114
  "@types/cookie-parser": "^1.4.6",
115
115
  "@types/cors": "^2.8.17",
116
116
  "@types/dotenv-flow": "^3.3.3",
@@ -149,5 +149,5 @@
149
149
  "parser": "typescript"
150
150
  }
151
151
  },
152
- "gitHead": "40d9eb4c215af29dc727fafab29b9ab7776f6e3a"
152
+ "gitHead": "2d898eb6fb22e234d95e5da8adb5e9ffdb1e0cb2"
153
153
  }