@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
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
import { paginate } from "../stripe-twin.js";
|
|
2
|
-
import { refundCharge } from "./refunds.js";
|
|
3
|
-
import { at, created, fail, path } from "./shared.js";
|
|
4
|
-
const CN = 'credit_note';
|
|
5
|
-
const noteMissing = (ctx, id) => fail(ctx, `No such credit note: '${id}'`, 404, 'resource_missing');
|
|
6
|
-
/** The credit note the request describes (the `amount` form: one custom line), or Stripe's refusal. */
|
|
7
|
-
function build(ctx, id) {
|
|
8
|
-
const params = ctx.params;
|
|
9
|
-
const invoiceId = typeof params.invoice === 'string' ? params.invoice : '';
|
|
10
|
-
if (!invoiceId)
|
|
11
|
-
return fail(ctx, 'Missing required param: invoice.', 400, 'parameter_missing');
|
|
12
|
-
const invoice = ctx.get('invoice', invoiceId);
|
|
13
|
-
if (!invoice)
|
|
14
|
-
return fail(ctx, `No such invoice: '${invoiceId}'`, 404, 'resource_missing');
|
|
15
|
-
if (params.amount === undefined)
|
|
16
|
-
return fail(ctx, 'Missing required param: amount.', 400, 'parameter_missing');
|
|
17
|
-
const amount = Number(params.amount);
|
|
18
|
-
if (!Number.isInteger(amount) || amount <= 0)
|
|
19
|
-
return fail(ctx, 'Invalid integer: amount must be a positive integer.', 400, 'parameter_invalid_integer');
|
|
20
|
-
const vendorType = invoice.status === 'paid' ? 'post_payment' : 'pre_payment';
|
|
21
|
-
const outOfBand = Number(params.out_of_band_amount) || 0;
|
|
22
|
-
// a paid invoice's credit is paid back: "The sum of refunds, customer balance credits, and outside of Stripe credits
|
|
23
|
-
// must equal the post_payment_amount" (docs.stripe.com/api/credit_notes/create); the message's wording is the twin's
|
|
24
|
-
if (vendorType === 'post_payment') {
|
|
25
|
-
const split = (Number(params.refund_amount) || 0) + (Number(params.credit_amount) || 0) + outOfBand;
|
|
26
|
-
if (split !== amount)
|
|
27
|
-
return fail(ctx, `The sum of refund_amount, credit_amount and out_of_band_amount (${split}) must equal the credit note's post_payment_amount (${amount}).`, 400, 'parameter_invalid_integer');
|
|
28
|
-
}
|
|
29
|
-
const line = {
|
|
30
|
-
object: 'credit_note_line_item', id: `cnli_${id}_1`, type: 'custom_line_item',
|
|
31
|
-
amount, description: typeof params.memo === 'string' ? params.memo : null,
|
|
32
|
-
// a custom line credits no invoice line: invoice_line_item ("ID of the invoice line item being credited") is left
|
|
33
|
-
// out, the served spec not letting it be null
|
|
34
|
-
discount_amount: 0, discount_amounts: [], livemode: false,
|
|
35
|
-
pretax_credit_amounts: [], quantity: null, tax_rates: [], taxes: [],
|
|
36
|
-
unit_amount: null, unit_amount_decimal: null,
|
|
37
|
-
};
|
|
38
|
-
return {
|
|
39
|
-
amount, amount_shipping: 0, created: ctx.now(), currency: typeof invoice.currency === 'string' ? invoice.currency : 'usd', customer: typeof invoice.customer === 'string' ? invoice.customer : null,
|
|
40
|
-
customer_balance_transaction: null,
|
|
41
|
-
// "The date when this credit note is in effect. Same as `created` unless overwritten" (the served spec)
|
|
42
|
-
discount_amount: 0, discount_amounts: [], effective_at: params.effective_at !== undefined ? Number(params.effective_at) : ctx.now(), invoice: invoiceId,
|
|
43
|
-
lines: { object: 'list', data: [line], has_more: false, total_count: 1, url: `/v1/credit_notes/${id}/lines` },
|
|
44
|
-
livemode: false, memo: params.memo ?? null, metadata: params.metadata && typeof params.metadata === 'object' ? params.metadata : {},
|
|
45
|
-
number: `${invoiceId}-CN-01`, out_of_band_amount: outOfBand || null,
|
|
46
|
-
pdf: `https://files.twin.local/credit_notes/${id}.pdf`,
|
|
47
|
-
post_payment_amount: vendorType === 'post_payment' ? amount : 0,
|
|
48
|
-
pre_payment_amount: vendorType === 'pre_payment' ? amount : 0,
|
|
49
|
-
pretax_credit_amounts: [],
|
|
50
|
-
reason: typeof params.reason === 'string' ? params.reason : null,
|
|
51
|
-
refunds: [], shipping_cost: null, status: 'issued',
|
|
52
|
-
subtotal: amount, subtotal_excluding_tax: amount,
|
|
53
|
-
type: vendorType, total: amount, total_excluding_tax: amount, total_taxes: [],
|
|
54
|
-
voided_at: null,
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
/** The invoice's credit-note sums, from its issued credit notes; a pre-payment credit lowers what is owed. */
|
|
58
|
-
async function syncInvoice(ctx, invoiceId) {
|
|
59
|
-
const inv = ctx.get('invoice', invoiceId);
|
|
60
|
-
if (!inv)
|
|
61
|
-
return;
|
|
62
|
-
let pre = 0;
|
|
63
|
-
let post = 0;
|
|
64
|
-
for (const cn of ctx.rows(CN)) {
|
|
65
|
-
if (cn.invoice !== invoiceId || cn.status === 'void')
|
|
66
|
-
continue;
|
|
67
|
-
if (cn.type === 'post_payment')
|
|
68
|
-
post += Number(cn.amount) || 0;
|
|
69
|
-
else
|
|
70
|
-
pre += Number(cn.amount) || 0;
|
|
71
|
-
}
|
|
72
|
-
const total = Number(inv.total ?? inv.amount_due) || 0;
|
|
73
|
-
const paid = Number(inv.amount_paid) || 0;
|
|
74
|
-
await ctx.write('invoice', invoiceId, { pre_payment_credit_notes_amount: pre, post_payment_credit_notes_amount: post, amount_remaining: Math.max(0, total - paid - pre) }, 'invoice.update');
|
|
75
|
-
}
|
|
76
|
-
// the preview computes the credit note without keeping it
|
|
77
|
-
const preview = async (ctx) => {
|
|
78
|
-
const id = 'cn_preview';
|
|
79
|
-
const cn = build(ctx, id);
|
|
80
|
-
return cn instanceof Response ? cn : ctx.reply({ object: CN, ...cn, id });
|
|
81
|
-
};
|
|
82
|
-
/** What a post-payment credit pays back: "Refunds: create a new refund (using refund_amount)"; "Customer balance credit:
|
|
83
|
-
* credit the customer's balance (using credit_amount) which will be automatically applied to their next invoice when
|
|
84
|
-
* it's finalized" (docs.stripe.com/api/credit_notes/create). The refund is made on the invoice's charge as a refund
|
|
85
|
-
* call makes it (refunds.ts); the credit is a customer balance transaction of type credit_note. Where the documentation
|
|
86
|
-
* stops and the twin decides: the refund carries no reason of its own. */
|
|
87
|
-
async function payBack(ctx, id, cn) {
|
|
88
|
-
const params = ctx.params;
|
|
89
|
-
const out = {};
|
|
90
|
-
const refundAmount = Number(params.refund_amount) || 0;
|
|
91
|
-
if (refundAmount > 0) {
|
|
92
|
-
const invoice = ctx.get('invoice', String(cn.invoice));
|
|
93
|
-
const pi = typeof invoice?.payment_intent === 'string' ? ctx.get('payment_intent', invoice.payment_intent) : undefined;
|
|
94
|
-
const chargeId = typeof invoice?.charge === 'string' ? invoice.charge : typeof pi?.latest_charge === 'string' ? pi.latest_charge : undefined;
|
|
95
|
-
const charge = chargeId ? ctx.get('charge', chargeId) : undefined;
|
|
96
|
-
if (!charge)
|
|
97
|
-
return fail(ctx, 'This invoice was not paid with a charge that can be refunded.', 400, 'invoice_no_charge_to_refund');
|
|
98
|
-
const answer = await refundCharge(ctx, charge, { amount: refundAmount });
|
|
99
|
-
if (answer.status >= 400)
|
|
100
|
-
return answer;
|
|
101
|
-
const refund = (await answer.json());
|
|
102
|
-
out.refunds = [{ amount_refunded: refundAmount, refund: refund.id, type: 'refund', payment_record_refund: null }];
|
|
103
|
-
}
|
|
104
|
-
const creditAmount = Number(params.credit_amount) || 0;
|
|
105
|
-
const customer = typeof cn.customer === 'string' ? cn.customer : undefined;
|
|
106
|
-
if (creditAmount > 0 && customer) {
|
|
107
|
-
const ending = (Number(ctx.get('customer', customer)?.balance) || 0) - creditAmount;
|
|
108
|
-
const txn = await created(ctx, 'customer_balance_transaction', { customer, amount: -creditAmount, currency: cn.currency, credit_note: id, invoice: cn.invoice }, {
|
|
109
|
-
ending_balance: ending, type: 'credit_note', livemode: false, metadata: {}, description: null, checkout_session: null,
|
|
110
|
-
});
|
|
111
|
-
await ctx.write('customer', customer, { balance: ending }, `customer.balance_adjusted:${String(txn.id)}`);
|
|
112
|
-
out.customer_balance_transaction = txn.id;
|
|
113
|
-
}
|
|
114
|
-
return out;
|
|
115
|
-
}
|
|
116
|
-
const create = async (ctx) => {
|
|
117
|
-
const id = ctx.mint(CN);
|
|
118
|
-
const cn = build(ctx, id);
|
|
119
|
-
if (cn instanceof Response)
|
|
120
|
-
return cn;
|
|
121
|
-
const paid = cn.type === 'post_payment' ? await payBack(ctx, id, cn) : {};
|
|
122
|
-
if (paid instanceof Response)
|
|
123
|
-
return paid;
|
|
124
|
-
const body = await created(ctx, CN, { id, ...cn, ...paid }, {});
|
|
125
|
-
await syncInvoice(ctx, String(cn.invoice));
|
|
126
|
-
return ctx.reply(body);
|
|
127
|
-
};
|
|
128
|
-
const retrieve = async (ctx) => {
|
|
129
|
-
const c = ctx.get(CN, at(ctx, 'id'));
|
|
130
|
-
return c ? ctx.reply(c) : noteMissing(ctx, at(ctx, 'id'));
|
|
131
|
-
};
|
|
132
|
-
const lines = async (ctx) => {
|
|
133
|
-
const c = ctx.get(CN, at(ctx, 'credit_note'));
|
|
134
|
-
if (!c)
|
|
135
|
-
return noteMissing(ctx, at(ctx, 'credit_note'));
|
|
136
|
-
const l = c.lines;
|
|
137
|
-
const { page, hasMore } = paginate(Array.isArray(l?.data) ? l.data : [], ctx.params);
|
|
138
|
-
return ctx.reply({ object: 'list', url: path(ctx), has_more: hasMore, data: page });
|
|
139
|
-
};
|
|
140
|
-
const voidNote = async (ctx) => {
|
|
141
|
-
const id = at(ctx, 'id');
|
|
142
|
-
const c = ctx.get(CN, id);
|
|
143
|
-
if (!c)
|
|
144
|
-
return noteMissing(ctx, id);
|
|
145
|
-
const refused = ctx.legal(CN, 'status', 'PostCreditNotesIdVoid', c.status, undefined, id);
|
|
146
|
-
if (refused)
|
|
147
|
-
return ctx.refuse(refused);
|
|
148
|
-
const voided = await ctx.write(CN, id, { status: 'void', voided_at: ctx.now() }, 'credit_note.void');
|
|
149
|
-
if (typeof c.invoice === 'string')
|
|
150
|
-
await syncInvoice(ctx, c.invoice);
|
|
151
|
-
return ctx.reply(voided);
|
|
152
|
-
};
|
|
153
|
-
// only the memo and metadata change
|
|
154
|
-
const update = async (ctx) => {
|
|
155
|
-
const id = at(ctx, 'id');
|
|
156
|
-
if (!ctx.get(CN, id))
|
|
157
|
-
return noteMissing(ctx, id);
|
|
158
|
-
const patch = {};
|
|
159
|
-
if (ctx.params.memo !== undefined)
|
|
160
|
-
patch.memo = ctx.params.memo;
|
|
161
|
-
if (ctx.params.metadata !== undefined)
|
|
162
|
-
patch.metadata = ctx.params.metadata;
|
|
163
|
-
return ctx.reply(await ctx.write(CN, id, patch, 'credit_note.update'));
|
|
164
|
-
};
|
|
165
|
-
export const creditNotes = {
|
|
166
|
-
GetCreditNotesPreview: preview,
|
|
167
|
-
PostCreditNotes: create,
|
|
168
|
-
GetCreditNotesId: retrieve,
|
|
169
|
-
GetCreditNotesCreditNoteLines: lines,
|
|
170
|
-
PostCreditNotesIdVoid: voidNote,
|
|
171
|
-
PostCreditNotesId: update,
|
|
172
|
-
};
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { asBool } from "../stripe-twin.js";
|
|
2
|
-
import { settleDisputeWon } from "./ledger.js";
|
|
3
|
-
import { at, fail } from "./shared.js";
|
|
4
|
-
const disputeMissing = (ctx, id) => fail(ctx, `No such dispute: '${id}'`, 404, 'resource_missing');
|
|
5
|
-
const retrieve = async (ctx) => {
|
|
6
|
-
const d = ctx.get('dispute', at(ctx, 'dispute'));
|
|
7
|
-
return d ? ctx.reply(d) : disputeMissing(ctx, at(ctx, 'dispute'));
|
|
8
|
-
};
|
|
9
|
-
const close = async (ctx) => {
|
|
10
|
-
const id = at(ctx, 'dispute');
|
|
11
|
-
const d = ctx.get('dispute', id);
|
|
12
|
-
if (!d)
|
|
13
|
-
return disputeMissing(ctx, id);
|
|
14
|
-
const refused = ctx.legal('dispute', 'status', 'PostDisputesDisputeClose', d.status, undefined, id);
|
|
15
|
-
if (refused)
|
|
16
|
-
return ctx.refuse(refused);
|
|
17
|
-
return ctx.reply(await ctx.write('dispute', id, { status: 'lost' }, 'dispute.close'));
|
|
18
|
-
};
|
|
19
|
-
/** Evidence staged without submitting it (submit=false), or on a dispute already under review or decided. */
|
|
20
|
-
async function keepEvidence(ctx, id, fields) {
|
|
21
|
-
return ctx.reply(await ctx.write('dispute', id, fields, 'dispute.update'));
|
|
22
|
-
}
|
|
23
|
-
const update = async (ctx) => {
|
|
24
|
-
const id = at(ctx, 'dispute');
|
|
25
|
-
const d = ctx.get('dispute', id);
|
|
26
|
-
if (!d)
|
|
27
|
-
return disputeMissing(ctx, id);
|
|
28
|
-
const params = ctx.params;
|
|
29
|
-
const given = params.evidence && typeof params.evidence === 'object' ? params.evidence : {};
|
|
30
|
-
const evidence = { ...(d.evidence ?? {}), ...given };
|
|
31
|
-
const fields = { evidence, ...(params.metadata && typeof params.metadata === 'object' ? { metadata: { ...(d.metadata ?? {}), ...params.metadata } } : {}) };
|
|
32
|
-
const submit = params.submit === undefined ? true : asBool(params.submit);
|
|
33
|
-
const review = d.status === 'warning_needs_response' ? 'warning_under_review' : 'under_review';
|
|
34
|
-
if (!submit || ctx.legal('dispute', 'status', 'PostDisputesDispute', d.status, review, id))
|
|
35
|
-
return keepEvidence(ctx, id, fields);
|
|
36
|
-
const details = d.evidence_details ?? {};
|
|
37
|
-
let body = await ctx.write('dispute', id, { ...fields, status: review, evidence_details: { ...details, has_evidence: true, submission_count: (Number(details.submission_count) || 0) + 1 } }, 'charge.dispute.updated');
|
|
38
|
-
const text = String(evidence.uncategorized_text ?? '');
|
|
39
|
-
const decided = review === 'under_review' ? (text.includes('winning_evidence') ? 'won' : text.includes('losing_evidence') ? 'lost' : undefined) : undefined;
|
|
40
|
-
if (decided && !ctx.legal('dispute', 'status', 'PostDisputesDispute', review, decided, id, 'vendor')) {
|
|
41
|
-
const bt = decided === 'won' ? await settleDisputeWon(ctx, id, Number(d.amount) || 0, String(d.currency ?? 'usd')) : undefined;
|
|
42
|
-
const kept = (ctx.get('dispute', id)?.balance_transactions ?? []);
|
|
43
|
-
body = await ctx.write('dispute', id, { status: decided, ...(bt ? { balance_transactions: [...kept, ctx.get('balance_transaction', bt) ?? bt] } : {}) }, 'charge.dispute.closed');
|
|
44
|
-
}
|
|
45
|
-
return ctx.reply(body);
|
|
46
|
-
};
|
|
47
|
-
export const disputes = {
|
|
48
|
-
GetDisputesDispute: retrieve,
|
|
49
|
-
PostDisputesDispute: update,
|
|
50
|
-
PostDisputesDisputeClose: close,
|
|
51
|
-
};
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { at, fail } from "./shared.js";
|
|
2
|
-
const create = async (ctx) => {
|
|
3
|
-
const version = ctx.call.request.headers.get('stripe-version');
|
|
4
|
-
if (!version)
|
|
5
|
-
return fail(ctx, 'You must pass the `Stripe-Version` header (e.g. via the apiVersion option) when creating an ephemeral key.', 400, 'parameter_missing');
|
|
6
|
-
const params = ctx.params;
|
|
7
|
-
const scopes = [];
|
|
8
|
-
if (typeof params.customer === 'string' && params.customer)
|
|
9
|
-
scopes.push(['customer', params.customer]);
|
|
10
|
-
if (typeof params.issuing_card === 'string' && params.issuing_card)
|
|
11
|
-
scopes.push(['issuing.card', params.issuing_card]);
|
|
12
|
-
if (typeof params.verification_session === 'string' && params.verification_session)
|
|
13
|
-
scopes.push(['identity.verification_session', params.verification_session]);
|
|
14
|
-
if (scopes.length !== 1)
|
|
15
|
-
return fail(ctx, 'You must pass exactly one of `customer`, `issuing_card`, or `verification_session`.', 400, 'parameter_missing');
|
|
16
|
-
const [scope, scopedId] = scopes[0];
|
|
17
|
-
if (scope === 'customer' && !ctx.get('customer', scopedId))
|
|
18
|
-
return fail(ctx, `No such customer: '${scopedId}'`, 400, 'resource_missing');
|
|
19
|
-
const id = ctx.mint('ephemeral_key');
|
|
20
|
-
const now = Number(ctx.now());
|
|
21
|
-
const associated_objects = [{ type: scope, id: scopedId }];
|
|
22
|
-
await ctx.write('ephemeral_key', id, { object: 'ephemeral_key', created: now, expires: now + 3600, livemode: false, associated_objects }, 'ephemeral_key.create');
|
|
23
|
-
return ctx.reply({ id, object: 'ephemeral_key', created: now, expires: now + 3600, livemode: false, secret: `ek_test_twin_${id}`, associated_objects });
|
|
24
|
-
};
|
|
25
|
-
const expire = async (ctx) => {
|
|
26
|
-
const id = at(ctx, 'key');
|
|
27
|
-
if (!ctx.get('ephemeral_key', id))
|
|
28
|
-
return fail(ctx, `No such ephemeral key: '${id}'`, 404, 'resource_missing');
|
|
29
|
-
return ctx.reply(await ctx.write('ephemeral_key', id, { expires: ctx.now() }, 'ephemeral_key.delete'));
|
|
30
|
-
};
|
|
31
|
-
export const ephemeralKeys = {
|
|
32
|
-
PostEphemeralKeys: create,
|
|
33
|
-
DeleteEphemeralKeysKey: expire,
|
|
34
|
-
};
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import { asBool } from "../stripe-twin.js";
|
|
2
|
-
import { actingAccount } from "./ledger.js";
|
|
3
|
-
import { at, created, fail, filePurposeRefused, list, mergeUpdate, newest, where } from "./shared.js";
|
|
4
|
-
/** The type Stripe answers for an uploaded file: "The returned file type (for example, csv, pdf, jpg, or png)"
|
|
5
|
-
* (docs.stripe.com/api/files/object). Where the documentation stops and the twin decides: read from the name's
|
|
6
|
-
* extension (jpeg as jpg), and null for a name without one. */
|
|
7
|
-
function fileType(name) {
|
|
8
|
-
const ext = /\.([a-z0-9]+)$/i.exec(name)?.[1]?.toLowerCase();
|
|
9
|
-
return ext ? (ext === 'jpeg' ? 'jpg' : ext) : null;
|
|
10
|
-
}
|
|
11
|
-
// multipart on Stripe; the file is described by the part uploaded: its name, its size in bytes and its type
|
|
12
|
-
const createFile = async (ctx) => {
|
|
13
|
-
const purpose = typeof ctx.params.purpose === 'string' ? ctx.params.purpose : '';
|
|
14
|
-
if (!purpose)
|
|
15
|
-
return fail(ctx, 'Missing required param: purpose.', 400, 'parameter_missing');
|
|
16
|
-
const part = ctx.params.file && typeof ctx.params.file === 'object' ? ctx.params.file : undefined;
|
|
17
|
-
const filename = typeof ctx.params.file === 'string' ? ctx.params.file : typeof part?.name === 'string' ? part.name : 'twin_upload';
|
|
18
|
-
const made = await created(ctx, 'file', { purpose }, {
|
|
19
|
-
filename, size: typeof part?.size === 'number' ? part.size : 0,
|
|
20
|
-
type: fileType(filename), title: null, expires_at: null, url: null,
|
|
21
|
-
links: { object: 'list', data: [], has_more: false, total_count: 0, url: '' },
|
|
22
|
-
});
|
|
23
|
-
await syncLinks(ctx, String(made.id));
|
|
24
|
-
return ctx.reply(ctx.get('file', String(made.id)));
|
|
25
|
-
};
|
|
26
|
-
/** A file's links, kept in step with the links made to it, at the address Stripe lists them
|
|
27
|
-
* (/v1/file_links?file=…, the File object's example). */
|
|
28
|
-
async function syncLinks(ctx, fileId) {
|
|
29
|
-
const data = newest(ctx, 'file_link').filter((l) => l.file === fileId);
|
|
30
|
-
await ctx.write('file', fileId, { links: { object: 'list', data, has_more: false, url: `/v1/file_links?file=${fileId}` } }, 'file.links_synced');
|
|
31
|
-
}
|
|
32
|
-
/** The purposes a file link may be made to: "The file's `purpose` must be one of the following: …" (the served
|
|
33
|
-
* spec, POST /v1/file_links `file`). */
|
|
34
|
-
const LINKABLE = ['business_icon', 'business_logo', 'customer_signature', 'dispute_evidence', 'finance_report_run', 'financial_account_statement', 'identity_document_downloadable', 'issuing_regulatory_reporting', 'pci_document', 'selfie', 'sigma_scheduled_query', 'tax_document_user_upload', 'terminal_android_apk', 'terminal_reader_splashscreen'];
|
|
35
|
-
// `file` is required; a link is kept, has its own public url, and is listed on its file
|
|
36
|
-
const createFileLink = async (ctx) => {
|
|
37
|
-
if (ctx.params.file === undefined || ctx.params.file === '')
|
|
38
|
-
return fail(ctx, 'Missing required param: file.', 400, 'parameter_missing');
|
|
39
|
-
const fileId = String(ctx.params.file);
|
|
40
|
-
const refused = filePurposeRefused(ctx, 'file', LINKABLE);
|
|
41
|
-
if (refused)
|
|
42
|
-
return refused;
|
|
43
|
-
const id = ctx.mint('file_link');
|
|
44
|
-
const link = await created(ctx, 'file_link', { ...ctx.params, id, file: fileId }, {
|
|
45
|
-
url: `https://files.twin.local/links/${id}`, expired: false, livemode: false, metadata: {},
|
|
46
|
-
expires_at: ctx.params.expires_at !== undefined ? Number(ctx.params.expires_at) : null,
|
|
47
|
-
});
|
|
48
|
-
await syncLinks(ctx, fileId);
|
|
49
|
-
return ctx.reply(link);
|
|
50
|
-
};
|
|
51
|
-
// the person verifies at the session's url, Stripe Identity's hosted page (../screens/identity.tsx)
|
|
52
|
-
const createVerificationSession = async (ctx) => {
|
|
53
|
-
const id = ctx.mint('identity.verification_session');
|
|
54
|
-
return ctx.reply(await created(ctx, 'identity.verification_session', { ...ctx.params, id }, {
|
|
55
|
-
status: 'requires_input', livemode: false, client_secret: `${id}_secret_twin`, url: `https://verify.stripe.com/start/${id}`,
|
|
56
|
-
last_error: null, last_verification_report: null, verified_outputs: null, return_url: ctx.params.return_url ?? null,
|
|
57
|
-
}));
|
|
58
|
-
};
|
|
59
|
-
// ── the customer portal ──
|
|
60
|
-
// the configuration defaults to the account's default one
|
|
61
|
-
const createPortalSession = async (ctx) => {
|
|
62
|
-
const customer = typeof ctx.params.customer === 'string' ? ctx.params.customer : '';
|
|
63
|
-
if (!customer)
|
|
64
|
-
return fail(ctx, 'Missing required param: customer.', 400, 'parameter_missing');
|
|
65
|
-
if (!ctx.row('customer', customer, { withDeleted: true }))
|
|
66
|
-
return fail(ctx, `No such customer: '${customer}'`, 404, 'resource_missing');
|
|
67
|
-
const configuration = typeof ctx.params.configuration === 'string' && ctx.params.configuration
|
|
68
|
-
? ctx.params.configuration
|
|
69
|
-
: (ctx.rowsRaw('billing_portal.configuration', { withDeleted: true }).find((c) => c.is_default)?.id ?? 'bpc_twin_default');
|
|
70
|
-
const id = ctx.mint('billing_portal.session');
|
|
71
|
-
return ctx.reply(await created(ctx, 'billing_portal.session', {
|
|
72
|
-
id, customer, configuration, return_url: ctx.params.return_url ?? null, url: `https://billing.stripe.com/p/session/${id}`,
|
|
73
|
-
locale: ctx.params.locale ?? null, on_behalf_of: ctx.params.on_behalf_of ?? null, livemode: false,
|
|
74
|
-
// the account the session was made on (Stripe-Account), whose name the portal shows (screens/portal.tsx)
|
|
75
|
-
...(actingAccount(ctx) ? { _brand_account: actingAccount(ctx) } : {}),
|
|
76
|
-
}, {}));
|
|
77
|
-
};
|
|
78
|
-
const PBC = 'billing_portal.configuration';
|
|
79
|
-
/** A portal configuration's features, each filled where the request leaves it: every feature is answered (the served
|
|
80
|
-
* spec requires all five), as the create page's example answers a request that sets only customer_update and
|
|
81
|
-
* invoice_history: payment_method_update disabled, subscription_cancel disabled at_period_end with proration_behavior
|
|
82
|
-
* none and its five default reasons, subscription_update disabled with no allowed updates and proration_behavior none
|
|
83
|
-
* (docs.stripe.com/api/customer_portal/configurations/create); trial_update_behavior "Defaults to a value of
|
|
84
|
-
* `end_trial` if you don't set it during creation" (the served spec). Where the documentation stops and the twin
|
|
85
|
-
* decides: a feature the request leaves out is disabled, and schedule_at_period_end has no conditions. */
|
|
86
|
-
const PORTAL_FEATURES = {
|
|
87
|
-
customer_update: { allowed_updates: [], enabled: false },
|
|
88
|
-
invoice_history: { enabled: false },
|
|
89
|
-
payment_method_update: { enabled: false, payment_method_configuration: null },
|
|
90
|
-
subscription_cancel: { cancellation_reason: { enabled: false, options: ['too_expensive', 'missing_features', 'switched_service', 'unused', 'other'] }, enabled: false, mode: 'at_period_end', proration_behavior: 'none' },
|
|
91
|
-
subscription_update: { default_allowed_updates: [], enabled: false, proration_behavior: 'none', schedule_at_period_end: { conditions: [] }, trial_update_behavior: 'end_trial' },
|
|
92
|
-
};
|
|
93
|
-
const filled = (base, given) => {
|
|
94
|
-
if (!given || typeof given !== 'object' || Array.isArray(given) || !base || typeof base !== 'object' || Array.isArray(base))
|
|
95
|
-
return given === undefined ? base : given;
|
|
96
|
-
const out = { ...base };
|
|
97
|
-
for (const [k, v] of Object.entries(given))
|
|
98
|
-
out[k] = filled(base[k], v);
|
|
99
|
-
return out;
|
|
100
|
-
};
|
|
101
|
-
const createPortalConfiguration = async (ctx) => 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) }, {
|
|
102
|
-
active: true, is_default: false, livemode: false,
|
|
103
|
-
login_page: { enabled: false, url: null },
|
|
104
|
-
metadata: {}, default_return_url: ctx.params.default_return_url ?? null,
|
|
105
|
-
updated: ctx.now(),
|
|
106
|
-
}));
|
|
107
|
-
const listPortalConfigurations = async (ctx) => list(ctx, PBC, where(ctx, newest(ctx, PBC), {
|
|
108
|
-
active: (c, v) => asBool(c.active) === asBool(v),
|
|
109
|
-
is_default: (c, v) => asBool(c.is_default) === asBool(v),
|
|
110
|
-
}));
|
|
111
|
-
const updatePortalConfiguration = async (ctx) => {
|
|
112
|
-
const id = at(ctx, 'configuration');
|
|
113
|
-
if (!ctx.get(PBC, id))
|
|
114
|
-
return ctx.notFound(PBC, id);
|
|
115
|
-
return ctx.reply(await ctx.write(PBC, id, mergeUpdate(ctx, PBC, id, { ...ctx.params, updated: ctx.now() }), 'billing_portal.configuration.update'));
|
|
116
|
-
};
|
|
117
|
-
export const files = {
|
|
118
|
-
PostFiles: createFile,
|
|
119
|
-
PostFileLinks: createFileLink,
|
|
120
|
-
PostIdentityVerificationSessions: createVerificationSession,
|
|
121
|
-
PostBillingPortalSessions: createPortalSession,
|
|
122
|
-
PostBillingPortalConfigurations: createPortalConfiguration,
|
|
123
|
-
GetBillingPortalConfigurations: listPortalConfigurations,
|
|
124
|
-
PostBillingPortalConfigurationsConfiguration: updatePortalConfiguration,
|
|
125
|
-
};
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import type { Semantics, SemanticsContext } from '@volter/world-core';
|
|
2
|
-
import { type Row } from './shared.js';
|
|
3
|
-
/** Whether a charge's funds go straight to the available balance: a bypass card as a raw number, a test name (pm_card_*
|
|
4
|
-
* or tok_*), or a stored PaymentMethod made from one (which records it as what follows its success, after-payment.ts);
|
|
5
|
-
* or a US bank account, stored or one of Stripe's test bank accounts named as one (pm_usBankAccount_*). */
|
|
6
|
-
export declare function bypassesPending(ctx: SemanticsContext, card: string | undefined): boolean;
|
|
7
|
-
/** The connected account a request acts for, or undefined for the platform. */
|
|
8
|
-
export declare const actingAccount: (ctx: SemanticsContext) => string | undefined;
|
|
9
|
-
/** A captured charge's credit: its amount less the fee, pending two days unless the card bypasses the pending
|
|
10
|
-
* balance (bypassesPending), when it is due at once. The
|
|
11
|
-
* caller mints the charge's id first and stores the returned id as the charge's balance_transaction. */
|
|
12
|
-
export declare function settleCharge(ctx: SemanticsContext, chargeId: string, amount: number, currency: string, card?: string): Promise<string>;
|
|
13
|
-
/** A refund's debit, at once, on the acting account's balance unless one is named (null names the platform). */
|
|
14
|
-
export declare function settleRefund(ctx: SemanticsContext, refundId: string, amount: number, currency: string, account?: string | null | undefined): Promise<string>;
|
|
15
|
-
/** What an account had available in a currency at a moment: every entry of its payments balance whose funds had come
|
|
16
|
-
* due by then. */
|
|
17
|
-
export declare function availableAt(ctx: SemanticsContext, account: string | undefined, currency: string, at: number): number;
|
|
18
|
-
/** The moments after `from` and up to `until` when funds of an account came due, in order: when a held refund can
|
|
19
|
-
* next be covered. */
|
|
20
|
-
export declare function fundsDueBetween(ctx: SemanticsContext, account: string | undefined, currency: string, from: number, until: number): number[];
|
|
21
|
-
/** A dispute's debit, at once: the disputed amount and the dispute fee (the twin's 1500 cents, Stripe's US $15). */
|
|
22
|
-
export declare function settleDispute(ctx: SemanticsContext, disputeId: string, amount: number, currency: string): Promise<string>;
|
|
23
|
-
/** A won dispute's credit, at once: the disputed amount returned (docs.stripe.com/disputes/how-disputes-work). Where the
|
|
24
|
-
* documentation stops and the twin decides: the dispute fee is not returned. */
|
|
25
|
-
export declare function settleDisputeWon(ctx: SemanticsContext, disputeId: string, amount: number, currency: string): Promise<string>;
|
|
26
|
-
/** An account's ledger entries an automatic payout has not yet paid out: every entry on its payments balance that no
|
|
27
|
-
* automatic payout took (the automatic payouts' own debits excluded), as stored. */
|
|
28
|
-
export declare function unpaidEntries(ctx: SemanticsContext, account: string | undefined): Row[];
|
|
29
|
-
/** An automatic payout's debit at `at`, and the entries it pays out marked with it, so the ledger lists them under
|
|
30
|
-
* the payout (docs.stripe.com/api/balance_transactions/list#balance_transaction_list-payout). */
|
|
31
|
-
export declare function settleAutomaticPayout(ctx: SemanticsContext, payoutId: string, amount: number, currency: string, account: string | undefined, at: number, entries: Row[]): Promise<string>;
|
|
32
|
-
/** A payout's debit (negative) or a cancellation's or reversal's credit (positive), at once, on the payout's account. */
|
|
33
|
-
export declare function settlePayout(ctx: SemanticsContext, payoutId: string, amount: number, currency: string, account?: string | null | undefined): Promise<string>;
|
|
34
|
-
/** A transfer's two entries: out of the platform's balance at once, into the destination's when `fromCharge` (its
|
|
35
|
-
* charge's funds' availability) comes (a plain transfer, with no `fromCharge`, moves funds available already).
|
|
36
|
-
* Answers the platform's entry. */
|
|
37
|
-
export declare function settleTransfer(ctx: SemanticsContext, transferId: string, amount: number, currency: string, destination: string, fromCharge?: number, fromPending?: boolean): Promise<string>;
|
|
38
|
-
/** A transfer reversal's two entries: back into the platform's balance, out of the destination's. */
|
|
39
|
-
export declare function settleTransferReversal(ctx: SemanticsContext, reversalId: string, amount: number, currency: string, destination: string): Promise<string>;
|
|
40
|
-
/** A direct charge's application fee: out of the connected account's balance, into the platform's. */
|
|
41
|
-
export declare function settleApplicationFee(ctx: SemanticsContext, feeId: string, amount: number, currency: string, account: string): Promise<string>;
|
|
42
|
-
/** A top-up's credit, to the payments balance or, with `destination_balance=issuing`, to Issuing's
|
|
43
|
-
* (docs.stripe.com/issuing/funding/balance). Where the documentation stops and the twin decides: a test-mode top-up
|
|
44
|
-
* is available at once. */
|
|
45
|
-
export declare function settleTopup(ctx: SemanticsContext, topupId: string, amount: number, currency: string, destination: string): Promise<string>;
|
|
46
|
-
/** Time's settlements, written: each entry on the acting account's balance whose funds came due by the World's clock
|
|
47
|
-
* moves pending → available (the clock's move the machine allows), so a settlement is recorded once. A read already
|
|
48
|
-
* sees it (asOf); the record is what lets Stripe's balance.available be sent once (stripe-server.ts, the drain).
|
|
49
|
-
* Funds that were available at once and not yet sent are taken too, and marked sent. Answers the entries taken. */
|
|
50
|
-
export declare function settleDueEntries(ctx: SemanticsContext): Promise<Row[]>;
|
|
51
|
-
/** An account's balance, by currency: what the clock has made available, what is still pending, and Issuing's own. */
|
|
52
|
-
export declare function balanceOf(ctx: SemanticsContext, account?: string | undefined): {
|
|
53
|
-
available: Map<string, number>;
|
|
54
|
-
pending: Map<string, number>;
|
|
55
|
-
issuing: Map<string, number>;
|
|
56
|
-
};
|
|
57
|
-
/** balance_insufficient when a payout or transfer would take more than the account has available in its currency. */
|
|
58
|
-
export declare function refusePayout(ctx: SemanticsContext, amount: number, currency: string, account?: string | undefined): Response | undefined;
|
|
59
|
-
export declare const ledger: Record<string, Semantics>;
|