@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,40 @@
|
|
|
1
|
+
import { externalList } from "../engine/common.js";
|
|
2
|
+
import { controllerOf, expressRequirements, keptKyc } from "../engine/connect.js";
|
|
3
|
+
import { ACCOUNT_TYPES, accountCapabilities, accountRequirements, accountSettings, nowUnix } from "../engine/stripe.js";
|
|
4
|
+
import { accountMissing, accountRow, at, connectReview, created, fail, list, newest } from "./shared.js";
|
|
5
|
+
export async function GetAccountsAccountExternalAccounts(ctx) {
|
|
6
|
+
const account = at(ctx, 'account');
|
|
7
|
+
if (!accountRow(ctx, account))
|
|
8
|
+
return accountMissing(ctx, account);
|
|
9
|
+
return list(ctx, 'external_account', newest(ctx, 'external_account').filter((e) => e.account === account));
|
|
10
|
+
}
|
|
11
|
+
// the requested capabilities become Stripe's status map, and settings its canonical shape
|
|
12
|
+
export async function PostAccounts(ctx) {
|
|
13
|
+
const params = ctx.params;
|
|
14
|
+
const type = typeof params.type === 'string' ? params.type : 'standard';
|
|
15
|
+
if (!ACCOUNT_TYPES.has(type))
|
|
16
|
+
return fail(ctx, 'Invalid account type: must be one of express, standard, or custom.', 400, 'parameter_invalid_string_enum');
|
|
17
|
+
const { capabilities: _caps, settings: _settings, ...accountParams } = keptKyc(params);
|
|
18
|
+
const id = ctx.mint('account');
|
|
19
|
+
const made = await created(ctx, 'account', { ...accountParams, id, type }, {
|
|
20
|
+
business_type: null, charges_enabled: false, payouts_enabled: false, details_submitted: false,
|
|
21
|
+
capabilities: accountCapabilities(params), requirements: type === 'express' ? expressRequirements(params) : accountRequirements(),
|
|
22
|
+
country: typeof params.country === 'string' ? params.country : 'US',
|
|
23
|
+
default_currency: 'usd', email: params.email ?? null, metadata: {}, livemode: false,
|
|
24
|
+
settings: accountSettings(params.settings), business_profile: {},
|
|
25
|
+
controller: controllerOf(type), external_accounts: externalList(id, []),
|
|
26
|
+
future_requirements: { alternatives: [], current_deadline: null, currently_due: [], disabled_reason: null, errors: [], eventually_due: [], past_due: [], pending_verification: [] },
|
|
27
|
+
tos_acceptance: { date: null, ip: null, user_agent: null },
|
|
28
|
+
});
|
|
29
|
+
await connectReview(ctx, String(made.id));
|
|
30
|
+
return ctx.reply(ctx.expand('account', ctx.get('account', String(made.id))));
|
|
31
|
+
}
|
|
32
|
+
// a single-use Express dashboard link, not stored
|
|
33
|
+
export async function PostAccountsAccountLoginLinks(ctx) {
|
|
34
|
+
const id = at(ctx, 'account');
|
|
35
|
+
if (!ctx.get('account', id))
|
|
36
|
+
return accountMissing(ctx, id);
|
|
37
|
+
return ctx.reply({ object: 'login_link', created: nowUnix(ctx.occurredAt), url: `https://connect.twin.local/express/${id}` });
|
|
38
|
+
}
|
|
39
|
+
// source: spec:PostAccountsAccount "left unchanged."
|
|
40
|
+
// source: https://docs.stripe.com/connect/account-capabilities "If a connected account has both card_payments and transfers"
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { HandlerContext } from '@volter/world-core';
|
|
2
|
+
export declare function GetAppsSecretsFind(ctx: HandlerContext): Promise<Response>;
|
|
3
|
+
export declare function PostAppsSecrets(ctx: HandlerContext): Promise<Response>;
|
|
4
|
+
export declare function PostAppsSecretsDelete(ctx: HandlerContext): Promise<Response>;
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
|
|
1
|
+
import { SECRET } from "../engine/apps-secrets.js";
|
|
2
|
+
import { nowUnix } from "../engine/stripe.js";
|
|
3
|
+
import { created, fail, named, scopeKeyOf } from "./shared.js";
|
|
4
|
+
export async function GetAppsSecretsFind(ctx) {
|
|
5
|
+
const name = typeof ctx.params.name === 'string' ? ctx.params.name : '';
|
|
6
|
+
if (!name)
|
|
7
|
+
return fail(ctx, 'Missing required param: name.', 400, 'parameter_missing');
|
|
8
|
+
const s = named(ctx, name);
|
|
9
|
+
return s ? ctx.reply(s) : fail(ctx, `No such secret: '${name}'`, 404, 'resource_missing');
|
|
7
10
|
}
|
|
8
|
-
|
|
9
|
-
const set = async (ctx) => {
|
|
11
|
+
export async function PostAppsSecrets(ctx) {
|
|
10
12
|
const params = ctx.params;
|
|
11
13
|
const name = typeof params.name === 'string' ? params.name : '';
|
|
12
14
|
if (!name)
|
|
@@ -22,21 +24,14 @@ const set = async (ctx) => {
|
|
|
22
24
|
const expiresAt = params.expires_at !== undefined ? Math.trunc(Number(params.expires_at)) : null;
|
|
23
25
|
const existing = named(ctx, name);
|
|
24
26
|
if (existing)
|
|
25
|
-
return ctx.reply(await ctx.write(SECRET, String(existing.id), { payload: params.payload, expires_at: expiresAt, _updated: ctx.
|
|
27
|
+
return ctx.reply(await ctx.write(SECRET, String(existing.id), { payload: params.payload, expires_at: expiresAt, _updated: nowUnix(ctx.occurredAt) }, 'apps_secret.update'));
|
|
26
28
|
return ctx.reply(await created(ctx, SECRET, { name }, {
|
|
27
29
|
livemode: false, deleted: false, expires_at: expiresAt, payload: params.payload,
|
|
28
30
|
scope: scopeType === 'user' ? { type: 'user', user: scope.user } : { type: 'account' },
|
|
29
31
|
_scope_key: scopeKeyOf(ctx),
|
|
30
32
|
}));
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const name = typeof ctx.params.name === 'string' ? ctx.params.name : '';
|
|
34
|
-
if (!name)
|
|
35
|
-
return fail(ctx, 'Missing required param: name.', 400, 'parameter_missing');
|
|
36
|
-
const s = named(ctx, name);
|
|
37
|
-
return s ? ctx.reply(s) : fail(ctx, `No such secret: '${name}'`, 404, 'resource_missing');
|
|
38
|
-
};
|
|
39
|
-
const remove = async (ctx) => {
|
|
33
|
+
}
|
|
34
|
+
export async function PostAppsSecretsDelete(ctx) {
|
|
40
35
|
const name = typeof ctx.params.name === 'string' ? ctx.params.name : '';
|
|
41
36
|
if (!name)
|
|
42
37
|
return fail(ctx, 'Missing required param: name.', 400, 'parameter_missing');
|
|
@@ -44,11 +39,4 @@ const remove = async (ctx) => {
|
|
|
44
39
|
if (!s)
|
|
45
40
|
return fail(ctx, `No such secret: '${name}'`, 404, 'resource_missing');
|
|
46
41
|
return ctx.reply(await ctx.write(SECRET, String(s.id), { deleted: true }, 'apps_secret.delete'));
|
|
47
|
-
}
|
|
48
|
-
const listSecrets = async (ctx) => list(ctx, SECRET, newest(ctx, SECRET).filter((s) => kept(ctx, SECRET, s, '_scope_key') === scopeKeyOf(ctx)));
|
|
49
|
-
export const appsSecrets = {
|
|
50
|
-
PostAppsSecrets: set,
|
|
51
|
-
GetAppsSecretsFind: find,
|
|
52
|
-
PostAppsSecretsDelete: remove,
|
|
53
|
-
GetAppsSecrets: listSecrets,
|
|
54
|
-
};
|
|
42
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { platformKeyRefused, publishableKeyRefused, refuseParameters, rendered, withMetadata } from "./shared.js";
|
|
2
|
+
export async function around(ctx, next) {
|
|
3
|
+
const arrived = ctx.call.request;
|
|
4
|
+
const unkeyed = platformKeyRefused(ctx, arrived);
|
|
5
|
+
if (unkeyed)
|
|
6
|
+
return unkeyed;
|
|
7
|
+
if (ctx.call.operation.id !== 'unmatched') {
|
|
8
|
+
const refused = publishableKeyRefused(ctx) ?? refuseParameters(ctx);
|
|
9
|
+
if (refused)
|
|
10
|
+
return refused;
|
|
11
|
+
}
|
|
12
|
+
return rendered(arrived, await next(withMetadata(ctx, arrived.clone())));
|
|
13
|
+
}
|
|
@@ -1,11 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
/** The acting account's Balance object (docs.stripe.com/api/balance/balance_object). */
|
|
4
|
-
export declare function balanceBody(ctx: SemanticsContext): Row;
|
|
5
|
-
/** Time's arrivals, written: each of the acting account's payouts whose arrival date has come moves pending → paid
|
|
6
|
-
* (the clock's move, as asOf reads it), written as `payout.paid`, the event Stripe sends for it. Answers their ids. */
|
|
7
|
-
export declare function payDuePayouts(ctx: SemanticsContext): Promise<string[]>;
|
|
8
|
-
/** Time's payouts, caught up to the World's clock: each account on an automatic schedule is paid out, on each of its
|
|
9
|
-
* scheduled days that has come, what became available by then. */
|
|
10
|
-
export declare function advancePayouts(ctx: SemanticsContext): Promise<void>;
|
|
11
|
-
export declare const balances: Record<string, Semantics>;
|
|
1
|
+
import type { HandlerContext } from '@volter/world-core';
|
|
2
|
+
export declare function GetBalance(ctx: HandlerContext): Promise<Response>;
|
|
@@ -1,195 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import { at, at_, created, fail, inRange, list, newest, send, where, kept } from "./shared.js";
|
|
5
|
-
const account = actingAccount;
|
|
6
|
-
const DAY = 86_400;
|
|
7
|
-
const payoutMissing = (ctx, id) => fail(ctx, `No such payout: '${id}'`, 404, 'resource_missing');
|
|
8
|
-
/** The acting account's Balance object (docs.stripe.com/api/balance/balance_object). */
|
|
9
|
-
export function balanceBody(ctx) {
|
|
10
|
-
const { available, pending, issuing } = balanceOf(ctx);
|
|
11
|
-
const toArr = (m) => {
|
|
12
|
-
const out = [...m.entries()].map(([currency, amount]) => ({ amount, currency, source_types: { card: amount } }));
|
|
13
|
-
return out.length ? out : [{ amount: 0, currency: 'usd', source_types: { card: 0 } }];
|
|
14
|
-
};
|
|
15
|
-
// a platform's balance holds its connected accounts' reserve, "Funds held due to negative balances on connected accounts
|
|
16
|
-
// where account.controller.requirement_collection is `application`" (docs.stripe.com/api/balance/balance_object, whose
|
|
17
|
-
// example answers `[{"amount": 0, "currency": "usd"}]`); the twin models no such reserve, so it is zero in each currency
|
|
18
|
-
const reserved = account(ctx) ? {} : { connect_reserved: toArr(available).map((b) => ({ amount: 0, currency: b.currency })) };
|
|
19
|
-
return {
|
|
20
|
-
object: 'balance', available: toArr(available), pending: toArr(pending), ...reserved, livemode: false,
|
|
21
|
-
...(issuing.size ? { issuing: { available: [...issuing.entries()].map(([currency, amount]) => ({ amount, currency, source_types: { card: amount } })) } } : {}),
|
|
22
|
-
};
|
|
1
|
+
import { balanceBody } from "./shared.js";
|
|
2
|
+
export async function GetBalance(ctx) {
|
|
3
|
+
return ctx.reply(balanceBody(ctx));
|
|
23
4
|
}
|
|
24
|
-
const balance = async (ctx) => ctx.reply(balanceBody(ctx));
|
|
25
|
-
/** Time's arrivals, written: each of the acting account's payouts whose arrival date has come moves pending → paid
|
|
26
|
-
* (the clock's move, as asOf reads it), written as `payout.paid`, the event Stripe sends for it. Answers their ids. */
|
|
27
|
-
export async function payDuePayouts(ctx) {
|
|
28
|
-
const acct = account(ctx);
|
|
29
|
-
const now = Number(ctx.now());
|
|
30
|
-
const paid = [];
|
|
31
|
-
for (const p of newest(ctx, 'payout')) {
|
|
32
|
-
if ((acct ? kept(ctx, 'payout', p, '_account') !== acct : !!kept(ctx, 'payout', p, '_account')) || p.status !== 'pending' || Number(p.arrival_date) > now)
|
|
33
|
-
continue;
|
|
34
|
-
if (ctx.legal('payout', 'status', ctx.call.operation.id, 'pending', 'paid', String(p.id), 'time'))
|
|
35
|
-
continue;
|
|
36
|
-
await ctx.write('payout', String(p.id), { status: 'paid' }, 'payout.paid');
|
|
37
|
-
paid.push(String(p.id));
|
|
38
|
-
}
|
|
39
|
-
return paid;
|
|
40
|
-
}
|
|
41
|
-
/** Where a connected account's payout goes: "ID of the bank account or card the payout is sent to" (served spec,
|
|
42
|
-
* payout.destination), its default external account for the currency, "When multiple accounts are available for a given
|
|
43
|
-
* currency, Stripe uses the one set as `default_for_currency`" (docs.stripe.com/connect/payouts-bank-accounts), the
|
|
44
|
-
* newest such. Where the documentation stops and the twin decides: the platform's own bank account is not modelled, so
|
|
45
|
-
* its payouts name none. */
|
|
46
|
-
function payoutBank(ctx, account, currency) {
|
|
47
|
-
const banks = newest(ctx, 'external_account').filter((e) => e.account === account && String(e.currency ?? currency) === currency);
|
|
48
|
-
return String((banks.find((e) => e.default_for_currency === true) ?? banks[0])?.id ?? '') || null;
|
|
49
|
-
}
|
|
50
|
-
const payoutDefaults = (ctx) => ({
|
|
51
|
-
method: 'standard', type: 'bank_account', source_type: 'card', automatic: false,
|
|
52
|
-
reconciliation_status: 'not_applicable', arrival_date: Number(ctx.now()) + 2 * DAY, livemode: false, metadata: {},
|
|
53
|
-
});
|
|
54
|
-
/** A payout as the clock reads it: paid once its arrival date has come, the clock's move, asked of the
|
|
55
|
-
* machine as a write asks it. */
|
|
56
|
-
function asOf(ctx, p) {
|
|
57
|
-
if (p.status !== 'pending' || Number(p.arrival_date) > Number(ctx.now()))
|
|
58
|
-
return p;
|
|
59
|
-
ctx.legal('payout', 'status', ctx.call.operation.id, 'pending', 'paid', String(p.id), 'time');
|
|
60
|
-
return { ...p, status: 'paid' };
|
|
61
|
-
}
|
|
62
|
-
/** A connected account's payout in a currency none of its bank accounts takes. */
|
|
63
|
-
function noExternalAccount(ctx, currency) {
|
|
64
|
-
return fail(ctx, `Sorry, you don't have any external accounts in that currency (${currency}).`, 400);
|
|
65
|
-
}
|
|
66
|
-
const createPayout = async (ctx) => {
|
|
67
|
-
const bad = validateMoney(ctx.params);
|
|
68
|
-
if (bad)
|
|
69
|
-
return send(ctx, bad);
|
|
70
|
-
const acct = account(ctx);
|
|
71
|
-
if (acct && !ctx.get('account', acct))
|
|
72
|
-
return fail(ctx, `No such account: '${acct}'`, 400, 'account_invalid');
|
|
73
|
-
const amount = Math.trunc(Number(ctx.params.amount) || 0);
|
|
74
|
-
const currency = String(ctx.params.currency ?? 'usd');
|
|
75
|
-
// a connected account is paid out to its own bank account
|
|
76
|
-
if (acct && !ctx.rows('external_account').some((e) => e.account === acct && (e.currency ?? currency) === currency))
|
|
77
|
-
return noExternalAccount(ctx, currency);
|
|
78
|
-
const refused = refusePayout(ctx, amount, currency);
|
|
79
|
-
if (refused)
|
|
80
|
-
return refused;
|
|
81
|
-
const id = ctx.mint('payout');
|
|
82
|
-
const bt = await settlePayout(ctx, id, -amount, currency);
|
|
83
|
-
return ctx.reply(await created(ctx, 'payout', { ...ctx.params, id }, { status: 'pending', ...payoutDefaults(ctx), balance_transaction: bt, destination: acct ? payoutBank(ctx, acct, currency) : null, ...(acct ? { _account: acct } : {}) }));
|
|
84
|
-
};
|
|
85
|
-
const listPayouts = async (ctx) => {
|
|
86
|
-
const acct = account(ctx);
|
|
87
|
-
const scoped = newest(ctx, 'payout').filter((p) => (acct ? kept(ctx, 'payout', p, '_account') === acct : !kept(ctx, 'payout', p, '_account'))).map((p) => asOf(ctx, p));
|
|
88
|
-
return list(ctx, 'payout', where(ctx, scoped, { status: (p, v) => p.status === v, created: (p, v) => inRange(p.created, v), arrival_date: (p, v) => inRange(p.arrival_date, v) }));
|
|
89
|
-
};
|
|
90
|
-
const DAYS = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
|
|
91
|
-
/** The first scheduled payout time on or after `from`: midnight UTC of a day the schedule pays out on. */
|
|
92
|
-
function payoutDay(from, schedule) {
|
|
93
|
-
const first = Math.ceil(from / DAY) * DAY;
|
|
94
|
-
const pays = (day) => {
|
|
95
|
-
const d = new Date(day * 1000);
|
|
96
|
-
if (schedule.interval === 'weekly')
|
|
97
|
-
return DAYS[d.getUTCDay()] === String(schedule.weekly_anchor ?? 'monday');
|
|
98
|
-
if (schedule.interval === 'monthly')
|
|
99
|
-
return d.getUTCDate() === Math.min(Number(schedule.monthly_anchor ?? 1), new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth() + 1, 0)).getUTCDate());
|
|
100
|
-
return true;
|
|
101
|
-
};
|
|
102
|
-
return Array.from({ length: 62 }, (_, i) => first + i * DAY).find(pays) ?? first;
|
|
103
|
-
}
|
|
104
|
-
/** Time's payouts, caught up to the World's clock: each account on an automatic schedule is paid out, on each of its
|
|
105
|
-
* scheduled days that has come, what became available by then. */
|
|
106
|
-
export async function advancePayouts(ctx) {
|
|
107
|
-
const now = Number(ctx.now());
|
|
108
|
-
const platform = ctx.get('account', PLATFORM_ACCOUNT_ID);
|
|
109
|
-
const accounts = [{ id: undefined, settings: platform?.settings }];
|
|
110
|
-
for (const a of ctx.rows('account')) {
|
|
111
|
-
if (a.id === PLATFORM_ACCOUNT_ID || a.payouts_enabled !== true)
|
|
112
|
-
continue;
|
|
113
|
-
if (!ctx.rows('external_account').some((e) => e.account === a.id))
|
|
114
|
-
continue;
|
|
115
|
-
accounts.push({ id: String(a.id), settings: a.settings });
|
|
116
|
-
}
|
|
117
|
-
for (const acct of accounts) {
|
|
118
|
-
const schedule = (accountSettings(acct.settings, acct.settings ?? undefined).payouts.schedule ?? {});
|
|
119
|
-
if (schedule.interval === 'manual')
|
|
120
|
-
continue;
|
|
121
|
-
const unpaid = unpaidEntries(ctx, acct.id);
|
|
122
|
-
const days = [...new Set(unpaid.map((t) => payoutDay(Number(t.available_on) || 0, schedule)))].filter((d) => d <= now).sort((x, y) => x - y);
|
|
123
|
-
const paid = new Set();
|
|
124
|
-
for (const day of days) {
|
|
125
|
-
const due = unpaid.filter((t) => !paid.has(t.id) && (Number(t.available_on) || 0) <= day);
|
|
126
|
-
const byCurrency = new Map();
|
|
127
|
-
for (const t of due)
|
|
128
|
-
byCurrency.set(String(t.currency ?? 'usd'), [...(byCurrency.get(String(t.currency ?? 'usd')) ?? []), t]);
|
|
129
|
-
for (const [currency, entries] of byCurrency) {
|
|
130
|
-
const amount = entries.reduce((n, t) => n + (Number(t.net) || 0), 0);
|
|
131
|
-
// nothing to pay yet: what came due is carried to the next payout
|
|
132
|
-
if (amount <= 0)
|
|
133
|
-
continue;
|
|
134
|
-
// made on its day, as Stripe makes it, whenever the request that catches it up comes
|
|
135
|
-
const c = await at_(ctx)(day);
|
|
136
|
-
const id = c.mint('payout');
|
|
137
|
-
const bt = await settleAutomaticPayout(c, id, amount, currency, acct.id, day, entries);
|
|
138
|
-
await created(c, 'payout', { id, amount, currency }, {
|
|
139
|
-
status: 'pending', ...payoutDefaults(c), arrival_date: day + 2 * DAY, automatic: true, balance_transaction: bt, destination: acct.id ? payoutBank(c, String(acct.id), currency) : null,
|
|
140
|
-
description: 'STRIPE PAYOUT', ...(acct.id ? { _account: acct.id } : {}),
|
|
141
|
-
});
|
|
142
|
-
for (const t of entries)
|
|
143
|
-
paid.add(t.id);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
const retrievePayout = async (ctx) => {
|
|
149
|
-
const p = ctx.get('payout', at(ctx, 'payout'));
|
|
150
|
-
return p ? ctx.reply(asOf(ctx, p)) : payoutMissing(ctx, at(ctx, 'payout'));
|
|
151
|
-
};
|
|
152
|
-
const cancelPayout = async (ctx) => {
|
|
153
|
-
const id = at(ctx, 'payout');
|
|
154
|
-
const po = ctx.get('payout', id);
|
|
155
|
-
if (!po)
|
|
156
|
-
return payoutMissing(ctx, id);
|
|
157
|
-
const refused = ctx.legal('payout', 'status', 'PostPayoutsPayoutCancel', asOf(ctx, po).status, undefined, id);
|
|
158
|
-
if (refused)
|
|
159
|
-
return ctx.refuse(refused);
|
|
160
|
-
// the money comes back to the balance it left
|
|
161
|
-
const owner = kept(ctx, 'payout', po, '_account');
|
|
162
|
-
await settlePayout(ctx, id, Number(po.amount) || 0, String(po.currency ?? 'usd'), typeof owner === 'string' ? owner : null);
|
|
163
|
-
return ctx.reply(await ctx.write('payout', id, { status: 'canceled' }, 'payout.cancel'));
|
|
164
|
-
};
|
|
165
|
-
// a reversal is itself a payout in the other direction, back into the connected account's balance, as the reverse page's
|
|
166
|
-
// example answers it: a negative amount, pending until it arrives, carrying the request's metadata
|
|
167
|
-
// (docs.stripe.com/api/payouts/reverse); the original stays paid and names it
|
|
168
|
-
const reversePayout = async (ctx) => {
|
|
169
|
-
const id = at(ctx, 'payout');
|
|
170
|
-
const po = ctx.get('payout', id);
|
|
171
|
-
if (!po)
|
|
172
|
-
return payoutMissing(ctx, id);
|
|
173
|
-
const owner = kept(ctx, 'payout', po, '_account');
|
|
174
|
-
if (typeof owner !== 'string')
|
|
175
|
-
return fail(ctx, "Payout reversals are only supported for payouts to connected accounts' bank accounts.", 400);
|
|
176
|
-
const status = String(asOf(ctx, po).status);
|
|
177
|
-
if (po.reversed_by || status !== 'paid')
|
|
178
|
-
return ctx.refuse({ status: 400, code: 'payout_reversal_not_allowed', message: po.reversed_by ? 'This payout has already been reversed.' : `This payout cannot be reversed because it has a status of ${status}. A pending payout can be canceled instead.` });
|
|
179
|
-
const reversalId = ctx.mint('payout');
|
|
180
|
-
const bt = await settlePayout(ctx, reversalId, Number(po.amount) || 0, String(po.currency ?? 'usd'), owner);
|
|
181
|
-
const metadata = ctx.params.metadata && typeof ctx.params.metadata === 'object' ? { metadata: ctx.params.metadata } : {};
|
|
182
|
-
const reversal = await created(ctx, 'payout', { id: reversalId, amount: -(Number(po.amount) || 0), currency: po.currency, ...metadata }, {
|
|
183
|
-
status: 'pending', ...payoutDefaults(ctx), balance_transaction: bt, original_payout: id, destination: po.destination ?? null, _account: owner,
|
|
184
|
-
});
|
|
185
|
-
await ctx.write('payout', id, { reversed_by: reversal.id }, 'payout.reversed');
|
|
186
|
-
return ctx.reply(reversal);
|
|
187
|
-
};
|
|
188
|
-
export const balances = {
|
|
189
|
-
GetBalance: balance,
|
|
190
|
-
PostPayouts: createPayout,
|
|
191
|
-
GetPayouts: listPayouts,
|
|
192
|
-
GetPayoutsPayout: retrievePayout,
|
|
193
|
-
PostPayoutsPayoutCancel: cancelPayout,
|
|
194
|
-
PostPayoutsPayoutReverse: reversePayout,
|
|
195
|
-
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { inRange } from "../engine/common.js";
|
|
2
|
+
import { BT } from "../engine/ledger.js";
|
|
3
|
+
import { commonAsOf, kept, list, mine, newest, where } from "./shared.js";
|
|
4
|
+
export async function GetBalanceTransactions(ctx) {
|
|
5
|
+
const own = mine(ctx);
|
|
6
|
+
return list(ctx, BT, where(ctx, newest(ctx, BT).filter((t) => own.has(t.id)).map((t) => commonAsOf(ctx, t)), {
|
|
7
|
+
type: (t, v) => t.type === v,
|
|
8
|
+
currency: (t, v) => t.currency === v,
|
|
9
|
+
source: (t, v) => t.source === v,
|
|
10
|
+
// an automatic payout lists the entries it paid out, its own debit among them
|
|
11
|
+
payout: (t, v) => t.source === v || kept(ctx, BT, t, '_payout') === v,
|
|
12
|
+
// a range of creation times (docs.stripe.com/api/balance_transactions/list#balance_transaction_list-created)
|
|
13
|
+
created: (t, v) => inRange(t.created, v),
|
|
14
|
+
}));
|
|
15
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { HandlerContext } from '@volter/world-core';
|
|
2
|
+
export declare function GetBillingPortalConfigurations(ctx: HandlerContext): Promise<Response>;
|
|
3
|
+
export declare function PostBillingPortalConfigurations(ctx: HandlerContext): Promise<Response>;
|
|
4
|
+
export declare function PostBillingPortalSessions(ctx: HandlerContext): Promise<Response>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { filled, PBC, PORTAL_FEATURES } from "../engine/files.js";
|
|
2
|
+
import { asBool, nowUnix } from "../engine/stripe.js";
|
|
3
|
+
import { actingAccount, created, fail, list, newest, where } from "./shared.js";
|
|
4
|
+
export async function GetBillingPortalConfigurations(ctx) {
|
|
5
|
+
return list(ctx, PBC, where(ctx, newest(ctx, PBC), {
|
|
6
|
+
active: (c, v) => asBool(c.active) === asBool(v),
|
|
7
|
+
is_default: (c, v) => asBool(c.is_default) === asBool(v),
|
|
8
|
+
}));
|
|
9
|
+
}
|
|
10
|
+
export async function PostBillingPortalConfigurations(ctx) {
|
|
11
|
+
return ctx.reply(await created(ctx, PBC, { ...ctx.params, business_profile: filled({ headline: null, privacy_policy_url: null, terms_of_service_url: null }, ctx.params.business_profile), features: filled(PORTAL_FEATURES, ctx.params.features) }, {
|
|
12
|
+
active: true, is_default: false, livemode: false,
|
|
13
|
+
login_page: { enabled: false, url: null },
|
|
14
|
+
metadata: {}, default_return_url: ctx.params.default_return_url ?? null,
|
|
15
|
+
updated: nowUnix(ctx.occurredAt),
|
|
16
|
+
}));
|
|
17
|
+
}
|
|
18
|
+
// ── the customer portal ──
|
|
19
|
+
// the configuration defaults to the account's default one
|
|
20
|
+
export async function PostBillingPortalSessions(ctx) {
|
|
21
|
+
const customer = typeof ctx.params.customer === 'string' ? ctx.params.customer : '';
|
|
22
|
+
if (!customer)
|
|
23
|
+
return fail(ctx, 'Missing required param: customer.', 400, 'parameter_missing');
|
|
24
|
+
if (!ctx.row('customer', customer, { withDeleted: true }))
|
|
25
|
+
return fail(ctx, `No such customer: '${customer}'`, 404, 'resource_missing');
|
|
26
|
+
const configuration = typeof ctx.params.configuration === 'string' && ctx.params.configuration
|
|
27
|
+
? ctx.params.configuration
|
|
28
|
+
: (ctx.rowsRaw('billing_portal.configuration', { withDeleted: true }).find((c) => c.is_default)?.id ?? 'bpc_twin_default');
|
|
29
|
+
const id = ctx.mint('billing_portal.session');
|
|
30
|
+
return ctx.reply(await created(ctx, 'billing_portal.session', {
|
|
31
|
+
id, customer, configuration, return_url: ctx.params.return_url ?? null, url: `https://billing.stripe.com/p/session/${id}`,
|
|
32
|
+
locale: ctx.params.locale ?? null, on_behalf_of: ctx.params.on_behalf_of ?? null, livemode: false,
|
|
33
|
+
// the account the session was made on (Stripe-Account), whose name the portal shows (screens/billing-portal.tsx)
|
|
34
|
+
...(actingAccount(ctx) ? { _brand_account: actingAccount(ctx) } : {}),
|
|
35
|
+
}, {}));
|
|
36
|
+
}
|
|
@@ -1,28 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export declare function chargeBody(ctx: SemanticsContext, c: Row): Row;
|
|
5
|
-
/** A capture=false charge refunded while uncaptured: its authorization is released by the refund, as it would be
|
|
6
|
-
* "automatically refunded if uncaptured" (spec/openapi.json.gz, `capture_before`). The charge stays uncaptured and
|
|
7
|
-
* becomes refunded in full, a Refund records the release, and no money moves: none was ever received. Written as
|
|
8
|
-
* charge.refunded. Where the documentation stops and the twin decides: Stripe's basil change ("Partially capturing or
|
|
9
|
-
* canceling payments no longer creates a Refund", docs.stripe.com/changelog/basil/2025-03-31/remove-refund-from-partial-
|
|
10
|
-
* capture-and-payment-cancellation-flow) names partial capture and cancellation, not a refund asked for, so a refund
|
|
11
|
-
* still makes one; its reason is null and it has no balance transaction. Answers the Refund. */
|
|
12
|
-
export declare function releaseAuthorization(ctx: SemanticsContext, ch: Row, operationId: string, given?: Row): Promise<Row>;
|
|
13
|
-
/** A PaymentIntent's authorization released by its cancel: "For PaymentIntents with a `status` of `requires_capture`, the
|
|
14
|
-
* remaining `amount_capturable` is automatically refunded" (docs.stripe.com/api/payment_intents/cancel), and since basil
|
|
15
|
-
* a cancellation makes no Refund: "`amount_captured` will be 0 instead of `nil` in payment cancellation flows",
|
|
16
|
-
* "`amount_refunded` will no longer be updated by these actions", "`refunded` will no longer be `true` for payment
|
|
17
|
-
* cancellation flows", and no charge.refunded is sent (docs.stripe.com/changelog/basil/2025-03-31/remove-refund-from-
|
|
18
|
-
* partial-capture-and-payment-cancellation-flow). The charge stays uncaptured; nothing is written as an event. */
|
|
19
|
-
export declare function cancelAuthorization(ctx: SemanticsContext, ch: Row): Promise<Row>;
|
|
20
|
-
/** An authorized charge captured, by the charge's capture or its PaymentIntent's: what is captured credits the balance.
|
|
21
|
-
* Written as charge.captured, "Occurs whenever a previously uncaptured charge is captured" (docs.stripe.com/api/events/types).
|
|
22
|
-
* A partial capture releases the rest with no Refund and leaves amount_refunded and refunded as they were: "The following
|
|
23
|
-
* flows no longer result in a `Refund` object created and linked to the payment: Partial capture", "`amount_refunded`
|
|
24
|
-
* will no longer be updated by these actions", and "There will only be a single balance transaction for partial captures"
|
|
25
|
-
* (docs.stripe.com/changelog/basil/2025-03-31/remove-refund-from-partial-capture-and-payment-cancellation-flow).
|
|
26
|
-
* The caller has asked the machine whether it may capture. */
|
|
27
|
-
export declare function captureAuthorization(ctx: SemanticsContext, ch: Row, toCapture: number, _operationId: string): Promise<Row>;
|
|
28
|
-
export declare const charges: Record<string, Semantics>;
|
|
1
|
+
import type { HandlerContext } from '@volter/world-core';
|
|
2
|
+
export declare function GetCharges(ctx: HandlerContext): Promise<Response>;
|
|
3
|
+
export declare function GetChargesCharge(ctx: HandlerContext): Promise<Response>;
|