@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,225 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { deletedOf, listOf, searchResultOf } from '../../common/envelopes.js';
|
|
3
|
+
import { defineComponent, defineObject, expandable } from '../../common/objects.js';
|
|
4
|
+
import { expandOnlyQuery, expandParam, listQuery, metadataCreateParam, metadataUpdateParam, searchQuery, } from '../../common/params.js';
|
|
5
|
+
import { livemode, metadata, unixSeconds } from '../../common/primitives.js';
|
|
6
|
+
import { defineRoute } from '../../route.js';
|
|
7
|
+
import { CATALOG_LIMITS } from '../../vocabulary/catalog.js';
|
|
8
|
+
import { isKnownTaxCode } from '../../vocabulary/tax.js';
|
|
9
|
+
import { defaultPriceDataParams } from './prices.js';
|
|
10
|
+
import { clearing, queryFlag, queryIdList } from './shared.js';
|
|
11
|
+
/**
|
|
12
|
+
* Products (`prod_…`, ADR 0018) — what a merchant sells; its prices say how
|
|
13
|
+
* much. A product with prices cannot be deleted: archive it with
|
|
14
|
+
* `active: false`.
|
|
15
|
+
*/
|
|
16
|
+
/** A product feature shown on pricing tables and checkout (Stripe's marketing features). */
|
|
17
|
+
export const productMarketingFeatureSchema = defineComponent('ProductMarketingFeature', z.object({ name: z.string() }).strict());
|
|
18
|
+
export const productSchema = defineObject('product', 'Product', z
|
|
19
|
+
.object({
|
|
20
|
+
id: z.string(),
|
|
21
|
+
object: z.literal('product'),
|
|
22
|
+
livemode,
|
|
23
|
+
active: z.boolean(),
|
|
24
|
+
name: z.string(),
|
|
25
|
+
description: z.string().nullable(),
|
|
26
|
+
images: z.array(z.string()).describe('Up to 8 image URLs.'),
|
|
27
|
+
metadata,
|
|
28
|
+
tax_code: z
|
|
29
|
+
.string()
|
|
30
|
+
.nullable()
|
|
31
|
+
.describe("A Peable Tax code (`txcd_…`), or `null` for the merchant's default."),
|
|
32
|
+
default_price: expandable('price', "The product's default price: `price_…`, or the Price with `expand[]=default_price`.").nullable(),
|
|
33
|
+
unit_label: z
|
|
34
|
+
.string()
|
|
35
|
+
.nullable()
|
|
36
|
+
.describe('The unit a quantity counts (`seat`), shown on receipts and invoices.'),
|
|
37
|
+
url: z.string().nullable(),
|
|
38
|
+
statement_descriptor: z
|
|
39
|
+
.string()
|
|
40
|
+
.nullable()
|
|
41
|
+
.describe('What appears on a card statement; at most 22 characters.'),
|
|
42
|
+
marketing_features: z.array(productMarketingFeatureSchema),
|
|
43
|
+
created: unixSeconds,
|
|
44
|
+
updated: unixSeconds,
|
|
45
|
+
})
|
|
46
|
+
.strict(), {
|
|
47
|
+
description: 'What a merchant sells. Its prices say how much. A product with prices cannot be deleted; set `active: false` to archive it.',
|
|
48
|
+
examples: [
|
|
49
|
+
{
|
|
50
|
+
id: 'prod_0193b8f2c1a87d3e9f4a',
|
|
51
|
+
object: 'product',
|
|
52
|
+
livemode: false,
|
|
53
|
+
active: true,
|
|
54
|
+
name: 'Mention Plus',
|
|
55
|
+
description: 'Everything in Mention, plus the Plus features.',
|
|
56
|
+
images: [],
|
|
57
|
+
metadata: {},
|
|
58
|
+
tax_code: 'txcd_10103000',
|
|
59
|
+
default_price: 'price_0193b8f2c1a87d3e9f4b',
|
|
60
|
+
unit_label: null,
|
|
61
|
+
url: null,
|
|
62
|
+
statement_descriptor: null,
|
|
63
|
+
marketing_features: [{ name: 'Longer posts' }],
|
|
64
|
+
created: 1793750400,
|
|
65
|
+
updated: 1793750400,
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
});
|
|
69
|
+
/** What `DELETE /v1/products/{id}` answers. */
|
|
70
|
+
export const deletedProductSchema = defineComponent('DeletedProduct', deletedOf('product'));
|
|
71
|
+
const url = z
|
|
72
|
+
.string()
|
|
73
|
+
.max(CATALOG_LIMITS.urlMax)
|
|
74
|
+
.regex(/^https?:\/\/\S+$/, 'must be an http(s) URL');
|
|
75
|
+
const fields = {
|
|
76
|
+
name: z.string().min(1).max(CATALOG_LIMITS.productNameMax),
|
|
77
|
+
description: z.string().min(1).max(CATALOG_LIMITS.productDescriptionMax),
|
|
78
|
+
images: z.array(url).max(CATALOG_LIMITS.productImagesMax),
|
|
79
|
+
tax_code: z
|
|
80
|
+
.string()
|
|
81
|
+
.refine(isKnownTaxCode, 'is not a Peable Tax code (GET /v1/tax/codes lists them)'),
|
|
82
|
+
unit_label: z.string().min(1).max(CATALOG_LIMITS.unitLabelMax),
|
|
83
|
+
url,
|
|
84
|
+
// Card networks print at most 22 characters, need one letter, and refuse
|
|
85
|
+
// `< > \ ' " *`.
|
|
86
|
+
statement_descriptor: z
|
|
87
|
+
.string()
|
|
88
|
+
.min(1)
|
|
89
|
+
.max(CATALOG_LIMITS.statementDescriptorMax)
|
|
90
|
+
.regex(/[A-Za-z]/, 'must contain at least one letter')
|
|
91
|
+
.refine((value) => !/[<>\\'"*]/.test(value), 'cannot contain < > \\ \' " or *'),
|
|
92
|
+
marketing_features: z
|
|
93
|
+
.array(z.object({ name: z.string().min(1).max(CATALOG_LIMITS.marketingFeatureNameMax) }).strict())
|
|
94
|
+
.max(CATALOG_LIMITS.marketingFeaturesMax),
|
|
95
|
+
};
|
|
96
|
+
export const createProductParams = z
|
|
97
|
+
.object({
|
|
98
|
+
name: fields.name,
|
|
99
|
+
active: z.boolean().optional(),
|
|
100
|
+
description: fields.description.optional(),
|
|
101
|
+
images: fields.images.optional(),
|
|
102
|
+
metadata: metadataCreateParam.optional(),
|
|
103
|
+
tax_code: fields.tax_code.optional(),
|
|
104
|
+
default_price_data: defaultPriceDataParams
|
|
105
|
+
.optional()
|
|
106
|
+
.describe("Create the product's default price with it."),
|
|
107
|
+
unit_label: fields.unit_label.optional(),
|
|
108
|
+
url: fields.url.optional(),
|
|
109
|
+
statement_descriptor: fields.statement_descriptor.optional(),
|
|
110
|
+
marketing_features: fields.marketing_features.optional(),
|
|
111
|
+
expand: expandParam.optional(),
|
|
112
|
+
})
|
|
113
|
+
.strict();
|
|
114
|
+
/** `""` clears an optional text field; `metadata` is a patch. */
|
|
115
|
+
export const updateProductParams = z
|
|
116
|
+
.object({
|
|
117
|
+
name: fields.name.optional(),
|
|
118
|
+
active: z.boolean().optional(),
|
|
119
|
+
description: clearing(fields.description).optional(),
|
|
120
|
+
images: fields.images.optional(),
|
|
121
|
+
metadata: metadataUpdateParam.optional(),
|
|
122
|
+
tax_code: clearing(fields.tax_code).optional(),
|
|
123
|
+
default_price: clearing(z.string().min(1).max(255))
|
|
124
|
+
.optional()
|
|
125
|
+
.describe('One of this product\'s active prices; `""` clears it.'),
|
|
126
|
+
unit_label: clearing(fields.unit_label).optional(),
|
|
127
|
+
url: clearing(fields.url).optional(),
|
|
128
|
+
statement_descriptor: clearing(fields.statement_descriptor).optional(),
|
|
129
|
+
marketing_features: fields.marketing_features.optional(),
|
|
130
|
+
expand: expandParam.optional(),
|
|
131
|
+
})
|
|
132
|
+
.strict();
|
|
133
|
+
export const listProductsQuery = listQuery({
|
|
134
|
+
active: queryFlag.optional(),
|
|
135
|
+
ids: queryIdList(CATALOG_LIMITS.idsFilterMax)
|
|
136
|
+
.optional()
|
|
137
|
+
.describe('Only these products (at most 100).'),
|
|
138
|
+
});
|
|
139
|
+
export const productRoutes = [
|
|
140
|
+
defineRoute({
|
|
141
|
+
operationId: 'createProduct',
|
|
142
|
+
method: 'post',
|
|
143
|
+
path: '/v1/products',
|
|
144
|
+
tag: 'Products',
|
|
145
|
+
summary: 'Create a product',
|
|
146
|
+
description: '`default_price_data` creates its default price in the same request.',
|
|
147
|
+
auth: 'service',
|
|
148
|
+
scope: 'payments:write',
|
|
149
|
+
idempotent: true,
|
|
150
|
+
body: createProductParams,
|
|
151
|
+
response: productSchema,
|
|
152
|
+
sdk: 'products.create',
|
|
153
|
+
expandable: 'product',
|
|
154
|
+
}),
|
|
155
|
+
defineRoute({
|
|
156
|
+
operationId: 'listProducts',
|
|
157
|
+
method: 'get',
|
|
158
|
+
path: '/v1/products',
|
|
159
|
+
tag: 'Products',
|
|
160
|
+
summary: 'List products',
|
|
161
|
+
auth: 'service',
|
|
162
|
+
scope: 'payments:read',
|
|
163
|
+
query: listProductsQuery,
|
|
164
|
+
response: listOf(productSchema),
|
|
165
|
+
sdk: 'products.list',
|
|
166
|
+
expandable: 'product',
|
|
167
|
+
}),
|
|
168
|
+
defineRoute({
|
|
169
|
+
operationId: 'retrieveProduct',
|
|
170
|
+
method: 'get',
|
|
171
|
+
path: '/v1/products/{id}',
|
|
172
|
+
tag: 'Products',
|
|
173
|
+
summary: 'Retrieve a product',
|
|
174
|
+
auth: 'service',
|
|
175
|
+
scope: 'payments:read',
|
|
176
|
+
params: { id: 'The product (`prod_…`).' },
|
|
177
|
+
query: expandOnlyQuery,
|
|
178
|
+
response: productSchema,
|
|
179
|
+
sdk: 'products.retrieve',
|
|
180
|
+
expandable: 'product',
|
|
181
|
+
}),
|
|
182
|
+
defineRoute({
|
|
183
|
+
operationId: 'updateProduct',
|
|
184
|
+
method: 'post',
|
|
185
|
+
path: '/v1/products/{id}',
|
|
186
|
+
tag: 'Products',
|
|
187
|
+
summary: 'Update a product',
|
|
188
|
+
description: 'A field sent as `""` is cleared; `metadata` is a patch.',
|
|
189
|
+
auth: 'service',
|
|
190
|
+
scope: 'payments:write',
|
|
191
|
+
idempotent: true,
|
|
192
|
+
params: { id: 'The product (`prod_…`).' },
|
|
193
|
+
body: updateProductParams,
|
|
194
|
+
response: productSchema,
|
|
195
|
+
sdk: 'products.update',
|
|
196
|
+
expandable: 'product',
|
|
197
|
+
}),
|
|
198
|
+
defineRoute({
|
|
199
|
+
operationId: 'deleteProduct',
|
|
200
|
+
method: 'delete',
|
|
201
|
+
path: '/v1/products/{id}',
|
|
202
|
+
tag: 'Products',
|
|
203
|
+
summary: 'Delete a product',
|
|
204
|
+
description: 'Only a product nothing names; one with prices is archived with `active: false`.',
|
|
205
|
+
auth: 'service',
|
|
206
|
+
scope: 'payments:write',
|
|
207
|
+
params: { id: 'The product (`prod_…`).' },
|
|
208
|
+
response: deletedProductSchema,
|
|
209
|
+
sdk: 'products.del',
|
|
210
|
+
}),
|
|
211
|
+
defineRoute({
|
|
212
|
+
operationId: 'searchProducts',
|
|
213
|
+
method: 'get',
|
|
214
|
+
path: '/v1/products/search',
|
|
215
|
+
tag: 'Products',
|
|
216
|
+
summary: 'Search products',
|
|
217
|
+
description: "Stripe's query language over `active`, `name`, `description`, `url`, `created` and `metadata['key']`.",
|
|
218
|
+
auth: 'service',
|
|
219
|
+
scope: 'payments:read',
|
|
220
|
+
query: searchQuery,
|
|
221
|
+
response: searchResultOf(productSchema),
|
|
222
|
+
sdk: 'products.search',
|
|
223
|
+
expandable: 'product',
|
|
224
|
+
}),
|
|
225
|
+
];
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { listOf } from '../../common/envelopes.js';
|
|
3
|
+
import { defineComponent, defineObject, expandable } from '../../common/objects.js';
|
|
4
|
+
import { expandOnlyQuery, expandParam, idParam, listQuery, metadataCreateParam, metadataUpdateParam, } from '../../common/params.js';
|
|
5
|
+
import { amount, currency, livemode, metadata, unixSeconds } from '../../common/primitives.js';
|
|
6
|
+
import { defineRoute } from '../../route.js';
|
|
7
|
+
import { CATALOG_LIMITS } from '../../vocabulary/catalog.js';
|
|
8
|
+
import { baseUnitAmountParam, checkAmountBound, countParam, positiveUnixSecondsParam, queryFlag, } from './shared.js';
|
|
9
|
+
/**
|
|
10
|
+
* Promotion codes (`promo_…`, ADR 0018) — a customer-facing `code` that
|
|
11
|
+
* redeems a coupon, with its own limits. Codes are case-insensitive and unique
|
|
12
|
+
* among a merchant's ACTIVE codes.
|
|
13
|
+
*/
|
|
14
|
+
export const promotionCodeRestrictionsSchema = defineComponent('PromotionCodeRestrictions', z
|
|
15
|
+
.object({
|
|
16
|
+
first_time_transaction: z
|
|
17
|
+
.boolean()
|
|
18
|
+
.describe("Only a customer's first transaction may redeem it."),
|
|
19
|
+
minimum_amount: amount
|
|
20
|
+
.nullable()
|
|
21
|
+
.describe('The smallest order total it applies to, in `minimum_amount_currency`.'),
|
|
22
|
+
minimum_amount_currency: currency.nullable(),
|
|
23
|
+
})
|
|
24
|
+
.strict());
|
|
25
|
+
export const promotionCodeSchema = defineObject('promotion_code', 'PromotionCode', z
|
|
26
|
+
.object({
|
|
27
|
+
id: z.string(),
|
|
28
|
+
object: z.literal('promotion_code'),
|
|
29
|
+
livemode,
|
|
30
|
+
code: z.string(),
|
|
31
|
+
coupon: expandable('coupon', 'The coupon it redeems: its id, or the Coupon with `expand[]=coupon`.'),
|
|
32
|
+
customer: expandable('customer', 'The one customer who may redeem it (`cus_…`, or the Customer with `expand[]=customer`); `null` for anyone.').nullable(),
|
|
33
|
+
active: z.boolean(),
|
|
34
|
+
max_redemptions: z.number().int().nullable(),
|
|
35
|
+
expires_at: unixSeconds.nullable().describe("Never after the coupon's `redeem_by`."),
|
|
36
|
+
times_redeemed: z.number().int(),
|
|
37
|
+
restrictions: promotionCodeRestrictionsSchema,
|
|
38
|
+
metadata,
|
|
39
|
+
created: unixSeconds,
|
|
40
|
+
})
|
|
41
|
+
.strict(), {
|
|
42
|
+
examples: [
|
|
43
|
+
{
|
|
44
|
+
id: 'promo_0193b8f2c1a87d3e9f4c',
|
|
45
|
+
object: 'promotion_code',
|
|
46
|
+
livemode: false,
|
|
47
|
+
code: 'SUMMER25',
|
|
48
|
+
coupon: 'SUMMER25',
|
|
49
|
+
customer: null,
|
|
50
|
+
active: true,
|
|
51
|
+
max_redemptions: null,
|
|
52
|
+
expires_at: null,
|
|
53
|
+
times_redeemed: 0,
|
|
54
|
+
restrictions: {
|
|
55
|
+
first_time_transaction: true,
|
|
56
|
+
minimum_amount: null,
|
|
57
|
+
minimum_amount_currency: null,
|
|
58
|
+
},
|
|
59
|
+
metadata: {},
|
|
60
|
+
created: 1793750400,
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
});
|
|
64
|
+
const code = z
|
|
65
|
+
.string()
|
|
66
|
+
.regex(new RegExp(`^[A-Za-z0-9]{1,${CATALOG_LIMITS.promotionCodeMax}}$`), `a code is 1–${CATALOG_LIMITS.promotionCodeMax} letters and digits`);
|
|
67
|
+
export const createPromotionCodeParams = z
|
|
68
|
+
.object({
|
|
69
|
+
coupon: idParam,
|
|
70
|
+
code: code.optional().describe('Letters and digits; generated when absent.'),
|
|
71
|
+
customer: idParam.optional().describe('Only this customer (`cus_…`) may redeem it.'),
|
|
72
|
+
active: z.boolean().optional(),
|
|
73
|
+
max_redemptions: countParam.optional(),
|
|
74
|
+
expires_at: positiveUnixSecondsParam.optional(),
|
|
75
|
+
restrictions: z
|
|
76
|
+
.object({
|
|
77
|
+
first_time_transaction: z.boolean().optional(),
|
|
78
|
+
minimum_amount: baseUnitAmountParam.optional(),
|
|
79
|
+
minimum_amount_currency: currency.optional(),
|
|
80
|
+
})
|
|
81
|
+
.strict()
|
|
82
|
+
.superRefine((restrictions, ctx) => {
|
|
83
|
+
if ((restrictions.minimum_amount === undefined) !==
|
|
84
|
+
(restrictions.minimum_amount_currency === undefined)) {
|
|
85
|
+
ctx.addIssue({
|
|
86
|
+
code: 'custom',
|
|
87
|
+
path: ['minimum_amount_currency'],
|
|
88
|
+
message: 'minimum_amount and minimum_amount_currency go together',
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
checkAmountBound(ctx, restrictions.minimum_amount, restrictions.minimum_amount_currency, [
|
|
92
|
+
'minimum_amount',
|
|
93
|
+
]);
|
|
94
|
+
})
|
|
95
|
+
.optional(),
|
|
96
|
+
metadata: metadataCreateParam.optional(),
|
|
97
|
+
expand: expandParam.optional(),
|
|
98
|
+
})
|
|
99
|
+
.strict();
|
|
100
|
+
export const updatePromotionCodeParams = z
|
|
101
|
+
.object({
|
|
102
|
+
active: z.boolean().optional(),
|
|
103
|
+
metadata: metadataUpdateParam.optional(),
|
|
104
|
+
expand: expandParam.optional(),
|
|
105
|
+
})
|
|
106
|
+
.strict();
|
|
107
|
+
export const listPromotionCodesQuery = listQuery({
|
|
108
|
+
code: z.string().min(1).max(255).optional().describe('Case-insensitive.'),
|
|
109
|
+
coupon: idParam.optional(),
|
|
110
|
+
customer: idParam.optional(),
|
|
111
|
+
active: queryFlag.optional(),
|
|
112
|
+
});
|
|
113
|
+
export const promotionCodeRoutes = [
|
|
114
|
+
defineRoute({
|
|
115
|
+
operationId: 'createPromotionCode',
|
|
116
|
+
method: 'post',
|
|
117
|
+
path: '/v1/promotion_codes',
|
|
118
|
+
tag: 'Promotion codes',
|
|
119
|
+
summary: 'Create a promotion code',
|
|
120
|
+
auth: 'service',
|
|
121
|
+
scope: 'payments:write',
|
|
122
|
+
idempotent: true,
|
|
123
|
+
body: createPromotionCodeParams,
|
|
124
|
+
response: promotionCodeSchema,
|
|
125
|
+
sdk: 'promotionCodes.create',
|
|
126
|
+
expandable: 'promotion_code',
|
|
127
|
+
}),
|
|
128
|
+
defineRoute({
|
|
129
|
+
operationId: 'listPromotionCodes',
|
|
130
|
+
method: 'get',
|
|
131
|
+
path: '/v1/promotion_codes',
|
|
132
|
+
tag: 'Promotion codes',
|
|
133
|
+
summary: 'List promotion codes',
|
|
134
|
+
auth: 'service',
|
|
135
|
+
scope: 'payments:read',
|
|
136
|
+
query: listPromotionCodesQuery,
|
|
137
|
+
response: listOf(promotionCodeSchema),
|
|
138
|
+
sdk: 'promotionCodes.list',
|
|
139
|
+
expandable: 'promotion_code',
|
|
140
|
+
}),
|
|
141
|
+
defineRoute({
|
|
142
|
+
operationId: 'retrievePromotionCode',
|
|
143
|
+
method: 'get',
|
|
144
|
+
path: '/v1/promotion_codes/{id}',
|
|
145
|
+
tag: 'Promotion codes',
|
|
146
|
+
summary: 'Retrieve a promotion code',
|
|
147
|
+
auth: 'service',
|
|
148
|
+
scope: 'payments:read',
|
|
149
|
+
params: { id: 'The promotion code (`promo_…`).' },
|
|
150
|
+
query: expandOnlyQuery,
|
|
151
|
+
response: promotionCodeSchema,
|
|
152
|
+
sdk: 'promotionCodes.retrieve',
|
|
153
|
+
expandable: 'promotion_code',
|
|
154
|
+
}),
|
|
155
|
+
defineRoute({
|
|
156
|
+
operationId: 'updatePromotionCode',
|
|
157
|
+
method: 'post',
|
|
158
|
+
path: '/v1/promotion_codes/{id}',
|
|
159
|
+
tag: 'Promotion codes',
|
|
160
|
+
summary: 'Update a promotion code',
|
|
161
|
+
description: 'Only `active` and `metadata` change.',
|
|
162
|
+
auth: 'service',
|
|
163
|
+
scope: 'payments:write',
|
|
164
|
+
idempotent: true,
|
|
165
|
+
params: { id: 'The promotion code (`promo_…`).' },
|
|
166
|
+
body: updatePromotionCodeParams,
|
|
167
|
+
response: promotionCodeSchema,
|
|
168
|
+
sdk: 'promotionCodes.update',
|
|
169
|
+
expandable: 'promotion_code',
|
|
170
|
+
}),
|
|
171
|
+
];
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { describe } from '../../common/objects.js';
|
|
3
|
+
import { MAX_UNIX_SECONDS, queryBoolean } from '../../common/params.js';
|
|
4
|
+
import { CATALOG_MAX_WHOLE_UNITS, maxBaseUnits } from '../../vocabulary/catalog.js';
|
|
5
|
+
import { isBaseUnitString } from '../../vocabulary/money.js';
|
|
6
|
+
/**
|
|
7
|
+
* Request pieces the catalog's bodies share — and that every other body naming
|
|
8
|
+
* an amount, a currency or an inline price reuses (checkout line items,
|
|
9
|
+
* invoice items), so one shape rule is written once and every caller refuses
|
|
10
|
+
* the same mistake with the same `param`.
|
|
11
|
+
*/
|
|
12
|
+
/** A canonical base-unit integer string: `"1999"`, never `"19.99"` or `1999`. */
|
|
13
|
+
export const baseUnitAmountParam = z
|
|
14
|
+
.string()
|
|
15
|
+
.refine(isBaseUnitString, 'must be a non-negative integer string in the smallest currency unit')
|
|
16
|
+
.describe('Base units of the currency, as an integer string (`"1999"` is 19.99 EUR).');
|
|
17
|
+
/** A positive count that fits a Postgres `integer`. */
|
|
18
|
+
export const countParam = z.number().int().min(1).max(2147483647);
|
|
19
|
+
/** A future instant in a body (`redeem_by`, `expires_at`): positive Unix seconds. */
|
|
20
|
+
export const positiveUnixSecondsParam = z.number().int().positive().max(MAX_UNIX_SECONDS);
|
|
21
|
+
/**
|
|
22
|
+
* A boolean filter in a query string. A typed caller passes `true` / `false`
|
|
23
|
+
* (the SDK spells it for the URL); the URL carries `'true'` / `'false'`,
|
|
24
|
+
* which the gateway reads the same.
|
|
25
|
+
*/
|
|
26
|
+
export const queryFlag = queryBoolean;
|
|
27
|
+
/** `ids[]=a&ids[]=b` or `ids=a`: one id is a list of one. */
|
|
28
|
+
export function queryIdList(max) {
|
|
29
|
+
return describe(z
|
|
30
|
+
.union([z.string(), z.array(z.string())])
|
|
31
|
+
.transform((value) => (typeof value === 'string' ? [value] : value))
|
|
32
|
+
.pipe(z.array(z.string().min(1).max(255)).min(1).max(max)), {
|
|
33
|
+
jsonSchema: {
|
|
34
|
+
type: 'array',
|
|
35
|
+
items: { type: 'string', maxLength: 255 },
|
|
36
|
+
minItems: 1,
|
|
37
|
+
maxItems: max,
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
/** `""` on an update clears the field (Stripe's rule): the parsed value is `null`. */
|
|
42
|
+
export const clearing = (schema) => z
|
|
43
|
+
.union([schema, z.literal('')])
|
|
44
|
+
.transform((value) => (value === '' ? null : value));
|
|
45
|
+
export function issuer(ctx) {
|
|
46
|
+
let failed = false;
|
|
47
|
+
return {
|
|
48
|
+
issue: (path, message) => {
|
|
49
|
+
failed = true;
|
|
50
|
+
ctx.addIssue({ code: 'custom', path, message });
|
|
51
|
+
},
|
|
52
|
+
failed: () => failed,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/** Refuse an amount above the catalog's bound for `currency`. */
|
|
56
|
+
export function amountWithinBound(issue, amount, currency, path) {
|
|
57
|
+
if (amount === undefined || !isBaseUnitString(amount))
|
|
58
|
+
return;
|
|
59
|
+
if (BigInt(amount) > maxBaseUnits(currency)) {
|
|
60
|
+
issue(path, `must be at most ${maxBaseUnits(currency)} (${CATALOG_MAX_WHOLE_UNITS} whole ${currency})`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/** Add a bound issue for a coupon or promotion amount in `currency`. */
|
|
64
|
+
export function checkAmountBound(ctx, amount, currency, path) {
|
|
65
|
+
if (currency !== undefined)
|
|
66
|
+
amountWithinBound(issuer(ctx).issue, amount, currency, path);
|
|
67
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { deletedOf, listOf } from '../../common/envelopes.js';
|
|
3
|
+
import { defineComponent, defineObject } from '../../common/objects.js';
|
|
4
|
+
import { expandOnlyQuery, listQuery, unixSecondsParam } from '../../common/params.js';
|
|
5
|
+
import { unixSeconds } from '../../common/primitives.js';
|
|
6
|
+
import { defineRoute } from '../../route.js';
|
|
7
|
+
import { TEST_CLOCK_STATUSES } from '../../vocabulary/catalog.js';
|
|
8
|
+
/**
|
|
9
|
+
* Test clocks (`clock_…`, ADR 0018 §3, test mode only). Customers attached to
|
|
10
|
+
* a clock — and every subscription and invoice of theirs — live at
|
|
11
|
+
* `frozen_time` instead of the wall clock, so a trial, a renewal or a dunning
|
|
12
|
+
* schedule runs in seconds. Advancing it runs the engine for everything on the
|
|
13
|
+
* clock up to the new time.
|
|
14
|
+
*/
|
|
15
|
+
export const testClockSchema = defineObject('test_helpers.test_clock', 'TestClock', z
|
|
16
|
+
.object({
|
|
17
|
+
id: z.string(),
|
|
18
|
+
object: z.literal('test_helpers.test_clock'),
|
|
19
|
+
livemode: z.literal(false).describe('Always `false`: test clocks exist in test mode only.'),
|
|
20
|
+
name: z.string().nullable(),
|
|
21
|
+
frozen_time: unixSeconds.describe('The instant everything on the clock lives at.'),
|
|
22
|
+
status: z.enum(TEST_CLOCK_STATUSES),
|
|
23
|
+
deletes_after: unixSeconds.describe('Deleted, with everything on it, after this instant.'),
|
|
24
|
+
created: unixSeconds,
|
|
25
|
+
})
|
|
26
|
+
.strict(), {
|
|
27
|
+
examples: [
|
|
28
|
+
{
|
|
29
|
+
id: 'clock_0193b8f2c1a87d3e9f4d',
|
|
30
|
+
object: 'test_helpers.test_clock',
|
|
31
|
+
livemode: false,
|
|
32
|
+
name: 'Annual renewal',
|
|
33
|
+
frozen_time: 1793750400,
|
|
34
|
+
status: 'ready',
|
|
35
|
+
deletes_after: 1796342400,
|
|
36
|
+
created: 1793750400,
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
});
|
|
40
|
+
export const deletedTestClockSchema = defineComponent('DeletedTestClock', deletedOf('test_helpers.test_clock'));
|
|
41
|
+
export const createTestClockParams = z
|
|
42
|
+
.object({ frozen_time: unixSecondsParam, name: z.string().min(1).max(300).optional() })
|
|
43
|
+
.strict();
|
|
44
|
+
export const advanceTestClockParams = z
|
|
45
|
+
.object({
|
|
46
|
+
frozen_time: unixSecondsParam.describe("Later than the clock's current `frozen_time`, and at most two years after it."),
|
|
47
|
+
})
|
|
48
|
+
.strict();
|
|
49
|
+
export const listTestClocksQuery = listQuery({});
|
|
50
|
+
const id = { id: 'The test clock (`clock_…`).' };
|
|
51
|
+
export const testClockRoutes = [
|
|
52
|
+
defineRoute({
|
|
53
|
+
operationId: 'createTestClock',
|
|
54
|
+
method: 'post',
|
|
55
|
+
path: '/v1/test_helpers/test_clocks',
|
|
56
|
+
tag: 'Test clocks',
|
|
57
|
+
summary: 'Create a test clock',
|
|
58
|
+
auth: 'service',
|
|
59
|
+
scope: 'payments:write',
|
|
60
|
+
idempotent: true,
|
|
61
|
+
testModeOnly: true,
|
|
62
|
+
body: createTestClockParams,
|
|
63
|
+
response: testClockSchema,
|
|
64
|
+
sdk: 'testHelpers.testClocks.create',
|
|
65
|
+
}),
|
|
66
|
+
defineRoute({
|
|
67
|
+
operationId: 'listTestClocks',
|
|
68
|
+
method: 'get',
|
|
69
|
+
path: '/v1/test_helpers/test_clocks',
|
|
70
|
+
tag: 'Test clocks',
|
|
71
|
+
summary: 'List test clocks',
|
|
72
|
+
auth: 'service',
|
|
73
|
+
scope: 'payments:read',
|
|
74
|
+
testModeOnly: true,
|
|
75
|
+
query: listTestClocksQuery,
|
|
76
|
+
response: listOf(testClockSchema),
|
|
77
|
+
sdk: 'testHelpers.testClocks.list',
|
|
78
|
+
expandable: 'test_helpers.test_clock',
|
|
79
|
+
}),
|
|
80
|
+
defineRoute({
|
|
81
|
+
operationId: 'retrieveTestClock',
|
|
82
|
+
method: 'get',
|
|
83
|
+
path: '/v1/test_helpers/test_clocks/{id}',
|
|
84
|
+
tag: 'Test clocks',
|
|
85
|
+
summary: 'Retrieve a test clock',
|
|
86
|
+
auth: 'service',
|
|
87
|
+
scope: 'payments:read',
|
|
88
|
+
testModeOnly: true,
|
|
89
|
+
params: id,
|
|
90
|
+
query: expandOnlyQuery,
|
|
91
|
+
response: testClockSchema,
|
|
92
|
+
sdk: 'testHelpers.testClocks.retrieve',
|
|
93
|
+
}),
|
|
94
|
+
defineRoute({
|
|
95
|
+
operationId: 'advanceTestClock',
|
|
96
|
+
method: 'post',
|
|
97
|
+
path: '/v1/test_helpers/test_clocks/{id}/advance',
|
|
98
|
+
tag: 'Test clocks',
|
|
99
|
+
summary: 'Advance a test clock',
|
|
100
|
+
description: 'Moves `frozen_time` forward and runs the billing engine for everything on the clock up to it: trials end, subscriptions renew, invoices finalize and dunning retries.',
|
|
101
|
+
auth: 'service',
|
|
102
|
+
scope: 'payments:write',
|
|
103
|
+
idempotent: true,
|
|
104
|
+
testModeOnly: true,
|
|
105
|
+
params: id,
|
|
106
|
+
body: advanceTestClockParams,
|
|
107
|
+
response: testClockSchema,
|
|
108
|
+
sdk: 'testHelpers.testClocks.advance',
|
|
109
|
+
}),
|
|
110
|
+
defineRoute({
|
|
111
|
+
operationId: 'deleteTestClock',
|
|
112
|
+
method: 'delete',
|
|
113
|
+
path: '/v1/test_helpers/test_clocks/{id}',
|
|
114
|
+
tag: 'Test clocks',
|
|
115
|
+
summary: 'Delete a test clock',
|
|
116
|
+
description: 'Every live subscription on the clock is cancelled at its frozen time; the clock stays readable to the objects that name it.',
|
|
117
|
+
auth: 'service',
|
|
118
|
+
scope: 'payments:write',
|
|
119
|
+
testModeOnly: true,
|
|
120
|
+
params: id,
|
|
121
|
+
response: deletedTestClockSchema,
|
|
122
|
+
sdk: 'testHelpers.testClocks.del',
|
|
123
|
+
}),
|
|
124
|
+
];
|