@volter/twin-stripe 2.0.38 → 3.0.1
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/README.md +112 -207
- package/dist/generated/pack-facts.json +94 -0
- package/dist/journeys/coverage.json +596 -0
- package/dist/journeys/customer-life.json +6108 -0
- package/dist/journeys/customer-life.outline.md +371 -0
- package/dist/journeys/decisions.json +677 -0
- package/dist/journeys/demand.json +706 -0
- package/dist/journeys/score.json +853 -0
- package/dist/journeys/unreachable.json +102 -0
- package/dist/journeys/vendor-examples.json +8010 -0
- package/dist/spec/SOURCE.md +18 -0
- package/dist/spec/doc-examples.json +445 -0
- package/dist/spec/fixtures3.json.gz +0 -0
- package/dist/spec/openapi.json.gz +0 -0
- package/dist/spec/patches.json +34 -0
- package/dist/spec/sources.json +306 -0
- package/dist/src/cli.d.ts +0 -1
- package/dist/src/cli.js +11 -31
- package/dist/src/engine/after-payment.d.ts +8 -0
- package/dist/src/engine/after-payment.js +27 -0
- package/dist/src/engine/apps-secrets.d.ts +1 -0
- package/dist/src/engine/apps-secrets.js +3 -0
- package/dist/src/engine/balance.d.ts +5 -0
- package/dist/src/engine/balance.js +15 -0
- package/dist/src/engine/checkout.d.ts +24 -0
- package/dist/src/engine/checkout.js +30 -0
- package/dist/src/engine/common.d.ts +19 -0
- package/dist/src/engine/common.js +34 -0
- package/dist/src/engine/connect.d.ts +45 -0
- package/dist/src/engine/connect.js +108 -0
- package/dist/src/engine/customers.d.ts +4 -0
- package/dist/src/engine/customers.js +8 -0
- package/dist/src/engine/display.d.ts +11 -0
- package/dist/src/engine/display.js +13 -0
- package/dist/src/engine/files.d.ts +11 -0
- package/dist/src/engine/files.js +23 -0
- package/dist/src/engine/invoices.d.ts +21 -0
- package/dist/src/engine/invoices.js +84 -0
- package/dist/src/engine/issuing.d.ts +33 -0
- package/dist/src/engine/issuing.js +54 -0
- package/dist/src/engine/ledger.d.ts +8 -0
- package/dist/src/engine/ledger.js +8 -0
- package/dist/src/engine/oauth.d.ts +4 -0
- package/dist/src/engine/oauth.js +24 -0
- package/dist/src/engine/onboarding.d.ts +13 -0
- package/dist/src/engine/onboarding.js +42 -0
- package/dist/src/{stripe-params.d.ts → engine/params.d.ts} +20 -3
- package/dist/src/{stripe-params.js → engine/params.js} +7 -60
- package/dist/src/engine/payment-intents.d.ts +10 -0
- package/dist/src/engine/payment-intents.js +27 -0
- package/dist/src/engine/payment-methods.d.ts +16 -0
- package/dist/src/engine/payment-methods.js +22 -0
- package/dist/src/engine/radar.d.ts +2 -0
- package/dist/src/engine/radar.js +5 -0
- package/dist/src/engine/refunds.d.ts +1 -0
- package/dist/src/engine/refunds.js +3 -0
- package/dist/src/engine/renewals.d.ts +36 -0
- package/dist/src/engine/renewals.js +65 -0
- package/dist/src/{stripe-twin.d.ts → engine/stripe.d.ts} +12 -45
- package/dist/src/{stripe-twin.js → engine/stripe.js} +53 -387
- package/dist/src/engine/subscriptions.d.ts +11 -0
- package/dist/src/engine/subscriptions.js +30 -0
- package/dist/src/engine/transfers.d.ts +2 -0
- package/dist/src/engine/transfers.js +1 -0
- package/dist/src/{stripe-version.d.ts → engine/version.d.ts} +0 -2
- package/dist/src/{stripe-version.js → engine/version.js} +21 -9
- package/dist/src/engine/webhook-endpoints.d.ts +1 -0
- package/dist/src/engine/webhook-endpoints.js +12 -0
- package/dist/src/engine/webhooks.d.ts +31 -0
- package/dist/src/engine/webhooks.js +68 -0
- package/dist/src/fetch.d.ts +2 -0
- package/dist/src/fetch.js +26 -0
- package/dist/src/generated/surface.gen.json +1 -1
- package/dist/src/generated/ui.gen.json +1 -1
- package/dist/src/index.d.ts +5 -14
- package/dist/src/index.js +10 -75
- package/dist/src/manifest.js +478 -876
- package/dist/src/screens/billing-portal.d.ts +3 -0
- package/dist/src/screens/{portal.js → billing-portal.js} +32 -58
- package/dist/src/screens/checkout-js.d.ts +2 -0
- package/dist/src/screens/checkout-js.js +84 -0
- package/dist/src/screens/checkout.d.ts +2 -31
- package/dist/src/screens/checkout.js +32 -121
- package/dist/src/screens/connect-onboarding.d.ts +3 -0
- package/dist/src/screens/{onboarding.js → connect-onboarding.js} +38 -104
- package/dist/src/screens/dashboard.d.ts +3 -0
- package/dist/src/screens/dashboard.js +116 -0
- package/dist/src/screens/shared.d.ts +27 -0
- package/dist/src/screens/shared.js +87 -0
- package/dist/src/screens/stripe-js.d.ts +3 -0
- package/dist/src/screens/stripe-js.js +95 -0
- package/dist/src/semantics/account.d.ts +2 -0
- package/dist/src/semantics/account.js +8 -0
- package/dist/src/semantics/account_links.d.ts +2 -0
- package/dist/src/semantics/account_links.js +22 -0
- package/dist/src/semantics/accounts.d.ts +4 -0
- package/dist/src/semantics/accounts.js +40 -0
- package/dist/src/semantics/apps.d.ts +4 -0
- package/dist/src/semantics/{apps-secrets.js → apps.js} +14 -26
- package/dist/src/semantics/around.d.ts +2 -0
- package/dist/src/semantics/around.js +13 -0
- package/dist/src/semantics/balance.d.ts +2 -11
- package/dist/src/semantics/balance.js +3 -194
- package/dist/src/semantics/balance_transactions.d.ts +2 -0
- package/dist/src/semantics/balance_transactions.js +15 -0
- package/dist/src/semantics/billing_portal.d.ts +4 -0
- package/dist/src/semantics/billing_portal.js +36 -0
- package/dist/src/semantics/charges.d.ts +3 -28
- package/dist/src/semantics/charges.js +5 -202
- package/dist/src/semantics/checkout.d.ts +3 -20
- package/dist/src/semantics/checkout.js +21 -271
- package/dist/src/semantics/clock.d.ts +2 -0
- package/dist/src/semantics/clock.js +15 -0
- package/dist/src/semantics/coupons.d.ts +2 -6
- package/dist/src/semantics/coupons.js +2 -60
- package/dist/src/semantics/customers.d.ts +5 -6
- package/dist/src/semantics/customers.js +47 -413
- package/dist/src/semantics/doors.d.ts +23 -0
- package/dist/src/semantics/doors.js +73 -0
- package/dist/src/semantics/entitlements.d.ts +0 -2
- package/dist/src/semantics/entitlements.js +4 -95
- package/dist/src/semantics/events.d.ts +11 -0
- package/dist/src/semantics/events.js +31 -0
- package/dist/src/semantics/index.d.ts +2 -0
- package/dist/src/semantics/index.js +85 -0
- package/dist/src/semantics/invoice_payments.d.ts +2 -0
- package/dist/src/semantics/invoice_payments.js +12 -0
- package/dist/src/semantics/invoices.d.ts +11 -18
- package/dist/src/semantics/invoices.js +121 -440
- package/dist/src/semantics/issuing.d.ts +6 -13
- package/dist/src/semantics/issuing.js +58 -556
- package/dist/src/semantics/payment_intents.d.ts +3 -0
- package/dist/src/semantics/payment_intents.js +71 -0
- package/dist/src/semantics/payment_methods.d.ts +3 -0
- package/dist/src/semantics/payment_methods.js +15 -0
- package/dist/src/semantics/payouts.d.ts +3 -0
- package/dist/src/semantics/payouts.js +28 -0
- package/dist/src/semantics/prices.d.ts +4 -0
- package/dist/src/semantics/prices.js +37 -0
- package/dist/src/semantics/products.d.ts +4 -2
- package/dist/src/semantics/products.js +12 -138
- package/dist/src/semantics/promotion_codes.d.ts +3 -0
- package/dist/src/semantics/promotion_codes.js +35 -0
- package/dist/src/semantics/radar.d.ts +2 -2
- package/dist/src/semantics/radar.js +5 -74
- package/dist/src/semantics/refunds.d.ts +2 -9
- package/dist/src/semantics/refunds.js +3 -193
- package/dist/src/semantics/shared.d.ts +558 -55
- package/dist/src/semantics/shared.js +2070 -114
- package/dist/src/semantics/states.d.ts +462 -0
- package/dist/src/semantics/states.js +634 -0
- package/dist/src/semantics/subscriptions.d.ts +6 -11
- package/dist/src/semantics/subscriptions.js +37 -530
- package/dist/src/semantics/test_helpers.d.ts +3 -0
- package/dist/src/semantics/test_helpers.js +125 -0
- package/dist/src/semantics/transfers.d.ts +2 -2
- package/dist/src/semantics/transfers.js +6 -101
- package/dist/src/semantics/webhook_endpoints.d.ts +2 -0
- package/dist/src/semantics/webhook_endpoints.js +26 -0
- package/dist/src/server.d.ts +7 -0
- package/dist/src/server.js +7 -0
- package/generated/pack-facts.json +94 -0
- package/journeys/coverage.json +596 -0
- package/journeys/customer-life.json +6108 -0
- package/journeys/customer-life.outline.md +371 -0
- package/journeys/decisions.json +677 -0
- package/journeys/demand.json +706 -0
- package/journeys/score.json +853 -0
- package/journeys/unreachable.json +102 -0
- package/journeys/vendor-examples.json +8010 -0
- package/package.json +11 -20
- package/spec/SOURCE.md +18 -0
- package/spec/doc-examples.json +445 -0
- package/spec/fixtures3.json.gz +0 -0
- package/spec/openapi.json.gz +0 -0
- package/spec/patches.json +34 -0
- package/spec/sources.json +306 -0
- package/src/cli.ts +11 -28
- package/src/engine/after-payment.ts +29 -0
- package/src/engine/apps-secrets.ts +4 -0
- package/src/engine/balance.ts +32 -0
- package/src/engine/checkout.ts +39 -0
- package/src/engine/common.ts +49 -0
- package/src/engine/connect.ts +106 -0
- package/src/engine/customers.ts +10 -0
- package/src/engine/display.ts +18 -0
- package/src/engine/files.ts +28 -0
- package/src/engine/invoices.ts +102 -0
- package/src/engine/issuing.ts +66 -0
- package/src/engine/ledger.ts +48 -0
- package/src/engine/oauth.ts +18 -0
- package/src/engine/onboarding.ts +53 -0
- package/src/{stripe-params.ts → engine/params.ts} +7 -56
- package/src/engine/payment-intents.ts +32 -0
- package/src/engine/payment-methods.ts +24 -0
- package/src/engine/radar.ts +6 -0
- package/src/engine/refunds.ts +3 -0
- package/src/engine/renewals.ts +72 -0
- package/src/{stripe-twin.ts → engine/stripe.ts} +57 -400
- package/src/engine/subscriptions.ts +37 -0
- package/src/engine/transfers.ts +22 -0
- package/src/{stripe-version.ts → engine/version.ts} +19 -10
- package/src/engine/webhook-endpoints.ts +14 -0
- package/src/engine/webhooks.ts +70 -0
- package/src/fetch.ts +27 -0
- package/src/generated/surface.gen.json +1 -1
- package/src/generated/ui.gen.json +1 -1
- package/src/index.ts +10 -116
- package/src/manifest.ts +480 -904
- package/src/screens/{portal.tsx → billing-portal.tsx} +35 -42
- package/src/screens/checkout-js.ts +80 -0
- package/src/screens/checkout.tsx +32 -96
- package/src/screens/{onboarding.tsx → connect-onboarding.tsx} +39 -85
- package/src/screens/dashboard.tsx +178 -0
- package/src/screens/shared.tsx +84 -0
- package/src/screens/stripe-js.ts +102 -0
- package/src/semantics/account.ts +10 -0
- package/src/semantics/account_links.ts +20 -0
- package/src/semantics/accounts.ts +44 -0
- package/src/semantics/{apps-secrets.ts → apps.ts} +17 -33
- package/src/semantics/around.ts +17 -0
- package/src/semantics/balance.ts +6 -208
- package/src/semantics/balance_transactions.ts +18 -0
- package/src/semantics/billing_portal.ts +45 -0
- package/src/semantics/charges.ts +8 -212
- package/src/semantics/checkout.ts +25 -276
- package/src/semantics/clock.ts +19 -0
- package/src/semantics/coupons.ts +5 -68
- package/src/semantics/customers.ts +48 -414
- package/src/semantics/doors.ts +79 -0
- package/src/semantics/entitlements.ts +3 -94
- package/src/semantics/events.ts +37 -0
- package/src/semantics/index.ts +89 -0
- package/src/semantics/invoice_payments.ts +16 -0
- package/src/semantics/invoices.ts +112 -441
- package/src/semantics/issuing.ts +57 -573
- package/src/semantics/payment_intents.ts +76 -0
- package/src/semantics/payment_methods.ts +20 -0
- package/src/semantics/payouts.ts +29 -0
- package/src/semantics/prices.ts +41 -0
- package/src/semantics/products.ts +12 -146
- package/src/semantics/promotion_codes.ts +38 -0
- package/src/semantics/radar.ts +8 -79
- package/src/semantics/refunds.ts +4 -216
- package/src/semantics/shared.ts +2089 -135
- package/src/semantics/states.ts +662 -0
- package/src/semantics/subscriptions.ts +39 -542
- package/src/semantics/test_helpers.ts +119 -0
- package/src/semantics/transfers.ts +10 -132
- package/src/semantics/webhook_endpoints.ts +27 -0
- package/src/server.ts +7 -0
- package/client/dashboard-api.ts +0 -286
- package/client/stripe-mirror.css +0 -277
- package/client/stripe-mirror.tsx +0 -1559
- package/dist/client/dashboard-api.d.ts +0 -107
- package/dist/client/dashboard-api.js +0 -238
- package/dist/client/dashboard-api.ts +0 -286
- package/dist/client/stripe-mirror.bundle.js +0 -236
- package/dist/client/stripe-mirror.css +0 -277
- package/dist/client/stripe-mirror.d.ts +0 -134
- package/dist/client/stripe-mirror.js +0 -859
- package/dist/client/stripe-mirror.tsx +0 -1559
- package/dist/src/screens/connect-oauth.d.ts +0 -27
- package/dist/src/screens/connect-oauth.js +0 -414
- package/dist/src/screens/connect-settings.d.ts +0 -22
- package/dist/src/screens/connect-settings.js +0 -103
- package/dist/src/screens/consent-skin.d.ts +0 -4
- package/dist/src/screens/consent-skin.js +0 -18
- package/dist/src/screens/financial-connections.d.ts +0 -5
- package/dist/src/screens/financial-connections.js +0 -90
- package/dist/src/screens/identity.d.ts +0 -5
- package/dist/src/screens/identity.js +0 -86
- package/dist/src/screens/onboarding.d.ts +0 -13
- package/dist/src/screens/portal.d.ts +0 -5
- package/dist/src/screens/public-details.d.ts +0 -5
- package/dist/src/screens/public-details.js +0 -90
- package/dist/src/semantics/after-payment.d.ts +0 -22
- package/dist/src/semantics/after-payment.js +0 -99
- package/dist/src/semantics/apps-secrets.d.ts +0 -2
- package/dist/src/semantics/billing.d.ts +0 -2
- package/dist/src/semantics/billing.js +0 -220
- package/dist/src/semantics/connect.d.ts +0 -5
- package/dist/src/semantics/connect.js +0 -493
- package/dist/src/semantics/credit-notes.d.ts +0 -2
- package/dist/src/semantics/credit-notes.js +0 -172
- package/dist/src/semantics/disputes.d.ts +0 -2
- package/dist/src/semantics/disputes.js +0 -51
- package/dist/src/semantics/ephemeral-keys.d.ts +0 -2
- package/dist/src/semantics/ephemeral-keys.js +0 -34
- package/dist/src/semantics/files.d.ts +0 -2
- package/dist/src/semantics/files.js +0 -125
- package/dist/src/semantics/ledger.d.ts +0 -59
- package/dist/src/semantics/ledger.js +0 -200
- package/dist/src/semantics/payment-intents.d.ts +0 -18
- package/dist/src/semantics/payment-intents.js +0 -452
- package/dist/src/semantics/payment-links.d.ts +0 -2
- package/dist/src/semantics/payment-links.js +0 -133
- package/dist/src/semantics/payment-methods.d.ts +0 -20
- package/dist/src/semantics/payment-methods.js +0 -140
- package/dist/src/semantics/plans.d.ts +0 -5
- package/dist/src/semantics/plans.js +0 -121
- package/dist/src/semantics/platform.d.ts +0 -9
- package/dist/src/semantics/platform.js +0 -206
- package/dist/src/semantics/renewals.d.ts +0 -47
- package/dist/src/semantics/renewals.js +0 -281
- package/dist/src/semantics/setup-intents.d.ts +0 -2
- package/dist/src/semantics/setup-intents.js +0 -84
- package/dist/src/semantics/subscription-schedules.d.ts +0 -2
- package/dist/src/semantics/subscription-schedules.js +0 -119
- package/dist/src/semantics/tax.d.ts +0 -2
- package/dist/src/semantics/tax.js +0 -197
- package/dist/src/semantics/terminal.d.ts +0 -5
- package/dist/src/semantics/terminal.js +0 -182
- package/dist/src/semantics/test-clocks.d.ts +0 -6
- package/dist/src/semantics/test-clocks.js +0 -73
- package/dist/src/semantics/tokens.d.ts +0 -4
- package/dist/src/semantics/tokens.js +0 -44
- package/dist/src/semantics/treasury.d.ts +0 -2
- package/dist/src/semantics/treasury.js +0 -377
- package/dist/src/semantics/webhook-endpoints.d.ts +0 -3
- package/dist/src/semantics/webhook-endpoints.js +0 -85
- package/dist/src/stripe-budget.d.ts +0 -55
- package/dist/src/stripe-budget.js +0 -155
- package/dist/src/stripe-capabilities.d.ts +0 -3
- package/dist/src/stripe-capabilities.js +0 -5836
- package/dist/src/stripe-conformance.d.ts +0 -43
- package/dist/src/stripe-conformance.js +0 -105
- package/dist/src/stripe-connector.d.ts +0 -161
- package/dist/src/stripe-connector.js +0 -414
- package/dist/src/stripe-emit.d.ts +0 -2
- package/dist/src/stripe-emit.js +0 -145
- package/dist/src/stripe-events.d.ts +0 -93
- package/dist/src/stripe-events.js +0 -392
- package/dist/src/stripe-js.d.ts +0 -4
- package/dist/src/stripe-js.js +0 -70
- package/dist/src/stripe-mirror-ui.d.ts +0 -15
- package/dist/src/stripe-mirror-ui.js +0 -87
- package/dist/src/stripe-perform-harness.d.ts +0 -9
- package/dist/src/stripe-perform-harness.js +0 -26
- package/dist/src/stripe-server.d.ts +0 -33
- package/dist/src/stripe-server.js +0 -429
- package/dist/src/stripe-shared.d.ts +0 -109
- package/dist/src/stripe-shared.js +0 -276
- package/dist/src/stripe-ui-conformance.d.ts +0 -5
- package/dist/src/stripe-ui-conformance.js +0 -79
- package/dist/src/stripe-ui-structure.d.ts +0 -3
- package/dist/src/stripe-ui-structure.js +0 -168
- package/dist/test-fixtures/stripe-known-deviations.json +0 -110
- package/dist/test-fixtures/stripe-openapi-operations.SOURCE.md +0 -14
- package/dist/test-fixtures/stripe-openapi-operations.json +0 -4717
- package/dist/test-fixtures/stripe-schemas.SOURCE.md +0 -35
- package/dist/test-fixtures/stripe-schemas.json +0 -3813
- package/src/screens/connect-oauth.tsx +0 -400
- package/src/screens/connect-settings.tsx +0 -121
- package/src/screens/consent-skin.ts +0 -20
- package/src/screens/financial-connections.tsx +0 -101
- package/src/screens/identity.tsx +0 -96
- package/src/screens/public-details.tsx +0 -105
- package/src/semantics/after-payment.ts +0 -118
- package/src/semantics/billing.ts +0 -216
- package/src/semantics/connect.ts +0 -487
- package/src/semantics/credit-notes.ts +0 -168
- package/src/semantics/disputes.ts +0 -62
- package/src/semantics/ephemeral-keys.ts +0 -34
- package/src/semantics/files.ts +0 -143
- package/src/semantics/ledger.ts +0 -253
- package/src/semantics/payment-intents.ts +0 -463
- package/src/semantics/payment-links.ts +0 -148
- package/src/semantics/payment-methods.ts +0 -145
- package/src/semantics/plans.ts +0 -131
- package/src/semantics/platform.ts +0 -220
- package/src/semantics/renewals.ts +0 -279
- package/src/semantics/setup-intents.ts +0 -87
- package/src/semantics/subscription-schedules.ts +0 -129
- package/src/semantics/tax.ts +0 -220
- package/src/semantics/terminal.ts +0 -195
- package/src/semantics/test-clocks.ts +0 -77
- package/src/semantics/tokens.ts +0 -52
- package/src/semantics/treasury.ts +0 -383
- package/src/semantics/webhook-endpoints.ts +0 -87
- package/src/stripe-budget.ts +0 -181
- package/src/stripe-capabilities.ts +0 -5651
- package/src/stripe-conformance.ts +0 -124
- package/src/stripe-connector.ts +0 -462
- package/src/stripe-emit.ts +0 -157
- package/src/stripe-events.ts +0 -434
- package/src/stripe-js.ts +0 -70
- package/src/stripe-mirror-ui.ts +0 -90
- package/src/stripe-perform-harness.ts +0 -29
- package/src/stripe-server.ts +0 -393
- package/src/stripe-shared.ts +0 -297
- package/src/stripe-ui-conformance.ts +0 -88
- package/src/stripe-ui-structure.ts +0 -182
- package/test-fixtures/stripe-known-deviations.json +0 -110
- package/test-fixtures/stripe-openapi-operations.json +0 -4717
- package/test-fixtures/stripe-schemas.json +0 -3813
- /package/dist/src/{screens → engine}/industries.d.ts +0 -0
- /package/dist/src/{screens → engine}/industries.js +0 -0
- /package/dist/src/{semantics → engine}/test-cards.d.ts +0 -0
- /package/dist/src/{semantics → engine}/test-cards.js +0 -0
- /package/src/{screens → engine}/industries.ts +0 -0
- /package/src/{semantics → engine}/test-cards.ts +0 -0
|
@@ -0,0 +1,634 @@
|
|
|
1
|
+
const OPEN = ['requires_payment_method', 'requires_confirmation', 'requires_action', 'requires_capture', 'processing'];
|
|
2
|
+
/** A move no API call makes: Stripe's own (`vendor`), the clock's (`time`), or the person on a
|
|
3
|
+
* Stripe-hosted page (`external`: Checkout, the billing portal, a hosted invoice or 3DS page). */
|
|
4
|
+
const by = (actor, from, to, source) => ({ actor, from, to, source });
|
|
5
|
+
/** A bank account's `status` as a payout or payment destination. Stripe validates its routing number,
|
|
6
|
+
* verifies it (micro-deposits, or instantly) and marks it errored when a payout or debit to it fails
|
|
7
|
+
* (the page each machine cites); no call the twin serves does any of that (the customer-source verify is
|
|
8
|
+
* a gap), so no move of it is the twin's. */
|
|
9
|
+
const bankAccountStatus = (_doc) => ({ initial: 'new', transitions: [] });
|
|
10
|
+
/** A flag an update sets either way. */
|
|
11
|
+
const flag = (operation, source) => ['true', 'false'].map((to) => ({ operation, from: '*', to, source }));
|
|
12
|
+
/** A PaymentIntent's `status`: which operation may move it from where, and what Stripe answers otherwise. */
|
|
13
|
+
const paymentIntentStatus = {
|
|
14
|
+
// "After you create the PaymentIntent, its status is `requires_payment_method` until you attach a payment method"
|
|
15
|
+
// (docs.stripe.com/payments/paymentintents/lifecycle)
|
|
16
|
+
initial: 'requires_payment_method',
|
|
17
|
+
transitions: [
|
|
18
|
+
// created with its payment method, it "enters the `requires_confirmation` status and is ready to confirm" (the same page)
|
|
19
|
+
{ operation: 'PostPaymentIntents', from: ['requires_payment_method'], to: 'requires_confirmation', source: 'https://docs.stripe.com/payments/paymentintents/lifecycle' },
|
|
20
|
+
// a bank debit confirmed (created with `confirm`, or confirmed) is submitted and processes: "The PaymentIntent you
|
|
21
|
+
// create initially has a status of `processing`"
|
|
22
|
+
...['PostPaymentIntents',].map((operation) => ({
|
|
23
|
+
operation, from: ['requires_payment_method', 'requires_confirmation', 'requires_action'], to: 'processing',
|
|
24
|
+
source: 'https://docs.stripe.com/payments/ach-direct-debit/accept-a-payment?payment-ui=direct-api',
|
|
25
|
+
})),
|
|
26
|
+
// and succeeds: "After the payment has succeeded, the PaymentIntent status is updated from `processing`
|
|
27
|
+
// to `succeeded`" (../engine/payment-intents.ts settleBankDebits)
|
|
28
|
+
by('vendor', ['processing'], 'succeeded', 'https://docs.stripe.com/payments/ach-direct-debit/accept-a-payment?payment-ui=direct-api'),
|
|
29
|
+
// creating one with `confirm` confirms it at once, landing where a confirm lands
|
|
30
|
+
...['requires_payment_method', 'requires_action', 'requires_capture', 'succeeded'].map((to) => ({
|
|
31
|
+
operation: 'PostPaymentIntents',
|
|
32
|
+
from: ['requires_payment_method', 'requires_confirmation'],
|
|
33
|
+
to,
|
|
34
|
+
source: 'spec:PostPaymentIntents "Set to `true` to attempt to [confirm this PaymentIntent](https://docs.stripe.com/api/payment_intents/confirm) immediately."',
|
|
35
|
+
})),
|
|
36
|
+
{
|
|
37
|
+
operation: 'PostPaymentIntentsIntentCancel', from: OPEN, to: 'canceled',
|
|
38
|
+
refusal: { status: 400, code: 'payment_intent_unexpected_state', message: 'You cannot cancel this PaymentIntent because it has a status of {from}. Only a PaymentIntent with one of the following statuses may be canceled: requires_payment_method, requires_capture, requires_confirmation, requires_action, processing.' },
|
|
39
|
+
source: 'https://docs.stripe.com/api/payment_intents/cancel',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
// paying the invoice an intent collects for settles the intent
|
|
43
|
+
operation: 'PostInvoicesInvoicePay',
|
|
44
|
+
from: OPEN,
|
|
45
|
+
to: 'succeeded',
|
|
46
|
+
source: 'https://docs.stripe.com/api/invoices/pay',
|
|
47
|
+
},
|
|
48
|
+
// the customer pays, in the billing portal, the invoice an intent collects for after its charge was declined
|
|
49
|
+
by('external', ['requires_payment_method'], 'succeeded', 'https://docs.stripe.com/customer-management'),
|
|
50
|
+
// Stripe also fails a bank debit back to needing a payment method, completes 3-D Secure on the bank's page and
|
|
51
|
+
// cancels a hold left uncaptured; the twin's bank debits succeed unless their test account stays processing, it has no 3-D Secure page, and it keeps
|
|
52
|
+
// holds until they are canceled. Capture, increment_authorization, verify_microdeposits, apply_customer_balance and
|
|
53
|
+
// the Terminal reader's present_payment_method are the gap (no demand, life step or refresh sends them:
|
|
54
|
+
// ../manifest.ts unmodeled), so no move of theirs is declared.
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
/** A charge's `captured`: an authorization (capture_method=manual) is captured once, by the Charges API's capture or
|
|
58
|
+
* its PaymentIntent's; both are the gap here (no demand, life step or refresh sends them: ../manifest.ts unmodeled), so
|
|
59
|
+
* a held charge stays uncaptured until its intent is canceled, and no move is declared. */
|
|
60
|
+
const chargeCaptured = {
|
|
61
|
+
initial: true,
|
|
62
|
+
transitions: [],
|
|
63
|
+
};
|
|
64
|
+
/** A charge's `refunded`: true once refunds take its whole amount. A capture or a cancel never makes it so: "`refunded` will no longer be `true` for payment cancellation
|
|
65
|
+
* flows", and a partial capture makes no Refund (docs.stripe.com/changelog/basil/2025-03-31/remove-refund-from-partial-
|
|
66
|
+
* capture-and-payment-cancellation-flow). */
|
|
67
|
+
const chargeRefunded = {
|
|
68
|
+
initial: false,
|
|
69
|
+
transitions: [
|
|
70
|
+
{ operation: 'PostRefunds', from: ['false'], to: 'true', source: 'https://docs.stripe.com/api/charges/object#charge_object-refunded' },
|
|
71
|
+
// (a charge's own refunds path, a credit note's refund and a refund's cancel are the gap here: ../manifest.ts unmodeled)
|
|
72
|
+
// (an authorization left uncaptured is canceled after seven days, "Uncaptured PaymentIntents are cancelled a set
|
|
73
|
+
// number of days (7 by default) after their creation", docs.stripe.com/api/payment_intents/capture; the twin keeps it)
|
|
74
|
+
],
|
|
75
|
+
};
|
|
76
|
+
/** A charge's `status`: the twin settles a charge when it is made (a declined one is never
|
|
77
|
+
* stored); an asynchronous one settles later, on the network's word. */
|
|
78
|
+
const chargeStatus = {
|
|
79
|
+
initial: 'succeeded',
|
|
80
|
+
transitions: [
|
|
81
|
+
// (an asynchronous charge is pending at Stripe until it settles or fails; the twin's settle when made)
|
|
82
|
+
],
|
|
83
|
+
};
|
|
84
|
+
/** A charge's `paid`: true once it succeeded or was authorized; a pending one becomes paid when it settles. */
|
|
85
|
+
const chargePaid = {
|
|
86
|
+
initial: true,
|
|
87
|
+
// (a charge is paid when it settles; the twin's settle when made)
|
|
88
|
+
transitions: [],
|
|
89
|
+
};
|
|
90
|
+
/** A refund's `status`: held pending for want of balance, then made; the rest is the network's. (Canceling one that
|
|
91
|
+
* waits on the customer is the gap here: ../manifest.ts unmodeled.) */
|
|
92
|
+
const refundStatus = {
|
|
93
|
+
initial: 'succeeded',
|
|
94
|
+
transitions: [
|
|
95
|
+
{ operation: 'PostRefunds', from: ['succeeded'], to: 'pending', source: 'https://docs.stripe.com/refunds' },
|
|
96
|
+
by('vendor', ['pending'], 'succeeded', 'https://docs.stripe.com/refunds'),
|
|
97
|
+
// a bank-transfer payment's refund waits in requires_action for the customer's bank details, and is made so
|
|
98
|
+
// (semantics/refunds.ts); (Stripe also fails some refunds; the twin's do not fail)
|
|
99
|
+
],
|
|
100
|
+
};
|
|
101
|
+
/** A SetupIntent's `status`: confirm settles it, or leaves a bank account awaiting micro-deposits. (Its cancel and its
|
|
102
|
+
* micro-deposit verification are the gap here: ../manifest.ts unmodeled.) */
|
|
103
|
+
const setupIntentStatus = {
|
|
104
|
+
// "After you create the SetupIntent, it has a status of `requires_payment_method` until you attach a payment method"
|
|
105
|
+
// (docs.stripe.com/payments/paymentintents/lifecycle)
|
|
106
|
+
initial: 'requires_payment_method',
|
|
107
|
+
transitions: [
|
|
108
|
+
// (Stripe completes 3-D Secure on the bank's page and settles an asynchronous method from processing; the
|
|
109
|
+
// twin has no such page and settles every method at once)
|
|
110
|
+
],
|
|
111
|
+
};
|
|
112
|
+
const invoiceRefusal = (message) => ({ status: 400, code: 'invoice_not_editable', message });
|
|
113
|
+
/** An invoice's `status`: a draft is finalized (or sent, which finalizes it) into open, an open one
|
|
114
|
+
* is paid, written off or voided. Sending leaves any other status where it is. */
|
|
115
|
+
const invoiceStatus = {
|
|
116
|
+
initial: 'draft',
|
|
117
|
+
transitions: [
|
|
118
|
+
{ operation: 'PostInvoicesInvoicePay', from: ['draft'], to: 'open', source: 'https://docs.stripe.com/invoicing/integration' },
|
|
119
|
+
{
|
|
120
|
+
// paying a draft finalizes it on the way: "To finalize a draft invoice, use the Dashboard, send it to the customer, or
|
|
121
|
+
// pay it" (docs.stripe.com/invoicing/integration)
|
|
122
|
+
operation: 'PostInvoicesInvoicePay',
|
|
123
|
+
from: ['draft', 'open', 'uncollectible'],
|
|
124
|
+
to: 'paid',
|
|
125
|
+
refusal: invoiceRefusal('This invoice cannot be paid because it has status {from}.'),
|
|
126
|
+
refusals: { paid: { status: 400, code: 'invoice_payment_intent_requires_action', message: 'This invoice has already been paid.' } },
|
|
127
|
+
source: 'https://docs.stripe.com/api/invoices/pay',
|
|
128
|
+
},
|
|
129
|
+
// (marking one uncollectible is the gap here: ../manifest.ts unmodeled)
|
|
130
|
+
// a guard: only a draft is deleted; a finalized invoice is voided instead
|
|
131
|
+
// in any other state it is refused (a refusal with no `to` refuses where it stands)
|
|
132
|
+
{
|
|
133
|
+
// only a finalized invoice is voided; a draft is deleted
|
|
134
|
+
operation: 'PostInvoicesInvoiceVoid',
|
|
135
|
+
from: ['open', 'uncollectible'],
|
|
136
|
+
to: 'void',
|
|
137
|
+
refusal: invoiceRefusal('This invoice cannot be voided because it has status {from}.'),
|
|
138
|
+
source: 'https://docs.stripe.com/api/invoices/void',
|
|
139
|
+
},
|
|
140
|
+
// confirming the PaymentIntent an invoice collects through pays the invoice
|
|
141
|
+
// as does its bank debit succeeding once submitted (../engine/payment-intents.ts settleBankDebits)
|
|
142
|
+
by('vendor', ['draft', 'open', 'uncollectible'], 'paid', 'https://docs.stripe.com/billing/subscriptions/build-subscriptions'),
|
|
143
|
+
// (a bank transfer reconciled from the customer's cash balance pays one at Stripe; funding a cash balance is the gap
|
|
144
|
+
// here: ../manifest.ts unmodeled)
|
|
145
|
+
// a subscription's first invoice is paid on the Checkout page that started it
|
|
146
|
+
by('external', ['draft'], 'paid', 'https://docs.stripe.com/payments/checkout/how-checkout-works'),
|
|
147
|
+
// a subscription's renewal, drafted at its period's end, is finalized about an hour later and charged: paid, or
|
|
148
|
+
// open when the charge is declined (../engine/renewals.ts)
|
|
149
|
+
by('time', ['draft'], 'paid', 'https://docs.stripe.com/invoicing/integration/workflow-transitions#finalized'),
|
|
150
|
+
by('time', ['draft'], 'open', 'https://docs.stripe.com/billing/subscriptions/overview#payment-status'),
|
|
151
|
+
// an update that ends a subscription's trial invoices its new period and attempts payment at once: paid, or open
|
|
152
|
+
// when the charge is declined or not attempted (semantics/subscriptions.ts applyTrialEnd)
|
|
153
|
+
{ operation: 'PostSubscriptionsSubscriptionExposedId', from: ['draft'], to: 'paid', source: 'https://docs.stripe.com/billing/subscriptions/upgrade-downgrade#immediate-payment' },
|
|
154
|
+
// a trialing subscription's first invoice, for nothing, is paid as it is made ("An immediate invoice is still
|
|
155
|
+
// created, but the amount is 0", docs.stripe.com/billing/subscriptions/trials/free-trials)
|
|
156
|
+
{ operation: 'PostSubscriptionsSubscriptionExposedId', from: ['draft'], to: 'open', source: 'https://docs.stripe.com/billing/subscriptions/upgrade-downgrade#immediate-payment' },
|
|
157
|
+
// the customer pays an open invoice in the billing portal
|
|
158
|
+
by('external', ['open'], 'paid', 'https://docs.stripe.com/customer-management'),
|
|
159
|
+
// (Stripe also finalizes any other auto-advancing draft after an hour, retries an open invoice on its schedule
|
|
160
|
+
// and, retries exhausted, may write it off, and takes payment on the hosted invoice page; the twin's other
|
|
161
|
+
// invoices move only by the calls above)
|
|
162
|
+
],
|
|
163
|
+
};
|
|
164
|
+
/** A subscription's `status` as the twin's own operations move it; canceling ends any subscription. */
|
|
165
|
+
const subscriptionStatus = {
|
|
166
|
+
initial: 'active',
|
|
167
|
+
transitions: [
|
|
168
|
+
{ operation: 'DeleteSubscriptionsSubscriptionExposedId', from: '*', to: 'canceled', source: 'https://docs.stripe.com/api/subscriptions/cancel' },
|
|
169
|
+
// (a test clock's advance moves no subscription itself: when the clock reaches its target, a trial that ended there
|
|
170
|
+
// ends by time's move below, on the next request; ../engine/test-clocks.ts finishClockAdvances)
|
|
171
|
+
// (canceling a subscription schedule, which cancels its subscription, is the gap here: ../manifest.ts unmodeled)
|
|
172
|
+
// confirming the first invoice's PaymentIntent, or paying the invoice itself, pays it and activates the subscription
|
|
173
|
+
// or when its bank debit succeeds once submitted (../engine/payment-intents.ts settleBankDebits)
|
|
174
|
+
by('vendor', ['incomplete'], 'active', 'https://docs.stripe.com/billing/subscriptions/build-subscriptions'),
|
|
175
|
+
// paying the invoice a subscription waits on (its first, or a renewal that failed) makes it active
|
|
176
|
+
{ operation: 'PostInvoicesInvoicePay', from: ['incomplete', 'past_due'], to: 'active', source: 'https://docs.stripe.com/billing/subscriptions/overview#payment-status' },
|
|
177
|
+
// an update's `trial_end`: `now` ends a trial at once and charges the new period, active when paid and past_due when
|
|
178
|
+
// not; a future timestamp starts a trial on a subscription out of one (semantics/subscriptions.ts applyTrialEnd)
|
|
179
|
+
{ operation: 'PostSubscriptionsSubscriptionExposedId', from: ['trialing'], to: 'active', source: 'https://docs.stripe.com/api/subscriptions/update#update_subscription-trial_end' },
|
|
180
|
+
{ operation: 'PostSubscriptionsSubscriptionExposedId', from: ['trialing'], to: 'past_due', source: 'https://docs.stripe.com/billing/subscriptions/upgrade-downgrade#immediate-payment' },
|
|
181
|
+
{
|
|
182
|
+
operation: 'PostSubscriptionsSubscriptionExposedId', from: ['active', 'past_due'], to: 'trialing',
|
|
183
|
+
// (Where the documentation stops and the twin decides: the wording of the refusal for a subscription neither
|
|
184
|
+
// active nor past_due; a canceled one answers what Stripe answers any update of a canceled subscription.)
|
|
185
|
+
refusal: { status: 400, message: 'A trial can only be added to an active or past_due subscription; this one is {from}.' },
|
|
186
|
+
refusals: { canceled: { status: 400, message: 'A canceled subscription can only update its cancellation_details and metadata.' } },
|
|
187
|
+
source: 'https://docs.stripe.com/billing/subscriptions/trials/free-trials#adding-a-new-trial-to-a-subscription-previously-in-a-trial',
|
|
188
|
+
},
|
|
189
|
+
// a trial ends on its own clock (Stripe pauses one that ends with no payment method to bill; the twin's
|
|
190
|
+
// trials end active), and a renewal whose charge is declined leaves the subscription past_due
|
|
191
|
+
// (../engine/renewals.ts)
|
|
192
|
+
by('time', ['trialing'], 'active', 'https://docs.stripe.com/billing/subscriptions/trials'),
|
|
193
|
+
by('time', ['active'], 'past_due', 'https://docs.stripe.com/billing/subscriptions/overview#payment-status'),
|
|
194
|
+
// one set to cancel at its period's end is canceled when the period ends
|
|
195
|
+
by('time', ['active', 'trialing', 'past_due'], 'canceled', 'https://docs.stripe.com/billing/subscriptions/cancel#cancel-at-end-of-cycle'),
|
|
196
|
+
// the customer pays the invoice it waits on in the billing portal
|
|
197
|
+
by('external', ['past_due'], 'active', 'https://docs.stripe.com/customer-management'),
|
|
198
|
+
// (Stripe also expires an incomplete subscription after 23 hours, and retries a failed renewal on its schedule,
|
|
199
|
+
// the settings ending the retries unpaid or canceled; the twin makes no retry)
|
|
200
|
+
// the customer cancels in the billing portal
|
|
201
|
+
by('external', ['active', 'trialing', 'past_due', 'unpaid', 'paused'], 'canceled', 'spec:/components/schemas/portal_subscription_cancel "Whether to cancel subscriptions immediately or at the end of the billing period."'),
|
|
202
|
+
],
|
|
203
|
+
};
|
|
204
|
+
const notOpen = (verb) => ({ status: 400, code: 'checkout_session_not_open', message: `You may only ${verb} a Checkout Session that is currently in the \`open\` state.` });
|
|
205
|
+
/** A Checkout Session's `status`: an open session expires (asked to, or 24 hours on), or completes
|
|
206
|
+
* when the customer pays on the hosted page. Completion is the external actor's move, the one the
|
|
207
|
+
* hosted Checkout page (src/screens/checkout.tsx) performs. */
|
|
208
|
+
const checkoutStatus = {
|
|
209
|
+
initial: 'open',
|
|
210
|
+
transitions: [
|
|
211
|
+
{ actor: 'external', from: ['open'], to: 'complete', refusal: notOpen('complete'), source: 'https://docs.stripe.com/api/checkout/sessions/object#checkout_session_object-status' },
|
|
212
|
+
// (Stripe expires an open session at expires_at; the twin keeps it open until asked)
|
|
213
|
+
],
|
|
214
|
+
};
|
|
215
|
+
/** A Checkout Session's `payment_status`: the customer completing a payment or subscription session
|
|
216
|
+
* pays it; a delayed payment method settles later. */
|
|
217
|
+
const checkoutPaymentStatus = {
|
|
218
|
+
initial: 'unpaid',
|
|
219
|
+
transitions: [
|
|
220
|
+
{ actor: 'external', from: '*', to: 'paid', source: 'https://docs.stripe.com/api/checkout/sessions/object#checkout_session_object-payment_status' },
|
|
221
|
+
// (a delayed method settles a session later at Stripe; the twin's settle on the page)
|
|
222
|
+
],
|
|
223
|
+
};
|
|
224
|
+
/** A dispute's `status`: a disputed test card's charge opens one (needs_response, or warning_needs_response for an
|
|
225
|
+
* inquiry). Submitting evidence and closing (conceding) are the gap here (../manifest.ts unmodeled), so nothing puts a
|
|
226
|
+
* dispute under review for the bank to decide; the bank escalates an inquiry and loses one left unanswered at
|
|
227
|
+
* Stripe, and the twin decides none. */
|
|
228
|
+
const disputeStatus = {
|
|
229
|
+
initial: 'warning_needs_response',
|
|
230
|
+
transitions: [],
|
|
231
|
+
};
|
|
232
|
+
/** A payout's `status`: cancel ends it; reversing cancels it and pays a reversal, never twice. */
|
|
233
|
+
const payoutStatus = {
|
|
234
|
+
initial: 'pending',
|
|
235
|
+
transitions: [
|
|
236
|
+
// (canceling a pending payout and reversing a paid one are the gap here: ../manifest.ts unmodeled)
|
|
237
|
+
// it arrives in the bank on its arrival date
|
|
238
|
+
by('time', ['pending'], 'paid', 'https://docs.stripe.com/payouts#payout-statuses'),
|
|
239
|
+
// (a bank may fail a payout at Stripe; the twin's arrive)
|
|
240
|
+
],
|
|
241
|
+
};
|
|
242
|
+
/** A credit note's `status`: issued, then voided once at Stripe. Issuing and voiding one are the gap here
|
|
243
|
+
* (../manifest.ts unmodeled): a vendor-backed World reads credit notes back from its root (GetCreditNotes). */
|
|
244
|
+
const creditNoteStatus = {
|
|
245
|
+
initial: 'issued',
|
|
246
|
+
transitions: [],
|
|
247
|
+
};
|
|
248
|
+
/** A subscription schedule's `status`: releasing ends it, and an ended one refuses it. (Canceling one is the gap here:
|
|
249
|
+
* ../manifest.ts unmodeled.) */
|
|
250
|
+
const scheduleStatus = {
|
|
251
|
+
initial: 'active',
|
|
252
|
+
transitions: [
|
|
253
|
+
// "A schedule can only be released if its status is not_started or active" (the release page)
|
|
254
|
+
// its phases run on the clock: it starts at its start date and ends with its last phase
|
|
255
|
+
// (a schedule whose end_behavior is cancel completes at its end at Stripe; the twin's release)
|
|
256
|
+
// (Stripe starts a schedule at its start date and ends it with its last phase; the twin's start at once
|
|
257
|
+
// and end when canceled or released)
|
|
258
|
+
],
|
|
259
|
+
};
|
|
260
|
+
/** A quote's `status`: at Stripe a draft is finalized into open, an open one accepted, and either canceled. Quotes are
|
|
261
|
+
* the gap here (../manifest.ts unmodeled): a vendor-backed World reads them back from its root (GetQuotes), so no
|
|
262
|
+
* move is the twin's. */
|
|
263
|
+
const quoteStatus = {
|
|
264
|
+
initial: 'draft',
|
|
265
|
+
transitions: [],
|
|
266
|
+
};
|
|
267
|
+
const setBy = (operation, values, source) => values.map((to) => ({ operation, from: '*', to, source }));
|
|
268
|
+
/** An Issuing authorization's `status`: approve and decline close a pending one, once; a capture
|
|
269
|
+
* closes it, or leaves it pending when told not to close. */
|
|
270
|
+
const issuingAuthorizationStatus = {
|
|
271
|
+
initial: 'pending',
|
|
272
|
+
transitions: [
|
|
273
|
+
// approving keeps it pending (approved) until the merchant captures; declining closes it
|
|
274
|
+
{ operation: 'PostIssuingAuthorizationsAuthorizationApprove', from: ['pending'], source: 'https://docs.stripe.com/issuing/purchases/authorizations' },
|
|
275
|
+
// in any other state it is refused (a refusal with no `to` refuses where it stands)
|
|
276
|
+
{ operation: 'PostIssuingAuthorizationsAuthorizationApprove', from: '*', refusal: { status: 400, code: 'authorization_already_finalized', message: 'This authorization has already been finalized (status {from}).' }, source: 'https://docs.stripe.com/issuing/purchases/authorizations' },
|
|
277
|
+
{ operation: 'PostIssuingAuthorizationsAuthorizationDecline', from: ['pending'], to: 'closed', refusal: { status: 400, code: 'authorization_already_finalized', message: 'This authorization has already been finalized (status {from}).' }, source: 'https://docs.stripe.com/api/issuing/authorizations/decline' },
|
|
278
|
+
{ operation: 'PostTestHelpersIssuingAuthorizationsAuthorizationCapture', from: ['pending'], to: 'closed', source: 'https://docs.stripe.com/api/issuing/authorizations/test_mode_capture' },
|
|
279
|
+
{ operation: 'PostTestHelpersIssuingAuthorizationsAuthorizationCapture', from: ['pending'], source: 'https://docs.stripe.com/api/issuing/authorizations/test_mode_capture' },
|
|
280
|
+
// a real-time request no one answered is decided when its window ends: "If Stripe doesn't receive your approve or
|
|
281
|
+
// decline response within 2 seconds, the Authorization is automatically approved or declined based on your timeout
|
|
282
|
+
// settings" (semantics/issuing.ts lapseRealtimeRequests)
|
|
283
|
+
by('time', ['pending'], 'closed', 'https://docs.stripe.com/issuing/controls/real-time-authorizations'),
|
|
284
|
+
// (Stripe also closes, reverses and expires one as the merchant and the clock act; in test mode the
|
|
285
|
+
// capture helper above closes it, and the twin serves no other)
|
|
286
|
+
],
|
|
287
|
+
};
|
|
288
|
+
/** A Treasury flow's `status`: at Stripe a processing flow cancels, the network posts or fails it, and a posted one may
|
|
289
|
+
* come back returned. Treasury's flows are the gap here (../manifest.ts unmodeled): a vendor-backed World reads them
|
|
290
|
+
* back from its root, so no move is the twin's. */
|
|
291
|
+
const flow = { initial: 'processing', transitions: [] };
|
|
292
|
+
export const states = {
|
|
293
|
+
'billing.meter': {
|
|
294
|
+
notState: ['event_time_window'],
|
|
295
|
+
// (deactivating and reactivating a meter are the gap here: ../manifest.ts unmodeled)
|
|
296
|
+
state: { status: { initial: 'active', transitions: [] } },
|
|
297
|
+
},
|
|
298
|
+
'billing.credit_grant': {
|
|
299
|
+
notState: ['category'],
|
|
300
|
+
},
|
|
301
|
+
'billing.alert': {
|
|
302
|
+
// (activating, deactivating and archiving an alert are the gap here: ../manifest.ts unmodeled)
|
|
303
|
+
state: { status: { initial: 'active', transitions: [] } },
|
|
304
|
+
},
|
|
305
|
+
payment_intent: {
|
|
306
|
+
state: { status: paymentIntentStatus },
|
|
307
|
+
notState: ['cancellation_reason', 'capture_method', 'confirmation_method', 'setup_future_usage'],
|
|
308
|
+
},
|
|
309
|
+
customer: {
|
|
310
|
+
notState: ['tax_exempt'],
|
|
311
|
+
},
|
|
312
|
+
tax_id: {
|
|
313
|
+
notState: ['type'],
|
|
314
|
+
},
|
|
315
|
+
customer_balance_transaction: {
|
|
316
|
+
notState: ['type'],
|
|
317
|
+
},
|
|
318
|
+
customer_cash_balance_transaction: {
|
|
319
|
+
notState: ['type'],
|
|
320
|
+
},
|
|
321
|
+
payment_source: {
|
|
322
|
+
state: { status: bankAccountStatus('https://docs.stripe.com/api/customer_bank_accounts/object#customer_bank_account_object-status') },
|
|
323
|
+
notState: ['allow_redisplay', 'business_type', 'regulated_status', 'type'],
|
|
324
|
+
},
|
|
325
|
+
source: {
|
|
326
|
+
state: {
|
|
327
|
+
status: {
|
|
328
|
+
initial: 'chargeable',
|
|
329
|
+
transitions: [
|
|
330
|
+
// (Stripe makes a redirect source chargeable when the customer authorizes it on the bank's page;
|
|
331
|
+
// the twin has no such page, so a non-card source stays pending)
|
|
332
|
+
// Stripe also fails a source the customer abandons, consumes a single-use one once charged and
|
|
333
|
+
// cancels one left unused; the twin's sources stay chargeable
|
|
334
|
+
],
|
|
335
|
+
},
|
|
336
|
+
},
|
|
337
|
+
notState: ['allow_redisplay', 'type'],
|
|
338
|
+
},
|
|
339
|
+
charge: {
|
|
340
|
+
state: { status: chargeStatus, captured: chargeCaptured, paid: chargePaid, refunded: chargeRefunded },
|
|
341
|
+
},
|
|
342
|
+
refund: {
|
|
343
|
+
state: { status: refundStatus },
|
|
344
|
+
notState: ['pending_reason', 'reason'],
|
|
345
|
+
},
|
|
346
|
+
setup_intent: {
|
|
347
|
+
state: { status: setupIntentStatus },
|
|
348
|
+
notState: ['cancellation_reason'],
|
|
349
|
+
},
|
|
350
|
+
payment_method: {
|
|
351
|
+
notState: ['allow_redisplay', 'type'],
|
|
352
|
+
},
|
|
353
|
+
subscription: {
|
|
354
|
+
state: { status: subscriptionStatus },
|
|
355
|
+
notState: ['collection_method'],
|
|
356
|
+
},
|
|
357
|
+
invoice: {
|
|
358
|
+
state: { status: invoiceStatus },
|
|
359
|
+
notState: ['billing_reason', 'collection_method', 'customer_tax_exempt'],
|
|
360
|
+
},
|
|
361
|
+
'checkout.session': {
|
|
362
|
+
state: { status: checkoutStatus, payment_status: checkoutPaymentStatus },
|
|
363
|
+
notState: ['billing_address_collection', 'customer_creation', 'locale', 'mode', 'origin_context', 'payment_method_collection', 'redirect_on_completion', 'submit_type', 'ui_mode'],
|
|
364
|
+
},
|
|
365
|
+
mandate: {
|
|
366
|
+
// Stripe activates a pending mandate, spends a single-use one with its payment and deactivates one revoked; the twin
|
|
367
|
+
// makes no mandate (micro-deposit verification, which accepts one, is the gap here: ../manifest.ts unmodeled), so no
|
|
368
|
+
// move is the twin's
|
|
369
|
+
state: { status: { initial: 'active', transitions: [] } },
|
|
370
|
+
notState: ['type'],
|
|
371
|
+
},
|
|
372
|
+
dispute: {
|
|
373
|
+
state: { status: disputeStatus },
|
|
374
|
+
notState: ['is_charge_refundable'],
|
|
375
|
+
},
|
|
376
|
+
payout: {
|
|
377
|
+
state: { status: payoutStatus },
|
|
378
|
+
notState: ['reconciliation_status', 'type'],
|
|
379
|
+
},
|
|
380
|
+
balance_transaction: {
|
|
381
|
+
state: { status: { initial: 'available', vendorInitial: 'pending', transitions: [by('time', ['pending'], 'available', 'https://docs.stripe.com/api/balance_transactions/object#balance_transaction_object-status')] } },
|
|
382
|
+
notState: ['balance_type', 'type'],
|
|
383
|
+
},
|
|
384
|
+
coupon: {
|
|
385
|
+
notState: ['duration'],
|
|
386
|
+
state: { valid: { initial: true, transitions: [by('time', ['true'], 'false', 'spec:/components/schemas/coupon/properties/redeem_by "Date after which the coupon can no longer be redeemed."')] } },
|
|
387
|
+
},
|
|
388
|
+
promotion_code: {
|
|
389
|
+
state: {
|
|
390
|
+
active: {
|
|
391
|
+
initial: true,
|
|
392
|
+
transitions: [
|
|
393
|
+
...flag('PostPromotionCodesPromotionCode', 'https://docs.stripe.com/api/promotion_codes/update'),
|
|
394
|
+
],
|
|
395
|
+
},
|
|
396
|
+
},
|
|
397
|
+
},
|
|
398
|
+
credit_note: {
|
|
399
|
+
state: { status: creditNoteStatus },
|
|
400
|
+
notState: ['reason', 'type'],
|
|
401
|
+
},
|
|
402
|
+
subscription_schedule: {
|
|
403
|
+
state: { status: scheduleStatus },
|
|
404
|
+
notState: ['end_behavior'],
|
|
405
|
+
},
|
|
406
|
+
'entitlements.feature': {
|
|
407
|
+
// (updating a feature, which "permanently" deactivates it, is the gap here: ../manifest.ts unmodeled)
|
|
408
|
+
state: { active: { initial: true, transitions: [] } },
|
|
409
|
+
},
|
|
410
|
+
'test_helpers.test_clock': {
|
|
411
|
+
state: {
|
|
412
|
+
status: {
|
|
413
|
+
initial: 'ready',
|
|
414
|
+
transitions: [
|
|
415
|
+
// "advancing: The clock has started to advance but hasn't reached the specified time"; "ready: The clock has
|
|
416
|
+
// completed advancing to the specified time" (docs.stripe.com/billing/testing/test-clocks/api-advanced-usage)
|
|
417
|
+
by('vendor', ['advancing'], 'ready', 'https://docs.stripe.com/billing/testing/test-clocks/api-advanced-usage'),
|
|
418
|
+
// (Stripe may also end an advance in internal_failure; the twin's advances complete)
|
|
419
|
+
],
|
|
420
|
+
},
|
|
421
|
+
},
|
|
422
|
+
},
|
|
423
|
+
webhook_endpoint: {
|
|
424
|
+
// (disabling and enabling an endpoint by its update is the gap here: ../manifest.ts unmodeled)
|
|
425
|
+
state: { status: { initial: 'enabled', transitions: [] } },
|
|
426
|
+
},
|
|
427
|
+
account: {
|
|
428
|
+
notState: ['business_type', 'type'],
|
|
429
|
+
},
|
|
430
|
+
person: {
|
|
431
|
+
notState: ['political_exposure'],
|
|
432
|
+
},
|
|
433
|
+
capability: {
|
|
434
|
+
state: {
|
|
435
|
+
status: {
|
|
436
|
+
initial: 'unrequested',
|
|
437
|
+
transitions: [
|
|
438
|
+
// (requesting or unrequesting a capability by its update is the gap here: ../manifest.ts unmodeled)
|
|
439
|
+
// Stripe reviews the account's requirements
|
|
440
|
+
],
|
|
441
|
+
},
|
|
442
|
+
},
|
|
443
|
+
},
|
|
444
|
+
external_account: {
|
|
445
|
+
state: { status: bankAccountStatus('https://docs.stripe.com/api/external_account_bank_accounts/object#account_bank_account_object-status') },
|
|
446
|
+
notState: ['allow_redisplay', 'regulated_status'],
|
|
447
|
+
},
|
|
448
|
+
application_fee: {
|
|
449
|
+
state: { refunded: { initial: false, transitions: [
|
|
450
|
+
{ operation: 'PostRefunds', from: ['false'], to: 'true', source: 'https://docs.stripe.com/connect/destination-charges#issue-refunds' },
|
|
451
|
+
] } },
|
|
452
|
+
},
|
|
453
|
+
file: {
|
|
454
|
+
notState: ['purpose'],
|
|
455
|
+
},
|
|
456
|
+
'identity.verification_session': {
|
|
457
|
+
// the person verifies on Stripe's hosted page, and Stripe decides (docs.stripe.com/identity/how-sessions-work);
|
|
458
|
+
// sessions are the gap here (../manifest.ts unmodeled) and a vendor-backed World reads them back from its root,
|
|
459
|
+
// so no move is the twin's
|
|
460
|
+
state: { status: { initial: 'requires_input', transitions: [] } },
|
|
461
|
+
notState: ['type'],
|
|
462
|
+
},
|
|
463
|
+
'identity.verification_report': {
|
|
464
|
+
notState: ['type'],
|
|
465
|
+
},
|
|
466
|
+
'billing_portal.session': {
|
|
467
|
+
notState: ['locale'],
|
|
468
|
+
},
|
|
469
|
+
'billing_portal.configuration': {
|
|
470
|
+
state: { active: { initial: true, transitions: [] } },
|
|
471
|
+
notState: ['is_default'],
|
|
472
|
+
},
|
|
473
|
+
tax_rate: {
|
|
474
|
+
// (archiving a rate by its update is the gap here: ../manifest.ts unmodeled)
|
|
475
|
+
state: { active: { initial: true, transitions: [] } },
|
|
476
|
+
notState: ['jurisdiction_level', 'rate_type', 'state', 'tax_type'],
|
|
477
|
+
},
|
|
478
|
+
'tax.settings': {
|
|
479
|
+
notState: ['status'],
|
|
480
|
+
},
|
|
481
|
+
'tax.registration': {
|
|
482
|
+
state: {
|
|
483
|
+
// Stripe schedules a registration with a future active_from and expires one at expires_at; the twin's
|
|
484
|
+
// are active from the start and never expire
|
|
485
|
+
status: { initial: 'active', transitions: [] },
|
|
486
|
+
},
|
|
487
|
+
},
|
|
488
|
+
'tax.transaction': {
|
|
489
|
+
notState: ['type'],
|
|
490
|
+
},
|
|
491
|
+
payment_link: {
|
|
492
|
+
// (switching a link off by its update is the gap here: ../manifest.ts unmodeled)
|
|
493
|
+
state: { active: { initial: true, transitions: [] } },
|
|
494
|
+
notState: ['billing_address_collection', 'customer_creation', 'payment_method_collection', 'submit_type'],
|
|
495
|
+
},
|
|
496
|
+
quote: {
|
|
497
|
+
state: { status: quoteStatus },
|
|
498
|
+
notState: ['collection_method'],
|
|
499
|
+
},
|
|
500
|
+
review: {
|
|
501
|
+
// an elevated-risk card's charge opens one (shared.ts openReview); approving it is the gap here (../manifest.ts
|
|
502
|
+
// unmodeled), and Stripe closes one when the payment is refunded or disputed, which the twin does not
|
|
503
|
+
state: { open: { initial: true, transitions: [] } },
|
|
504
|
+
notState: ['closed_reason', 'opened_reason'],
|
|
505
|
+
},
|
|
506
|
+
'radar.value_list': {
|
|
507
|
+
notState: ['item_type'],
|
|
508
|
+
},
|
|
509
|
+
'issuing.cardholder': {
|
|
510
|
+
// (a cardholder's status set by its update is the gap here: ../manifest.ts unmodeled)
|
|
511
|
+
state: { status: { initial: 'active', transitions: [] } },
|
|
512
|
+
notState: ['type'],
|
|
513
|
+
},
|
|
514
|
+
'issuing.card': {
|
|
515
|
+
// a card is made inactive unless its create names a status: "Defaults to inactive" (docs.stripe.com/api/issuing/cards/create)
|
|
516
|
+
state: { status: { initial: 'inactive', transitions: setBy('PostIssuingCardsCard', ['active', 'inactive', 'canceled'], 'https://docs.stripe.com/api/issuing/cards/update') } },
|
|
517
|
+
notState: ['cancellation_reason', 'replacement_reason', 'type'],
|
|
518
|
+
},
|
|
519
|
+
'issuing.authorization': {
|
|
520
|
+
state: { status: issuingAuthorizationStatus },
|
|
521
|
+
notState: ['authorization_method', 'card_presence'],
|
|
522
|
+
},
|
|
523
|
+
'issuing.transaction': {
|
|
524
|
+
notState: ['type', 'wallet'],
|
|
525
|
+
},
|
|
526
|
+
'issuing.dispute': {
|
|
527
|
+
// (submitting one to the network is the gap here, ../manifest.ts unmodeled, and Stripe decides a submitted dispute
|
|
528
|
+
// won or lost and expires one never submitted: a vendor-backed World reads them back from its root)
|
|
529
|
+
state: { status: { initial: 'unsubmitted', transitions: [] } },
|
|
530
|
+
notState: ['loss_reason'],
|
|
531
|
+
},
|
|
532
|
+
'issuing.personalization_design': {
|
|
533
|
+
// a new design waits on Stripe's review (docs.stripe.com/issuing/cards/physical/personalization-design); designs and
|
|
534
|
+
// the test helpers that decide them are the gap here (../manifest.ts unmodeled), read back from a vendor-backed root
|
|
535
|
+
state: { status: { initial: 'review', transitions: [] } },
|
|
536
|
+
},
|
|
537
|
+
'terminal.reader': {
|
|
538
|
+
notState: ['device_type'],
|
|
539
|
+
// (a real reader goes offline and back; the twin's simulated readers stay online)
|
|
540
|
+
state: { status: { initial: 'online', transitions: [] } },
|
|
541
|
+
},
|
|
542
|
+
'terminal.configuration': {
|
|
543
|
+
notState: ['is_account_default'],
|
|
544
|
+
},
|
|
545
|
+
topup: {
|
|
546
|
+
state: {
|
|
547
|
+
status: {
|
|
548
|
+
// a top-up starts pending (the create page's example answers "status": "pending") and its funds arrive days
|
|
549
|
+
// later: "USA (USD) ACH Debit Transfer 5 days" (docs.stripe.com/connect/top-ups; semantics/terminal.ts)
|
|
550
|
+
initial: 'pending',
|
|
551
|
+
transitions: [
|
|
552
|
+
// (canceling a pending top-up is the gap here: ../manifest.ts unmodeled)
|
|
553
|
+
// to the Issuing balance alike: "Your top-ups can take up to 5 business days to become available"
|
|
554
|
+
// (docs.stripe.com/issuing/funding/balance)
|
|
555
|
+
by('vendor', ['pending'], 'succeeded', 'https://docs.stripe.com/connect/top-ups'),
|
|
556
|
+
// (Stripe also fails a top-up or reverses a settled one; the twin's top-ups do neither)
|
|
557
|
+
],
|
|
558
|
+
},
|
|
559
|
+
},
|
|
560
|
+
notState: ['initiated_by'],
|
|
561
|
+
},
|
|
562
|
+
'treasury.financial_account': {
|
|
563
|
+
state: { status: { initial: 'open', transitions: [] } },
|
|
564
|
+
notState: ['is_default'],
|
|
565
|
+
},
|
|
566
|
+
'treasury.outbound_payment': {
|
|
567
|
+
state: { status: flow },
|
|
568
|
+
},
|
|
569
|
+
'treasury.outbound_transfer': {
|
|
570
|
+
state: { status: flow },
|
|
571
|
+
},
|
|
572
|
+
'treasury.inbound_transfer': {
|
|
573
|
+
state: { status: flow },
|
|
574
|
+
},
|
|
575
|
+
'treasury.received_credit': {
|
|
576
|
+
state: { status: { initial: 'succeeded', transitions: [] } },
|
|
577
|
+
notState: ['failure_code', 'network'],
|
|
578
|
+
},
|
|
579
|
+
'treasury.received_debit': {
|
|
580
|
+
state: { status: { initial: 'succeeded', transitions: [] } },
|
|
581
|
+
notState: ['failure_code', 'network'],
|
|
582
|
+
},
|
|
583
|
+
'treasury.transaction': {
|
|
584
|
+
notState: ['flow_type'],
|
|
585
|
+
// a transaction posts as its flow settles and is voided when its flow is canceled, both Stripe's (the flows are the
|
|
586
|
+
// gap here: ../manifest.ts unmodeled)
|
|
587
|
+
state: { status: { initial: 'open', transitions: [] } },
|
|
588
|
+
},
|
|
589
|
+
'treasury.transaction_entry': {
|
|
590
|
+
notState: ['flow_type', 'type'],
|
|
591
|
+
},
|
|
592
|
+
'climate.order': {
|
|
593
|
+
state: {
|
|
594
|
+
status: {
|
|
595
|
+
// an order is created confirmed: the create page's example answers "status": "confirmed" with confirmed_at set
|
|
596
|
+
// (docs.stripe.com/api/climate/order/create)
|
|
597
|
+
initial: 'confirmed',
|
|
598
|
+
// (Stripe funds, confirms and delivers an order over months, and cancels one asked to; orders are the gap here,
|
|
599
|
+
// ../manifest.ts unmodeled, read back from a vendor-backed root)
|
|
600
|
+
transitions: [],
|
|
601
|
+
},
|
|
602
|
+
},
|
|
603
|
+
notState: ['cancellation_reason'],
|
|
604
|
+
},
|
|
605
|
+
'financial_connections.account': {
|
|
606
|
+
state: {
|
|
607
|
+
status: {
|
|
608
|
+
initial: 'active',
|
|
609
|
+
// (disconnecting one is the gap here, ../manifest.ts unmodeled; Stripe marks an account inactive when the bank
|
|
610
|
+
// link breaks, and active again)
|
|
611
|
+
transitions: [],
|
|
612
|
+
},
|
|
613
|
+
},
|
|
614
|
+
notState: ['category', 'subcategory'],
|
|
615
|
+
},
|
|
616
|
+
'financial_connections.transaction': {
|
|
617
|
+
// (a bank's pending transaction posts or is voided at Stripe; the twin's arrive posted)
|
|
618
|
+
state: { status: { initial: 'posted', transitions: [] } },
|
|
619
|
+
},
|
|
620
|
+
'reporting.report_run': {
|
|
621
|
+
// "When first created, the object appears with status="pending""; "When the run completes, Stripe updates the
|
|
622
|
+
// object, and it has a status of succeeded" (docs.stripe.com/reports/api). Report runs are the gap here
|
|
623
|
+
// (../manifest.ts unmodeled), read back from a vendor-backed root, so Stripe's move is not the twin's.
|
|
624
|
+
state: { status: { initial: 'pending', transitions: [] } },
|
|
625
|
+
},
|
|
626
|
+
product: {
|
|
627
|
+
state: { active: { initial: true, transitions: [] } },
|
|
628
|
+
},
|
|
629
|
+
price: {
|
|
630
|
+
notState: ['billing_scheme', 'tax_behavior', 'tiers_mode', 'type'],
|
|
631
|
+
// (deleting a plan, which leaves its price inactive, is the gap here: ../manifest.ts unmodeled)
|
|
632
|
+
state: { active: { initial: true, transitions: [] } },
|
|
633
|
+
},
|
|
634
|
+
};
|