@peable.to/contracts 0.3.0 → 1.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/common/address.js +81 -0
- package/dist/cjs/common/envelopes.js +101 -0
- package/dist/cjs/common/objects.js +85 -0
- package/dist/cjs/common/params.js +211 -0
- package/dist/cjs/common/primitives.js +39 -0
- package/dist/cjs/contributions.js +22 -0
- package/dist/cjs/index.js +40 -97
- package/dist/cjs/openapi/document.js +297 -0
- package/dist/cjs/openapi/index.js +7 -0
- package/dist/cjs/openapi/webhooks.js +17 -0
- package/dist/cjs/resources/billingEngine/billingPortal.js +237 -0
- package/dist/cjs/resources/billingEngine/creditNotes.js +189 -0
- package/dist/cjs/resources/billingEngine/customerBalanceTransactions.js +90 -0
- package/dist/cjs/resources/billingEngine/index.js +43 -0
- package/dist/cjs/resources/billingEngine/invoiceItems.js +155 -0
- package/dist/cjs/resources/billingEngine/invoices.js +509 -0
- package/dist/cjs/resources/billingEngine/params.js +43 -0
- package/dist/cjs/resources/billingEngine/public.js +326 -0
- package/dist/cjs/resources/billingEngine/subscriptions.js +476 -0
- package/dist/cjs/resources/catalog/billing.js +755 -0
- package/dist/cjs/resources/catalog/billingSettings.js +131 -0
- package/dist/cjs/resources/catalog/coupons.js +222 -0
- package/dist/cjs/resources/catalog/entitlements.js +257 -0
- package/dist/cjs/resources/catalog/index.js +58 -0
- package/dist/cjs/resources/catalog/meters.js +279 -0
- package/dist/cjs/resources/catalog/prices.js +423 -0
- package/dist/cjs/resources/catalog/products.js +228 -0
- package/dist/cjs/resources/catalog/promotionCodes.js +174 -0
- package/dist/cjs/resources/catalog/shared.js +75 -0
- package/dist/cjs/resources/catalog/testClocks.js +127 -0
- package/dist/cjs/resources/checkout/checkoutSessions.js +582 -0
- package/dist/cjs/resources/checkout/contributions.js +172 -0
- package/dist/cjs/resources/checkout/files.js +133 -0
- package/dist/cjs/resources/checkout/index.js +57 -0
- package/dist/cjs/resources/checkout/merchants.js +290 -0
- package/dist/cjs/resources/checkout/paymentLinks.js +330 -0
- package/dist/cjs/resources/checkout/paymentMethodConfigurations.js +262 -0
- package/dist/cjs/resources/checkout/shared.js +368 -0
- package/dist/cjs/resources/connect/account.js +332 -0
- package/dist/cjs/resources/connect/applicationFees.js +113 -0
- package/dist/cjs/resources/connect/balance.js +212 -0
- package/dist/cjs/resources/connect/connectedAccounts.js +260 -0
- package/dist/cjs/resources/connect/index.js +51 -0
- package/dist/cjs/resources/connect/onboarding.js +82 -0
- package/dist/cjs/resources/connect/payouts.js +196 -0
- package/dist/cjs/resources/connect/reporting.js +235 -0
- package/dist/cjs/resources/connect/requestLogs.js +110 -0
- package/dist/cjs/resources/connect/transfers.js +227 -0
- package/dist/cjs/resources/core/customers.js +194 -0
- package/dist/cjs/resources/core/index.js +23 -0
- package/dist/cjs/resources/core/paymentMethods.js +134 -0
- package/dist/cjs/resources/events/events.js +357 -0
- package/dist/cjs/resources/events/index.js +29 -0
- package/dist/cjs/resources/events/webhookDeliveries.js +93 -0
- package/dist/cjs/resources/events/webhookEndpoints.js +215 -0
- package/dist/cjs/resources/payments/charges.js +157 -0
- package/dist/cjs/resources/payments/disputes.js +204 -0
- package/dist/cjs/resources/payments/index.js +41 -0
- package/dist/cjs/resources/payments/paymentIntents.js +529 -0
- package/dist/cjs/resources/payments/refunds.js +245 -0
- package/dist/cjs/resources/payments/setupIntents.js +158 -0
- package/dist/cjs/resources/payments/social.js +182 -0
- package/dist/cjs/resources/payments/testHelpers.js +39 -0
- package/dist/cjs/resources/tax/assessments.js +217 -0
- package/dist/cjs/resources/tax/businessProfile.js +99 -0
- package/dist/cjs/resources/tax/calculations.js +176 -0
- package/dist/cjs/resources/tax/capabilities.js +42 -0
- package/dist/cjs/resources/tax/codes.js +37 -0
- package/dist/cjs/resources/tax/complianceActions.js +56 -0
- package/dist/cjs/resources/tax/deadlines.js +59 -0
- package/dist/cjs/resources/tax/documents.js +128 -0
- package/dist/cjs/resources/tax/index.js +80 -0
- package/dist/cjs/resources/tax/locationEvidence.js +131 -0
- package/dist/cjs/resources/tax/operatingLocations.js +98 -0
- package/dist/cjs/resources/tax/products.js +67 -0
- package/dist/cjs/resources/tax/registrationDeclarations.js +124 -0
- package/dist/cjs/resources/tax/registrations.js +82 -0
- package/dist/cjs/resources/tax/reports.js +92 -0
- package/dist/cjs/resources/tax/reviewItems.js +116 -0
- package/dist/cjs/resources/tax/ruleSet.js +68 -0
- package/dist/cjs/resources/tax/salesDestinations.js +94 -0
- package/dist/cjs/resources/tax/settings.js +104 -0
- package/dist/cjs/resources/tax/shared.js +62 -0
- package/dist/cjs/resources/tax/transactions.js +102 -0
- package/dist/cjs/route.js +22 -0
- package/dist/cjs/routes.js +31 -0
- package/dist/cjs/vocabulary/billingPortal.js +15 -0
- package/dist/cjs/vocabulary/catalog.js +110 -0
- package/dist/cjs/vocabulary/checkout.js +53 -0
- package/dist/cjs/vocabulary/connect.js +95 -0
- package/dist/cjs/vocabulary/errors.js +174 -0
- package/dist/cjs/vocabulary/events.js +176 -0
- package/dist/cjs/vocabulary/files.js +44 -0
- package/dist/cjs/vocabulary/index.js +37 -0
- package/dist/cjs/vocabulary/invoices.js +52 -0
- package/dist/cjs/vocabulary/lists.js +22 -0
- package/dist/cjs/vocabulary/merchants.js +23 -0
- package/dist/cjs/vocabulary/money.js +104 -0
- package/dist/cjs/vocabulary/paymentMethodConfigurations.js +36 -0
- package/dist/cjs/vocabulary/payments.js +195 -0
- package/dist/cjs/vocabulary/reporting.js +27 -0
- package/dist/cjs/vocabulary/subscriptions.js +60 -0
- package/dist/cjs/vocabulary/tax.js +237 -0
- package/dist/cjs/vocabulary/version.js +12 -0
- package/dist/esm/common/address.js +76 -0
- package/dist/esm/common/envelopes.js +95 -0
- package/dist/esm/common/objects.js +74 -0
- package/dist/esm/common/params.js +203 -0
- package/dist/esm/common/primitives.js +35 -0
- package/dist/esm/contributions.js +5 -0
- package/dist/esm/index.js +26 -94
- package/dist/esm/openapi/document.js +294 -0
- package/dist/esm/openapi/index.js +2 -0
- package/dist/esm/openapi/webhooks.js +14 -0
- package/dist/esm/resources/billingEngine/billingPortal.js +234 -0
- package/dist/esm/resources/billingEngine/creditNotes.js +186 -0
- package/dist/esm/resources/billingEngine/customerBalanceTransactions.js +87 -0
- package/dist/esm/resources/billingEngine/index.js +26 -0
- package/dist/esm/resources/billingEngine/invoiceItems.js +152 -0
- package/dist/esm/resources/billingEngine/invoices.js +506 -0
- package/dist/esm/resources/billingEngine/params.js +39 -0
- package/dist/esm/resources/billingEngine/public.js +323 -0
- package/dist/esm/resources/billingEngine/subscriptions.js +473 -0
- package/dist/esm/resources/catalog/billing.js +752 -0
- package/dist/esm/resources/catalog/billingSettings.js +128 -0
- package/dist/esm/resources/catalog/coupons.js +219 -0
- package/dist/esm/resources/catalog/entitlements.js +254 -0
- package/dist/esm/resources/catalog/index.js +38 -0
- package/dist/esm/resources/catalog/meters.js +276 -0
- package/dist/esm/resources/catalog/prices.js +419 -0
- package/dist/esm/resources/catalog/products.js +225 -0
- package/dist/esm/resources/catalog/promotionCodes.js +171 -0
- package/dist/esm/resources/catalog/shared.js +67 -0
- package/dist/esm/resources/catalog/testClocks.js +124 -0
- package/dist/esm/resources/checkout/checkoutSessions.js +579 -0
- package/dist/esm/resources/checkout/contributions.js +167 -0
- package/dist/esm/resources/checkout/files.js +130 -0
- package/dist/esm/resources/checkout/index.js +25 -0
- package/dist/esm/resources/checkout/merchants.js +287 -0
- package/dist/esm/resources/checkout/paymentLinks.js +327 -0
- package/dist/esm/resources/checkout/paymentMethodConfigurations.js +259 -0
- package/dist/esm/resources/checkout/shared.js +363 -0
- package/dist/esm/resources/connect/account.js +329 -0
- package/dist/esm/resources/connect/applicationFees.js +110 -0
- package/dist/esm/resources/connect/balance.js +209 -0
- package/dist/esm/resources/connect/connectedAccounts.js +257 -0
- package/dist/esm/resources/connect/index.js +34 -0
- package/dist/esm/resources/connect/onboarding.js +79 -0
- package/dist/esm/resources/connect/payouts.js +193 -0
- package/dist/esm/resources/connect/reporting.js +232 -0
- package/dist/esm/resources/connect/requestLogs.js +107 -0
- package/dist/esm/resources/connect/transfers.js +224 -0
- package/dist/esm/resources/core/customers.js +191 -0
- package/dist/esm/resources/core/index.js +6 -0
- package/dist/esm/resources/core/paymentMethods.js +131 -0
- package/dist/esm/resources/events/events.js +353 -0
- package/dist/esm/resources/events/index.js +12 -0
- package/dist/esm/resources/events/webhookDeliveries.js +90 -0
- package/dist/esm/resources/events/webhookEndpoints.js +212 -0
- package/dist/esm/resources/payments/charges.js +154 -0
- package/dist/esm/resources/payments/disputes.js +201 -0
- package/dist/esm/resources/payments/index.js +24 -0
- package/dist/esm/resources/payments/paymentIntents.js +526 -0
- package/dist/esm/resources/payments/refunds.js +242 -0
- package/dist/esm/resources/payments/setupIntents.js +155 -0
- package/dist/esm/resources/payments/social.js +179 -0
- package/dist/esm/resources/payments/testHelpers.js +36 -0
- package/dist/esm/resources/tax/assessments.js +214 -0
- package/dist/esm/resources/tax/businessProfile.js +96 -0
- package/dist/esm/resources/tax/calculations.js +173 -0
- package/dist/esm/resources/tax/capabilities.js +39 -0
- package/dist/esm/resources/tax/codes.js +34 -0
- package/dist/esm/resources/tax/complianceActions.js +53 -0
- package/dist/esm/resources/tax/deadlines.js +56 -0
- package/dist/esm/resources/tax/documents.js +125 -0
- package/dist/esm/resources/tax/index.js +63 -0
- package/dist/esm/resources/tax/locationEvidence.js +128 -0
- package/dist/esm/resources/tax/operatingLocations.js +95 -0
- package/dist/esm/resources/tax/products.js +64 -0
- package/dist/esm/resources/tax/registrationDeclarations.js +121 -0
- package/dist/esm/resources/tax/registrations.js +79 -0
- package/dist/esm/resources/tax/reports.js +89 -0
- package/dist/esm/resources/tax/reviewItems.js +113 -0
- package/dist/esm/resources/tax/ruleSet.js +65 -0
- package/dist/esm/resources/tax/salesDestinations.js +91 -0
- package/dist/esm/resources/tax/settings.js +101 -0
- package/dist/esm/resources/tax/shared.js +58 -0
- package/dist/esm/resources/tax/transactions.js +99 -0
- package/dist/esm/route.js +16 -0
- package/dist/esm/routes.js +27 -0
- package/dist/esm/vocabulary/billingPortal.js +12 -0
- package/dist/esm/vocabulary/catalog.js +106 -0
- package/dist/esm/vocabulary/checkout.js +50 -0
- package/dist/esm/vocabulary/connect.js +92 -0
- package/dist/esm/vocabulary/errors.js +169 -0
- package/dist/esm/vocabulary/events.js +173 -0
- package/dist/esm/vocabulary/files.js +41 -0
- package/dist/esm/vocabulary/index.js +21 -0
- package/dist/esm/vocabulary/invoices.js +49 -0
- package/dist/esm/vocabulary/lists.js +19 -0
- package/dist/esm/vocabulary/merchants.js +20 -0
- package/dist/esm/vocabulary/money.js +98 -0
- package/dist/esm/vocabulary/paymentMethodConfigurations.js +33 -0
- package/dist/esm/vocabulary/payments.js +192 -0
- package/dist/esm/vocabulary/reporting.js +24 -0
- package/dist/esm/vocabulary/subscriptions.js +57 -0
- package/dist/esm/vocabulary/tax.js +233 -0
- package/dist/esm/vocabulary/version.js +9 -0
- package/dist/types/common/address.d.ts +62 -0
- package/dist/types/common/envelopes.d.ts +88 -0
- package/dist/types/common/objects.d.ts +107 -0
- package/dist/types/common/params.d.ts +156 -0
- package/dist/types/common/primitives.d.ts +56 -0
- package/dist/types/contributions.d.ts +1 -0
- package/dist/types/index.d.ts +16 -134
- package/dist/types/openapi/document.d.ts +16 -0
- package/dist/types/openapi/index.d.ts +2 -0
- package/dist/types/openapi/webhooks.d.ts +15 -0
- package/dist/types/resources/billingEngine/billingPortal.d.ts +742 -0
- package/dist/types/resources/billingEngine/creditNotes.d.ts +655 -0
- package/dist/types/resources/billingEngine/customerBalanceTransactions.d.ts +282 -0
- package/dist/types/resources/billingEngine/index.d.ts +6071 -0
- package/dist/types/resources/billingEngine/invoiceItems.d.ts +502 -0
- package/dist/types/resources/billingEngine/invoices.d.ts +2547 -0
- package/dist/types/resources/billingEngine/params.d.ts +51 -0
- package/dist/types/resources/billingEngine/public.d.ts +1860 -0
- package/dist/types/resources/billingEngine/subscriptions.d.ts +1519 -0
- package/dist/types/resources/catalog/billing.d.ts +1723 -0
- package/dist/types/resources/catalog/billingSettings.d.ts +160 -0
- package/dist/types/resources/catalog/coupons.d.ts +403 -0
- package/dist/types/resources/catalog/entitlements.d.ts +422 -0
- package/dist/types/resources/catalog/index.d.ts +3155 -0
- package/dist/types/resources/catalog/meters.d.ts +474 -0
- package/dist/types/resources/catalog/prices.d.ts +1091 -0
- package/dist/types/resources/catalog/products.d.ts +430 -0
- package/dist/types/resources/catalog/promotionCodes.d.ts +369 -0
- package/dist/types/resources/catalog/shared.d.ts +34 -0
- package/dist/types/resources/catalog/testClocks.d.ts +220 -0
- package/dist/types/resources/checkout/checkoutSessions.d.ts +3207 -0
- package/dist/types/resources/checkout/contributions.d.ts +375 -0
- package/dist/types/resources/checkout/files.d.ts +280 -0
- package/dist/types/resources/checkout/index.d.ts +5678 -0
- package/dist/types/resources/checkout/merchants.d.ts +395 -0
- package/dist/types/resources/checkout/paymentLinks.d.ts +1728 -0
- package/dist/types/resources/checkout/paymentMethodConfigurations.d.ts +2104 -0
- package/dist/types/resources/checkout/shared.d.ts +419 -0
- package/dist/types/resources/connect/account.d.ts +483 -0
- package/dist/types/resources/connect/applicationFees.d.ts +198 -0
- package/dist/types/resources/connect/balance.d.ts +399 -0
- package/dist/types/resources/connect/connectedAccounts.d.ts +494 -0
- package/dist/types/resources/connect/index.d.ts +2094 -0
- package/dist/types/resources/connect/onboarding.d.ts +95 -0
- package/dist/types/resources/connect/payouts.d.ts +527 -0
- package/dist/types/resources/connect/reporting.d.ts +506 -0
- package/dist/types/resources/connect/requestLogs.d.ts +236 -0
- package/dist/types/resources/connect/transfers.d.ts +436 -0
- package/dist/types/resources/core/customers.d.ts +619 -0
- package/dist/types/resources/core/index.d.ts +679 -0
- package/dist/types/resources/core/paymentMethods.d.ts +336 -0
- package/dist/types/resources/events/events.d.ts +731 -0
- package/dist/types/resources/events/index.d.ts +1727 -0
- package/dist/types/resources/events/webhookDeliveries.d.ts +436 -0
- package/dist/types/resources/events/webhookEndpoints.d.ts +1502 -0
- package/dist/types/resources/payments/charges.d.ts +390 -0
- package/dist/types/resources/payments/disputes.d.ts +822 -0
- package/dist/types/resources/payments/index.d.ts +3517 -0
- package/dist/types/resources/payments/paymentIntents.d.ts +2080 -0
- package/dist/types/resources/payments/refunds.d.ts +684 -0
- package/dist/types/resources/payments/setupIntents.d.ts +391 -0
- package/dist/types/resources/payments/social.d.ts +266 -0
- package/dist/types/resources/payments/testHelpers.d.ts +178 -0
- package/dist/types/resources/tax/assessments.d.ts +787 -0
- package/dist/types/resources/tax/businessProfile.d.ts +134 -0
- package/dist/types/resources/tax/calculations.d.ts +261 -0
- package/dist/types/resources/tax/capabilities.d.ts +81 -0
- package/dist/types/resources/tax/codes.d.ts +29 -0
- package/dist/types/resources/tax/complianceActions.d.ts +97 -0
- package/dist/types/resources/tax/deadlines.d.ts +133 -0
- package/dist/types/resources/tax/documents.d.ts +257 -0
- package/dist/types/resources/tax/index.d.ts +1946 -0
- package/dist/types/resources/tax/locationEvidence.d.ts +246 -0
- package/dist/types/resources/tax/operatingLocations.d.ts +170 -0
- package/dist/types/resources/tax/products.d.ts +68 -0
- package/dist/types/resources/tax/registrationDeclarations.d.ts +270 -0
- package/dist/types/resources/tax/registrations.d.ts +103 -0
- package/dist/types/resources/tax/reports.d.ts +129 -0
- package/dist/types/resources/tax/reviewItems.d.ts +226 -0
- package/dist/types/resources/tax/ruleSet.d.ts +219 -0
- package/dist/types/resources/tax/salesDestinations.d.ts +158 -0
- package/dist/types/resources/tax/settings.d.ts +122 -0
- package/dist/types/resources/tax/shared.d.ts +43 -0
- package/dist/types/resources/tax/transactions.d.ts +404 -0
- package/dist/types/route.d.ts +86 -0
- package/dist/types/routes.d.ts +23 -0
- package/dist/types/vocabulary/billingPortal.d.ts +15 -0
- package/dist/types/vocabulary/catalog.d.ts +97 -0
- package/dist/types/vocabulary/checkout.d.ts +49 -0
- package/dist/types/vocabulary/connect.d.ts +62 -0
- package/dist/types/vocabulary/errors.d.ts +145 -0
- package/dist/types/vocabulary/events.d.ts +171 -0
- package/dist/types/vocabulary/files.d.ts +30 -0
- package/dist/types/vocabulary/index.d.ts +17 -0
- package/dist/types/vocabulary/invoices.d.ts +39 -0
- package/dist/types/vocabulary/lists.d.ts +9 -0
- package/dist/types/vocabulary/merchants.d.ts +9 -0
- package/dist/types/vocabulary/money.d.ts +59 -0
- package/dist/types/vocabulary/paymentMethodConfigurations.d.ts +22 -0
- package/dist/types/vocabulary/payments.d.ts +117 -0
- package/dist/types/vocabulary/reporting.d.ts +18 -0
- package/dist/types/vocabulary/subscriptions.d.ts +45 -0
- package/dist/types/vocabulary/tax.d.ts +163 -0
- package/dist/types/vocabulary/version.d.ts +10 -0
- package/package.json +51 -11
- package/dist/cjs/openapi.js +0 -138
- package/dist/esm/openapi.js +0 -134
- package/dist/types/openapi.d.ts +0 -145
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { PAYMENT_INTENT_RAILS } from '../../vocabulary/payments.js';
|
|
3
|
+
import { addressSchema } from '../../common/address.js';
|
|
4
|
+
import { defineComponent, defineObject, expandable } from '../../common/objects.js';
|
|
5
|
+
import { amount, currency } from '../../common/primitives.js';
|
|
6
|
+
import { CHECKOUT_BILLING_ADDRESS_COLLECTIONS, CHECKOUT_CUSTOM_FIELD_TYPES, CHECKOUT_LIMITS, CHECKOUT_LOCALES, CHECKOUT_SESSION_ID_TEMPLATE, CHECKOUT_TAX_ID_TYPES, } from '../../vocabulary/checkout.js';
|
|
7
|
+
import { BRANDING_BORDER_STYLES, BRANDING_FONTS } from '../../vocabulary/merchants.js';
|
|
8
|
+
import { BASE_UNIT_PATTERN } from '../../vocabulary/money.js';
|
|
9
|
+
/**
|
|
10
|
+
* What Checkout Sessions and Payment Links share: the `item` a line renders
|
|
11
|
+
* as, the collection options (address, phone, tax id, terms, custom fields),
|
|
12
|
+
* the payer-facing merchant and branding, and the request halves of those.
|
|
13
|
+
* One shape rule is written once, so a link and a session refuse the same
|
|
14
|
+
* mistake with the same `param`.
|
|
15
|
+
*/
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Response side
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
/** The payment rail: FairCoin on chain, or a card (and the methods riding on it). */
|
|
20
|
+
export const railSchema = z.enum(PAYMENT_INTENT_RAILS);
|
|
21
|
+
export const checkoutAdjustableQuantitySchema = defineComponent('CheckoutAdjustableQuantity', z
|
|
22
|
+
.object({
|
|
23
|
+
enabled: z.boolean(),
|
|
24
|
+
minimum: z.number().int().nullable().describe('Default 0 when enabled.'),
|
|
25
|
+
maximum: z.number().int().nullable().describe('Default 99 when enabled.'),
|
|
26
|
+
})
|
|
27
|
+
.strict());
|
|
28
|
+
/** One line of a session or link — Stripe's `item`. */
|
|
29
|
+
export const checkoutLineItemSchema = defineObject('item', 'CheckoutLineItem', z
|
|
30
|
+
.object({
|
|
31
|
+
id: z.string(),
|
|
32
|
+
object: z.literal('item'),
|
|
33
|
+
description: z.string().describe("The product's name, or the inline `product_data.name`."),
|
|
34
|
+
price: expandable('price', 'The catalog price (`price_…`, or the Price with `expand[]=data.price`); `null` for an inline `price_data` line, which is a snapshot on the line and never a stored price.').nullable(),
|
|
35
|
+
product: expandable('product', 'The catalog product (`prod_…`, expandable); `null` for `product_data`.').nullable(),
|
|
36
|
+
images: z
|
|
37
|
+
.array(z.string())
|
|
38
|
+
.describe("Images to show beside the line (the product's, or `product_data.images`)."),
|
|
39
|
+
quantity: z.number().int(),
|
|
40
|
+
adjustable_quantity: checkoutAdjustableQuantitySchema.nullable(),
|
|
41
|
+
currency,
|
|
42
|
+
unit_amount: amount
|
|
43
|
+
.nullable()
|
|
44
|
+
.describe('The per-unit amount for a per-unit price; `null` for a tiered one.'),
|
|
45
|
+
amount_subtotal: amount.describe('Before discount and tax.'),
|
|
46
|
+
amount_discount: amount,
|
|
47
|
+
amount_tax: amount,
|
|
48
|
+
amount_total: amount.describe('`amount_subtotal - amount_discount + amount_tax` (exclusive tax only).'),
|
|
49
|
+
})
|
|
50
|
+
.strict(), {
|
|
51
|
+
examples: [
|
|
52
|
+
{
|
|
53
|
+
id: 'li_0193b8f2c1a87d3e9f4a',
|
|
54
|
+
object: 'item',
|
|
55
|
+
description: 'Pro plan',
|
|
56
|
+
price: 'price_0193b8f2c1a87d3e9f4b',
|
|
57
|
+
product: 'prod_0193b8f2c1a87d3e9f4c',
|
|
58
|
+
images: [],
|
|
59
|
+
quantity: 1,
|
|
60
|
+
adjustable_quantity: null,
|
|
61
|
+
currency: 'EUR',
|
|
62
|
+
unit_amount: '1999',
|
|
63
|
+
amount_subtotal: '1999',
|
|
64
|
+
amount_discount: '0',
|
|
65
|
+
amount_tax: '0',
|
|
66
|
+
amount_total: '1999',
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
});
|
|
70
|
+
export const checkoutTaxIdSchema = defineComponent('CheckoutTaxId', z.object({ type: z.enum(CHECKOUT_TAX_ID_TYPES), value: z.string() }).strict());
|
|
71
|
+
/** What the payer told checkout about themselves — Stripe's `customer_details`. */
|
|
72
|
+
export const checkoutCustomerDetailsSchema = defineComponent('CheckoutCustomerDetails', z
|
|
73
|
+
.object({
|
|
74
|
+
email: z.string().nullable(),
|
|
75
|
+
name: z.string().nullable(),
|
|
76
|
+
phone: z.string().nullable(),
|
|
77
|
+
address: addressSchema.nullable(),
|
|
78
|
+
tax_ids: z.array(checkoutTaxIdSchema),
|
|
79
|
+
})
|
|
80
|
+
.strict());
|
|
81
|
+
export const checkoutShippingDetailsSchema = defineComponent('CheckoutShippingDetails', z.object({ name: z.string(), address: addressSchema }).strict());
|
|
82
|
+
export const checkoutCustomFieldLabelSchema = z
|
|
83
|
+
.object({ type: z.literal('custom'), custom: z.string() })
|
|
84
|
+
.strict();
|
|
85
|
+
export const checkoutCustomFieldDropdownOptionSchema = z
|
|
86
|
+
.object({ label: z.string(), value: z.string() })
|
|
87
|
+
.strict();
|
|
88
|
+
const customFieldBounds = z
|
|
89
|
+
.object({
|
|
90
|
+
minimum_length: z.number().int().nullable(),
|
|
91
|
+
maximum_length: z.number().int().nullable(),
|
|
92
|
+
value: z.string().nullable().describe('What the payer entered.'),
|
|
93
|
+
})
|
|
94
|
+
.strict();
|
|
95
|
+
/** A merchant-defined field the payer fills in; `value`s are what they entered. */
|
|
96
|
+
export const checkoutCustomFieldSchema = defineComponent('CheckoutCustomField', z
|
|
97
|
+
.object({
|
|
98
|
+
key: z.string(),
|
|
99
|
+
label: checkoutCustomFieldLabelSchema,
|
|
100
|
+
type: z.enum(CHECKOUT_CUSTOM_FIELD_TYPES),
|
|
101
|
+
optional: z.boolean(),
|
|
102
|
+
dropdown: z
|
|
103
|
+
.object({
|
|
104
|
+
options: z.array(checkoutCustomFieldDropdownOptionSchema),
|
|
105
|
+
value: z.string().nullable(),
|
|
106
|
+
})
|
|
107
|
+
.strict()
|
|
108
|
+
.nullable(),
|
|
109
|
+
text: customFieldBounds.nullable(),
|
|
110
|
+
numeric: customFieldBounds.nullable(),
|
|
111
|
+
})
|
|
112
|
+
.strict());
|
|
113
|
+
export const checkoutDiscountSchema = defineComponent('CheckoutDiscount', z
|
|
114
|
+
.object({
|
|
115
|
+
coupon: z.string().describe('The coupon applied (merchant-chosen id or `coupon_…`).'),
|
|
116
|
+
promotion_code: z
|
|
117
|
+
.string()
|
|
118
|
+
.nullable()
|
|
119
|
+
.describe('The promotion code it was redeemed through (`promo_…`), or `null`.'),
|
|
120
|
+
})
|
|
121
|
+
.strict());
|
|
122
|
+
export const checkoutTotalDetailsSchema = defineComponent('CheckoutTotalDetails', z.object({ amount_discount: amount, amount_tax: amount, amount_shipping: amount }).strict());
|
|
123
|
+
/**
|
|
124
|
+
* `automatic_tax` — Peable Tax (ADR 0011). `requires_location_inputs` until
|
|
125
|
+
* the payer gave an address Peable Tax can locate them with; `failed` when the
|
|
126
|
+
* sale is covered and could not be priced (checkout refuses to proceed: tax
|
|
127
|
+
* fails CLOSED, never zero).
|
|
128
|
+
*/
|
|
129
|
+
export const checkoutAutomaticTaxSchema = defineComponent('CheckoutAutomaticTax', z
|
|
130
|
+
.object({
|
|
131
|
+
enabled: z.boolean(),
|
|
132
|
+
status: z.enum(['complete', 'requires_location_inputs', 'failed']).nullable(),
|
|
133
|
+
})
|
|
134
|
+
.strict());
|
|
135
|
+
export const checkoutConsentCollectionSchema = z
|
|
136
|
+
.object({ terms_of_service: z.enum(['none', 'required']) })
|
|
137
|
+
.strict();
|
|
138
|
+
export const checkoutConsentSchema = z
|
|
139
|
+
.object({ terms_of_service: z.literal('accepted').nullable() })
|
|
140
|
+
.strict();
|
|
141
|
+
/** The collection options, as a session or link reports them. */
|
|
142
|
+
export const collectionResponseFields = {
|
|
143
|
+
billing_address_collection: z.enum(CHECKOUT_BILLING_ADDRESS_COLLECTIONS),
|
|
144
|
+
shipping_address_collection: z
|
|
145
|
+
.object({ allowed_countries: z.array(z.string()) })
|
|
146
|
+
.strict()
|
|
147
|
+
.nullable(),
|
|
148
|
+
phone_number_collection: z.object({ enabled: z.boolean() }).strict(),
|
|
149
|
+
tax_id_collection: z.object({ enabled: z.boolean() }).strict(),
|
|
150
|
+
custom_fields: z.array(checkoutCustomFieldSchema),
|
|
151
|
+
consent_collection: checkoutConsentCollectionSchema.nullable(),
|
|
152
|
+
};
|
|
153
|
+
/** The public, secret-free merchant identity a payer surface renders. */
|
|
154
|
+
export const merchantDisplaySchema = defineComponent('MerchantDisplay', z
|
|
155
|
+
.object({
|
|
156
|
+
name: z.string().describe("The merchant's display name, or a neutral fallback when unset."),
|
|
157
|
+
avatar_url: z
|
|
158
|
+
.string()
|
|
159
|
+
.nullable()
|
|
160
|
+
.describe('Resolved server-side; `null` when the merchant has no avatar.'),
|
|
161
|
+
logo_url: z
|
|
162
|
+
.string()
|
|
163
|
+
.nullable()
|
|
164
|
+
.describe("The merchant's `business_logo`, resolved; `null` when unset or not served."),
|
|
165
|
+
description: z.string().nullable(),
|
|
166
|
+
})
|
|
167
|
+
.strict());
|
|
168
|
+
/**
|
|
169
|
+
* Branding as a payer surface renders it: every field resolved (defaults
|
|
170
|
+
* filled in), the logo and icon as URLs the gateway built through Oxy's media
|
|
171
|
+
* chokepoint — a withheld file is `null`, never a broken image.
|
|
172
|
+
*/
|
|
173
|
+
export const checkoutBrandingSchema = defineComponent('CheckoutBranding', z
|
|
174
|
+
.object({
|
|
175
|
+
icon_url: z.string().nullable(),
|
|
176
|
+
logo_url: z.string().nullable(),
|
|
177
|
+
primary_color: z.string(),
|
|
178
|
+
accent_color: z.string(),
|
|
179
|
+
font: z.enum(BRANDING_FONTS),
|
|
180
|
+
border_style: z.enum(BRANDING_BORDER_STYLES),
|
|
181
|
+
})
|
|
182
|
+
.strict());
|
|
183
|
+
// ---------------------------------------------------------------------------
|
|
184
|
+
// Request side
|
|
185
|
+
// ---------------------------------------------------------------------------
|
|
186
|
+
export const checkoutIdParam = z.string().min(1).max(255);
|
|
187
|
+
export const countryCodeParam = z
|
|
188
|
+
.string()
|
|
189
|
+
.regex(/^[A-Z]{2}$/, 'must be an ISO 3166-1 alpha-2 country code');
|
|
190
|
+
/** A base-unit amount in a request. */
|
|
191
|
+
export const amountParam = z
|
|
192
|
+
.string()
|
|
193
|
+
.regex(BASE_UNIT_PATTERN, 'must be a non-negative integer string in the smallest currency unit');
|
|
194
|
+
/**
|
|
195
|
+
* A redirect target. `https` only, except `http://localhost` for development —
|
|
196
|
+
* a payer is sent there after paying, so an `http` URL elsewhere would leak the
|
|
197
|
+
* session id in the clear. `{CHECKOUT_SESSION_ID}` may appear anywhere.
|
|
198
|
+
*/
|
|
199
|
+
export const redirectUrlParam = z
|
|
200
|
+
.string()
|
|
201
|
+
.max(2048)
|
|
202
|
+
.refine((value) => {
|
|
203
|
+
const probe = value.split(CHECKOUT_SESSION_ID_TEMPLATE).join('cs_template');
|
|
204
|
+
try {
|
|
205
|
+
const url = new URL(probe);
|
|
206
|
+
return (url.protocol === 'https:' ||
|
|
207
|
+
(url.protocol === 'http:' && (url.hostname === 'localhost' || url.hostname === '127.0.0.1')));
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
}, 'must be an https URL (http only on localhost)')
|
|
213
|
+
.describe('`https` (or `http://localhost`); may carry `{CHECKOUT_SESSION_ID}`.');
|
|
214
|
+
/** `auto` follows the payer's browser: parsed as `null`. */
|
|
215
|
+
export const localeParam = z
|
|
216
|
+
.enum([...CHECKOUT_LOCALES, 'auto'])
|
|
217
|
+
.transform((value) => (value === 'auto' ? null : value))
|
|
218
|
+
.describe("`auto` follows the payer's browser.");
|
|
219
|
+
export const checkoutEmailParam = z.string().trim().max(254).email('must be an email address');
|
|
220
|
+
const customFieldParam = z
|
|
221
|
+
.object({
|
|
222
|
+
key: z
|
|
223
|
+
.string()
|
|
224
|
+
.regex(new RegExp(`^[A-Za-z0-9_]{1,${CHECKOUT_LIMITS.customFieldKeyMax}}$`), 'a key is letters, digits and underscores'),
|
|
225
|
+
label: z
|
|
226
|
+
.object({
|
|
227
|
+
type: z.literal('custom'),
|
|
228
|
+
custom: z.string().trim().min(1).max(CHECKOUT_LIMITS.customFieldLabelMax),
|
|
229
|
+
})
|
|
230
|
+
.strict(),
|
|
231
|
+
type: z.enum(CHECKOUT_CUSTOM_FIELD_TYPES),
|
|
232
|
+
optional: z.boolean().optional(),
|
|
233
|
+
dropdown: z
|
|
234
|
+
.object({
|
|
235
|
+
options: z
|
|
236
|
+
.array(z
|
|
237
|
+
.object({
|
|
238
|
+
label: z.string().trim().min(1).max(CHECKOUT_LIMITS.dropdownOptionLabelMax),
|
|
239
|
+
value: z
|
|
240
|
+
.string()
|
|
241
|
+
.regex(new RegExp(`^[A-Za-z0-9]{1,${CHECKOUT_LIMITS.dropdownOptionValueMax}}$`), 'an option value is letters and digits'),
|
|
242
|
+
})
|
|
243
|
+
.strict())
|
|
244
|
+
.min(1)
|
|
245
|
+
.max(CHECKOUT_LIMITS.dropdownOptionsMax),
|
|
246
|
+
})
|
|
247
|
+
.strict()
|
|
248
|
+
.optional(),
|
|
249
|
+
text: z
|
|
250
|
+
.object({
|
|
251
|
+
minimum_length: z.number().int().min(1).max(CHECKOUT_LIMITS.customFieldTextMax).optional(),
|
|
252
|
+
maximum_length: z.number().int().min(1).max(CHECKOUT_LIMITS.customFieldTextMax).optional(),
|
|
253
|
+
})
|
|
254
|
+
.strict()
|
|
255
|
+
.optional(),
|
|
256
|
+
numeric: z
|
|
257
|
+
.object({
|
|
258
|
+
minimum_length: z.number().int().min(1).max(CHECKOUT_LIMITS.customFieldTextMax).optional(),
|
|
259
|
+
maximum_length: z.number().int().min(1).max(CHECKOUT_LIMITS.customFieldTextMax).optional(),
|
|
260
|
+
})
|
|
261
|
+
.strict()
|
|
262
|
+
.optional(),
|
|
263
|
+
})
|
|
264
|
+
.strict()
|
|
265
|
+
.superRefine((field, ctx) => {
|
|
266
|
+
const issue = (path, message) => ctx.addIssue({ code: 'custom', path, message });
|
|
267
|
+
if (field.type === 'dropdown' && !field.dropdown) {
|
|
268
|
+
issue(['dropdown'], 'a dropdown field needs dropdown.options');
|
|
269
|
+
}
|
|
270
|
+
if (field.type !== 'dropdown' && field.dropdown) {
|
|
271
|
+
issue(['dropdown'], 'dropdown is only for a dropdown field');
|
|
272
|
+
}
|
|
273
|
+
if (field.type !== 'text' && field.text)
|
|
274
|
+
issue(['text'], 'text is only for a text field');
|
|
275
|
+
if (field.type !== 'numeric' && field.numeric) {
|
|
276
|
+
issue(['numeric'], 'numeric is only for a numeric field');
|
|
277
|
+
}
|
|
278
|
+
const bounds = field.text ?? field.numeric;
|
|
279
|
+
if (bounds?.minimum_length !== undefined &&
|
|
280
|
+
bounds.maximum_length !== undefined &&
|
|
281
|
+
bounds.minimum_length > bounds.maximum_length) {
|
|
282
|
+
issue([field.type, 'minimum_length'], 'minimum_length cannot exceed maximum_length');
|
|
283
|
+
}
|
|
284
|
+
if (field.dropdown) {
|
|
285
|
+
const values = field.dropdown.options.map((option) => option.value);
|
|
286
|
+
if (new Set(values).size !== values.length) {
|
|
287
|
+
issue(['dropdown', 'options'], 'option values must be unique');
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
/** At most three, keys unique. */
|
|
292
|
+
export const customFieldsParam = z
|
|
293
|
+
.array(customFieldParam)
|
|
294
|
+
.max(CHECKOUT_LIMITS.customFieldsMax)
|
|
295
|
+
.superRefine((fields, ctx) => {
|
|
296
|
+
const keys = fields.map((field) => field.key);
|
|
297
|
+
if (new Set(keys).size !== keys.length) {
|
|
298
|
+
ctx.addIssue({ code: 'custom', message: 'custom field keys must be unique' });
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
/** The collection options, as a request names them — shared by sessions and links. */
|
|
302
|
+
export const collectionParams = {
|
|
303
|
+
billing_address_collection: z.enum(CHECKOUT_BILLING_ADDRESS_COLLECTIONS).optional(),
|
|
304
|
+
shipping_address_collection: z
|
|
305
|
+
.object({
|
|
306
|
+
allowed_countries: z.array(countryCodeParam).min(1).max(CHECKOUT_LIMITS.shippingCountriesMax),
|
|
307
|
+
})
|
|
308
|
+
.strict()
|
|
309
|
+
.optional(),
|
|
310
|
+
phone_number_collection: z.object({ enabled: z.boolean() }).strict().optional(),
|
|
311
|
+
tax_id_collection: z.object({ enabled: z.boolean() }).strict().optional(),
|
|
312
|
+
consent_collection: z
|
|
313
|
+
.object({ terms_of_service: z.enum(['none', 'required']).optional() })
|
|
314
|
+
.strict()
|
|
315
|
+
.optional(),
|
|
316
|
+
custom_fields: customFieldsParam.optional(),
|
|
317
|
+
};
|
|
318
|
+
export const adjustableQuantityParam = z
|
|
319
|
+
.object({
|
|
320
|
+
enabled: z.boolean(),
|
|
321
|
+
minimum: z.number().int().min(0).max(CHECKOUT_LIMITS.quantityMax).optional(),
|
|
322
|
+
maximum: z.number().int().min(1).max(CHECKOUT_LIMITS.quantityMax).optional(),
|
|
323
|
+
})
|
|
324
|
+
.strict();
|
|
325
|
+
export const quantityParam = z.number().int().min(1).max(CHECKOUT_LIMITS.quantityMax);
|
|
326
|
+
/** Stripe's defaults: 0–99 when enabled. */
|
|
327
|
+
export function adjustableBoundsOf(adjustable) {
|
|
328
|
+
if (!adjustable?.enabled)
|
|
329
|
+
return null;
|
|
330
|
+
return { minimum: adjustable.minimum ?? 0, maximum: adjustable.maximum ?? 99 };
|
|
331
|
+
}
|
|
332
|
+
/** The refusals of a line's `quantity` against its `adjustable_quantity`. */
|
|
333
|
+
export function adjustableIssues(quantity, adjustable, ctx) {
|
|
334
|
+
if (!adjustable)
|
|
335
|
+
return;
|
|
336
|
+
if (!adjustable.enabled) {
|
|
337
|
+
if (adjustable.minimum !== undefined || adjustable.maximum !== undefined) {
|
|
338
|
+
ctx.addIssue({
|
|
339
|
+
code: 'custom',
|
|
340
|
+
path: ['adjustable_quantity', 'enabled'],
|
|
341
|
+
message: 'minimum and maximum need adjustable_quantity.enabled',
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
const bounds = adjustableBoundsOf(adjustable);
|
|
347
|
+
if (!bounds)
|
|
348
|
+
return;
|
|
349
|
+
if (bounds.minimum > bounds.maximum) {
|
|
350
|
+
ctx.addIssue({
|
|
351
|
+
code: 'custom',
|
|
352
|
+
path: ['adjustable_quantity', 'minimum'],
|
|
353
|
+
message: 'minimum cannot exceed maximum',
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
else if (quantity < bounds.minimum || quantity > bounds.maximum) {
|
|
357
|
+
ctx.addIssue({
|
|
358
|
+
code: 'custom',
|
|
359
|
+
path: ['quantity'],
|
|
360
|
+
message: `quantity must be between ${bounds.minimum} and ${bounds.maximum}`,
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
}
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { defineComponent, defineObject } from '../../common/objects.js';
|
|
3
|
+
import { expandOnlyQuery } from '../../common/params.js';
|
|
4
|
+
import { livemode, unixSeconds } from '../../common/primitives.js';
|
|
5
|
+
import { defineRoute } from '../../route.js';
|
|
6
|
+
import { ACCOUNT_BUSINESS_TYPES, ACCOUNT_CAPABILITY_STATUSES, ACCOUNT_LINK_TYPES, ACCOUNT_TYPES, PAYOUT_INTERVALS, PAYOUT_WEEKLY_ANCHORS, } from '../../vocabulary/connect.js';
|
|
7
|
+
/**
|
|
8
|
+
* The merchant's fiat account (ADR 0015 §1) — `GET /v1/account`.
|
|
9
|
+
*
|
|
10
|
+
* Orbit's funds never reach a Peable bank account: a merchant that takes fiat
|
|
11
|
+
* has its OWN provider account, opened and onboarded through Peable, and this
|
|
12
|
+
* object mirrors it. Everything here is what the provider last reported; the
|
|
13
|
+
* provider is the authority and Orbit never decides readiness itself. The
|
|
14
|
+
* provider's own `acct_…` never crosses (ADR 0016 D2).
|
|
15
|
+
*
|
|
16
|
+
* A marketplace's sellers (`/v1/connected_accounts`) are provider accounts too,
|
|
17
|
+
* and a platform reads one of them in this same shape by sending
|
|
18
|
+
* `Peable-Account: ca_…` to `GET /v1/account`.
|
|
19
|
+
*/
|
|
20
|
+
const capabilityStatus = z.enum(ACCOUNT_CAPABILITY_STATUSES);
|
|
21
|
+
/**
|
|
22
|
+
* What the provider is waiting on. Requirement IDENTIFIERS only
|
|
23
|
+
* (`individual.verification.document`), never their values: the gateway
|
|
24
|
+
* records that a document is owed and never learns what it says.
|
|
25
|
+
*/
|
|
26
|
+
export const accountRequirementsSchema = defineComponent('AccountRequirements', z
|
|
27
|
+
.object({
|
|
28
|
+
currently_due: z.array(z.string()),
|
|
29
|
+
eventually_due: z.array(z.string()),
|
|
30
|
+
past_due: z.array(z.string()),
|
|
31
|
+
pending_verification: z
|
|
32
|
+
.array(z.string())
|
|
33
|
+
.describe('Submitted and being checked — nothing for the merchant to do.'),
|
|
34
|
+
disabled_reason: z
|
|
35
|
+
.string()
|
|
36
|
+
.nullable()
|
|
37
|
+
.describe("Why charges or payouts are disabled, in the provider's own code, or `null`."),
|
|
38
|
+
})
|
|
39
|
+
.strict());
|
|
40
|
+
export const accountBusinessProfileSchema = defineComponent('AccountBusinessProfile', z
|
|
41
|
+
.object({
|
|
42
|
+
name: z.string().nullable(),
|
|
43
|
+
url: z.string().nullable(),
|
|
44
|
+
support_email: z.string().nullable(),
|
|
45
|
+
support_url: z.string().nullable(),
|
|
46
|
+
product_description: z.string().nullable(),
|
|
47
|
+
mcc: z.string().nullable().describe('Merchant category code.'),
|
|
48
|
+
})
|
|
49
|
+
.strict());
|
|
50
|
+
/**
|
|
51
|
+
* When the provider pays the balance out. `manual` means only an explicit
|
|
52
|
+
* `POST /v1/payouts` does — the provider still executes it; Orbit never moves
|
|
53
|
+
* the money itself (ADR 0015 §4).
|
|
54
|
+
*/
|
|
55
|
+
export const accountPayoutScheduleSchema = defineComponent('AccountPayoutSchedule', z
|
|
56
|
+
.object({
|
|
57
|
+
interval: z.enum(PAYOUT_INTERVALS),
|
|
58
|
+
delay_days: z
|
|
59
|
+
.number()
|
|
60
|
+
.int()
|
|
61
|
+
.nullable()
|
|
62
|
+
.describe('Days between a payment and its funds becoming payable; `null` when not reported.'),
|
|
63
|
+
weekly_anchor: z.enum(PAYOUT_WEEKLY_ANCHORS).nullable().describe('`weekly` only.'),
|
|
64
|
+
monthly_anchor: z
|
|
65
|
+
.number()
|
|
66
|
+
.int()
|
|
67
|
+
.nullable()
|
|
68
|
+
.describe('`monthly` only: the day of the month, 1–31.'),
|
|
69
|
+
})
|
|
70
|
+
.strict());
|
|
71
|
+
export const accountSettingsSchema = defineComponent('AccountSettings', z
|
|
72
|
+
.object({
|
|
73
|
+
payouts: z
|
|
74
|
+
.object({
|
|
75
|
+
schedule: accountPayoutScheduleSchema.nullable(),
|
|
76
|
+
statement_descriptor: z
|
|
77
|
+
.string()
|
|
78
|
+
.nullable()
|
|
79
|
+
.describe("What the merchant's bank statement shows for a payout."),
|
|
80
|
+
})
|
|
81
|
+
.strict(),
|
|
82
|
+
payments: z
|
|
83
|
+
.object({
|
|
84
|
+
statement_descriptor: z
|
|
85
|
+
.string()
|
|
86
|
+
.nullable()
|
|
87
|
+
.describe("What a cardholder's statement shows — the merchant is the merchant of record."),
|
|
88
|
+
})
|
|
89
|
+
.strict(),
|
|
90
|
+
branding: z
|
|
91
|
+
.object({
|
|
92
|
+
primary_color: z.string().nullable(),
|
|
93
|
+
secondary_color: z.string().nullable(),
|
|
94
|
+
})
|
|
95
|
+
.strict(),
|
|
96
|
+
})
|
|
97
|
+
.strict());
|
|
98
|
+
export const accountSchema = defineObject('account', 'Account', z
|
|
99
|
+
.object({
|
|
100
|
+
id: z.string().describe('`ca_…` — the same id space as a marketplace seller.'),
|
|
101
|
+
object: z.literal('account'),
|
|
102
|
+
livemode,
|
|
103
|
+
type: z.enum(ACCOUNT_TYPES),
|
|
104
|
+
country: z.string().describe('ISO 3166-1 alpha-2. Fixed at the provider once created.'),
|
|
105
|
+
default_currency: z.string().nullable(),
|
|
106
|
+
business_profile: accountBusinessProfileSchema,
|
|
107
|
+
capabilities: z
|
|
108
|
+
.object({
|
|
109
|
+
card_payments: capabilityStatus.nullable(),
|
|
110
|
+
transfers: capabilityStatus.nullable(),
|
|
111
|
+
})
|
|
112
|
+
.strict()
|
|
113
|
+
.describe('`null`: never requested — a different fact from the provider declining it.'),
|
|
114
|
+
requirements: accountRequirementsSchema,
|
|
115
|
+
charges_enabled: z
|
|
116
|
+
.boolean()
|
|
117
|
+
.describe('Whether the account can take payments as merchant of record (`on_behalf_of`).'),
|
|
118
|
+
payouts_enabled: z
|
|
119
|
+
.boolean()
|
|
120
|
+
.describe("Whether the provider will pay this account's balance out."),
|
|
121
|
+
settings: accountSettingsSchema,
|
|
122
|
+
last_synced_at: unixSeconds
|
|
123
|
+
.nullable()
|
|
124
|
+
.describe('The last provider read; `null` before the first one completed.'),
|
|
125
|
+
created: unixSeconds,
|
|
126
|
+
})
|
|
127
|
+
.strict(), {
|
|
128
|
+
examples: [
|
|
129
|
+
{
|
|
130
|
+
id: 'ca_0193b8f2c1a87d3e9f4a',
|
|
131
|
+
object: 'account',
|
|
132
|
+
livemode: false,
|
|
133
|
+
type: 'merchant',
|
|
134
|
+
country: 'ES',
|
|
135
|
+
default_currency: 'EUR',
|
|
136
|
+
business_profile: {
|
|
137
|
+
name: 'Rosen Ceramics',
|
|
138
|
+
url: 'https://rosen.example',
|
|
139
|
+
support_email: 'help@rosen.example',
|
|
140
|
+
support_url: null,
|
|
141
|
+
product_description: 'Handmade tableware',
|
|
142
|
+
mcc: '5719',
|
|
143
|
+
},
|
|
144
|
+
capabilities: { card_payments: 'active', transfers: 'active' },
|
|
145
|
+
requirements: {
|
|
146
|
+
currently_due: [],
|
|
147
|
+
eventually_due: [],
|
|
148
|
+
past_due: [],
|
|
149
|
+
pending_verification: [],
|
|
150
|
+
disabled_reason: null,
|
|
151
|
+
},
|
|
152
|
+
charges_enabled: true,
|
|
153
|
+
payouts_enabled: true,
|
|
154
|
+
settings: {
|
|
155
|
+
payouts: {
|
|
156
|
+
schedule: {
|
|
157
|
+
interval: 'weekly',
|
|
158
|
+
delay_days: 7,
|
|
159
|
+
weekly_anchor: 'friday',
|
|
160
|
+
monthly_anchor: null,
|
|
161
|
+
},
|
|
162
|
+
statement_descriptor: 'ROSEN CERAMICS',
|
|
163
|
+
},
|
|
164
|
+
payments: { statement_descriptor: 'ROSEN CERAMICS' },
|
|
165
|
+
branding: { primary_color: '#1f2937', secondary_color: null },
|
|
166
|
+
},
|
|
167
|
+
last_synced_at: 1793750460,
|
|
168
|
+
created: 1793750400,
|
|
169
|
+
},
|
|
170
|
+
],
|
|
171
|
+
});
|
|
172
|
+
/**
|
|
173
|
+
* A hosted onboarding link — the merchant's own account's
|
|
174
|
+
* (`POST /v1/account_links`) or a seller's
|
|
175
|
+
* (`POST /v1/connected_accounts/{accountId}/account_links`). Single-use and
|
|
176
|
+
* short-lived: mint one when the person is about to open it, never store it.
|
|
177
|
+
*/
|
|
178
|
+
export const accountLinkSchema = defineObject('account_link', 'AccountLink', z
|
|
179
|
+
.object({
|
|
180
|
+
object: z.literal('account_link'),
|
|
181
|
+
livemode,
|
|
182
|
+
url: z.string().describe('Where to send the person. Single use.'),
|
|
183
|
+
expires_at: unixSeconds.describe('When the link stops working (minutes, not days).'),
|
|
184
|
+
})
|
|
185
|
+
.strict(), {
|
|
186
|
+
examples: [
|
|
187
|
+
{
|
|
188
|
+
object: 'account_link',
|
|
189
|
+
livemode: false,
|
|
190
|
+
url: 'https://connect.peable.to/onboarding/Zk3s9v…',
|
|
191
|
+
expires_at: 1793750700,
|
|
192
|
+
},
|
|
193
|
+
],
|
|
194
|
+
});
|
|
195
|
+
/** A statement descriptor: what a bank or card statement shows. */
|
|
196
|
+
const statementDescriptor = z
|
|
197
|
+
.string()
|
|
198
|
+
.min(5)
|
|
199
|
+
.max(22)
|
|
200
|
+
.regex(/^[^<>\\'"*]*$/, 'a statement descriptor may not contain < > \\ \' " *');
|
|
201
|
+
const hexColor = z.string().regex(/^#[0-9a-fA-F]{6}$/);
|
|
202
|
+
/**
|
|
203
|
+
* `POST /v1/account`: the account's settings, written to the provider and read
|
|
204
|
+
* back. `country` + `business_type` OPEN the account the first time (when the
|
|
205
|
+
* merchant has none) and are refused afterwards — a provider account's country
|
|
206
|
+
* cannot change.
|
|
207
|
+
*/
|
|
208
|
+
export const updateAccountParams = z
|
|
209
|
+
.object({
|
|
210
|
+
country: z.string().length(2).optional(),
|
|
211
|
+
business_type: z.enum(ACCOUNT_BUSINESS_TYPES).optional(),
|
|
212
|
+
business_profile: z
|
|
213
|
+
.object({
|
|
214
|
+
name: z.string().min(1).max(200).optional(),
|
|
215
|
+
url: z.url().max(2048).optional(),
|
|
216
|
+
support_email: z.email().max(320).optional(),
|
|
217
|
+
support_url: z.url().max(2048).optional(),
|
|
218
|
+
product_description: z.string().max(1000).optional(),
|
|
219
|
+
mcc: z
|
|
220
|
+
.string()
|
|
221
|
+
.regex(/^[0-9]{4}$/)
|
|
222
|
+
.optional(),
|
|
223
|
+
})
|
|
224
|
+
.strict()
|
|
225
|
+
.optional(),
|
|
226
|
+
settings: z
|
|
227
|
+
.object({
|
|
228
|
+
payouts: z
|
|
229
|
+
.object({
|
|
230
|
+
schedule: z
|
|
231
|
+
.object({
|
|
232
|
+
interval: z.enum(PAYOUT_INTERVALS),
|
|
233
|
+
delay_days: z.number().int().min(1).max(365).optional(),
|
|
234
|
+
weekly_anchor: z.enum(PAYOUT_WEEKLY_ANCHORS).optional(),
|
|
235
|
+
monthly_anchor: z.number().int().min(1).max(31).optional(),
|
|
236
|
+
})
|
|
237
|
+
.strict()
|
|
238
|
+
.superRefine((schedule, ctx) => {
|
|
239
|
+
if (schedule.weekly_anchor !== undefined && schedule.interval !== 'weekly') {
|
|
240
|
+
ctx.addIssue({
|
|
241
|
+
code: 'custom',
|
|
242
|
+
path: ['weekly_anchor'],
|
|
243
|
+
message: 'weekly_anchor is for a weekly schedule',
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
if (schedule.monthly_anchor !== undefined && schedule.interval !== 'monthly') {
|
|
247
|
+
ctx.addIssue({
|
|
248
|
+
code: 'custom',
|
|
249
|
+
path: ['monthly_anchor'],
|
|
250
|
+
message: 'monthly_anchor is for a monthly schedule',
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
})
|
|
254
|
+
.optional(),
|
|
255
|
+
statement_descriptor: statementDescriptor.optional(),
|
|
256
|
+
})
|
|
257
|
+
.strict()
|
|
258
|
+
.optional(),
|
|
259
|
+
payments: z
|
|
260
|
+
.object({ statement_descriptor: statementDescriptor.optional() })
|
|
261
|
+
.strict()
|
|
262
|
+
.optional(),
|
|
263
|
+
branding: z
|
|
264
|
+
.object({
|
|
265
|
+
primary_color: hexColor.optional(),
|
|
266
|
+
secondary_color: hexColor.optional(),
|
|
267
|
+
})
|
|
268
|
+
.strict()
|
|
269
|
+
.optional(),
|
|
270
|
+
})
|
|
271
|
+
.strict()
|
|
272
|
+
.optional(),
|
|
273
|
+
})
|
|
274
|
+
.strict();
|
|
275
|
+
/** `POST /v1/account_links`: hosted onboarding (or an update of what was submitted). */
|
|
276
|
+
export const createAccountLinkParams = z
|
|
277
|
+
.object({
|
|
278
|
+
refresh_url: z.url().describe('Where the person goes when the link has expired.'),
|
|
279
|
+
return_url: z.url().describe('Where the person returns when they leave the flow.'),
|
|
280
|
+
type: z.enum(ACCOUNT_LINK_TYPES).optional().describe('Defaults to `account_onboarding`.'),
|
|
281
|
+
})
|
|
282
|
+
.strict();
|
|
283
|
+
export const accountRoutes = [
|
|
284
|
+
defineRoute({
|
|
285
|
+
operationId: 'retrieveAccount',
|
|
286
|
+
method: 'get',
|
|
287
|
+
path: '/v1/account',
|
|
288
|
+
tag: 'Account',
|
|
289
|
+
summary: 'Retrieve the account',
|
|
290
|
+
description: "The merchant's own fiat account, or with `Peable-Account: ca_…` one of a platform's sellers. A merchant without one is told so (404 `account_missing`).",
|
|
291
|
+
auth: 'service',
|
|
292
|
+
scope: 'payments:read',
|
|
293
|
+
peableAccount: true,
|
|
294
|
+
query: expandOnlyQuery,
|
|
295
|
+
response: accountSchema,
|
|
296
|
+
sdk: 'account.retrieve',
|
|
297
|
+
}),
|
|
298
|
+
defineRoute({
|
|
299
|
+
operationId: 'updateAccount',
|
|
300
|
+
method: 'post',
|
|
301
|
+
path: '/v1/account',
|
|
302
|
+
tag: 'Account',
|
|
303
|
+
summary: 'Open or update the account',
|
|
304
|
+
description: 'The first call, with `country` and `business_type`, opens the account (201); every later one writes its settings to the provider and answers the account read back (200).',
|
|
305
|
+
auth: 'service',
|
|
306
|
+
scope: 'payments:write',
|
|
307
|
+
idempotent: true,
|
|
308
|
+
peableAccount: true,
|
|
309
|
+
body: updateAccountParams,
|
|
310
|
+
response: accountSchema,
|
|
311
|
+
sdk: 'account.update',
|
|
312
|
+
}),
|
|
313
|
+
defineRoute({
|
|
314
|
+
operationId: 'createAccountLink',
|
|
315
|
+
method: 'post',
|
|
316
|
+
path: '/v1/account_links',
|
|
317
|
+
tag: 'Account links',
|
|
318
|
+
summary: 'Create an account link',
|
|
319
|
+
description: "Hosted onboarding for the merchant's own account (or, with `Peable-Account`, a seller's card account), minted on demand.",
|
|
320
|
+
auth: 'service',
|
|
321
|
+
scope: 'payments:write',
|
|
322
|
+
idempotent: true,
|
|
323
|
+
peableAccount: true,
|
|
324
|
+
body: createAccountLinkParams,
|
|
325
|
+
response: accountLinkSchema,
|
|
326
|
+
status: 201,
|
|
327
|
+
sdk: 'accountLinks.create',
|
|
328
|
+
}),
|
|
329
|
+
];
|