@drawbridge/drawbridge-stripe 0.1.12 → 0.1.14

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.
Files changed (3) hide show
  1. package/dist/index.js +214 -114
  2. package/dist/index.mjs +214 -114
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -18,6 +18,22 @@ var require_billing = __commonJS({
18
18
  "Stripe-Version": "2026-01-28.preview"
19
19
  }
20
20
  };
21
+ const withIdem = (base, suffix) => {
22
+ if (!base) return options;
23
+ return {
24
+ ...options,
25
+ headers: {
26
+ ...options.headers,
27
+ "Idempotency-Key": base + ":" + suffix
28
+ }
29
+ };
30
+ };
31
+ const idem = (base, suffix) => {
32
+ if (!base) return void 0;
33
+ return {
34
+ idempotencyKey: base + ":" + suffix
35
+ };
36
+ };
21
37
  const billableItems = async () => {
22
38
  var _a, _b, _c, _d, _e, _f;
23
39
  try {
@@ -55,6 +71,7 @@ var require_billing = __commonJS({
55
71
  currency,
56
72
  customer,
57
73
  default_payment_method = null,
74
+ idempotencyKey,
58
75
  metadata = {}
59
76
  }) => {
60
77
  var _a, _b, _c, _d;
@@ -94,17 +111,17 @@ var require_billing = __commonJS({
94
111
  }
95
112
  ]
96
113
  },
97
- options
114
+ withIdem(idempotencyKey, "intent.create")
98
115
  );
99
116
  const { data: reserve } = await axios.post(
100
117
  billing + "/intents/" + (intent == null ? void 0 : intent.id) + "/reserve",
101
118
  {},
102
- options
119
+ withIdem(idempotencyKey, "intent.reserve")
103
120
  );
104
121
  const { data: commit } = await axios.post(
105
122
  billing + "/intents/" + (intent == null ? void 0 : intent.id) + "/commit",
106
123
  {},
107
- options
124
+ withIdem(idempotencyKey, "intent.commit")
108
125
  );
109
126
  const { data: actions } = await axios.get(
110
127
  billing + "/intents/" + (intent == null ? void 0 : intent.id) + "/actions",
@@ -124,36 +141,42 @@ var require_billing = __commonJS({
124
141
  type: "customer"
125
142
  }
126
143
  ];
127
- const replenish = await stripe2.billing.alerts.create({
128
- alert_type: "credit_balance_threshold",
129
- credit_balance_threshold: {
130
- filters,
131
- lte: {
132
- balance_type: "monetary",
133
- monetary: {
134
- currency,
135
- value: 200
136
- // cents
144
+ const replenish = await stripe2.billing.alerts.create(
145
+ {
146
+ alert_type: "credit_balance_threshold",
147
+ credit_balance_threshold: {
148
+ filters,
149
+ lte: {
150
+ balance_type: "monetary",
151
+ monetary: {
152
+ currency,
153
+ value: 200
154
+ // cents
155
+ }
137
156
  }
138
- }
157
+ },
158
+ title: customer + ".credit_balance_replenish"
139
159
  },
140
- title: customer + ".credit_balance_replenish"
141
- });
142
- const depleted = await stripe2.billing.alerts.create({
143
- alert_type: "credit_balance_threshold",
144
- credit_balance_threshold: {
145
- filters,
146
- lte: {
147
- balance_type: "monetary",
148
- monetary: {
149
- currency,
150
- value: 1
151
- // cents
160
+ idem(idempotencyKey, "alert.replenish")
161
+ );
162
+ const depleted = await stripe2.billing.alerts.create(
163
+ {
164
+ alert_type: "credit_balance_threshold",
165
+ credit_balance_threshold: {
166
+ filters,
167
+ lte: {
168
+ balance_type: "monetary",
169
+ monetary: {
170
+ currency,
171
+ value: 1
172
+ // cents
173
+ }
152
174
  }
153
- }
175
+ },
176
+ title: customer + ".credit_balance_depleted"
154
177
  },
155
- title: customer + ".credit_balance_depleted"
156
- });
178
+ idem(idempotencyKey, "alert.depleted")
179
+ );
157
180
  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;
158
181
  if (!stripePricingPlanSubscriptionId) {
159
182
  throw new Error("Stripe billing intent did not return a pricing plan subscription ID for customer: " + customer);
@@ -193,7 +216,8 @@ var require_billing = __commonJS({
193
216
  };
194
217
  const unsubscribe = async ({
195
218
  currency,
196
- id
219
+ id,
220
+ idempotencyKey
197
221
  }) => {
198
222
  try {
199
223
  const { data } = await axios.post(
@@ -212,17 +236,17 @@ var require_billing = __commonJS({
212
236
  }
213
237
  ]
214
238
  },
215
- options
239
+ withIdem(idempotencyKey, "intent.create")
216
240
  );
217
241
  await axios.post(
218
242
  billing + "/intents/" + (data == null ? void 0 : data.id) + "/reserve",
219
243
  {},
220
- options
244
+ withIdem(idempotencyKey, "intent.reserve")
221
245
  );
222
246
  const commit = await axios.post(
223
247
  billing + "/intents/" + (data == null ? void 0 : data.id) + "/commit",
224
248
  {},
225
- options
249
+ withIdem(idempotencyKey, "intent.commit")
226
250
  );
227
251
  return commit;
228
252
  } catch (error) {
@@ -288,18 +312,28 @@ var require_subscription = __commonJS({
288
312
  "Stripe-Version": "2026-03-25.preview"
289
313
  }
290
314
  };
315
+ const idem = (base, suffix) => {
316
+ if (!base) return void 0;
317
+ return {
318
+ idempotencyKey: base + ":" + suffix
319
+ };
320
+ };
291
321
  const createMeter = async ({
322
+ idempotencyKey,
292
323
  metadata,
293
324
  name
294
325
  }) => {
295
326
  const usage = (metadata == null ? void 0 : metadata.organization) + "_usage_" + name;
296
- const meter = await stripe2.billing.meters.create({
297
- default_aggregation: {
298
- formula: "sum"
327
+ const meter = await stripe2.billing.meters.create(
328
+ {
329
+ default_aggregation: {
330
+ formula: "sum"
331
+ },
332
+ display_name: usage,
333
+ event_name: usage
299
334
  },
300
- display_name: usage,
301
- event_name: usage
302
- });
335
+ idem(idempotencyKey, "meter.create." + name)
336
+ );
303
337
  return {
304
338
  meter: meter == null ? void 0 : meter.id,
305
339
  usage
@@ -307,6 +341,7 @@ var require_subscription = __commonJS({
307
341
  };
308
342
  const createTier = async ({
309
343
  currency,
344
+ idempotencyKey,
310
345
  interval,
311
346
  limit,
312
347
  metadata,
@@ -315,42 +350,49 @@ var require_subscription = __commonJS({
315
350
  overage
316
351
  }) => {
317
352
  const response = {};
318
- const product = await stripe2.products.create({
319
- metadata,
320
- name
321
- });
322
- response["product"] = product == null ? void 0 : product.id;
323
- const price = await stripe2.prices.create({
324
- billing_scheme: "tiered",
325
- currency,
326
- metadata,
327
- nickname: name,
328
- product: product == null ? void 0 : product.id,
329
- recurring: {
330
- interval,
331
- meter,
332
- usage_type: "metered"
353
+ const product = await stripe2.products.create(
354
+ {
355
+ metadata,
356
+ name
333
357
  },
334
- tax_behavior: "exclusive",
335
- tiers: [
336
- {
337
- flat_amount: "0",
338
- // included in the plan. Should not be a value.
339
- up_to: limit
358
+ idem(idempotencyKey, "product.create." + name)
359
+ );
360
+ response["product"] = product == null ? void 0 : product.id;
361
+ const price = await stripe2.prices.create(
362
+ {
363
+ billing_scheme: "tiered",
364
+ currency,
365
+ metadata,
366
+ nickname: name,
367
+ product: product == null ? void 0 : product.id,
368
+ recurring: {
369
+ interval,
370
+ meter,
371
+ usage_type: "metered"
340
372
  },
341
- {
342
- unit_amount_decimal: overage,
343
- up_to: "inf"
344
- }
345
- ],
346
- tiers_mode: "graduated"
347
- });
373
+ tax_behavior: "exclusive",
374
+ tiers: [
375
+ {
376
+ flat_amount: "0",
377
+ // included in the plan. Should not be a value.
378
+ up_to: limit
379
+ },
380
+ {
381
+ unit_amount_decimal: overage,
382
+ up_to: "inf"
383
+ }
384
+ ],
385
+ tiers_mode: "graduated"
386
+ },
387
+ idem(idempotencyKey, "price.create." + name)
388
+ );
348
389
  response["price"] = price == null ? void 0 : price.id;
349
390
  return response;
350
391
  ;
351
392
  };
352
393
  const createItem = async ({
353
394
  currency,
395
+ idempotencyKey,
354
396
  interval,
355
397
  limit,
356
398
  metadata,
@@ -361,6 +403,7 @@ var require_subscription = __commonJS({
361
403
  }) => {
362
404
  const response = {};
363
405
  const { meter, usage } = await createMeter({
406
+ idempotencyKey,
364
407
  metadata,
365
408
  name
366
409
  });
@@ -368,6 +411,7 @@ var require_subscription = __commonJS({
368
411
  response["usage"] = usage;
369
412
  const { price, product } = await createTier({
370
413
  currency,
414
+ idempotencyKey,
371
415
  interval,
372
416
  limit,
373
417
  metadata,
@@ -378,12 +422,15 @@ var require_subscription = __commonJS({
378
422
  response["price"] = price;
379
423
  response["product"] = product;
380
424
  if (subscription) {
381
- const { id } = await stripe2.subscriptionItems.create({
382
- metadata,
383
- price,
384
- proration_behavior,
385
- subscription
386
- });
425
+ const { id } = await stripe2.subscriptionItems.create(
426
+ {
427
+ metadata,
428
+ price,
429
+ proration_behavior,
430
+ subscription
431
+ },
432
+ idem(idempotencyKey, "subscriptionItem.create." + name)
433
+ );
387
434
  response["id"] = id;
388
435
  }
389
436
  ;
@@ -392,6 +439,7 @@ var require_subscription = __commonJS({
392
439
  return {
393
440
  change: async ({
394
441
  direction,
442
+ idempotencyKey,
395
443
  items,
396
444
  metadata,
397
445
  stripeSubscriptionId,
@@ -444,19 +492,26 @@ var require_subscription = __commonJS({
444
492
  proration_behavior: "none"
445
493
  }
446
494
  ];
447
- const schedule = await stripe2.subscriptionSchedules.create({
448
- from_subscription: stripeSubscriptionId
449
- });
495
+ const schedule = await stripe2.subscriptionSchedules.create(
496
+ {
497
+ from_subscription: stripeSubscriptionId
498
+ },
499
+ idem(idempotencyKey, "schedule.create")
500
+ );
450
501
  try {
451
502
  await stripe2.subscriptionSchedules.update(
452
503
  schedule.id,
453
504
  {
454
505
  end_behavior: "release",
455
506
  phases
456
- }
507
+ },
508
+ idem(idempotencyKey, "schedule.update")
457
509
  );
458
510
  } catch (error) {
459
- await stripe2.subscriptionSchedules.release(schedule.id).catch(() => {
511
+ await stripe2.subscriptionSchedules.release(
512
+ schedule.id,
513
+ idem(idempotencyKey, "schedule.release")
514
+ ).catch(() => {
460
515
  });
461
516
  throw error;
462
517
  }
@@ -479,7 +534,8 @@ var require_subscription = __commonJS({
479
534
  ...props,
480
535
  price: (_f = items == null ? void 0 : items.plan) == null ? void 0 : _f.price,
481
536
  proration_behavior: "always_invoice"
482
- }
537
+ },
538
+ idem(idempotencyKey, "plan.update")
483
539
  );
484
540
  let actions = (items == null ? void 0 : items.actions) || {};
485
541
  if ((actions == null ? void 0 : actions.id) && (actions == null ? void 0 : actions.price)) {
@@ -489,11 +545,13 @@ var require_subscription = __commonJS({
489
545
  ...props,
490
546
  price: actions.price,
491
547
  proration_behavior: "none"
492
- }
548
+ },
549
+ idem(idempotencyKey, "actions.update")
493
550
  ));
494
551
  } else {
495
552
  actions = await createItem({
496
553
  currency: to.currency,
554
+ idempotencyKey,
497
555
  interval: to.interval,
498
556
  limit: to.limits.organization.actions,
499
557
  metadata,
@@ -507,7 +565,8 @@ var require_subscription = __commonJS({
507
565
  stripeSubscriptionId,
508
566
  {
509
567
  metadata
510
- }
568
+ },
569
+ idem(idempotencyKey, "subscription.update")
511
570
  );
512
571
  return {
513
572
  items: {
@@ -527,6 +586,7 @@ var require_subscription = __commonJS({
527
586
  billingCycleAnchor,
528
587
  customer,
529
588
  discounts = [],
589
+ idempotencyKey,
530
590
  metadata,
531
591
  stripePaymentMethodId,
532
592
  to
@@ -535,6 +595,7 @@ var require_subscription = __commonJS({
535
595
  try {
536
596
  const actions = await createItem({
537
597
  currency: to.currency,
598
+ idempotencyKey,
538
599
  interval: to.interval,
539
600
  limit: to.limits.organization.actions,
540
601
  metadata,
@@ -542,31 +603,37 @@ var require_subscription = __commonJS({
542
603
  overage: to.overages.actions,
543
604
  proration_behavior: "none"
544
605
  });
545
- const subscription = await stripe2.subscriptions.create({
546
- automatic_tax: {
547
- enabled: true
548
- },
549
- customer,
550
- description: "Organization subscription: " + metadata.organization,
551
- default_payment_method: stripePaymentMethodId,
552
- discounts: (discounts == null ? void 0 : discounts.length) > 0 ? discounts : "",
553
- items: [
554
- {
555
- price: actions.price
606
+ const subscription = await stripe2.subscriptions.create(
607
+ {
608
+ automatic_tax: {
609
+ enabled: true
610
+ },
611
+ customer,
612
+ description: "Organization subscription: " + metadata.organization,
613
+ default_payment_method: stripePaymentMethodId,
614
+ discounts: (discounts == null ? void 0 : discounts.length) > 0 ? discounts : "",
615
+ items: [
616
+ {
617
+ price: actions.price
618
+ }
619
+ ],
620
+ metadata,
621
+ ...billingCycleAnchor && {
622
+ billing_cycle_anchor: billingCycleAnchor
556
623
  }
557
- ],
558
- metadata,
559
- ...billingCycleAnchor && {
560
- billing_cycle_anchor: billingCycleAnchor
561
- }
562
- });
624
+ },
625
+ idem(idempotencyKey, "subscription.create")
626
+ );
563
627
  const { product } = await stripe2.prices.retrieve(to == null ? void 0 : to.stripePriceId);
564
- const plan = await stripe2.subscriptionItems.create({
565
- subscription: subscription == null ? void 0 : subscription.id,
566
- price: to == null ? void 0 : to.stripePriceId,
567
- quantity: 1,
568
- proration_behavior: "always_invoice"
569
- });
628
+ const plan = await stripe2.subscriptionItems.create(
629
+ {
630
+ subscription: subscription == null ? void 0 : subscription.id,
631
+ price: to == null ? void 0 : to.stripePriceId,
632
+ quantity: 1,
633
+ proration_behavior: "always_invoice"
634
+ },
635
+ idem(idempotencyKey, "plan.create")
636
+ );
570
637
  return {
571
638
  discounts,
572
639
  items: {
@@ -588,6 +655,7 @@ var require_subscription = __commonJS({
588
655
  }
589
656
  },
590
657
  pause: async ({
658
+ idempotencyKey,
591
659
  stripeSubscriptionId
592
660
  }) => {
593
661
  try {
@@ -599,7 +667,15 @@ var require_subscription = __commonJS({
599
667
  const { data } = await axios.post(
600
668
  subscriptions + "/" + stripeSubscriptionId + "/pause",
601
669
  body,
602
- options
670
+ {
671
+ ...options,
672
+ ...idempotencyKey && {
673
+ headers: {
674
+ ...options.headers,
675
+ "Idempotency-Key": idempotencyKey
676
+ }
677
+ }
678
+ }
603
679
  );
604
680
  return data;
605
681
  } catch (error) {
@@ -607,6 +683,7 @@ var require_subscription = __commonJS({
607
683
  }
608
684
  },
609
685
  resume: async ({
686
+ idempotencyKey,
610
687
  stripeSubscriptionId
611
688
  }) => {
612
689
  try {
@@ -616,7 +693,15 @@ var require_subscription = __commonJS({
616
693
  const { data } = await axios.post(
617
694
  subscriptions + "/" + stripeSubscriptionId + "/resume",
618
695
  body,
619
- options
696
+ {
697
+ ...options,
698
+ ...idempotencyKey && {
699
+ headers: {
700
+ ...options.headers,
701
+ "Idempotency-Key": idempotencyKey
702
+ }
703
+ }
704
+ }
620
705
  );
621
706
  return data;
622
707
  } catch (error) {
@@ -626,6 +711,7 @@ var require_subscription = __commonJS({
626
711
  update: async ({
627
712
  current,
628
713
  direction,
714
+ idempotencyKey,
629
715
  metadata,
630
716
  stripeSubscriptionId,
631
717
  to
@@ -638,6 +724,7 @@ var require_subscription = __commonJS({
638
724
  if ((_b = (_a = current == null ? void 0 : current.items) == null ? void 0 : _a.actions) == null ? void 0 : _b.meter) {
639
725
  actions2 = await createTier({
640
726
  currency: to.currency,
727
+ idempotencyKey,
641
728
  interval: to.interval,
642
729
  limit: to.limits.organization.actions,
643
730
  metadata,
@@ -648,6 +735,7 @@ var require_subscription = __commonJS({
648
735
  } else {
649
736
  const created = await createItem({
650
737
  currency: to.currency,
738
+ idempotencyKey,
651
739
  interval: to.interval,
652
740
  limit: to.limits.organization.actions,
653
741
  metadata,
@@ -701,19 +789,26 @@ var require_subscription = __commonJS({
701
789
  proration_behavior: "none"
702
790
  }
703
791
  ];
704
- const schedule = await stripe2.subscriptionSchedules.create({
705
- from_subscription: stripeSubscriptionId
706
- });
792
+ const schedule = await stripe2.subscriptionSchedules.create(
793
+ {
794
+ from_subscription: stripeSubscriptionId
795
+ },
796
+ idem(idempotencyKey, "schedule.create")
797
+ );
707
798
  try {
708
799
  await stripe2.subscriptionSchedules.update(
709
800
  schedule.id,
710
801
  {
711
802
  end_behavior: "release",
712
803
  phases
713
- }
804
+ },
805
+ idem(idempotencyKey, "schedule.update")
714
806
  );
715
807
  } catch (error) {
716
- await stripe2.subscriptionSchedules.release(schedule.id).catch(() => {
808
+ await stripe2.subscriptionSchedules.release(
809
+ schedule.id,
810
+ idem(idempotencyKey, "schedule.release")
811
+ ).catch(() => {
717
812
  });
718
813
  throw error;
719
814
  }
@@ -742,12 +837,14 @@ var require_subscription = __commonJS({
742
837
  ...props,
743
838
  price: to.stripePriceId,
744
839
  proration_behavior: "always_invoice"
745
- }
840
+ },
841
+ idem(idempotencyKey, "plan.update")
746
842
  );
747
843
  let actions;
748
844
  if (((_j = (_i = current == null ? void 0 : current.items) == null ? void 0 : _i.actions) == null ? void 0 : _j.id) && ((_l = (_k = current == null ? void 0 : current.items) == null ? void 0 : _k.actions) == null ? void 0 : _l.meter)) {
749
845
  actions = await createTier({
750
846
  currency: to.currency,
847
+ idempotencyKey,
751
848
  interval: to.interval,
752
849
  limit: to.limits.organization.actions,
753
850
  metadata,
@@ -761,11 +858,13 @@ var require_subscription = __commonJS({
761
858
  ...props,
762
859
  price: actions == null ? void 0 : actions.price,
763
860
  proration_behavior: "none"
764
- }
861
+ },
862
+ idem(idempotencyKey, "actions.update")
765
863
  ));
766
864
  } else {
767
865
  actions = await createItem({
768
866
  currency: to.currency,
867
+ idempotencyKey,
769
868
  interval: to.interval,
770
869
  limit: to.limits.organization.actions,
771
870
  metadata,
@@ -780,7 +879,8 @@ var require_subscription = __commonJS({
780
879
  stripeSubscriptionId,
781
880
  {
782
881
  metadata
783
- }
882
+ },
883
+ idem(idempotencyKey, "subscription.update")
784
884
  );
785
885
  return {
786
886
  items: {
package/dist/index.mjs CHANGED
@@ -24,6 +24,22 @@ var require_billing = __commonJS({
24
24
  "Stripe-Version": "2026-01-28.preview"
25
25
  }
26
26
  };
27
+ const withIdem = (base, suffix) => {
28
+ if (!base) return options;
29
+ return {
30
+ ...options,
31
+ headers: {
32
+ ...options.headers,
33
+ "Idempotency-Key": base + ":" + suffix
34
+ }
35
+ };
36
+ };
37
+ const idem = (base, suffix) => {
38
+ if (!base) return void 0;
39
+ return {
40
+ idempotencyKey: base + ":" + suffix
41
+ };
42
+ };
27
43
  const billableItems = async () => {
28
44
  var _a, _b, _c, _d, _e, _f;
29
45
  try {
@@ -61,6 +77,7 @@ var require_billing = __commonJS({
61
77
  currency,
62
78
  customer,
63
79
  default_payment_method = null,
80
+ idempotencyKey,
64
81
  metadata = {}
65
82
  }) => {
66
83
  var _a, _b, _c, _d;
@@ -100,17 +117,17 @@ var require_billing = __commonJS({
100
117
  }
101
118
  ]
102
119
  },
103
- options
120
+ withIdem(idempotencyKey, "intent.create")
104
121
  );
105
122
  const { data: reserve } = await axios.post(
106
123
  billing + "/intents/" + (intent == null ? void 0 : intent.id) + "/reserve",
107
124
  {},
108
- options
125
+ withIdem(idempotencyKey, "intent.reserve")
109
126
  );
110
127
  const { data: commit } = await axios.post(
111
128
  billing + "/intents/" + (intent == null ? void 0 : intent.id) + "/commit",
112
129
  {},
113
- options
130
+ withIdem(idempotencyKey, "intent.commit")
114
131
  );
115
132
  const { data: actions } = await axios.get(
116
133
  billing + "/intents/" + (intent == null ? void 0 : intent.id) + "/actions",
@@ -130,36 +147,42 @@ var require_billing = __commonJS({
130
147
  type: "customer"
131
148
  }
132
149
  ];
133
- const replenish = await stripe.billing.alerts.create({
134
- alert_type: "credit_balance_threshold",
135
- credit_balance_threshold: {
136
- filters,
137
- lte: {
138
- balance_type: "monetary",
139
- monetary: {
140
- currency,
141
- value: 200
142
- // cents
150
+ const replenish = await stripe.billing.alerts.create(
151
+ {
152
+ alert_type: "credit_balance_threshold",
153
+ credit_balance_threshold: {
154
+ filters,
155
+ lte: {
156
+ balance_type: "monetary",
157
+ monetary: {
158
+ currency,
159
+ value: 200
160
+ // cents
161
+ }
143
162
  }
144
- }
163
+ },
164
+ title: customer + ".credit_balance_replenish"
145
165
  },
146
- title: customer + ".credit_balance_replenish"
147
- });
148
- const depleted = await stripe.billing.alerts.create({
149
- alert_type: "credit_balance_threshold",
150
- credit_balance_threshold: {
151
- filters,
152
- lte: {
153
- balance_type: "monetary",
154
- monetary: {
155
- currency,
156
- value: 1
157
- // cents
166
+ idem(idempotencyKey, "alert.replenish")
167
+ );
168
+ const depleted = await stripe.billing.alerts.create(
169
+ {
170
+ alert_type: "credit_balance_threshold",
171
+ credit_balance_threshold: {
172
+ filters,
173
+ lte: {
174
+ balance_type: "monetary",
175
+ monetary: {
176
+ currency,
177
+ value: 1
178
+ // cents
179
+ }
158
180
  }
159
- }
181
+ },
182
+ title: customer + ".credit_balance_depleted"
160
183
  },
161
- title: customer + ".credit_balance_depleted"
162
- });
184
+ idem(idempotencyKey, "alert.depleted")
185
+ );
163
186
  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;
164
187
  if (!stripePricingPlanSubscriptionId) {
165
188
  throw new Error("Stripe billing intent did not return a pricing plan subscription ID for customer: " + customer);
@@ -199,7 +222,8 @@ var require_billing = __commonJS({
199
222
  };
200
223
  const unsubscribe = async ({
201
224
  currency,
202
- id
225
+ id,
226
+ idempotencyKey
203
227
  }) => {
204
228
  try {
205
229
  const { data } = await axios.post(
@@ -218,17 +242,17 @@ var require_billing = __commonJS({
218
242
  }
219
243
  ]
220
244
  },
221
- options
245
+ withIdem(idempotencyKey, "intent.create")
222
246
  );
223
247
  await axios.post(
224
248
  billing + "/intents/" + (data == null ? void 0 : data.id) + "/reserve",
225
249
  {},
226
- options
250
+ withIdem(idempotencyKey, "intent.reserve")
227
251
  );
228
252
  const commit = await axios.post(
229
253
  billing + "/intents/" + (data == null ? void 0 : data.id) + "/commit",
230
254
  {},
231
- options
255
+ withIdem(idempotencyKey, "intent.commit")
232
256
  );
233
257
  return commit;
234
258
  } catch (error) {
@@ -294,18 +318,28 @@ var require_subscription = __commonJS({
294
318
  "Stripe-Version": "2026-03-25.preview"
295
319
  }
296
320
  };
321
+ const idem = (base, suffix) => {
322
+ if (!base) return void 0;
323
+ return {
324
+ idempotencyKey: base + ":" + suffix
325
+ };
326
+ };
297
327
  const createMeter = async ({
328
+ idempotencyKey,
298
329
  metadata,
299
330
  name
300
331
  }) => {
301
332
  const usage = (metadata == null ? void 0 : metadata.organization) + "_usage_" + name;
302
- const meter = await stripe.billing.meters.create({
303
- default_aggregation: {
304
- formula: "sum"
333
+ const meter = await stripe.billing.meters.create(
334
+ {
335
+ default_aggregation: {
336
+ formula: "sum"
337
+ },
338
+ display_name: usage,
339
+ event_name: usage
305
340
  },
306
- display_name: usage,
307
- event_name: usage
308
- });
341
+ idem(idempotencyKey, "meter.create." + name)
342
+ );
309
343
  return {
310
344
  meter: meter == null ? void 0 : meter.id,
311
345
  usage
@@ -313,6 +347,7 @@ var require_subscription = __commonJS({
313
347
  };
314
348
  const createTier = async ({
315
349
  currency,
350
+ idempotencyKey,
316
351
  interval,
317
352
  limit,
318
353
  metadata,
@@ -321,42 +356,49 @@ var require_subscription = __commonJS({
321
356
  overage
322
357
  }) => {
323
358
  const response = {};
324
- const product = await stripe.products.create({
325
- metadata,
326
- name
327
- });
328
- response["product"] = product == null ? void 0 : product.id;
329
- const price = await stripe.prices.create({
330
- billing_scheme: "tiered",
331
- currency,
332
- metadata,
333
- nickname: name,
334
- product: product == null ? void 0 : product.id,
335
- recurring: {
336
- interval,
337
- meter,
338
- usage_type: "metered"
359
+ const product = await stripe.products.create(
360
+ {
361
+ metadata,
362
+ name
339
363
  },
340
- tax_behavior: "exclusive",
341
- tiers: [
342
- {
343
- flat_amount: "0",
344
- // included in the plan. Should not be a value.
345
- up_to: limit
364
+ idem(idempotencyKey, "product.create." + name)
365
+ );
366
+ response["product"] = product == null ? void 0 : product.id;
367
+ const price = await stripe.prices.create(
368
+ {
369
+ billing_scheme: "tiered",
370
+ currency,
371
+ metadata,
372
+ nickname: name,
373
+ product: product == null ? void 0 : product.id,
374
+ recurring: {
375
+ interval,
376
+ meter,
377
+ usage_type: "metered"
346
378
  },
347
- {
348
- unit_amount_decimal: overage,
349
- up_to: "inf"
350
- }
351
- ],
352
- tiers_mode: "graduated"
353
- });
379
+ tax_behavior: "exclusive",
380
+ tiers: [
381
+ {
382
+ flat_amount: "0",
383
+ // included in the plan. Should not be a value.
384
+ up_to: limit
385
+ },
386
+ {
387
+ unit_amount_decimal: overage,
388
+ up_to: "inf"
389
+ }
390
+ ],
391
+ tiers_mode: "graduated"
392
+ },
393
+ idem(idempotencyKey, "price.create." + name)
394
+ );
354
395
  response["price"] = price == null ? void 0 : price.id;
355
396
  return response;
356
397
  ;
357
398
  };
358
399
  const createItem = async ({
359
400
  currency,
401
+ idempotencyKey,
360
402
  interval,
361
403
  limit,
362
404
  metadata,
@@ -367,6 +409,7 @@ var require_subscription = __commonJS({
367
409
  }) => {
368
410
  const response = {};
369
411
  const { meter, usage } = await createMeter({
412
+ idempotencyKey,
370
413
  metadata,
371
414
  name
372
415
  });
@@ -374,6 +417,7 @@ var require_subscription = __commonJS({
374
417
  response["usage"] = usage;
375
418
  const { price, product } = await createTier({
376
419
  currency,
420
+ idempotencyKey,
377
421
  interval,
378
422
  limit,
379
423
  metadata,
@@ -384,12 +428,15 @@ var require_subscription = __commonJS({
384
428
  response["price"] = price;
385
429
  response["product"] = product;
386
430
  if (subscription) {
387
- const { id } = await stripe.subscriptionItems.create({
388
- metadata,
389
- price,
390
- proration_behavior,
391
- subscription
392
- });
431
+ const { id } = await stripe.subscriptionItems.create(
432
+ {
433
+ metadata,
434
+ price,
435
+ proration_behavior,
436
+ subscription
437
+ },
438
+ idem(idempotencyKey, "subscriptionItem.create." + name)
439
+ );
393
440
  response["id"] = id;
394
441
  }
395
442
  ;
@@ -398,6 +445,7 @@ var require_subscription = __commonJS({
398
445
  return {
399
446
  change: async ({
400
447
  direction,
448
+ idempotencyKey,
401
449
  items,
402
450
  metadata,
403
451
  stripeSubscriptionId,
@@ -450,19 +498,26 @@ var require_subscription = __commonJS({
450
498
  proration_behavior: "none"
451
499
  }
452
500
  ];
453
- const schedule = await stripe.subscriptionSchedules.create({
454
- from_subscription: stripeSubscriptionId
455
- });
501
+ const schedule = await stripe.subscriptionSchedules.create(
502
+ {
503
+ from_subscription: stripeSubscriptionId
504
+ },
505
+ idem(idempotencyKey, "schedule.create")
506
+ );
456
507
  try {
457
508
  await stripe.subscriptionSchedules.update(
458
509
  schedule.id,
459
510
  {
460
511
  end_behavior: "release",
461
512
  phases
462
- }
513
+ },
514
+ idem(idempotencyKey, "schedule.update")
463
515
  );
464
516
  } catch (error) {
465
- await stripe.subscriptionSchedules.release(schedule.id).catch(() => {
517
+ await stripe.subscriptionSchedules.release(
518
+ schedule.id,
519
+ idem(idempotencyKey, "schedule.release")
520
+ ).catch(() => {
466
521
  });
467
522
  throw error;
468
523
  }
@@ -485,7 +540,8 @@ var require_subscription = __commonJS({
485
540
  ...props,
486
541
  price: (_f = items == null ? void 0 : items.plan) == null ? void 0 : _f.price,
487
542
  proration_behavior: "always_invoice"
488
- }
543
+ },
544
+ idem(idempotencyKey, "plan.update")
489
545
  );
490
546
  let actions = (items == null ? void 0 : items.actions) || {};
491
547
  if ((actions == null ? void 0 : actions.id) && (actions == null ? void 0 : actions.price)) {
@@ -495,11 +551,13 @@ var require_subscription = __commonJS({
495
551
  ...props,
496
552
  price: actions.price,
497
553
  proration_behavior: "none"
498
- }
554
+ },
555
+ idem(idempotencyKey, "actions.update")
499
556
  ));
500
557
  } else {
501
558
  actions = await createItem({
502
559
  currency: to.currency,
560
+ idempotencyKey,
503
561
  interval: to.interval,
504
562
  limit: to.limits.organization.actions,
505
563
  metadata,
@@ -513,7 +571,8 @@ var require_subscription = __commonJS({
513
571
  stripeSubscriptionId,
514
572
  {
515
573
  metadata
516
- }
574
+ },
575
+ idem(idempotencyKey, "subscription.update")
517
576
  );
518
577
  return {
519
578
  items: {
@@ -533,6 +592,7 @@ var require_subscription = __commonJS({
533
592
  billingCycleAnchor,
534
593
  customer,
535
594
  discounts = [],
595
+ idempotencyKey,
536
596
  metadata,
537
597
  stripePaymentMethodId,
538
598
  to
@@ -541,6 +601,7 @@ var require_subscription = __commonJS({
541
601
  try {
542
602
  const actions = await createItem({
543
603
  currency: to.currency,
604
+ idempotencyKey,
544
605
  interval: to.interval,
545
606
  limit: to.limits.organization.actions,
546
607
  metadata,
@@ -548,31 +609,37 @@ var require_subscription = __commonJS({
548
609
  overage: to.overages.actions,
549
610
  proration_behavior: "none"
550
611
  });
551
- const subscription = await stripe.subscriptions.create({
552
- automatic_tax: {
553
- enabled: true
554
- },
555
- customer,
556
- description: "Organization subscription: " + metadata.organization,
557
- default_payment_method: stripePaymentMethodId,
558
- discounts: (discounts == null ? void 0 : discounts.length) > 0 ? discounts : "",
559
- items: [
560
- {
561
- price: actions.price
612
+ const subscription = await stripe.subscriptions.create(
613
+ {
614
+ automatic_tax: {
615
+ enabled: true
616
+ },
617
+ customer,
618
+ description: "Organization subscription: " + metadata.organization,
619
+ default_payment_method: stripePaymentMethodId,
620
+ discounts: (discounts == null ? void 0 : discounts.length) > 0 ? discounts : "",
621
+ items: [
622
+ {
623
+ price: actions.price
624
+ }
625
+ ],
626
+ metadata,
627
+ ...billingCycleAnchor && {
628
+ billing_cycle_anchor: billingCycleAnchor
562
629
  }
563
- ],
564
- metadata,
565
- ...billingCycleAnchor && {
566
- billing_cycle_anchor: billingCycleAnchor
567
- }
568
- });
630
+ },
631
+ idem(idempotencyKey, "subscription.create")
632
+ );
569
633
  const { product } = await stripe.prices.retrieve(to == null ? void 0 : to.stripePriceId);
570
- const plan = await stripe.subscriptionItems.create({
571
- subscription: subscription == null ? void 0 : subscription.id,
572
- price: to == null ? void 0 : to.stripePriceId,
573
- quantity: 1,
574
- proration_behavior: "always_invoice"
575
- });
634
+ const plan = await stripe.subscriptionItems.create(
635
+ {
636
+ subscription: subscription == null ? void 0 : subscription.id,
637
+ price: to == null ? void 0 : to.stripePriceId,
638
+ quantity: 1,
639
+ proration_behavior: "always_invoice"
640
+ },
641
+ idem(idempotencyKey, "plan.create")
642
+ );
576
643
  return {
577
644
  discounts,
578
645
  items: {
@@ -594,6 +661,7 @@ var require_subscription = __commonJS({
594
661
  }
595
662
  },
596
663
  pause: async ({
664
+ idempotencyKey,
597
665
  stripeSubscriptionId
598
666
  }) => {
599
667
  try {
@@ -605,7 +673,15 @@ var require_subscription = __commonJS({
605
673
  const { data } = await axios.post(
606
674
  subscriptions + "/" + stripeSubscriptionId + "/pause",
607
675
  body,
608
- options
676
+ {
677
+ ...options,
678
+ ...idempotencyKey && {
679
+ headers: {
680
+ ...options.headers,
681
+ "Idempotency-Key": idempotencyKey
682
+ }
683
+ }
684
+ }
609
685
  );
610
686
  return data;
611
687
  } catch (error) {
@@ -613,6 +689,7 @@ var require_subscription = __commonJS({
613
689
  }
614
690
  },
615
691
  resume: async ({
692
+ idempotencyKey,
616
693
  stripeSubscriptionId
617
694
  }) => {
618
695
  try {
@@ -622,7 +699,15 @@ var require_subscription = __commonJS({
622
699
  const { data } = await axios.post(
623
700
  subscriptions + "/" + stripeSubscriptionId + "/resume",
624
701
  body,
625
- options
702
+ {
703
+ ...options,
704
+ ...idempotencyKey && {
705
+ headers: {
706
+ ...options.headers,
707
+ "Idempotency-Key": idempotencyKey
708
+ }
709
+ }
710
+ }
626
711
  );
627
712
  return data;
628
713
  } catch (error) {
@@ -632,6 +717,7 @@ var require_subscription = __commonJS({
632
717
  update: async ({
633
718
  current,
634
719
  direction,
720
+ idempotencyKey,
635
721
  metadata,
636
722
  stripeSubscriptionId,
637
723
  to
@@ -644,6 +730,7 @@ var require_subscription = __commonJS({
644
730
  if ((_b = (_a = current == null ? void 0 : current.items) == null ? void 0 : _a.actions) == null ? void 0 : _b.meter) {
645
731
  actions2 = await createTier({
646
732
  currency: to.currency,
733
+ idempotencyKey,
647
734
  interval: to.interval,
648
735
  limit: to.limits.organization.actions,
649
736
  metadata,
@@ -654,6 +741,7 @@ var require_subscription = __commonJS({
654
741
  } else {
655
742
  const created = await createItem({
656
743
  currency: to.currency,
744
+ idempotencyKey,
657
745
  interval: to.interval,
658
746
  limit: to.limits.organization.actions,
659
747
  metadata,
@@ -707,19 +795,26 @@ var require_subscription = __commonJS({
707
795
  proration_behavior: "none"
708
796
  }
709
797
  ];
710
- const schedule = await stripe.subscriptionSchedules.create({
711
- from_subscription: stripeSubscriptionId
712
- });
798
+ const schedule = await stripe.subscriptionSchedules.create(
799
+ {
800
+ from_subscription: stripeSubscriptionId
801
+ },
802
+ idem(idempotencyKey, "schedule.create")
803
+ );
713
804
  try {
714
805
  await stripe.subscriptionSchedules.update(
715
806
  schedule.id,
716
807
  {
717
808
  end_behavior: "release",
718
809
  phases
719
- }
810
+ },
811
+ idem(idempotencyKey, "schedule.update")
720
812
  );
721
813
  } catch (error) {
722
- await stripe.subscriptionSchedules.release(schedule.id).catch(() => {
814
+ await stripe.subscriptionSchedules.release(
815
+ schedule.id,
816
+ idem(idempotencyKey, "schedule.release")
817
+ ).catch(() => {
723
818
  });
724
819
  throw error;
725
820
  }
@@ -748,12 +843,14 @@ var require_subscription = __commonJS({
748
843
  ...props,
749
844
  price: to.stripePriceId,
750
845
  proration_behavior: "always_invoice"
751
- }
846
+ },
847
+ idem(idempotencyKey, "plan.update")
752
848
  );
753
849
  let actions;
754
850
  if (((_j = (_i = current == null ? void 0 : current.items) == null ? void 0 : _i.actions) == null ? void 0 : _j.id) && ((_l = (_k = current == null ? void 0 : current.items) == null ? void 0 : _k.actions) == null ? void 0 : _l.meter)) {
755
851
  actions = await createTier({
756
852
  currency: to.currency,
853
+ idempotencyKey,
757
854
  interval: to.interval,
758
855
  limit: to.limits.organization.actions,
759
856
  metadata,
@@ -767,11 +864,13 @@ var require_subscription = __commonJS({
767
864
  ...props,
768
865
  price: actions == null ? void 0 : actions.price,
769
866
  proration_behavior: "none"
770
- }
867
+ },
868
+ idem(idempotencyKey, "actions.update")
771
869
  ));
772
870
  } else {
773
871
  actions = await createItem({
774
872
  currency: to.currency,
873
+ idempotencyKey,
775
874
  interval: to.interval,
776
875
  limit: to.limits.organization.actions,
777
876
  metadata,
@@ -786,7 +885,8 @@ var require_subscription = __commonJS({
786
885
  stripeSubscriptionId,
787
886
  {
788
887
  metadata
789
- }
888
+ },
889
+ idem(idempotencyKey, "subscription.update")
790
890
  );
791
891
  return {
792
892
  items: {
package/package.json CHANGED
@@ -24,5 +24,5 @@
24
24
  "build": "tsup ./index.js && npm publish"
25
25
  },
26
26
  "types": "dist/index.d.ts",
27
- "version": "0.1.12"
27
+ "version": "0.1.14"
28
28
  }