@volter/twin-stripe 2.0.37 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -207
- package/dist/generated/pack-facts.json +94 -0
- package/dist/spec/SOURCE.md +14 -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 +378 -0
- package/dist/src/cli.js +12 -30
- package/dist/src/engine/after-payment.d.ts +9 -0
- package/dist/src/engine/after-payment.js +28 -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/billing.d.ts +5 -0
- package/dist/src/engine/billing.js +6 -0
- package/dist/src/engine/charges.d.ts +6 -0
- package/dist/src/engine/charges.js +13 -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 +32 -0
- package/dist/src/{screens → engine}/connect-settings.d.ts +1 -7
- package/dist/src/engine/connect-settings.js +26 -0
- package/dist/src/engine/connect.d.ts +66 -0
- package/dist/src/engine/connect.js +189 -0
- package/dist/src/engine/coupons.d.ts +0 -0
- package/dist/src/engine/coupons.js +5 -0
- package/dist/src/engine/credit-notes.d.ts +1 -0
- package/dist/src/engine/credit-notes.js +5 -0
- package/dist/src/engine/customers.d.ts +12 -0
- package/dist/src/engine/customers.js +30 -0
- package/dist/src/engine/display.d.ts +14 -0
- package/dist/src/engine/display.js +16 -0
- package/dist/src/engine/disputes.d.ts +0 -0
- package/dist/src/engine/disputes.js +9 -0
- package/dist/src/engine/entitlements.d.ts +1 -0
- package/dist/src/engine/entitlements.js +4 -0
- package/dist/src/engine/ephemeral-keys.d.ts +0 -0
- package/dist/src/engine/ephemeral-keys.js +4 -0
- package/dist/src/engine/files.d.ts +18 -0
- package/dist/src/engine/files.js +33 -0
- package/dist/src/engine/front.d.ts +5 -0
- package/dist/src/engine/front.js +25 -0
- package/dist/src/engine/invoices.d.ts +24 -0
- package/dist/src/engine/invoices.js +57 -0
- package/dist/src/engine/issuing.d.ts +35 -0
- package/dist/src/engine/issuing.js +45 -0
- package/dist/src/engine/ledger.d.ts +9 -0
- package/dist/src/engine/ledger.js +9 -0
- package/dist/src/engine/oauth.d.ts +4 -0
- package/dist/src/engine/oauth.js +25 -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-links.d.ts +1 -0
- package/dist/src/engine/payment-links.js +5 -0
- package/dist/src/engine/payment-methods.d.ts +16 -0
- package/dist/src/engine/payment-methods.js +22 -0
- package/dist/src/engine/plans.d.ts +6 -0
- package/dist/src/engine/plans.js +26 -0
- package/dist/src/engine/platform.d.ts +39 -0
- package/dist/src/engine/platform.js +34 -0
- package/dist/src/engine/products.d.ts +0 -0
- package/dist/src/engine/products.js +4 -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 +28 -0
- package/dist/src/engine/renewals.d.ts +36 -0
- package/dist/src/engine/renewals.js +65 -0
- package/dist/src/engine/setup-intents.d.ts +1 -0
- package/dist/src/engine/setup-intents.js +4 -0
- package/dist/src/{stripe-twin.d.ts → engine/stripe.d.ts} +11 -39
- package/dist/src/{stripe-twin.js → engine/stripe.js} +25 -310
- package/dist/src/engine/subscription-schedules.d.ts +3 -0
- package/dist/src/engine/subscription-schedules.js +1 -0
- package/dist/src/engine/subscriptions.d.ts +12 -0
- package/dist/src/engine/subscriptions.js +31 -0
- package/dist/src/engine/tax.d.ts +7 -0
- package/dist/src/engine/tax.js +28 -0
- package/dist/src/engine/terminal.d.ts +4 -0
- package/dist/src/engine/terminal.js +20 -0
- package/dist/src/engine/test-clocks.d.ts +5 -0
- package/dist/src/engine/test-clocks.js +9 -0
- package/dist/src/engine/tokens.d.ts +7 -0
- package/dist/src/engine/tokens.js +20 -0
- package/dist/src/engine/transfers.d.ts +2 -0
- package/dist/src/engine/transfers.js +1 -0
- package/dist/src/engine/treasury.d.ts +23 -0
- package/dist/src/engine/treasury.js +45 -0
- package/dist/src/{stripe-version.js → engine/version.js} +4 -3
- 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 +8 -75
- package/dist/src/manifest.js +232 -758
- package/dist/src/screens/billing-portal.d.ts +3 -0
- package/dist/src/screens/{portal.js → billing-portal.js} +28 -54
- package/dist/src/screens/checkout.d.ts +2 -31
- package/dist/src/screens/checkout.js +32 -121
- package/dist/src/screens/connect-oauth.d.ts +3 -27
- package/dist/src/screens/connect-oauth.js +51 -132
- package/dist/src/screens/connect-onboarding.d.ts +3 -0
- package/dist/src/screens/{onboarding.js → connect-onboarding.js} +36 -102
- package/dist/src/screens/dashboard.d.ts +3 -0
- package/dist/src/screens/dashboard.js +117 -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 +135 -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 +38 -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 +16 -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 +5 -0
- package/dist/src/semantics/billing_portal.js +42 -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 +8 -261
- package/dist/src/semantics/clock.d.ts +2 -0
- package/dist/src/semantics/clock.js +21 -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 +6 -6
- package/dist/src/semantics/customers.js +27 -387
- package/dist/src/semantics/disputes.d.ts +2 -2
- package/dist/src/semantics/disputes.js +3 -49
- package/dist/src/semantics/doors.d.ts +23 -0
- package/dist/src/semantics/doors.js +73 -0
- package/dist/src/semantics/entitlements.d.ts +2 -2
- package/dist/src/semantics/entitlements.js +5 -50
- package/dist/src/semantics/events.d.ts +12 -0
- package/dist/src/semantics/events.js +36 -0
- package/dist/src/semantics/index.d.ts +2 -0
- package/dist/src/semantics/index.js +107 -0
- package/dist/src/semantics/invoice_payments.d.ts +2 -0
- package/dist/src/semantics/invoice_payments.js +12 -0
- package/dist/src/semantics/invoiceitems.d.ts +3 -0
- package/dist/src/semantics/invoiceitems.js +59 -0
- package/dist/src/semantics/invoices.d.ts +16 -18
- package/dist/src/semantics/invoices.js +118 -444
- package/dist/src/semantics/payment_intents.d.ts +4 -0
- package/dist/src/semantics/payment_intents.js +79 -0
- package/dist/src/semantics/payment_methods.d.ts +5 -0
- package/dist/src/semantics/payment_methods.js +39 -0
- package/dist/src/semantics/payouts.d.ts +2 -0
- package/dist/src/semantics/payouts.js +21 -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 +6 -2
- package/dist/src/semantics/products.js +15 -130
- 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 +3 -9
- package/dist/src/semantics/refunds.js +6 -192
- package/dist/src/semantics/setup_intents.d.ts +3 -0
- package/dist/src/semantics/{setup-intents.js → setup_intents.js} +10 -53
- package/dist/src/semantics/shared.d.ts +822 -47
- package/dist/src/semantics/shared.js +3044 -78
- package/dist/src/semantics/states.d.ts +531 -0
- package/dist/src/semantics/states.js +852 -0
- package/dist/src/semantics/subscription_items.d.ts +5 -0
- package/dist/src/semantics/subscription_items.js +55 -0
- package/dist/src/semantics/subscription_schedules.d.ts +4 -0
- package/dist/src/semantics/subscription_schedules.js +60 -0
- package/dist/src/semantics/subscriptions.d.ts +7 -11
- package/dist/src/semantics/subscriptions.js +44 -415
- package/dist/src/semantics/test_helpers.d.ts +6 -0
- package/dist/src/semantics/{test-clocks.js → test_helpers.js} +14 -40
- package/dist/src/semantics/transfers.d.ts +2 -2
- package/dist/src/semantics/transfers.js +6 -101
- package/dist/src/server.d.ts +7 -0
- package/dist/src/server.js +7 -0
- package/generated/pack-facts.json +94 -0
- package/package.json +10 -20
- package/spec/SOURCE.md +14 -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 +378 -0
- package/src/cli.ts +12 -26
- package/src/engine/after-payment.ts +31 -0
- package/src/engine/apps-secrets.ts +4 -0
- package/src/engine/balance.ts +33 -0
- package/src/engine/billing.ts +16 -0
- package/src/engine/charges.ts +19 -0
- package/src/engine/checkout.ts +40 -0
- package/src/engine/common.ts +47 -0
- package/src/engine/connect-settings.ts +23 -0
- package/src/engine/connect.ts +184 -0
- package/src/engine/coupons.ts +5 -0
- package/src/engine/credit-notes.ts +6 -0
- package/src/engine/customers.ts +35 -0
- package/src/engine/display.ts +19 -0
- package/src/engine/disputes.ts +9 -0
- package/src/engine/entitlements.ts +5 -0
- package/src/engine/ephemeral-keys.ts +3 -0
- package/src/engine/files.ts +41 -0
- package/src/engine/front.ts +31 -0
- package/src/engine/invoices.ts +71 -0
- package/src/engine/issuing.ts +61 -0
- package/src/engine/ledger.ts +50 -0
- package/src/engine/oauth.ts +19 -0
- package/src/engine/onboarding.ts +54 -0
- package/src/{stripe-params.ts → engine/params.ts} +8 -56
- package/src/engine/payment-intents.ts +33 -0
- package/src/engine/payment-links.ts +6 -0
- package/src/engine/payment-methods.ts +25 -0
- package/src/engine/plans.ts +42 -0
- package/src/engine/platform.ts +47 -0
- package/src/engine/products.ts +3 -0
- package/src/engine/radar.ts +6 -0
- package/src/engine/refunds.ts +29 -0
- package/src/engine/renewals.ts +73 -0
- package/src/engine/setup-intents.ts +5 -0
- package/src/{stripe-twin.ts → engine/stripe.ts} +28 -323
- package/src/engine/subscription-schedules.ts +10 -0
- package/src/engine/subscriptions.ts +40 -0
- package/src/engine/tax.ts +39 -0
- package/src/engine/terminal.ts +23 -0
- package/src/engine/test-clocks.ts +11 -0
- package/src/engine/tokens.ts +22 -0
- package/src/engine/transfers.ts +23 -0
- package/src/engine/treasury.ts +47 -0
- package/src/{stripe-version.ts → engine/version.ts} +4 -3
- package/src/engine/webhook-endpoints.ts +14 -0
- package/src/engine/webhooks.ts +72 -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 +8 -116
- package/src/manifest.ts +234 -786
- package/src/screens/{portal.tsx → billing-portal.tsx} +32 -37
- package/src/screens/checkout.tsx +33 -95
- package/src/screens/connect-oauth.tsx +64 -88
- package/src/screens/{onboarding.tsx → connect-onboarding.tsx} +38 -82
- package/src/screens/dashboard.tsx +198 -0
- package/src/screens/shared.tsx +84 -0
- package/src/screens/stripe-js.ts +170 -0
- package/src/semantics/account_links.ts +21 -0
- package/src/semantics/accounts.ts +43 -0
- package/src/semantics/{apps-secrets.ts → apps.ts} +17 -32
- package/src/semantics/around.ts +20 -0
- package/src/semantics/balance.ts +6 -207
- package/src/semantics/balance_transactions.ts +20 -0
- package/src/semantics/billing_portal.ts +51 -0
- package/src/semantics/charges.ts +12 -211
- package/src/semantics/checkout.ts +13 -268
- package/src/semantics/clock.ts +26 -0
- package/src/semantics/coupons.ts +5 -67
- package/src/semantics/customers.ts +29 -392
- package/src/semantics/disputes.ts +9 -59
- package/src/semantics/doors.ts +80 -0
- package/src/semantics/entitlements.ts +9 -56
- package/src/semantics/events.ts +44 -0
- package/src/semantics/index.ts +111 -0
- package/src/semantics/invoice_payments.ts +18 -0
- package/src/semantics/invoiceitems.ts +59 -0
- package/src/semantics/invoices.ts +109 -443
- package/src/semantics/payment_intents.ts +83 -0
- package/src/semantics/payment_methods.ts +43 -0
- package/src/semantics/payouts.ts +23 -0
- package/src/semantics/prices.ts +42 -0
- package/src/semantics/products.ts +18 -142
- package/src/semantics/promotion_codes.ts +39 -0
- package/src/semantics/radar.ts +8 -77
- package/src/semantics/refunds.ts +9 -212
- package/src/semantics/setup_intents.ts +45 -0
- package/src/semantics/shared.ts +3092 -106
- package/src/semantics/states.ts +883 -0
- package/src/semantics/subscription_items.ts +54 -0
- package/src/semantics/subscription_schedules.ts +66 -0
- package/src/semantics/subscriptions.ts +49 -432
- package/src/semantics/{test-clocks.ts → test_helpers.ts} +23 -47
- package/src/semantics/transfers.ts +11 -131
- package/src/server.ts +8 -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-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/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/issuing.d.ts +0 -13
- package/dist/src/semantics/issuing.js +0 -575
- 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/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/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-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/ephemeral-keys.ts +0 -34
- package/src/semantics/files.ts +0 -143
- package/src/semantics/issuing.ts +0 -590
- 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/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/dist/src/{stripe-version.d.ts → engine/version.d.ts} +0 -0
- /package/src/{screens → engine}/industries.ts +0 -0
- /package/src/{semantics → engine}/test-cards.ts +0 -0
package/src/semantics/refunds.ts
CHANGED
|
@@ -1,218 +1,15 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
//
|
|
6
|
-
// Refunding a destination charge can take back the connected account's share (reverse_transfer: a reversal of the
|
|
7
|
-
// charge's transfer, in proportion to the refund) and the platform's (refund_application_fee: a refund of the
|
|
8
|
-
// application fee, in proportion) (docs.stripe.com/api/refunds/create#create_refund-reverse_transfer,
|
|
9
|
-
// docs.stripe.com/connect/destination-charges#issue-refunds). Where the documentation stops and the twin decides: the
|
|
10
|
-
// twin's destination charge transfers the amount less the fee (the fee is kept back rather than collected from the
|
|
11
|
-
// connected account), so a fee refund moves no money of its own; the reversal and the refund settle both shares.
|
|
12
|
-
//
|
|
13
|
-
// A payment made by bank transfer (from the customer's cash balance) is refunded to the customer's bank account: Stripe
|
|
14
|
-
// emails the customer (instructions_email, else the customer's email) for their bank details and the refund waits in
|
|
15
|
-
// requires_action, moving no money, until they answer; only then can it still be canceled. With origin=customer_balance
|
|
16
|
-
// it goes back to the cash balance at once (docs.stripe.com/payments/customer-balance/refunding,
|
|
17
|
-
// docs.stripe.com/api/refunds/cancel). Where the documentation stops and the twin decides: the customer never answers
|
|
18
|
-
// the email in the World, and its link expires 30 days on.
|
|
19
|
-
//
|
|
20
|
-
// An uncaptured charge holds an authorization, not money. A PaymentIntent's is not refunded: "the charge attached to the
|
|
21
|
-
// PaymentIntent remains uncaptured and can't be refunded directly. You must cancel the PaymentIntent"
|
|
22
|
-
// (docs.stripe.com/refunds), which releases it (charges.ts cancelAuthorization). A charge made with capture=false is
|
|
23
|
-
// released by its refund, as its authorization would be "automatically refunded if uncaptured" (spec/openapi.json.gz,
|
|
24
|
-
// `capture_before`): refunded in full, no balance moved, and its capture refused afterwards. Where the documentation
|
|
25
|
-
// stops and the twin decides: the refusal's code (payment_intent_unexpected_state) and wording, and that a refund of a
|
|
26
|
-
// capture=false charge releases the whole authorization, so an `amount` short of it is refused.
|
|
27
|
-
import type { Semantics, SemanticsContext } from '@volter/world-core';
|
|
28
|
-
import { releaseAuthorization } from './charges.ts';
|
|
29
|
-
import { actingAccount, availableAt, fundsDueBetween, settleRefund, settleTransferReversal } from './ledger.ts';
|
|
30
|
-
import { asBool } from '../stripe-twin.ts';
|
|
31
|
-
import { at, at_, created, fail, newest, refundDestination, type Row } from './shared.ts';
|
|
1
|
+
// Stripe's refunds operations (docs/contributing/architecture.md, "What an author writes"): each handler over the
|
|
2
|
+
// handler contract's context, computing with the engine (../engine/).
|
|
3
|
+
import type { HandlerContext } from '@volter/world-core';
|
|
4
|
+
import { at, refundCharge, refundMissing, target } from './shared.ts';
|
|
32
5
|
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Create a refund and land it on its charge. An omitted amount is the whole remaining balance. The
|
|
38
|
-
* charge's write records `charge.refunded`, the event Stripe sends carrying the charge's new totals;
|
|
39
|
-
* `refunded` is true only at the full amount.
|
|
40
|
-
*/
|
|
41
|
-
/** A reason Stripe does not take (docs.stripe.com/api/refunds/create#create_refund-reason). */
|
|
42
|
-
function badReason(ctx: SemanticsContext): Response {
|
|
43
|
-
return fail(ctx, `Invalid refund reason: must be one of ${[...REFUND_REASONS].join(', ')}.`, 400, 'parameter_invalid_string_enum');
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/** A bank-transfer payment refunded with origin=customer_balance goes back to the cash balance
|
|
47
|
-
* (docs.stripe.com/payments/customer-balance/refunding). */
|
|
48
|
-
async function backToCashBalance(ctx: SemanticsContext, customer: string, currency: string, amount: number, refundId: string): Promise<void> {
|
|
49
|
-
const before = ctx.rows('customer_cash_balance_transaction').filter((t) => t.customer === customer && String(t.currency) === currency).reduce((n, t) => n + (Number(t.net_amount) || 0), 0);
|
|
50
|
-
await created(ctx, 'customer_cash_balance_transaction', { customer }, { currency, type: 'refunded_from_payment', net_amount: amount, ending_balance: before + amount, refunded_from_payment: { refund: refundId }, livemode: false });
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/** A capture=false charge's refund, which releases its whole authorization (see the header). */
|
|
54
|
-
async function refundUncaptured(ctx: SemanticsContext, charge: Row, amount: number, remaining: number, params: Row): Promise<Response> {
|
|
55
|
-
if (amount < remaining) return fail(ctx, `Charge ${String(charge.id)} is uncaptured: refunding it releases the whole authorization (${remaining}).`, 400, 'amount_too_small');
|
|
56
|
-
const { reason, metadata } = params;
|
|
57
|
-
return ctx.reply(await releaseAuthorization(ctx, charge, ctx.call.operation.id, { ...(reason !== undefined ? { reason } : {}), ...(metadata !== undefined ? { metadata } : {}) }));
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export async function refundCharge(ctx: SemanticsContext, charge: Row, params: Row): Promise<Response> {
|
|
61
|
-
const chargeId = String(charge.id);
|
|
62
|
-
const total = Number(charge.amount) || 0;
|
|
63
|
-
const already = Number(charge.amount_refunded) || 0;
|
|
64
|
-
const remaining = Math.max(0, total - already);
|
|
65
|
-
const amount = params.amount === undefined ? remaining : Math.trunc(Number(params.amount));
|
|
66
|
-
if (!Number.isFinite(amount) || amount <= 0) return fail(ctx, 'Invalid integer: amount must be a positive integer.', 400, 'parameter_invalid_integer');
|
|
67
|
-
if (amount > remaining) return fail(ctx, `Refund amount (${amount}) is greater than unrefunded amount on charge (${remaining}).`, 400, 'amount_too_large');
|
|
68
|
-
if (params.reason !== undefined && !REFUND_REASONS.has(String(params.reason))) return badReason(ctx);
|
|
69
|
-
// an authorization is released, never refunded out of the balance: a PaymentIntent's by cancelling the intent, a
|
|
70
|
-
// capture=false charge's by its refund (refundUncaptured)
|
|
71
|
-
if (charge.captured === false && typeof charge.payment_intent === 'string') return fail(ctx, `Charge ${chargeId} is uncaptured and can't be refunded directly; cancel its PaymentIntent (${charge.payment_intent}) to release the authorization.`, 400, 'payment_intent_unexpected_state');
|
|
72
|
-
if (charge.captured === false) return refundUncaptured(ctx, charge, amount, remaining, params);
|
|
73
|
-
const refunded = already + amount;
|
|
74
|
-
// the refund that takes the rest refunds the charge: the charge machine's move under this operation
|
|
75
|
-
if (refunded >= total && charge.refunded !== true) {
|
|
76
|
-
const refused = ctx.legal('charge', 'refunded', ctx.call.operation.id, 'false', 'true', chargeId);
|
|
77
|
-
if (refused) return ctx.refuse(refused);
|
|
78
|
-
}
|
|
79
|
-
// a refund has no `livemode` field; it debits the balance at once
|
|
80
|
-
const refundId = ctx.mint('refund');
|
|
81
|
-
const currency = String(charge.currency ?? 'usd');
|
|
82
|
-
const pi = typeof charge.payment_intent === 'string' ? ctx.get('payment_intent', charge.payment_intent) : undefined;
|
|
83
|
-
const byTransfer = ((pi?.payment_method_types as unknown[] | undefined) ?? []).includes('customer_balance');
|
|
84
|
-
const toCashBalance = byTransfer && params.origin === 'customer_balance';
|
|
85
|
-
const awaitsBank = byTransfer && !toCashBalance;
|
|
86
|
-
const now = Number(ctx.now());
|
|
87
|
-
const customer = typeof charge.customer === 'string' ? charge.customer : typeof pi?.customer === 'string' ? pi.customer : undefined;
|
|
88
|
-
const emailTo = typeof params.instructions_email === 'string' ? params.instructions_email : (customer ? ctx.get('customer', customer)?.email : undefined) ?? null;
|
|
89
|
-
// "Refunds use your available Stripe balance (not including pending amounts). If your available balance doesn't
|
|
90
|
-
// cover the amount of the refund, Stripe holds the refund as pending for card transactions ... until your Stripe
|
|
91
|
-
// balance becomes sufficient" (docs.stripe.com/refunds): the refund waits, moving no money, until the balance covers
|
|
92
|
-
// it (settleHeldRefunds). Where the documentation stops and the twin decides: a refund of another payment method
|
|
93
|
-
// short of balance is not modelled (Stripe fails it); the twin makes it as a card's.
|
|
94
|
-
const account = actingAccount(ctx);
|
|
95
|
-
const isCard = (charge.payment_method_details as Row | null | undefined)?.type === 'card';
|
|
96
|
-
const held = !awaitsBank && !toCashBalance && isCard && availableAt(ctx, account, currency, now) < amount;
|
|
97
|
-
if (held) ctx.legal('refund', 'status', ctx.call.operation.id, 'succeeded', 'pending', refundId);
|
|
98
|
-
const bt = awaitsBank || held ? null : await settleRefund(ctx, refundId, amount, currency);
|
|
99
|
-
if (toCashBalance && customer) await backToCashBalance(ctx, customer, currency, amount, refundId);
|
|
100
|
-
const { reverse_transfer: reverseTransfer, refund_application_fee: refundFee, instructions_email: _email, origin: _origin, ...stored } = params;
|
|
101
|
-
const share = (whole: number): number => Math.round((whole * amount) / (total || 1));
|
|
102
|
-
let transferReversal: string | null = null;
|
|
103
|
-
const transfer = typeof charge.transfer === 'string' ? ctx.get('transfer', charge.transfer) : undefined;
|
|
104
|
-
if (reverseTransfer !== undefined && asBool(reverseTransfer) && transfer) {
|
|
105
|
-
const back = Math.min(share(Number(transfer.amount) || 0), (Number(transfer.amount) || 0) - (Number(transfer.amount_reversed) || 0));
|
|
106
|
-
const trr = await created(ctx, 'transfer_reversal', { amount: back, currency, transfer: transfer.id }, { balance_transaction: null, destination_payment_refund: null, source_refund: refundId, metadata: {} });
|
|
107
|
-
const trrBt = await settleTransferReversal(ctx, String(trr.id), back, currency, String(transfer.destination));
|
|
108
|
-
const reversal = await ctx.write('transfer_reversal', String(trr.id), { balance_transaction: trrBt }, 'transfer_reversal.updated');
|
|
109
|
-
const reversed = (Number(transfer.amount_reversed) || 0) + back;
|
|
110
|
-
const list = (transfer.reversals as Row | undefined) ?? { object: 'list', data: [], has_more: false, total_count: 0 };
|
|
111
|
-
const data = [...(((list.data as unknown[]) ?? [])), reversal];
|
|
112
|
-
await ctx.write('transfer', String(transfer.id), { amount_reversed: reversed, reversed: reversed >= (Number(transfer.amount) || 0), reversals: { ...list, data, total_count: data.length, url: `/v1/transfers/${String(transfer.id)}/reversals` } }, 'transfer.reversed');
|
|
113
|
-
transferReversal = String(trr.id);
|
|
114
|
-
}
|
|
115
|
-
const fee = typeof charge.application_fee === 'string' ? ctx.get('application_fee', charge.application_fee) : undefined;
|
|
116
|
-
if (refundFee !== undefined && asBool(refundFee) && fee) {
|
|
117
|
-
const feeTotal = Number(fee.amount) || 0;
|
|
118
|
-
const back = Math.min(share(feeTotal), feeTotal - (Number(fee.amount_refunded) || 0));
|
|
119
|
-
const done = (Number(fee.amount_refunded) || 0) + back;
|
|
120
|
-
if (!(done >= feeTotal && fee.refunded !== true && ctx.legal('application_fee', 'refunded', ctx.call.operation.id, 'false', 'true', String(fee.id)))) {
|
|
121
|
-
const fr = await created(ctx, 'fee_refund', { amount: back, currency, fee: fee.id }, { balance_transaction: null, metadata: {} });
|
|
122
|
-
const list = (fee.refunds as Row | undefined) ?? { object: 'list', data: [], has_more: false, total_count: 0 };
|
|
123
|
-
const data = [...(((list.data as unknown[]) ?? [])), fr];
|
|
124
|
-
await ctx.write('application_fee', String(fee.id), { amount_refunded: done, refunded: done >= feeTotal, refunds: { ...list, data, total_count: data.length, url: `/v1/application_fees/${String(fee.id)}/refunds` } }, 'application_fee.refunded');
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
const body = await created(ctx, 'refund', {
|
|
128
|
-
...stored, id: refundId, charge: chargeId, amount, currency, transfer_reversal: transferReversal,
|
|
129
|
-
...(typeof charge.payment_intent === 'string' ? { payment_intent: charge.payment_intent } : {}),
|
|
130
|
-
}, {
|
|
131
|
-
status: awaitsBank ? 'requires_action' : held ? 'pending' : 'succeeded', metadata: {}, reason: null, receipt_number: null,
|
|
132
|
-
...(held ? { pending_reason: 'insufficient_funds', _account: account ?? null } : {}),
|
|
133
|
-
balance_transaction: bt, source_transfer_reversal: null,
|
|
134
|
-
// a bank transfer's refund goes to the customer's bank (a us_bank_transfer) or back to its cash balance
|
|
135
|
-
// (customer_cash_balance): "If this is a `us_bank_transfer` refund, this hash contains the transaction specific details",
|
|
136
|
-
// "If this is a `customer_cash_balance` refund ..." (docs.stripe.com/api/refunds/object, destination_details)
|
|
137
|
-
...(byTransfer
|
|
138
|
-
? { destination_details: toCashBalance ? { type: 'customer_cash_balance', customer_cash_balance: {} } : { type: 'us_bank_transfer', us_bank_transfer: { reference: null, reference_status: null } } }
|
|
139
|
-
: refundDestination(charge, 'refund')),
|
|
140
|
-
...(awaitsBank ? { next_action: { type: 'display_details', display_details: { email_sent: { email_sent_at: now, email_sent_to: emailTo }, expires_at: now + 30 * 86_400 } } } : {}),
|
|
141
|
-
});
|
|
142
|
-
await ctx.write('charge', chargeId, { amount_refunded: refunded, refunded: refunded >= total }, 'charge.refunded');
|
|
143
|
-
return ctx.reply(body);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/** Time's settling of held refunds, caught up to the World's clock: each refund held for want of balance, oldest first,
|
|
147
|
-
* is made at the first moment the account's available balance covers it (the funds that come due then), its debit
|
|
148
|
-
* written then, as `refund.updated`. Where the documentation stops and the twin decides: a held refund is made the
|
|
149
|
-
* moment the balance covers it. */
|
|
150
|
-
export async function settleHeldRefunds(ctx: SemanticsContext): Promise<void> {
|
|
151
|
-
const now = Number(ctx.now());
|
|
152
|
-
const heldRefunds = ctx.rowsRaw('refund').filter((r) => r.status === 'pending' && r.pending_reason === 'insufficient_funds').sort((a, b) => Number(a.created) - Number(b.created));
|
|
153
|
-
for (const r of heldRefunds) {
|
|
154
|
-
const account = typeof r._account === 'string' ? r._account : undefined;
|
|
155
|
-
const currency = String(r.currency ?? 'usd');
|
|
156
|
-
const amount = Number(r.amount) || 0;
|
|
157
|
-
const when = [Number(r.created), ...fundsDueBetween(ctx, account, currency, Number(r.created), now)].find((t) => availableAt(ctx, account, currency, t) >= amount);
|
|
158
|
-
if (when === undefined) continue;
|
|
159
|
-
const c = await at_(ctx)(when);
|
|
160
|
-
c.legal('refund', 'status', ctx.call.operation.id, 'pending', 'succeeded', String(r.id), 'vendor');
|
|
161
|
-
const bt = await settleRefund(c, String(r.id), amount, currency, account ?? null);
|
|
162
|
-
await c.write('refund', String(r.id), { status: 'succeeded', pending_reason: null, balance_transaction: bt }, 'refund.updated');
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/** The charge a refund aims at: named directly, or reached through its PaymentIntent. */
|
|
167
|
-
function target(ctx: SemanticsContext): Row | Response {
|
|
168
|
-
const chargeId = typeof ctx.params.charge === 'string' ? ctx.params.charge : '';
|
|
169
|
-
const piId = typeof ctx.params.payment_intent === 'string' ? ctx.params.payment_intent : '';
|
|
170
|
-
if (!chargeId && !piId) return fail(ctx, 'One of `charge` or `payment_intent` is required.', 400, 'parameter_missing');
|
|
171
|
-
if (chargeId) return ctx.get('charge', chargeId) ?? fail(ctx, `No such charge: '${chargeId}'`, 404, 'resource_missing');
|
|
172
|
-
const pi = ctx.get('payment_intent', piId);
|
|
173
|
-
if (!pi) return fail(ctx, `No such payment_intent: '${piId}'`, 404, 'resource_missing');
|
|
174
|
-
const latest = typeof pi.latest_charge === 'string' ? pi.latest_charge : undefined;
|
|
175
|
-
const ch = (latest ? ctx.get('charge', latest) : undefined) ?? newest(ctx, 'charge').find((c) => c.payment_intent === piId);
|
|
176
|
-
return ch ?? fail(ctx, `This PaymentIntent does not have a successful charge to refund. Its status is ${String(pi.status)}.`, 400, 'payment_intent_unexpected_state');
|
|
6
|
+
export async function GetRefundsRefund(ctx: HandlerContext): Promise<Response> {
|
|
7
|
+
const r = ctx.get('refund', at(ctx, 'refund'));
|
|
8
|
+
return r ? ctx.reply(r) : refundMissing(ctx, at(ctx, 'refund'));
|
|
177
9
|
}
|
|
178
10
|
|
|
179
|
-
|
|
11
|
+
export async function PostRefunds(ctx: HandlerContext): Promise<Response> {
|
|
180
12
|
const ch = target(ctx);
|
|
181
13
|
return ch instanceof Response ? ch : refundCharge(ctx, ch, ctx.params);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
const refundMissing = (ctx: SemanticsContext, id: string): Response => fail(ctx, `No such refund: '${id}'`, 404, 'resource_missing');
|
|
185
|
-
|
|
186
|
-
const retrieve: Semantics = async (ctx) => {
|
|
187
|
-
const r = ctx.get('refund', at(ctx, 'refund'));
|
|
188
|
-
return r ? ctx.reply(r) : refundMissing(ctx, at(ctx, 'refund'));
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
// a canceled pending refund gives its money back to the charge: pending funds were already taken out
|
|
192
|
-
const cancel: Semantics = async (ctx) => {
|
|
193
|
-
const id = at(ctx, 'refund');
|
|
194
|
-
const r = ctx.get('refund', id);
|
|
195
|
-
if (!r) return refundMissing(ctx, id);
|
|
196
|
-
const refused = ctx.legal('refund', 'status', 'PostRefundsRefundCancel', r.status, undefined, id);
|
|
197
|
-
if (refused) return ctx.refuse(refused);
|
|
198
|
-
// next_action says what a refund "needs to continue processing" "If the refund has a status of requires_action"
|
|
199
|
-
// (docs.stripe.com/api/refunds/object): a canceled one needs nothing
|
|
200
|
-
const canceled = await ctx.write('refund', id, { status: 'canceled', next_action: null }, 'refund.updated');
|
|
201
|
-
const chargeId = typeof r.charge === 'string' ? r.charge : '';
|
|
202
|
-
const ch = chargeId ? ctx.get('charge', chargeId) : undefined;
|
|
203
|
-
if (ch) {
|
|
204
|
-
const total = Number(ch.amount) || 0;
|
|
205
|
-
const back = Math.max(0, (Number(ch.amount_refunded) || 0) - (Number(r.amount) || 0));
|
|
206
|
-
const refunded = back > 0 && back >= total;
|
|
207
|
-
// a charge the canceled refund had fully refunded is no longer refunded
|
|
208
|
-
if (refunded !== (ch.refunded === true)) ctx.legal('charge', 'refunded', 'PostRefundsRefundCancel', String(ch.refunded === true), String(refunded), chargeId);
|
|
209
|
-
await ctx.write('charge', chargeId, { amount_refunded: back, refunded }, 'charge.update');
|
|
210
|
-
}
|
|
211
|
-
return ctx.reply(canceled);
|
|
212
|
-
};
|
|
14
|
+
}
|
|
213
15
|
|
|
214
|
-
export const refunds: Record<string, Semantics> = {
|
|
215
|
-
PostRefunds: create,
|
|
216
|
-
GetRefundsRefund: retrieve,
|
|
217
|
-
PostRefundsRefundCancel: cancel,
|
|
218
|
-
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Stripe's setup_intents operations (docs/contributing/architecture.md, "What an author writes"): each handler over the
|
|
2
|
+
// handler contract's context, computing with the engine (../engine/).
|
|
3
|
+
import type { HandlerContext } from '@volter/world-core';
|
|
4
|
+
import { SI } from '../engine/setup-intents.ts';
|
|
5
|
+
import { asBool, microdepositsNextAction, mintClientSecret, requiresMicrodeposits, verifyMicrodeposits } from '../engine/stripe.ts';
|
|
6
|
+
import { at, attachable, attachPaymentMethod, confirmOnly, created, fail, load, mergeUpdate, methodFromData, microdepositsAsked, mintMandate, send } from './shared.ts';
|
|
7
|
+
|
|
8
|
+
export async function PostSetupIntents(ctx: HandlerContext): Promise<Response> {
|
|
9
|
+
// mandate_data and return_url each "can only be used with `confirm=true`" (the served spec; shared.ts confirmOnly)
|
|
10
|
+
const unconfirmed = confirmOnly(ctx, ['mandate_data', 'return_url'], asBool(ctx.params.confirm));
|
|
11
|
+
if (unconfirmed) return unconfirmed;
|
|
12
|
+
// the id is minted first so the client secret can carry it: Stripe.js parses the id back out
|
|
13
|
+
const id = typeof ctx.params.id === 'string' && ctx.params.id ? ctx.params.id : ctx.mint(SI);
|
|
14
|
+
// it waits for a payment method until it has one, then for its confirmation (manifest.ts)
|
|
15
|
+
const hasMethod = typeof ctx.params.payment_method === 'string' && ctx.params.payment_method !== '';
|
|
16
|
+
if (hasMethod) ctx.legal(SI, 'status', 'PostSetupIntents', 'requires_payment_method', 'requires_confirmation', id);
|
|
17
|
+
return ctx.reply(
|
|
18
|
+
// allowed_payment_method_types in the served version names the methods (docs.stripe.com/api/setup_intents/create)
|
|
19
|
+
await created(ctx, SI, { ...ctx.params, ...(Array.isArray(ctx.params.allowed_payment_method_types) ? { payment_method_types: ctx.params.allowed_payment_method_types.map(String) } : {}), id }, {
|
|
20
|
+
status: hasMethod ? 'requires_confirmation' : 'requires_payment_method', usage: 'off_session', client_secret: mintClientSecret(id, await ctx.secret(`client-secret:${id}`)), payment_method_types: ['card'],
|
|
21
|
+
next_action: null, latest_attempt: null, last_setup_error: null, livemode: false,
|
|
22
|
+
}),
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// a bank account that needs micro-deposit verification waits in requires_action; anything else succeeds. The confirm's
|
|
27
|
+
// payment_method_data and mandate_data are instructions, not fields of the SetupIntent.
|
|
28
|
+
export async function PostSetupIntentsIntentConfirm(ctx: HandlerContext): Promise<Response> {
|
|
29
|
+
const loaded = load(ctx, 'PostSetupIntentsIntentConfirm');
|
|
30
|
+
if ('answer' in loaded) return loaded.answer;
|
|
31
|
+
const si = loaded.si;
|
|
32
|
+
const id = String(si.id);
|
|
33
|
+
const given = ctx.params;
|
|
34
|
+
const { payment_method_data: data, mandate_data: _mandate, ...fields } = given;
|
|
35
|
+
const made = await methodFromData(ctx, data);
|
|
36
|
+
const pm = made ?? (typeof ctx.params.payment_method === 'string' ? ctx.params.payment_method : typeof si.payment_method === 'string' ? si.payment_method : undefined);
|
|
37
|
+
if (si.status !== 'requires_action' && (requiresMicrodeposits(ctx.params, si) || microdepositsAsked(ctx, ctx.params, si, pm))) {
|
|
38
|
+
return ctx.reply(await ctx.write(SI, id, mergeUpdate(ctx, SI, id, { ...fields, ...(pm ? { payment_method: pm } : {}), status: 'requires_action', next_action: microdepositsNextAction() }), 'setup_intent.requires_action'));
|
|
39
|
+
}
|
|
40
|
+
// a setup for a customer saves the method to them (docs.stripe.com/payments/save-and-reuse): its payment method is attached
|
|
41
|
+
const customer = typeof si.customer === 'string' ? si.customer : undefined;
|
|
42
|
+
const saved = pm && customer && attachable(ctx, pm) && ctx.get('payment_method', pm)?.customer !== customer ? String((await attachPaymentMethod(ctx, pm, customer)).id) : pm;
|
|
43
|
+
return ctx.reply(await ctx.write(SI, id, mergeUpdate(ctx, SI, id, { ...fields, ...(saved ? { payment_method: saved } : {}), status: 'succeeded' }), 'setup_intent.confirm'));
|
|
44
|
+
}
|
|
45
|
+
|