@peable.to/contracts 1.2.0 → 3.0.0

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 (43) hide show
  1. package/dist/cjs/resources/catalog/index.js +1 -5
  2. package/dist/cjs/resources/checkout/checkoutSessions.js +0 -4
  3. package/dist/cjs/resources/events/events.js +1 -32
  4. package/dist/cjs/resources/tax/calculations.js +33 -30
  5. package/dist/cjs/resources/tax/reports.js +4 -4
  6. package/dist/cjs/resources/tax/shared.js +7 -11
  7. package/dist/cjs/resources/tax/transactions.js +7 -10
  8. package/dist/cjs/vocabulary/catalog.js +1 -17
  9. package/dist/cjs/vocabulary/errors.js +0 -13
  10. package/dist/cjs/vocabulary/events.js +0 -1
  11. package/dist/esm/resources/catalog/index.js +1 -5
  12. package/dist/esm/resources/checkout/checkoutSessions.js +0 -4
  13. package/dist/esm/resources/events/events.js +0 -31
  14. package/dist/esm/resources/tax/calculations.js +29 -26
  15. package/dist/esm/resources/tax/reports.js +6 -6
  16. package/dist/esm/resources/tax/shared.js +6 -10
  17. package/dist/esm/resources/tax/transactions.js +8 -11
  18. package/dist/esm/vocabulary/catalog.js +0 -16
  19. package/dist/esm/vocabulary/errors.js +0 -13
  20. package/dist/esm/vocabulary/events.js +0 -1
  21. package/dist/types/resources/catalog/index.d.ts +1 -851
  22. package/dist/types/resources/checkout/checkoutSessions.d.ts +13 -61
  23. package/dist/types/resources/checkout/index.d.ts +10 -46
  24. package/dist/types/resources/events/events.d.ts +0 -22
  25. package/dist/types/resources/events/index.d.ts +2 -15
  26. package/dist/types/resources/events/webhookDeliveries.d.ts +0 -3
  27. package/dist/types/resources/events/webhookEndpoints.d.ts +4 -16
  28. package/dist/types/resources/payments/index.d.ts +10 -10
  29. package/dist/types/resources/payments/paymentIntents.d.ts +10 -10
  30. package/dist/types/resources/payments/testHelpers.d.ts +1 -1
  31. package/dist/types/resources/tax/calculations.d.ts +37 -37
  32. package/dist/types/resources/tax/index.d.ts +57 -57
  33. package/dist/types/resources/tax/registrations.d.ts +2 -2
  34. package/dist/types/resources/tax/reports.d.ts +6 -6
  35. package/dist/types/resources/tax/shared.d.ts +6 -7
  36. package/dist/types/resources/tax/transactions.d.ts +61 -61
  37. package/dist/types/vocabulary/catalog.d.ts +0 -9
  38. package/dist/types/vocabulary/errors.d.ts +0 -13
  39. package/dist/types/vocabulary/events.d.ts +0 -1
  40. package/package.json +1 -1
  41. package/dist/cjs/resources/catalog/billing.js +0 -755
  42. package/dist/esm/resources/catalog/billing.js +0 -752
  43. package/dist/types/resources/catalog/billing.d.ts +0 -1723
@@ -17,7 +17,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  exports.catalogRoutes = exports.queryIdList = exports.queryFlag = exports.baseUnitAmountParam = void 0;
18
18
  // Contracts of this group: one module per resource, re-exported here, and
19
19
  // their routes concatenated into `catalogRoutes`.
20
- const billing_1 = require("./billing");
21
20
  const billingSettings_1 = require("./billingSettings");
22
21
  const coupons_1 = require("./coupons");
23
22
  const entitlements_1 = require("./entitlements");
@@ -26,7 +25,6 @@ const prices_1 = require("./prices");
26
25
  const products_1 = require("./products");
27
26
  const promotionCodes_1 = require("./promotionCodes");
28
27
  const testClocks_1 = require("./testClocks");
29
- __exportStar(require("./billing"), exports);
30
28
  __exportStar(require("./billingSettings"), exports);
31
29
  __exportStar(require("./coupons"), exports);
32
30
  __exportStar(require("./entitlements"), exports);
