payment-kit 1.15.19 → 1.15.20
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/queues/subscription.ts +1 -2
- package/api/src/routes/subscription-items.ts +49 -11
- package/blocklet.yml +1 -1
- package/package.json +4 -4
- package/tsconfig.json +2 -2
|
@@ -863,8 +863,7 @@ events.on('customer.subscription.deleted', (subscription: Subscription) => {
|
|
|
863
863
|
});
|
|
864
864
|
|
|
865
865
|
events.on('customer.subscription.upgraded', async (subscription: Subscription) => {
|
|
866
|
-
await
|
|
867
|
-
await addSubscriptionJob(subscription, 'cancel', true, subscription.current_period_end);
|
|
866
|
+
await addSubscriptionJob(subscription, 'cycle', true, subscription.current_period_end);
|
|
868
867
|
logger.info('subscription cycle job rescheduled after upgrade', {
|
|
869
868
|
subscription: subscription.id,
|
|
870
869
|
runAt: subscription.current_period_end,
|
|
@@ -8,7 +8,9 @@ import { createListParamSchema, MetadataSchema } from '../libs/api';
|
|
|
8
8
|
import { authenticate } from '../libs/security';
|
|
9
9
|
import { expandLineItems } from '../libs/session';
|
|
10
10
|
import { formatMetadata } from '../libs/util';
|
|
11
|
-
import { Price, Product, SubscriptionItem, UsageRecord } from '../store/models';
|
|
11
|
+
import { Price, Product, Subscription, SubscriptionItem, UsageRecord } from '../store/models';
|
|
12
|
+
import { forwardUsageRecordToStripe } from '../integrations/stripe/resource';
|
|
13
|
+
import { usageRecordQueue } from '../queues/usage-record';
|
|
12
14
|
|
|
13
15
|
const router = Router();
|
|
14
16
|
const auth = authenticate<SubscriptionItem>({ component: true, roles: ['owner', 'admin'] });
|
|
@@ -164,19 +166,55 @@ router.post('/:id/add-usage-quantity', auth, async (req, res) => {
|
|
|
164
166
|
return res.status(403).json({ error: 'add usage quantity not allowed in livemode' });
|
|
165
167
|
}
|
|
166
168
|
|
|
167
|
-
const
|
|
168
|
-
if (
|
|
169
|
-
return res.status(
|
|
169
|
+
const quantity = Number(req.body.quantity);
|
|
170
|
+
if (quantity <= 0) {
|
|
171
|
+
return res.status(400).json({ error: 'quantity must be positive' });
|
|
170
172
|
}
|
|
171
173
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
174
|
+
try {
|
|
175
|
+
const subscriptionItem = await SubscriptionItem.findByPk(req.params.id);
|
|
176
|
+
if (!subscriptionItem) {
|
|
177
|
+
return res.status(404).json({ error: `SubscriptionItem(${req.params.id}) item not found` });
|
|
178
|
+
}
|
|
179
|
+
const subscription = await Subscription.findByPk(subscriptionItem.subscription_id);
|
|
180
|
+
if (!subscription) {
|
|
181
|
+
return res.status(400).json({ error: `Subscription not found: ${subscriptionItem.subscription_id}` });
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (subscription.isImmutable()) {
|
|
185
|
+
return res.status(400).json({ error: `subscription(${subscription.id}) is immutable` });
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const now = dayjs().unix();
|
|
189
|
+
|
|
190
|
+
if (now < subscription.current_period_start || now > subscription.current_period_end) {
|
|
191
|
+
return res.status(400).json({ error: 'timestamp must be within the current period' });
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const usageRecord = await UsageRecord.create({
|
|
195
|
+
livemode: Boolean(livemode),
|
|
196
|
+
subscription_item_id: subscriptionItem.id,
|
|
197
|
+
quantity,
|
|
198
|
+
timestamp: now,
|
|
199
|
+
} as UsageRecord);
|
|
200
|
+
|
|
201
|
+
if (subscription.billing_thresholds?.amount_gte) {
|
|
202
|
+
usageRecordQueue.push({
|
|
203
|
+
id: `usage-${subscription.id}`,
|
|
204
|
+
job: { subscriptionId: subscription.id, subscriptionItemId: subscriptionItem.id },
|
|
205
|
+
});
|
|
206
|
+
}
|
|
178
207
|
|
|
179
|
-
|
|
208
|
+
await forwardUsageRecordToStripe(subscriptionItem, {
|
|
209
|
+
quantity,
|
|
210
|
+
timestamp: now,
|
|
211
|
+
action: 'increment',
|
|
212
|
+
});
|
|
213
|
+
return res.json(usageRecord);
|
|
214
|
+
} catch (err) {
|
|
215
|
+
console.error(err);
|
|
216
|
+
return res.status(400).json({ error: `Failed to add usage quantity: ${err.message}` });
|
|
217
|
+
}
|
|
180
218
|
});
|
|
181
219
|
|
|
182
220
|
export default router;
|
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.20",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "blocklet dev --open",
|
|
6
6
|
"eject": "vite eject",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"@arcblock/validator": "^1.18.135",
|
|
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.20",
|
|
56
56
|
"@blocklet/sdk": "^1.16.32",
|
|
57
57
|
"@blocklet/ui-react": "^2.10.45",
|
|
58
58
|
"@blocklet/uploader": "^0.1.43",
|
|
@@ -118,7 +118,7 @@
|
|
|
118
118
|
"devDependencies": {
|
|
119
119
|
"@abtnode/types": "^1.16.32",
|
|
120
120
|
"@arcblock/eslint-config-ts": "^0.3.2",
|
|
121
|
-
"@blocklet/payment-types": "1.15.
|
|
121
|
+
"@blocklet/payment-types": "1.15.20",
|
|
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": "0499ea79c00bb48d7a2479af589c21698c6388a0"
|
|
164
164
|
}
|
package/tsconfig.json
CHANGED