@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.
- package/dist/cjs/resources/catalog/index.js +1 -5
- package/dist/cjs/resources/checkout/checkoutSessions.js +0 -4
- package/dist/cjs/resources/events/events.js +1 -32
- package/dist/cjs/resources/tax/calculations.js +33 -30
- package/dist/cjs/resources/tax/reports.js +4 -4
- package/dist/cjs/resources/tax/shared.js +7 -11
- package/dist/cjs/resources/tax/transactions.js +7 -10
- package/dist/cjs/vocabulary/catalog.js +1 -17
- package/dist/cjs/vocabulary/errors.js +0 -13
- package/dist/cjs/vocabulary/events.js +0 -1
- package/dist/esm/resources/catalog/index.js +1 -5
- package/dist/esm/resources/checkout/checkoutSessions.js +0 -4
- package/dist/esm/resources/events/events.js +0 -31
- package/dist/esm/resources/tax/calculations.js +29 -26
- package/dist/esm/resources/tax/reports.js +6 -6
- package/dist/esm/resources/tax/shared.js +6 -10
- package/dist/esm/resources/tax/transactions.js +8 -11
- package/dist/esm/vocabulary/catalog.js +0 -16
- package/dist/esm/vocabulary/errors.js +0 -13
- package/dist/esm/vocabulary/events.js +0 -1
- package/dist/types/resources/catalog/index.d.ts +1 -851
- package/dist/types/resources/checkout/checkoutSessions.d.ts +13 -61
- package/dist/types/resources/checkout/index.d.ts +10 -46
- package/dist/types/resources/events/events.d.ts +0 -22
- package/dist/types/resources/events/index.d.ts +2 -15
- package/dist/types/resources/events/webhookDeliveries.d.ts +0 -3
- package/dist/types/resources/events/webhookEndpoints.d.ts +4 -16
- package/dist/types/resources/payments/index.d.ts +10 -10
- package/dist/types/resources/payments/paymentIntents.d.ts +10 -10
- package/dist/types/resources/payments/testHelpers.d.ts +1 -1
- package/dist/types/resources/tax/calculations.d.ts +37 -37
- package/dist/types/resources/tax/index.d.ts +57 -57
- package/dist/types/resources/tax/registrations.d.ts +2 -2
- package/dist/types/resources/tax/reports.d.ts +6 -6
- package/dist/types/resources/tax/shared.d.ts +6 -7
- package/dist/types/resources/tax/transactions.d.ts +61 -61
- package/dist/types/vocabulary/catalog.d.ts +0 -9
- package/dist/types/vocabulary/errors.d.ts +0 -13
- package/dist/types/vocabulary/events.d.ts +0 -1
- package/package.json +1 -1
- package/dist/cjs/resources/catalog/billing.js +0 -755
- package/dist/esm/resources/catalog/billing.js +0 -752
- 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 =
|
|
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("
|
|
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:
|
|
19
|
-
state:
|
|
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:
|
|
25
|
-
amount:
|
|
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:
|
|
39
|
-
amount_tax:
|
|
40
|
-
amount_net:
|
|
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:
|
|
57
|
-
state:
|
|
58
|
-
amount_total:
|
|
59
|
-
amount_net:
|
|
60
|
-
tax_amount_exclusive:
|
|
61
|
-
tax_amount_inclusive:
|
|
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:
|
|
121
|
-
.
|
|
122
|
-
.
|
|
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:
|
|
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:
|
|
30
|
-
tax_amount:
|
|
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.
|
|
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
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
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:
|
|
28
|
-
amount_net:
|
|
29
|
-
tax_amount:
|
|
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:
|
|
63
|
-
.
|
|
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
|
|
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.
|
|
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 {
|
|
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:
|
|
22
|
-
amount:
|
|
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:
|
|
36
|
-
amount_tax:
|
|
37
|
-
amount_net:
|
|
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:
|
|
56
|
-
amount_net:
|
|
57
|
-
tax_amount_exclusive:
|
|
58
|
-
tax_amount_inclusive:
|
|
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:
|
|
118
|
-
.
|
|
119
|
-
.
|
|
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()
|