@@ -42,8 +40,7 @@ Object.defineProperty(exports, "queryFlag", { enumerable: true, get: function ()
42
40
  Object.defineProperty(exports, "queryIdList", { enumerable: true, get: function () { return shared_1.queryIdList; } });
43
41
  /**
44
42
  * The catalog (products, prices, coupons, promotion codes), entitlements, the
45
- * billing engine's platform objects (test clocks, billing settings, meters)
46
- * and the recurring billing transport (`/v1/billing/*`).
43
+ * billing engine's platform objects (test clocks, billing settings, meters).
47
44
  */
48
45
  exports.catalogRoutes = [
49
46
  ...products_1.productRoutes,
@@ -54,5 +51,4 @@ exports.catalogRoutes = [
54
51
  ...testClocks_1.testClockRoutes,
55
52
  ...billingSettings_1.billingSettingsRoutes,
56
53
  ...meters_1.meterRoutes,
57
- ...billing_1.billingRoutes,
58
54
  ];
@@ -4,7 +4,6 @@ exports.checkoutSessionRoutes = exports.expireCheckoutSessionTestHelperParams =
4
4
  const zod_1 = require("zod");
5
5
  const catalog_1 = require("../../vocabulary/catalog");
6
6
  const payments_1 = require("../../vocabulary/payments");
7
- const billing_1 = require("../catalog/billing");
8
7
  const objects_1 = require("../../common/objects");
9
8
  const envelopes_1 = require("../../common/envelopes");
10
9
  const objects_2 = require("../../common/objects");
@@ -183,9 +182,6 @@ exports.checkoutSessionPublicSchema = (0, objects_2.defineComponent)('CheckoutSe
183
182
  .string()
184
183
  .nullable()
185
184
  .describe("The card provider's PUBLIC key for this session's mode, so the payment fields can mount before the payment exists. `null` on FairCoin."),
186
- billing_quote: billing_1.billingFaircoinFxQuoteSchema
187
- .optional()
188
- .describe('FairCoin billing invoices: the frozen USD price and FAIR settlement quote.'),
189
185
  })
190
186
  .strict());
191
187
  // ---- Merchant create/update ---------------------------------------------------
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.eventRoutes = exports.WEBHOOK_EVENT_DESCRIPTIONS = exports.streamEventsQuery = exports.retrieveEventQuery = exports.listEventsQuery = exports.listEventsFilters = exports.eventSchema = exports.eventRequestSchema = exports.billingObservationSchema = void 0;
3
+ exports.eventRoutes = exports.WEBHOOK_EVENT_DESCRIPTIONS = exports.streamEventsQuery = exports.retrieveEventQuery = exports.listEventsQuery = exports.listEventsFilters = exports.eventSchema = exports.eventRequestSchema = void 0;
4
4
  exports.eventSchemaOf = eventSchemaOf;
5
5
  const zod_1 = require("zod");
6
6
  const envelopes_1 = require("../../common/envelopes");
@@ -16,36 +16,6 @@ const events_1 = require("../../vocabulary/events");
16
16
  * every matching webhook endpoint: a delivery's body and `GET /v1/events/:id`
17
17
  * are byte for byte the same object.
18
18
  */
19
- /**
20
- * The payload of `billing.observation.updated`: a wake-up, never paid or grant
21
- * authority. Re-read the owner-bound resource it names.
22
- */
23
- exports.billingObservationSchema = (0, objects_1.defineObject)('billing_observation', 'BillingObservation', zod_1.z
24
- .object({
25
- object: zod_1.z.literal('billing_observation'),
26
- livemode: primitives_1.livemode.describe('The mode of the billing cohort observed (ADR 0017).'),
27
- resource_kind: zod_1.z.enum(['subscription', 'invoice']),
28
- resource_id: zod_1.z.string().describe('The provider subscription or invoice observed.'),
29
- subscription_id: zod_1.z
30
- .string()
31
- .optional()
32
- .describe('Owner-scoped wake-up hint only; re-read the subscription before resolving a payer.'),
33
- revision: zod_1.z.number().int().describe('The observation revision; later revisions are newer.'),
34
- observed_at: primitives_1.unixSeconds,
35
- })
36
- .strict(), {
37
- examples: [
38
- {
39
- object: 'billing_observation',
40
- livemode: false,
41
- resource_kind: 'subscription',
42
- resource_id: 'sub_1Q2w3E4r5T6y7U8i',
43
- subscription_id: 'sub_1Q2w3E4r5T6y7U8i',
44
- revision: 3,
45
- observed_at: 1793750400,
46
- },
47
- ],
48
- });
49
19
  /**
50
20
  * What caused an event, when an API request did (Stripe's `event.request`).
51
21
  * Both `null` for an event caused by something else — the chain watcher, the
@@ -242,7 +212,6 @@ exports.WEBHOOK_EVENT_DESCRIPTIONS = {
242
212
  'setup_intent.succeeded': 'A SetupIntent succeeded: its PaymentMethod is saved.',
243
213
  'setup_intent.setup_failed': 'A SetupIntent attempt failed.',
244
214
  'setup_intent.canceled': 'A SetupIntent was canceled.',
245
- 'billing.observation.updated': 'A recurring billing resource was observed to change. A wake-up only: re-read the resource.',
246
215
  'connected_account.updated': "A seller's connected account changed — its readiness, in practice.",
247
216
  'product.created': 'A Product was created.',
248
217
  'product.updated': 'A Product was updated; `previous_attributes` names what moved.',
@@ -6,7 +6,8 @@ const objects_1 = require("../../common/objects");
6
6
  const primitives_1 = require("../../common/primitives");
7
7
  const route_1 = require("../../route");
8
8
  const tax_1 = require("../../vocabulary/tax");
9
- const shared_1 = require("./shared");
9
+ const shared_1 = require("../catalog/shared");
10
+ const shared_2 = require("./shared");
10
11
  /**
11
12
  * A tax calculation (`taxcalc_…`, ADR 0011): a frozen answer. Peable decides
12
13
  * whether a registration covers the customer's evidenced location and asks
@@ -15,14 +16,14 @@ const shared_1 = require("./shared");
15
16
  */
16
17
  exports.taxBreakdownEntrySchema = (0, objects_1.defineComponent)('TaxBreakdownEntry', zod_1.z
17
18
  .object({
18
- country: shared_1.taxCountry,
19
- state: shared_1.taxState,
19
+ country: shared_2.taxCountry,
20
+ state: shared_2.taxState,
20
21
  level: primitives_1.nullableString.describe('The jurisdiction level (`country`, `state`, …).'),
21
22
  display_name: primitives_1.nullableString,
22
23
  tax_type: primitives_1.nullableString.describe('`vat`, `sales_tax`, …; `null` when no tax is imposed.'),
23
24
  rate_percentage: primitives_1.nullableString.describe('Decimal string, e.g. `"20.0"`; `null` when no tax is imposed.'),
24
- taxable_amount: shared_1.taxMinorAmount,
25
- amount: shared_1.taxMinorAmount,
25
+ taxable_amount: primitives_1.signedAmount,
26
+ amount: primitives_1.signedAmount,
26
27
  inclusive: zod_1.z.boolean(),
27
28
  taxability_reason: zod_1.z
28
29
  .string()
@@ -35,9 +36,9 @@ exports.taxCalculationLineItemSchema = (0, objects_1.defineComponent)('TaxCalcul
35
36
  quantity: zod_1.z.number().int(),
36
37
  tax_code: zod_1.z.string(),
37
38
  tax_behavior: zod_1.z.enum(tax_1.TAX_BEHAVIORS),
38
- amount: shared_1.taxMinorAmount.describe('As given: includes tax when inclusive.'),
39
- amount_tax: shared_1.taxMinorAmount,
40
- amount_net: shared_1.taxMinorAmount.describe('Excluding tax.'),
39
+ amount: primitives_1.signedAmount.describe('As given: includes tax when inclusive.'),
40
+ amount_tax: primitives_1.signedAmount,
41
+ amount_net: primitives_1.signedAmount.describe('Excluding tax.'),
41
42
  breakdown: zod_1.z.array(exports.taxBreakdownEntrySchema),
42
43
  })
43
44
  .strict());
@@ -53,12 +54,12 @@ exports.taxCalculationSchema = (0, objects_1.defineObject)('tax.calculation', 'T
53
54
  provider: primitives_1.nullableString,
54
55
  provider_calculation_ref: primitives_1.nullableString,
55
56
  customer_location_evidence_id: zod_1.z.string().describe('`taxloc_…`.'),
56
- country: shared_1.taxCountry,
57
- state: shared_1.taxState,
58
- amount_total: shared_1.taxMinorAmount.describe('What the customer pays.'),
59
- amount_net: shared_1.taxMinorAmount,
60
- tax_amount_exclusive: shared_1.taxMinorAmount,
61
- tax_amount_inclusive: shared_1.taxMinorAmount,
57
+ country: shared_2.taxCountry,
58
+ state: shared_2.taxState,
59
+ amount_total: primitives_1.amount.describe('What the customer pays.'),
60
+ amount_net: primitives_1.amount,
61
+ tax_amount_exclusive: primitives_1.amount,
62
+ tax_amount_inclusive: primitives_1.amount,
62
63
  line_items: zod_1.z.array(exports.taxCalculationLineItemSchema),
63
64
  tax_date: primitives_1.unixSeconds,
64
65
  created: primitives_1.unixSeconds,
@@ -78,19 +79,19 @@ exports.taxCalculationSchema = (0, objects_1.defineObject)('tax.calculation', 'T
78
79
  customer_location_evidence_id: 'taxloc_0193b8f2c1a87d3e9f4a',
79
80
  country: 'DE',
80
81
  state: null,
81
- amount_total: 1190,
82
- amount_net: 1000,
83
- tax_amount_exclusive: 190,
84
- tax_amount_inclusive: 0,
82
+ amount_total: '1190',
83
+ amount_net: '1000',
84
+ tax_amount_exclusive: '190',
85
+ tax_amount_inclusive: '0',
85
86
  line_items: [
86
87
  {
87
88
  reference: 'plan_pro_monthly',
88
89
  quantity: 1,
89
90
  tax_code: 'txcd_10103001',
90
91
  tax_behavior: 'exclusive',
91
- amount: 1000,
92
- amount_tax: 190,
93
- amount_net: 1000,
92
+ amount: '1000',
93
+ amount_tax: '190',
94
+ amount_net: '1000',
94
95
  breakdown: [
95
96
  {
96
97
  country: 'DE',
@@ -99,8 +100,8 @@ exports.taxCalculationSchema = (0, objects_1.defineObject)('tax.calculation', 'T
99
100
  display_name: 'VAT',
100
101
  tax_type: 'vat',
101
102
  rate_percentage: '19.0',
102
- taxable_amount: 1000,
103
- amount: 190,
103
+ taxable_amount: '1000',
104
+ amount: '190',
104
105
  inclusive: false,
105
106
  taxability_reason: 'standard_rated',
106
107
  },
@@ -114,15 +115,17 @@ exports.taxCalculationSchema = (0, objects_1.defineObject)('tax.calculation', 'T
114
115
  },
115
116
  ],
116
117
  });
118
+ /**
119
+ * The largest line a tax provider is asked to price: the provider's own API
120
+ * counts amounts in integers that stay exact in a JS number (Stripe Tax).
121
+ */
122
+ const TAX_LINE_AMOUNT_MAX = BigInt(Number.MAX_SAFE_INTEGER);
117
123
  exports.taxLineItemParams = zod_1.z
118
124
  .object({
119
125
  reference: zod_1.z.string().min(1).max(200),
120
- amount: zod_1.z
121
- .number()
122
- .int()
123
- .nonnegative()
124
- .safe()
125
- .describe('Unit amount × quantity, minor units. Includes tax when inclusive.'),
126
+ amount: shared_1.baseUnitAmountParam
127
+ .refine((value) => BigInt(value) <= TAX_LINE_AMOUNT_MAX, 'exceeds the largest amount a tax provider prices')
128
+ .describe('Unit amount × quantity, base units. Includes tax when inclusive.'),
126
129
  quantity: zod_1.z.number().int().positive().max(1000000).optional(),
127
130
  tax_code: zod_1.z
128
131
  .string()
@@ -137,7 +140,7 @@ exports.taxLineItemParams = zod_1.z
137
140
  exports.createTaxCalculationParams = zod_1.z
138
141
  .object({
139
142
  currency: zod_1.z.string().regex(/^[A-Za-z]{3}$/),
140
- customer_location_evidence_id: shared_1.taxReferenceParam.describe('Sufficient, unexpired evidence (`taxloc_…`).'),
143
+ customer_location_evidence_id: shared_2.taxReferenceParam.describe('Sufficient, unexpired evidence (`taxloc_…`).'),
141
144
  line_items: zod_1.z
142
145
  .array(exports.taxLineItemParams)
143
146
  .min(1)
@@ -26,8 +26,8 @@ exports.taxReportRowSchema = (0, objects_1.defineComponent)('TaxReportRow', zod_
26
26
  currency: zod_1.z.string().describe('Uppercase ISO 4217.'),
27
27
  transactions: zod_1.z.number().int().nonnegative(),
28
28
  reversals: zod_1.z.number().int().nonnegative().describe('Reversals netted into this row.'),
29
- taxable_amount: shared_1.taxMinorAmount,
30
- tax_amount: shared_1.taxMinorAmount,
29
+ taxable_amount: primitives_1.signedAmount,
30
+ tax_amount: primitives_1.signedAmount,
31
31
  })
32
32
  .strict());
33
33
  exports.taxReportSchema = (0, objects_1.defineObject)('tax.report', 'TaxReport', zod_1.z
@@ -55,8 +55,8 @@ exports.taxReportSchema = (0, objects_1.defineObject)('tax.report', 'TaxReport',
55
55
  currency: 'EUR',
56
56
  transactions: 42,
57
57
  reversals: 1,
58
- taxable_amount: 41000,
59
- tax_amount: 7790,
58
+ taxable_amount: '41000',
59
+ tax_amount: '7790',
60
60
  },
61
61
  ],
62
62
  },
@@ -1,17 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.complianceIdParam = exports.complianceTextParam = exports.complianceStateParam = exports.complianceCountryParam = exports.taxFacts = exports.taxCoverageLimitSchema = exports.taxRuleSourceSchema = exports.taxInstantParam = exports.taxReferenceParam = exports.taxMinorAmount = exports.taxState = exports.taxCountry = void 0;
3
+ exports.complianceIdParam = exports.complianceTextParam = exports.complianceStateParam = exports.complianceCountryParam = exports.taxFacts = exports.taxCoverageLimitSchema = exports.taxRuleSourceSchema = exports.taxInstantParam = exports.taxReferenceParam = exports.taxState = exports.taxCountry = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const objects_1 = require("../../common/objects");
6
6
  const params_1 = require("../../common/params");
7
7
  /**
8
8
  * Building blocks every Peable Tax resource shares.
9
9
  *
10
- * Tax AMOUNTS (calculations, transactions, the report) are integer JSON
11
- * numbers in the currency's minor unit, as Peable Tax has always answered
12
- * them: unlike a FAIR amount, a tax amount is denominated in a fiat currency
13
- * and is bounded by the safe-integer checks the calculator applies. Business
14
- * compliance (ADR 0020) amounts are base-unit strings, as ADR 0014 D1 has it.
10
+ * Every tax amount — a calculation's, a transaction's, a reversal's, a report
11
+ * row's, a compliance measure's — is a base-unit integer STRING of its
12
+ * `currency`, as ADR 0014 D1 has it for every amount on the wire: `amount`
13
+ * where it cannot be negative, `signedAmount` where a reversal makes it so
14
+ * (a line item and its breakdown carry a reversal's negative share, and a
15
+ * report row nets them in).
15
16
  */
16
17
  /** ISO 3166-1 alpha-2, as returned. */
17
18
  exports.taxCountry = zod_1.z.string().describe('ISO 3166-1 alpha-2.');
@@ -20,11 +21,6 @@ exports.taxState = zod_1.z
20
21
  .string()
21
22
  .nullable()
22
23
  .describe('ISO 3166-2 subdivision without the country prefix (`CA`, `QC`).');
23
- /** A minor-unit integer amount (cents), signed: a reversal's amounts are negative. */
24
- exports.taxMinorAmount = zod_1.z
25
- .number()
26
- .int()
27
- .describe('Minor units of `currency` (cents), as an integer.');
28
24
  /** A Peable-side reference: a product, a customer, a refund. */
29
25
  exports.taxReferenceParam = zod_1.z
30
26
  .string()
@@ -8,8 +8,8 @@ const params_1 = require("../../common/params");
8
8
  const primitives_1 = require("../../common/primitives");
9
9
  const route_1 = require("../../route");
10
10
  const tax_1 = require("../../vocabulary/tax");
11
+ const shared_1 = require("../catalog/shared");
11
12
  const calculations_1 = require("./calculations");
12
- const shared_1 = require("./shared");
13
13
  /**
14
14
  * A tax transaction (`taxtxn_…`, ADR 0011/0013): a calculation that was paid,
15
15
  * created by Peable when the payment it priced is accepted on its rail. The
@@ -24,9 +24,9 @@ const shared_1 = require("./shared");
24
24
  */
25
25
  exports.taxTransactionReversalSchema = (0, objects_1.defineComponent)('TaxTransactionReversal', zod_1.z
26
26
  .object({
27
- amount_total: shared_1.taxMinorAmount,
28
- amount_net: shared_1.taxMinorAmount,
29
- tax_amount: shared_1.taxMinorAmount,
27
+ amount_total: primitives_1.signedAmount,
28
+ amount_net: primitives_1.signedAmount,
29
+ tax_amount: primitives_1.signedAmount,
30
30
  line_items: zod_1.z.array(calculations_1.taxCalculationLineItemSchema),
31
31
  })
32
32
  .strict());
@@ -59,13 +59,10 @@ exports.createTaxReversalParams = zod_1.z
59
59
  .max(200)
60
60
  .regex(/^[A-Za-z0-9_.:-]+$/)
61
61
  .describe("The refund's own reference; a repeated reference returns the same reversal."),
62
- amount: zod_1.z
63
- .number()
64
- .int()
65
- .positive()
66
- .safe()
62
+ amount: shared_1.baseUnitAmountParam
63
+ .refine((value) => value !== '0', 'must be positive')
67
64
  .optional()
68
- .describe('Gross minor units refunded (what the payer got back). Omitted: everything not yet reversed.'),
65
+ .describe('Gross base units refunded (what the payer got back). Omitted: everything not yet reversed.'),
69
66
  })
70
67
  .strict();
71
68
  exports.taxTransactionRoutes = [
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BILLING_RAIL_RENEWALS = exports.BILLING_RAIL_SETTLEMENTS = exports.BILLING_SUBSCRIPTION_STATUSES = exports.METER_STATUSES = exports.METER_AGGREGATIONS = exports.BILLING_SETTINGS_LIMITS = exports.DUNNING_INVOICE_ACTIONS = exports.DUNNING_FINAL_ACTIONS = exports.TEST_CLOCK_STATUSES = exports.RECURRING_INTERVAL_COUNT_MAX = exports.CATALOG_MAX_WHOLE_UNITS = exports.CATALOG_LIMITS = exports.COUPON_DURATIONS = exports.TRANSFORM_QUANTITY_ROUNDS = exports.PRICE_TAX_BEHAVIORS = exports.RECURRING_USAGE_TYPES = exports.RECURRING_INTERVALS = exports.PRICE_TYPES = exports.PRICE_TIERS_MODES = exports.PRICE_BILLING_SCHEMES = void 0;
3
+ exports.METER_STATUSES = exports.METER_AGGREGATIONS = exports.BILLING_SETTINGS_LIMITS = exports.DUNNING_INVOICE_ACTIONS = exports.DUNNING_FINAL_ACTIONS = exports.TEST_CLOCK_STATUSES = exports.RECURRING_INTERVAL_COUNT_MAX = exports.CATALOG_MAX_WHOLE_UNITS = exports.CATALOG_LIMITS = exports.COUPON_DURATIONS = exports.TRANSFORM_QUANTITY_ROUNDS = exports.PRICE_TAX_BEHAVIORS = exports.RECURRING_USAGE_TYPES = exports.RECURRING_INTERVALS = exports.PRICE_TYPES = exports.PRICE_TIERS_MODES = exports.PRICE_BILLING_SCHEMES = void 0;
4
4
  exports.maxBaseUnits = maxBaseUnits;
5
5
  // The catalog's and the billing engine platform's closed value sets (ADR 0016,
6
6
  // ADR 0018): what a price, a coupon, a test clock, a meter and the billing
@@ -91,20 +91,4 @@ exports.BILLING_SETTINGS_LIMITS = Object.freeze({
91
91
  /** How a meter combines a period's events into the quantity billed. */
92
92
  exports.METER_AGGREGATIONS = ['sum', 'count', 'last'];
93
93
  exports.METER_STATUSES = ['active', 'inactive'];
94
- // ---- Recurring billing transport (`/v1/billing/*`) ---------------------------
95
- /** A provider subscription's status, as the recurring transport observes it. */
96
- exports.BILLING_SUBSCRIPTION_STATUSES = [
97
- 'incomplete',
98
- 'incomplete_expired',
99
- 'trialing',
100
- 'active',
101
- 'past_due',
102
- 'canceled',
103
- 'unpaid',
104
- 'paused',
105
- ];
106
- /** `fiat` (Stripe and any further provider) or `faircoin` (native, to the merchant's watch-only wallet). */
107
- exports.BILLING_RAIL_SETTLEMENTS = ['fiat', 'faircoin'];
108
- /** `automatic`: the provider charges each period. `payer_initiated`: each period is an explicit payment. */
109
- exports.BILLING_RAIL_RENEWALS = ['automatic', 'payer_initiated'];
110
94
  // Product tax codes are Peable Tax's vocabulary: `vocabulary/tax.ts` (`TAX_CODES`).
@@ -47,19 +47,15 @@ exports.ERROR_CODE_DESCRIPTIONS = {
47
47
  account_invalid: 'The `Peable-Account` header names no connected account of this platform.',
48
48
  account_missing: 'The merchant has no account object yet.',
49
49
  amount_not_representable: 'The amount does not fit the currency or the rail.',
50
- billing_not_enabled: 'Billing is not enabled for this merchant.',
51
- billing_provider_unavailable: 'The billing provider could not be reached; retry.',
52
50
  domain_taken: 'The domain is already registered by another merchant.',
53
51
  file_too_large: 'The uploaded file is larger than its purpose allows.',
54
52
  file_unavailable: 'The file exists but its contents cannot be served right now.',
55
53
  idempotency_error: 'The `Idempotency-Key` was used with a different request, or its first request is still running.',
56
54
  idempotency_key_invalid: 'The `Idempotency-Key` header is not a valid key.',
57
55
  insufficient_scope: 'The credential is valid but was not granted the Oxy scope this route requires (`payments:read`, `payments:write`, …); `message` names it.',
58
- invalid_billing_request: 'The billing request is not valid for this subscription or offer.',
59
56
  keyless_recipient: 'The recipient has no receive key, so no address can be derived for them.',
60
57
  link_not_found: 'The link does not exist or is no longer active.',
61
58
  live_payments_gated: 'Live payments are not enabled for this application yet.',
62
- local_test_request_required: 'This test helper only answers a local test request.',
63
59
  parameter_invalid: 'A parameter is invalid; `param` names it.',
64
60
  parameter_missing: 'A required parameter is missing; `param` names it.',
65
61
  parameter_unknown: 'The request carries a parameter this route does not accept; `param` names it.',
@@ -88,10 +84,7 @@ exports.ERROR_CODE_DESCRIPTIONS = {
88
84
  customer_location_invalid: "The tax provider could not use the customer's location.",
89
85
  dispute_already_submitted: 'Evidence for this dispute has already been submitted; it is one shot.',
90
86
  dispute_not_answerable: 'The dispute is in a status that no longer accepts evidence.',
91
- idempotency_conflict: 'The same operation key was used for a different billing request.',
92
- identity_conflict: 'The billing identity already belongs to another customer or subscription.',
93
87
  in_progress: 'The same operation is still running; retry with the same key.',
94
- invalid_provider_response: 'The provider answered with something Peable cannot trust; the operation was not applied.',
95
88
  invalid_registration: 'The tax registration is not valid.',
96
89
  invalid_registration_declaration: 'The tax registration declaration is not valid.',
97
90
  invalid_tax_code: 'The tax code does not exist.',
@@ -106,12 +99,9 @@ exports.ERROR_CODE_DESCRIPTIONS = {
106
99
  product_in_use: 'The product is referenced by a subscription or a link.',
107
100
  promotion_code_invalid: 'The promotion code does not exist, is inactive or does not apply.',
108
101
  promotion_code_taken: 'Another active promotion code already uses this `code`.',
109
- provider_unavailable: 'The payment provider could not be reached; retry.',
110
102
  rail_unavailable: 'The payment rail this request needs is not available.',
111
- reconciliation_required: 'The billing operation has an unknown outcome at the provider and is being reconciled.',
112
103
  registration_immutable: 'An approved or ended tax registration cannot be deleted or changed this way; end it instead.',
113
104
  resource_already_exists: 'An object with this identity already exists.',
114
- result_expired: 'The stored result of this operation has expired.',
115
105
  review_item_not_open: 'The review item is already resolved or dismissed.',
116
106
  rule_set_version_unavailable: 'The tax rule set version is not available.',
117
107
  subscription_line_invalid: 'A subscription line item is not valid for Checkout.',
@@ -119,9 +109,6 @@ exports.ERROR_CODE_DESCRIPTIONS = {
119
109
  tax_calculation_unavailable: 'Tax could not be calculated; a covered sale fails closed.',
120
110
  tax_provider_registration_mismatch: "The provider's registrations disagree with the ones Peable has approved.",
121
111
  tax_settings_not_active: 'Tax settings are not active for this merchant.',
122
- local_test_unavailable: 'The local test checkout is not available.',
123
- local_test_configuration_unavailable: 'The local test checkout has no provider configuration.',
124
- local_test_subscription_unavailable: 'The local test subscription cannot be read.',
125
112
  rail_mismatch: 'The operation does not apply to the rail this payment uses.',
126
113
  checkout_session_changed: 'The Checkout Session changed while this request ran (a price, a discount, its tax); read it again and retry.',
127
114
  checkout_session_locked: 'The Checkout Session is being confirmed and cannot change.',
@@ -61,7 +61,6 @@ exports.WEBHOOK_EVENT_OBJECTS = {
61
61
  'setup_intent.succeeded': 'setup_intent',
62
62
  'setup_intent.setup_failed': 'setup_intent',
63
63
  'setup_intent.canceled': 'setup_intent',
64
- 'billing.observation.updated': 'billing_observation',
65
64
  'connected_account.updated': 'connected_account',
66
65
  'product.created': 'product',
67
66
  'product.updated': 'product',
@@ -1,6 +1,5 @@
1
1
  // Contracts of this group: one module per resource, re-exported here, and
2
2
  // their routes concatenated into `catalogRoutes`.
3
- import { billingRoutes } from './billing.js';
4
3
  import { billingSettingsRoutes } from './billingSettings.js';
5
4
  import { couponRoutes } from './coupons.js';
6
5
  import { entitlementRoutes } from './entitlements.js';
@@ -9,7 +8,6 @@ import { priceRoutes } from './prices.js';
9
8
  import { productRoutes } from './products.js';
10
9
  import { promotionCodeRoutes } from './promotionCodes.js';
11
10
  import { testClockRoutes } from './testClocks.js';
12
- export * from './billing.js';
13
11
  export * from './billingSettings.js';
14
12
  export * from './coupons.js';
15
13
  export * from './entitlements.js';
@@ -22,8 +20,7 @@ export * from './testClocks.js';
22
20
  export { baseUnitAmountParam, queryFlag, queryIdList } from './shared.js';
23
21
  /**
24
22
  * The catalog (products, prices, coupons, promotion codes), entitlements, the
25
- * billing engine's platform objects (test clocks, billing settings, meters)
26
- * and the recurring billing transport (`/v1/billing/*`).
23
+ * billing engine's platform objects (test clocks, billing settings, meters).
27
24
  */
28
25
  export const catalogRoutes = [
29
26
  ...productRoutes,
@@ -34,5 +31,4 @@ export const catalogRoutes = [
34
31
  ...testClockRoutes,
35
32
  ...billingSettingsRoutes,
36
33
  ...meterRoutes,
37
- ...billingRoutes,
38
34
  ];
@@ -1,7 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  import { CATALOG_LIMITS, PRICE_TAX_BEHAVIORS, RECURRING_INTERVALS } from '../../vocabulary/catalog.js';
3
3
  import { SETUP_INTENT_STATUSES } from '../../vocabulary/payments.js';
4
- import { billingFaircoinFxQuoteSchema } from '../catalog/billing.js';
5
4
  import { embedded } from '../../common/objects.js';
6
5
  import { listOf } from '../../common/envelopes.js';
7
6
  import { defineComponent, defineObject, expandable } from '../../common/objects.js';
@@ -180,9 +179,6 @@ export const checkoutSessionPublicSchema = defineComponent('CheckoutSessionPubli
180
179
  .string()
181
180
  .nullable()
182
181
  .describe("The card provider's PUBLIC key for this session's mode, so the payment fields can mount before the payment exists. `null` on FairCoin."),
183
- billing_quote: billingFaircoinFxQuoteSchema
184
- .optional()
185
- .describe('FairCoin billing invoices: the frozen USD price and FAIR settlement quote.'),
186
182
  })
187
183
  .strict());
188
184
  // ---- Merchant create/update ---------------------------------------------------
@@ -12,36 +12,6 @@ import { WEBHOOK_EVENT_OBJECTS, WEBHOOK_EVENT_TYPES, } from '../../vocabulary/ev
12
12
  * every matching webhook endpoint: a delivery's body and `GET /v1/events/:id`
13
13
  * are byte for byte the same object.
14
14
  */
15
- /**
16
- * The payload of `billing.observation.updated`: a wake-up, never paid or grant
17
- * authority. Re-read the owner-bound resource it names.
18
- */
19
- export const billingObservationSchema = defineObject('billing_observation', 'BillingObservation', z
20
- .object({
21
- object: z.literal('billing_observation'),
22
- livemode: livemode.describe('The mode of the billing cohort observed (ADR 0017).'),
23
- resource_kind: z.enum(['subscription', 'invoice']),
24
- resource_id: z.string().describe('The provider subscription or invoice observed.'),
25
- subscription_id: z
26
- .string()
27
- .optional()
28
- .describe('Owner-scoped wake-up hint only; re-read the subscription before resolving a payer.'),
29
- revision: z.number().int().describe('The observation revision; later revisions are newer.'),
30
- observed_at: unixSeconds,
31
- })
32
- .strict(), {
33
- examples: [
34
- {
35
- object: 'billing_observation',
36
- livemode: false,
37
- resource_kind: 'subscription',
38
- resource_id: 'sub_1Q2w3E4r5T6y7U8i',
39
- subscription_id: 'sub_1Q2w3E4r5T6y7U8i',
40
- revision: 3,
41
- observed_at: 1793750400,
42
- },
43
- ],
44
- });
45
15
  /**
46
16
  * What caused an event, when an API request did (Stripe's `event.request`).
47
17
  * Both `null` for an event caused by something else — the chain watcher, the
@@ -238,7 +208,6 @@ export const WEBHOOK_EVENT_DESCRIPTIONS = {
238
208
  'setup_intent.succeeded': 'A SetupIntent succeeded: its PaymentMethod is saved.',
239
209
  'setup_intent.setup_failed': 'A SetupIntent attempt failed.',
240
210
  'setup_intent.canceled': 'A SetupIntent was canceled.',
241
- 'billing.observation.updated': 'A recurring billing resource was observed to change. A wake-up only: re-read the resource.',
242
211
  'connected_account.updated': "A seller's connected account changed — its readiness, in practice.",
243
212
  'product.created': 'A Product was created.',
244
213
  'product.updated': 'A Product was updated; `previous_attributes` names what moved.',
@@ -1,9 +1,10 @@
1
1
  import { z } from 'zod';
2
2
  import { defineComponent, defineObject } from '../../common/objects.js';
3
- import { livemode, nullableString, unixSeconds } from '../../common/primitives.js';
3
+ import { amount, livemode, nullableString, signedAmount, unixSeconds, } from '../../common/primitives.js';
4
4
  import { defineRoute } from '../../route.js';
5
5
  import { TAX_BEHAVIORS, TAX_COLLECTIONS } from '../../vocabulary/tax.js';
6
- import { taxCountry, taxMinorAmount, taxReferenceParam, taxState } from './shared.js';
6
+ import { baseUnitAmountParam } from '../catalog/shared.js';
7
+ import { taxCountry, taxReferenceParam, taxState } from './shared.js';
7
8
  /**
8
9
  * A tax calculation (`taxcalc_…`, ADR 0011): a frozen answer. Peable decides
9
10
  * whether a registration covers the customer's evidenced location and asks
@@ -18,8 +19,8 @@ export const taxBreakdownEntrySchema = defineComponent('TaxBreakdownEntry', z
18
19
  display_name: nullableString,
19
20
  tax_type: nullableString.describe('`vat`, `sales_tax`, …; `null` when no tax is imposed.'),
20
21
  rate_percentage: nullableString.describe('Decimal string, e.g. `"20.0"`; `null` when no tax is imposed.'),
21
- taxable_amount: taxMinorAmount,
22
- amount: taxMinorAmount,
22
+ taxable_amount: signedAmount,
23
+ amount: signedAmount,
23
24
  inclusive: z.boolean(),
24
25
  taxability_reason: z
25
26
  .string()
@@ -32,9 +33,9 @@ export const taxCalculationLineItemSchema = defineComponent('TaxCalculationLineI
32
33
  quantity: z.number().int(),
33
34
  tax_code: z.string(),
34
35
  tax_behavior: z.enum(TAX_BEHAVIORS),
35
- amount: taxMinorAmount.describe('As given: includes tax when inclusive.'),
36
- amount_tax: taxMinorAmount,
37
- amount_net: taxMinorAmount.describe('Excluding tax.'),
36
+ amount: signedAmount.describe('As given: includes tax when inclusive.'),
37
+ amount_tax: signedAmount,
38
+ amount_net: signedAmount.describe('Excluding tax.'),
38
39
  breakdown: z.array(taxBreakdownEntrySchema),
39
40
  })
40
41
  .strict());
@@ -52,10 +53,10 @@ export const taxCalculationSchema = defineObject('tax.calculation', 'TaxCalculat
52
53
  customer_location_evidence_id: z.string().describe('`taxloc_…`.'),
53
54
  country: taxCountry,
54
55
  state: taxState,
55
- amount_total: taxMinorAmount.describe('What the customer pays.'),
56
- amount_net: taxMinorAmount,
57
- tax_amount_exclusive: taxMinorAmount,
58
- tax_amount_inclusive: taxMinorAmount,
56
+ amount_total: amount.describe('What the customer pays.'),
57
+ amount_net: amount,
58
+ tax_amount_exclusive: amount,
59
+ tax_amount_inclusive: amount,
59
60
  line_items: z.array(taxCalculationLineItemSchema),
60
61
  tax_date: unixSeconds,
61
62
  created: unixSeconds,
@@ -75,19 +76,19 @@ export const taxCalculationSchema = defineObject('tax.calculation', 'TaxCalculat
75
76
  customer_location_evidence_id: 'taxloc_0193b8f2c1a87d3e9f4a',
76
77
  country: 'DE',
77
78
  state: null,
78
- amount_total: 1190,
79
- amount_net: 1000,
80
- tax_amount_exclusive: 190,
81
- tax_amount_inclusive: 0,
79
+ amount_total: '1190',
80
+ amount_net: '1000',
81
+ tax_amount_exclusive: '190',
82
+ tax_amount_inclusive: '0',
82
83
  line_items: [
83
84
  {
84
85
  reference: 'plan_pro_monthly',
85
86
  quantity: 1,
86
87
  tax_code: 'txcd_10103001',
87
88
  tax_behavior: 'exclusive',
88
- amount: 1000,
89
- amount_tax: 190,
90
- amount_net: 1000,
89
+ amount: '1000',
90
+ amount_tax: '190',
91
+ amount_net: '1000',
91
92
  breakdown: [
92
93
  {
93
94
  country: 'DE',
@@ -96,8 +97,8 @@ export const taxCalculationSchema = defineObject('tax.calculation', 'TaxCalculat
96
97
  display_name: 'VAT',
97
98
  tax_type: 'vat',
98
99
  rate_percentage: '19.0',
99
- taxable_amount: 1000,
100
- amount: 190,
100
+ taxable_amount: '1000',
101
+ amount: '190',
101
102
  inclusive: false,
102
103
  taxability_reason: 'standard_rated',
103
104
  },
@@ -111,15 +112,17 @@ export const taxCalculationSchema = defineObject('tax.calculation', 'TaxCalculat
111
112
  },
112
113
  ],
113
114
  });
115
+ /**
116
+ * The largest line a tax provider is asked to price: the provider's own API
117
+ * counts amounts in integers that stay exact in a JS number (Stripe Tax).
118
+ */
119
+ const TAX_LINE_AMOUNT_MAX = BigInt(Number.MAX_SAFE_INTEGER);
114
120
  export const taxLineItemParams = z
115
121
  .object({
116
122
  reference: z.string().min(1).max(200),
117
- amount: z
118
- .number()
119
- .int()
120
- .nonnegative()
121
- .safe()
122
- .describe('Unit amount × quantity, minor units. Includes tax when inclusive.'),
123
+ amount: baseUnitAmountParam
124
+ .refine((value) => BigInt(value) <= TAX_LINE_AMOUNT_MAX, 'exceeds the largest amount a tax provider prices')
125
+ .describe('Unit amount × quantity, base units. Includes tax when inclusive.'),
123
126
  quantity: z.number().int().positive().max(1000000).optional(),
124
127
  tax_code: z
125
128
  .string()