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', {
|
package/api/src/routes/prices.ts
CHANGED
|
@@ -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
|
-
|
|
324
|
+
try {
|
|
325
|
+
const price = await Price.findByPkOrLookupKey(req.params.id as string);
|
|
309
326
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
327
|
+
if (!price) {
|
|
328
|
+
return res.status(404).json({ error: 'Can not delete none existing price' });
|
|
329
|
+
}
|
|
313
330
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
331
|
+
if (price.locked) {
|
|
332
|
+
return res.status(403).json({ error: 'Can not delete locked price' });
|
|
333
|
+
}
|
|
317
334
|
|
|
318
|
-
|
|
319
|
-
|
|
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
|
-
|
|
323
|
-
|
|
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(
|
|
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(
|
|
377
|
+
public async isUsed(checkProduct: boolean = false) {
|
|
377
378
|
const { SubscriptionItem, InvoiceItem, Product } = this.sequelize.models;
|
|
378
379
|
|
|
379
|
-
let used =
|
|
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
|
-
|
|
382
|
-
|
|
383
|
-
|
|
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
|
-
|
|
386
|
-
|
|
387
|
-
|
|
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
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
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
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
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
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
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
|
|
433
|
+
return false;
|
|
415
434
|
}
|
|
416
435
|
}
|
|
417
436
|
|
package/blocklet.yml
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "payment-kit",
|
|
3
|
-
"version": "1.13.
|
|
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.
|
|
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": "
|
|
152
|
+
"gitHead": "2d898eb6fb22e234d95e5da8adb5e9ffdb1e0cb2"
|
|
153
153
|
}
|