@drawbridge/drawbridge-stripe 0.1.18 → 0.1.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/dist/index.js +315 -256
- package/dist/index.mjs +315 -256
- package/package.json +4 -3
package/dist/index.js
CHANGED
|
@@ -6,26 +6,20 @@ var __commonJS = (cb, mod) => function __require() {
|
|
|
6
6
|
// lib/billing.js
|
|
7
7
|
var require_billing = __commonJS({
|
|
8
8
|
"lib/billing.js"(exports2, module2) {
|
|
9
|
-
var
|
|
9
|
+
var { request } = require("@drawbridge/drawbridge-utils/http");
|
|
10
10
|
var billing = "https://api.stripe.com/v2/billing";
|
|
11
11
|
module2.exports = ({
|
|
12
12
|
stripe: stripe2
|
|
13
13
|
}) => {
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"Content-Type": "application/json",
|
|
18
|
-
"Stripe-Version": "2026-01-28.preview"
|
|
19
|
-
}
|
|
14
|
+
const headers = {
|
|
15
|
+
"Authorization": "Bearer " + process.env.STRIPE_API_KEY,
|
|
16
|
+
"Stripe-Version": "2026-01-28.preview"
|
|
20
17
|
};
|
|
21
18
|
const withIdem = (base, suffix) => {
|
|
22
|
-
if (!base) return
|
|
19
|
+
if (!base) return headers;
|
|
23
20
|
return {
|
|
24
|
-
...
|
|
25
|
-
|
|
26
|
-
...options.headers,
|
|
27
|
-
"Idempotency-Key": base + ":" + suffix
|
|
28
|
-
}
|
|
21
|
+
...headers,
|
|
22
|
+
"Idempotency-Key": base + ":" + suffix
|
|
29
23
|
};
|
|
30
24
|
};
|
|
31
25
|
const idem = (base, suffix) => {
|
|
@@ -36,38 +30,34 @@ var require_billing = __commonJS({
|
|
|
36
30
|
};
|
|
37
31
|
const billableItems = async () => {
|
|
38
32
|
var _a;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
for (const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
;
|
|
33
|
+
const components = await request({
|
|
34
|
+
url: billing + "/pricing_plans/" + process.env.STRIPE_PRICING_AI_PLAN_ID + "/components",
|
|
35
|
+
headers
|
|
36
|
+
});
|
|
37
|
+
const rateCardIds = ((components == null ? void 0 : components.data) || []).map((plan) => {
|
|
38
|
+
var _a2;
|
|
39
|
+
return (_a2 = plan == null ? void 0 : plan.rate_card) == null ? void 0 : _a2.id;
|
|
40
|
+
}).filter(Boolean);
|
|
41
|
+
const rateResults = await Promise.all(
|
|
42
|
+
rateCardIds.map((id) => request({
|
|
43
|
+
url: billing + "/rate_cards/" + id + "/rates",
|
|
44
|
+
headers
|
|
45
|
+
}))
|
|
46
|
+
);
|
|
47
|
+
const items = [];
|
|
48
|
+
for (const rates of rateResults) {
|
|
49
|
+
for (const element of (rates == null ? void 0 : rates.data) || []) {
|
|
50
|
+
if ((_a = element == null ? void 0 : element.metered_item) == null ? void 0 : _a.id) {
|
|
51
|
+
items.push({
|
|
52
|
+
id: element.metered_item.id
|
|
53
|
+
});
|
|
63
54
|
}
|
|
64
55
|
;
|
|
65
56
|
}
|
|
66
57
|
;
|
|
67
|
-
return items;
|
|
68
|
-
} catch (error) {
|
|
69
|
-
throw error;
|
|
70
58
|
}
|
|
59
|
+
;
|
|
60
|
+
return items;
|
|
71
61
|
};
|
|
72
62
|
const subscribe = async ({
|
|
73
63
|
currency,
|
|
@@ -77,183 +67,182 @@ var require_billing = __commonJS({
|
|
|
77
67
|
metadata = {}
|
|
78
68
|
}) => {
|
|
79
69
|
var _a, _b, _c, _d;
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
customer
|
|
84
|
-
}
|
|
85
|
-
};
|
|
86
|
-
if (Boolean(default_payment_method)) {
|
|
87
|
-
payer.billing_profile_data.default_payment_method = default_payment_method;
|
|
70
|
+
const payer = {
|
|
71
|
+
billing_profile_data: {
|
|
72
|
+
customer
|
|
88
73
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
74
|
+
};
|
|
75
|
+
if (Boolean(default_payment_method)) {
|
|
76
|
+
payer.billing_profile_data.default_payment_method = default_payment_method;
|
|
77
|
+
}
|
|
78
|
+
;
|
|
79
|
+
const intent = await request({
|
|
80
|
+
method: "POST",
|
|
81
|
+
url: billing + "/intents",
|
|
82
|
+
headers: withIdem(idempotencyKey, "intent.create"),
|
|
83
|
+
body: {
|
|
84
|
+
currency,
|
|
85
|
+
cadence_data: {
|
|
86
|
+
billing_cycle: {
|
|
87
|
+
type: process.env.STRIPE_SUBSCRIPTION_INTERVAL,
|
|
88
|
+
interval_count: 1
|
|
100
89
|
},
|
|
101
|
-
|
|
102
|
-
{
|
|
103
|
-
type: "subscribe",
|
|
104
|
-
subscribe: {
|
|
105
|
-
type: "pricing_plan_subscription_details",
|
|
106
|
-
pricing_plan_subscription_details: {
|
|
107
|
-
component_configurations: [],
|
|
108
|
-
pricing_plan: process.env.STRIPE_PRICING_AI_PLAN_ID,
|
|
109
|
-
pricing_plan_version: process.env.STRIPE_PRICING_AI_PLAN_VERSION,
|
|
110
|
-
metadata
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
]
|
|
90
|
+
payer
|
|
115
91
|
},
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
withIdem(idempotencyKey, "intent.commit")
|
|
127
|
-
);
|
|
128
|
-
const { data: actions } = await axios.get(
|
|
129
|
-
billing + "/intents/" + (intent == null ? void 0 : intent.id) + "/actions",
|
|
130
|
-
options
|
|
131
|
-
);
|
|
132
|
-
const billable_items = await billableItems();
|
|
133
|
-
const filters = [
|
|
134
|
-
{
|
|
135
|
-
credit_grants: {
|
|
136
|
-
applicability_config: {
|
|
137
|
-
scope: {
|
|
138
|
-
billable_items
|
|
92
|
+
actions: [
|
|
93
|
+
{
|
|
94
|
+
type: "subscribe",
|
|
95
|
+
subscribe: {
|
|
96
|
+
type: "pricing_plan_subscription_details",
|
|
97
|
+
pricing_plan_subscription_details: {
|
|
98
|
+
component_configurations: [],
|
|
99
|
+
pricing_plan: process.env.STRIPE_PRICING_AI_PLAN_ID,
|
|
100
|
+
pricing_plan_version: process.env.STRIPE_PRICING_AI_PLAN_VERSION,
|
|
101
|
+
metadata
|
|
139
102
|
}
|
|
140
103
|
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
await request({
|
|
109
|
+
method: "POST",
|
|
110
|
+
url: billing + "/intents/" + (intent == null ? void 0 : intent.id) + "/reserve",
|
|
111
|
+
headers: withIdem(idempotencyKey, "intent.reserve"),
|
|
112
|
+
body: {}
|
|
113
|
+
});
|
|
114
|
+
await request({
|
|
115
|
+
method: "POST",
|
|
116
|
+
url: billing + "/intents/" + (intent == null ? void 0 : intent.id) + "/commit",
|
|
117
|
+
headers: withIdem(idempotencyKey, "intent.commit"),
|
|
118
|
+
body: {}
|
|
119
|
+
});
|
|
120
|
+
const actions = await request({
|
|
121
|
+
url: billing + "/intents/" + (intent == null ? void 0 : intent.id) + "/actions",
|
|
122
|
+
headers
|
|
123
|
+
});
|
|
124
|
+
const billable_items = await billableItems();
|
|
125
|
+
const filters = [
|
|
126
|
+
{
|
|
127
|
+
credit_grants: {
|
|
128
|
+
applicability_config: {
|
|
129
|
+
scope: {
|
|
130
|
+
billable_items
|
|
158
131
|
}
|
|
159
|
-
}
|
|
160
|
-
title: customer + ".credit_balance_replenish"
|
|
132
|
+
}
|
|
161
133
|
},
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
134
|
+
customer,
|
|
135
|
+
type: "customer"
|
|
136
|
+
}
|
|
137
|
+
];
|
|
138
|
+
const replenish = await stripe2.billing.alerts.create(
|
|
139
|
+
{
|
|
140
|
+
alert_type: "credit_balance_threshold",
|
|
141
|
+
credit_balance_threshold: {
|
|
142
|
+
filters,
|
|
143
|
+
lte: {
|
|
144
|
+
balance_type: "monetary",
|
|
145
|
+
monetary: {
|
|
146
|
+
currency,
|
|
147
|
+
value: 200
|
|
148
|
+
// cents
|
|
176
149
|
}
|
|
177
|
-
}
|
|
178
|
-
title: customer + ".credit_balance_depleted"
|
|
150
|
+
}
|
|
179
151
|
},
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
options
|
|
197
|
-
);
|
|
198
|
-
if (cadence == null ? void 0 : cadence.next_billing_date) {
|
|
199
|
-
stripePricingPlanSubscriptionNextBillingDate = cadence.next_billing_date;
|
|
152
|
+
title: customer + ".credit_balance_replenish"
|
|
153
|
+
},
|
|
154
|
+
idem(idempotencyKey, "alert.replenish")
|
|
155
|
+
);
|
|
156
|
+
const depleted = await stripe2.billing.alerts.create(
|
|
157
|
+
{
|
|
158
|
+
alert_type: "credit_balance_threshold",
|
|
159
|
+
credit_balance_threshold: {
|
|
160
|
+
filters,
|
|
161
|
+
lte: {
|
|
162
|
+
balance_type: "monetary",
|
|
163
|
+
monetary: {
|
|
164
|
+
currency,
|
|
165
|
+
value: 1
|
|
166
|
+
// cents
|
|
167
|
+
}
|
|
200
168
|
}
|
|
169
|
+
},
|
|
170
|
+
title: customer + ".credit_balance_depleted"
|
|
171
|
+
},
|
|
172
|
+
idem(idempotencyKey, "alert.depleted")
|
|
173
|
+
);
|
|
174
|
+
const stripePricingPlanSubscriptionId = (_d = (_c = (_b = (_a = actions == null ? void 0 : actions.data) == null ? void 0 : _a[0]) == null ? void 0 : _b.subscribe) == null ? void 0 : _c.pricing_plan_subscription_details) == null ? void 0 : _d.pricing_plan_subscription;
|
|
175
|
+
if (!stripePricingPlanSubscriptionId) {
|
|
176
|
+
throw new Error("Stripe billing intent did not return a pricing plan subscription ID for customer: " + customer);
|
|
177
|
+
}
|
|
178
|
+
;
|
|
179
|
+
let stripePricingPlanSubscriptionNextBillingDate;
|
|
180
|
+
if (!default_payment_method) {
|
|
181
|
+
const subscription = await request({
|
|
182
|
+
url: billing + "/pricing_plan_subscriptions/" + stripePricingPlanSubscriptionId,
|
|
183
|
+
headers
|
|
184
|
+
});
|
|
185
|
+
if (subscription == null ? void 0 : subscription.billing_cadence) {
|
|
186
|
+
const cadence = await request({
|
|
187
|
+
url: billing + "/cadences/" + subscription.billing_cadence,
|
|
188
|
+
headers
|
|
189
|
+
});
|
|
190
|
+
if (cadence == null ? void 0 : cadence.next_billing_date) {
|
|
191
|
+
stripePricingPlanSubscriptionNextBillingDate = cadence.next_billing_date;
|
|
201
192
|
}
|
|
202
193
|
;
|
|
203
194
|
}
|
|
204
195
|
;
|
|
205
|
-
return {
|
|
206
|
-
stripeAlerts: {
|
|
207
|
-
ai: {
|
|
208
|
-
depleted: depleted == null ? void 0 : depleted.id,
|
|
209
|
-
replenish: replenish == null ? void 0 : replenish.id
|
|
210
|
-
}
|
|
211
|
-
},
|
|
212
|
-
stripePricingPlanSubscriptionId,
|
|
213
|
-
stripePricingPlanSubscriptionNextBillingDate
|
|
214
|
-
};
|
|
215
|
-
} catch (error) {
|
|
216
|
-
throw error;
|
|
217
196
|
}
|
|
197
|
+
;
|
|
198
|
+
return {
|
|
199
|
+
stripeAlerts: {
|
|
200
|
+
ai: {
|
|
201
|
+
depleted: depleted == null ? void 0 : depleted.id,
|
|
202
|
+
replenish: replenish == null ? void 0 : replenish.id
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
stripePricingPlanSubscriptionId,
|
|
206
|
+
stripePricingPlanSubscriptionNextBillingDate
|
|
207
|
+
};
|
|
218
208
|
};
|
|
219
209
|
const unsubscribe = async ({
|
|
220
210
|
currency,
|
|
221
211
|
id,
|
|
222
212
|
idempotencyKey
|
|
223
213
|
}) => {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
214
|
+
const data = await request({
|
|
215
|
+
method: "POST",
|
|
216
|
+
url: billing + "/intents",
|
|
217
|
+
headers: withIdem(idempotencyKey, "intent.create"),
|
|
218
|
+
body: {
|
|
219
|
+
currency,
|
|
220
|
+
actions: [
|
|
221
|
+
{
|
|
222
|
+
type: "deactivate",
|
|
223
|
+
deactivate: {
|
|
224
|
+
type: "pricing_plan_subscription_details",
|
|
225
|
+
pricing_plan_subscription_details: {
|
|
226
|
+
pricing_plan_subscription: id
|
|
237
227
|
}
|
|
238
228
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
)
|
|
253
|
-
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
}
|
|
229
|
+
}
|
|
230
|
+
]
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
await request({
|
|
234
|
+
method: "POST",
|
|
235
|
+
url: billing + "/intents/" + (data == null ? void 0 : data.id) + "/reserve",
|
|
236
|
+
headers: withIdem(idempotencyKey, "intent.reserve"),
|
|
237
|
+
body: {}
|
|
238
|
+
});
|
|
239
|
+
const commit = await request({
|
|
240
|
+
method: "POST",
|
|
241
|
+
url: billing + "/intents/" + (data == null ? void 0 : data.id) + "/commit",
|
|
242
|
+
headers: withIdem(idempotencyKey, "intent.commit"),
|
|
243
|
+
body: {}
|
|
244
|
+
});
|
|
245
|
+
return commit;
|
|
257
246
|
};
|
|
258
247
|
const usage = ({
|
|
259
248
|
customer,
|
|
@@ -304,17 +293,14 @@ var require_billing = __commonJS({
|
|
|
304
293
|
// lib/subscription.js
|
|
305
294
|
var require_subscription = __commonJS({
|
|
306
295
|
"lib/subscription.js"(exports2, module2) {
|
|
307
|
-
var
|
|
296
|
+
var { request } = require("@drawbridge/drawbridge-utils/http");
|
|
308
297
|
var subscriptions = "https://api.stripe.com/v1/subscriptions";
|
|
309
298
|
module2.exports = ({
|
|
310
299
|
stripe: stripe2
|
|
311
300
|
}) => {
|
|
312
|
-
const
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
316
|
-
"Stripe-Version": "2026-03-25.preview"
|
|
317
|
-
}
|
|
301
|
+
const headers = {
|
|
302
|
+
"Authorization": "Bearer " + process.env.STRIPE_API_KEY,
|
|
303
|
+
"Stripe-Version": "2026-03-25.preview"
|
|
318
304
|
};
|
|
319
305
|
const idem = (base, suffix) => {
|
|
320
306
|
if (!base) return void 0;
|
|
@@ -478,14 +464,14 @@ var require_subscription = __commonJS({
|
|
|
478
464
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
479
465
|
try {
|
|
480
466
|
if (direction === "downgrade") {
|
|
481
|
-
const
|
|
482
|
-
const currentPlanItem =
|
|
467
|
+
const live2 = await stripe2.subscriptions.retrieve(stripeSubscriptionId);
|
|
468
|
+
const currentPlanItem = live2.items.data.find(
|
|
483
469
|
(item) => {
|
|
484
470
|
var _a2, _b2;
|
|
485
471
|
return ((_b2 = (_a2 = item == null ? void 0 : item.price) == null ? void 0 : _a2.recurring) == null ? void 0 : _b2.usage_type) !== "metered";
|
|
486
472
|
}
|
|
487
473
|
);
|
|
488
|
-
const currentActionsItem =
|
|
474
|
+
const currentActionsItem = live2.items.data.find(
|
|
489
475
|
(item) => {
|
|
490
476
|
var _a2, _b2;
|
|
491
477
|
return ((_b2 = (_a2 = item == null ? void 0 : item.price) == null ? void 0 : _a2.recurring) == null ? void 0 : _b2.usage_type) === "metered";
|
|
@@ -558,8 +544,21 @@ var require_subscription = __commonJS({
|
|
|
558
544
|
const props = {
|
|
559
545
|
metadata
|
|
560
546
|
};
|
|
547
|
+
const live = await stripe2.subscriptions.retrieve(stripeSubscriptionId);
|
|
548
|
+
const livePlanItem = live.items.data.find(
|
|
549
|
+
(item) => {
|
|
550
|
+
var _a2, _b2;
|
|
551
|
+
return ((_b2 = (_a2 = item == null ? void 0 : item.price) == null ? void 0 : _a2.recurring) == null ? void 0 : _b2.usage_type) !== "metered";
|
|
552
|
+
}
|
|
553
|
+
);
|
|
554
|
+
const liveActionsItem = live.items.data.find(
|
|
555
|
+
(item) => {
|
|
556
|
+
var _a2, _b2;
|
|
557
|
+
return ((_b2 = (_a2 = item == null ? void 0 : item.price) == null ? void 0 : _a2.recurring) == null ? void 0 : _b2.usage_type) === "metered";
|
|
558
|
+
}
|
|
559
|
+
);
|
|
561
560
|
const plan = await stripe2.subscriptionItems.update(
|
|
562
|
-
(_e = items == null ? void 0 : items.plan) == null ? void 0 : _e.id,
|
|
561
|
+
(livePlanItem == null ? void 0 : livePlanItem.id) || ((_e = items == null ? void 0 : items.plan) == null ? void 0 : _e.id),
|
|
563
562
|
{
|
|
564
563
|
...props,
|
|
565
564
|
price: (_f = items == null ? void 0 : items.plan) == null ? void 0 : _f.price,
|
|
@@ -568,9 +567,10 @@ var require_subscription = __commonJS({
|
|
|
568
567
|
idem(idempotencyKey, "plan.update")
|
|
569
568
|
);
|
|
570
569
|
let actions = (items == null ? void 0 : items.actions) || {};
|
|
571
|
-
|
|
570
|
+
const actionsItemId = (liveActionsItem == null ? void 0 : liveActionsItem.id) || (actions == null ? void 0 : actions.id);
|
|
571
|
+
if (actionsItemId && (actions == null ? void 0 : actions.price)) {
|
|
572
572
|
({ id: actions["id"] } = await stripe2.subscriptionItems.update(
|
|
573
|
-
|
|
573
|
+
actionsItemId,
|
|
574
574
|
{
|
|
575
575
|
...props,
|
|
576
576
|
price: actions.price,
|
|
@@ -686,55 +686,43 @@ var require_subscription = __commonJS({
|
|
|
686
686
|
idempotencyKey,
|
|
687
687
|
stripeSubscriptionId
|
|
688
688
|
}) => {
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
body,
|
|
698
|
-
{
|
|
699
|
-
...options,
|
|
700
|
-
...idempotencyKey && {
|
|
701
|
-
headers: {
|
|
702
|
-
...options.headers,
|
|
703
|
-
"Idempotency-Key": idempotencyKey
|
|
704
|
-
}
|
|
705
|
-
}
|
|
689
|
+
return await request({
|
|
690
|
+
method: "POST",
|
|
691
|
+
url: subscriptions + "/" + stripeSubscriptionId + "/pause",
|
|
692
|
+
type: "form",
|
|
693
|
+
headers: {
|
|
694
|
+
...headers,
|
|
695
|
+
...idempotencyKey && {
|
|
696
|
+
"Idempotency-Key": idempotencyKey
|
|
706
697
|
}
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
698
|
+
},
|
|
699
|
+
body: {
|
|
700
|
+
"type": "subscription",
|
|
701
|
+
"bill_for[unused_time_from][type]": "now",
|
|
702
|
+
"bill_for[outstanding_usage_through][type]": "now",
|
|
703
|
+
"invoicing_behavior": "pending_invoice_item"
|
|
704
|
+
}
|
|
705
|
+
});
|
|
712
706
|
},
|
|
713
707
|
resume: async ({
|
|
714
708
|
idempotencyKey,
|
|
715
709
|
stripeSubscriptionId
|
|
716
710
|
}) => {
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
...options,
|
|
726
|
-
...idempotencyKey && {
|
|
727
|
-
headers: {
|
|
728
|
-
...options.headers,
|
|
729
|
-
"Idempotency-Key": idempotencyKey
|
|
730
|
-
}
|
|
731
|
-
}
|
|
711
|
+
return await request({
|
|
712
|
+
method: "POST",
|
|
713
|
+
url: subscriptions + "/" + stripeSubscriptionId + "/resume",
|
|
714
|
+
type: "form",
|
|
715
|
+
headers: {
|
|
716
|
+
...headers,
|
|
717
|
+
...idempotencyKey && {
|
|
718
|
+
"Idempotency-Key": idempotencyKey
|
|
732
719
|
}
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
720
|
+
},
|
|
721
|
+
body: {
|
|
722
|
+
"billing_cycle_anchor": "unchanged",
|
|
723
|
+
"proration_behavior": "create_prorations"
|
|
724
|
+
}
|
|
725
|
+
});
|
|
738
726
|
},
|
|
739
727
|
update: async ({
|
|
740
728
|
current,
|
|
@@ -747,7 +735,7 @@ var require_subscription = __commonJS({
|
|
|
747
735
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
|
|
748
736
|
try {
|
|
749
737
|
if (direction === "downgrade") {
|
|
750
|
-
const
|
|
738
|
+
const live2 = await stripe2.subscriptions.retrieve(stripeSubscriptionId);
|
|
751
739
|
let actions2;
|
|
752
740
|
if ((_b = (_a = current == null ? void 0 : current.items) == null ? void 0 : _a.actions) == null ? void 0 : _b.meter) {
|
|
753
741
|
actions2 = await createTier({
|
|
@@ -780,14 +768,14 @@ var require_subscription = __commonJS({
|
|
|
780
768
|
}
|
|
781
769
|
;
|
|
782
770
|
const product = await stripe2.prices.retrieve(to == null ? void 0 : to.stripePriceId);
|
|
783
|
-
const
|
|
771
|
+
const livePlanItem2 = live2.items.data.find(
|
|
784
772
|
(item) => {
|
|
785
773
|
var _a2, _b2;
|
|
786
774
|
return ((_b2 = (_a2 = item == null ? void 0 : item.price) == null ? void 0 : _a2.recurring) == null ? void 0 : _b2.usage_type) !== "metered";
|
|
787
775
|
}
|
|
788
776
|
);
|
|
789
|
-
const currentPeriodStart =
|
|
790
|
-
const currentPeriodEnd =
|
|
777
|
+
const currentPeriodStart = livePlanItem2 == null ? void 0 : livePlanItem2.current_period_start;
|
|
778
|
+
const currentPeriodEnd = livePlanItem2 == null ? void 0 : livePlanItem2.current_period_end;
|
|
791
779
|
const phases = [
|
|
792
780
|
{
|
|
793
781
|
items: [
|
|
@@ -859,8 +847,22 @@ var require_subscription = __commonJS({
|
|
|
859
847
|
const props = {
|
|
860
848
|
metadata
|
|
861
849
|
};
|
|
850
|
+
const live = await stripe2.subscriptions.retrieve(stripeSubscriptionId);
|
|
851
|
+
const livePlanItem = live.items.data.find(
|
|
852
|
+
(item) => {
|
|
853
|
+
var _a2, _b2;
|
|
854
|
+
return ((_b2 = (_a2 = item == null ? void 0 : item.price) == null ? void 0 : _a2.recurring) == null ? void 0 : _b2.usage_type) !== "metered";
|
|
855
|
+
}
|
|
856
|
+
);
|
|
857
|
+
const liveActionsItem = live.items.data.find(
|
|
858
|
+
(item) => {
|
|
859
|
+
var _a2, _b2;
|
|
860
|
+
return ((_b2 = (_a2 = item == null ? void 0 : item.price) == null ? void 0 : _a2.recurring) == null ? void 0 : _b2.usage_type) === "metered";
|
|
861
|
+
}
|
|
862
|
+
);
|
|
863
|
+
const liveActionsItemId = (liveActionsItem == null ? void 0 : liveActionsItem.id) || ((_h = (_g = current == null ? void 0 : current.items) == null ? void 0 : _g.actions) == null ? void 0 : _h.id);
|
|
862
864
|
const plan = await stripe2.subscriptionItems.update(
|
|
863
|
-
(
|
|
865
|
+
(livePlanItem == null ? void 0 : livePlanItem.id) || ((_j = (_i = current == null ? void 0 : current.items) == null ? void 0 : _i.plan) == null ? void 0 : _j.id),
|
|
864
866
|
{
|
|
865
867
|
...props,
|
|
866
868
|
price: to.stripePriceId,
|
|
@@ -869,7 +871,7 @@ var require_subscription = __commonJS({
|
|
|
869
871
|
idem(idempotencyKey, "plan.update")
|
|
870
872
|
);
|
|
871
873
|
let actions;
|
|
872
|
-
if (
|
|
874
|
+
if (liveActionsItemId && ((_l = (_k = current == null ? void 0 : current.items) == null ? void 0 : _k.actions) == null ? void 0 : _l.meter)) {
|
|
873
875
|
actions = await createTier({
|
|
874
876
|
currency: to.currency,
|
|
875
877
|
idempotencyKey,
|
|
@@ -881,7 +883,7 @@ var require_subscription = __commonJS({
|
|
|
881
883
|
overage: to.overages.actions
|
|
882
884
|
});
|
|
883
885
|
({ id: actions["id"] } = await stripe2.subscriptionItems.update(
|
|
884
|
-
|
|
886
|
+
liveActionsItemId,
|
|
885
887
|
{
|
|
886
888
|
...props,
|
|
887
889
|
price: actions == null ? void 0 : actions.price,
|
|
@@ -926,6 +928,63 @@ var require_subscription = __commonJS({
|
|
|
926
928
|
} catch (error) {
|
|
927
929
|
throw error;
|
|
928
930
|
}
|
|
931
|
+
},
|
|
932
|
+
// Pure. Given a subscription document, return the Stripe artifacts that
|
|
933
|
+
// are safe to deactivate at org-delete — the terminal point, the only
|
|
934
|
+
// place deactivation is ever safe. Meters are per-org (actions/ai/
|
|
935
|
+
// storage) and the actions price/product are created fresh per
|
|
936
|
+
// subscription, so all are reclaimable. Never the plan price/product
|
|
937
|
+
// (shared STRIPE_PRICE_* catalog) and never the ai/storage price/product
|
|
938
|
+
// (they only carry a meter, and the ai price is a shared env catalog
|
|
939
|
+
// price). `items` is an untyped, possibly-partial object — optional-chain
|
|
940
|
+
// everything and drop entries without an id.
|
|
941
|
+
deactivatableItems: (subscription) => {
|
|
942
|
+
var _a, _b, _c, _d, _e;
|
|
943
|
+
const items = (subscription == null ? void 0 : subscription.items) || {};
|
|
944
|
+
return [
|
|
945
|
+
{ type: "meter", id: (_a = items == null ? void 0 : items.actions) == null ? void 0 : _a.meter },
|
|
946
|
+
{ type: "price", id: (_b = items == null ? void 0 : items.actions) == null ? void 0 : _b.price },
|
|
947
|
+
{ type: "product", id: (_c = items == null ? void 0 : items.actions) == null ? void 0 : _c.product },
|
|
948
|
+
{ type: "meter", id: (_d = items == null ? void 0 : items.ai) == null ? void 0 : _d.meter },
|
|
949
|
+
{ type: "meter", id: (_e = items == null ? void 0 : items.storage) == null ? void 0 : _e.meter }
|
|
950
|
+
].filter((entry) => entry.id);
|
|
951
|
+
},
|
|
952
|
+
// Consume a deactivatableItems list. Each artifact is deactivated with an
|
|
953
|
+
// artifact-id idempotency key (`<type>.deactivate:<id>`) so re-running a
|
|
954
|
+
// delete is a safe no-op. Runs concurrently via Promise.allSettled;
|
|
955
|
+
// rejections are logged through the injected logger and never rethrown,
|
|
956
|
+
// so a single Stripe failure cannot block org-doc deletion. The logger is
|
|
957
|
+
// injected because drawbridge-stripe stays a pure SDK wrapper — telemetry
|
|
958
|
+
// remains the single Sentry owner.
|
|
959
|
+
deactivate: async ({
|
|
960
|
+
items = [],
|
|
961
|
+
logger = { info() {
|
|
962
|
+
}, warn() {
|
|
963
|
+
}, error() {
|
|
964
|
+
} }
|
|
965
|
+
}) => {
|
|
966
|
+
const deactivateOne = ({ type, id }) => {
|
|
967
|
+
const options = idem(type + ".deactivate", id);
|
|
968
|
+
if (type === "meter") {
|
|
969
|
+
return stripe2.billing.meters.deactivate(id, {}, options);
|
|
970
|
+
}
|
|
971
|
+
;
|
|
972
|
+
if (type === "price") {
|
|
973
|
+
return stripe2.prices.update(id, { active: false }, options);
|
|
974
|
+
}
|
|
975
|
+
;
|
|
976
|
+
if (type === "product") {
|
|
977
|
+
return stripe2.products.update(id, { active: false }, options);
|
|
978
|
+
}
|
|
979
|
+
;
|
|
980
|
+
};
|
|
981
|
+
return Promise.allSettled(
|
|
982
|
+
items.map((item) => Promise.resolve(deactivateOne(item)).catch((error) => {
|
|
983
|
+
logger.error(
|
|
984
|
+
"Stripe deactivate failed for " + (item == null ? void 0 : item.type) + " " + (item == null ? void 0 : item.id) + ": " + (error == null ? void 0 : error.message)
|
|
985
|
+
);
|
|
986
|
+
}))
|
|
987
|
+
);
|
|
929
988
|
}
|
|
930
989
|
};
|
|
931
990
|
};
|