@volter/twin-stripe 3.0.0 → 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 +51 -21
- package/dist/generated/pack-facts.json +3 -3
- 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 +5 -1
- package/dist/spec/doc-examples.json +445 -0
- package/dist/spec/sources.json +135 -207
- package/dist/src/cli.d.ts +0 -1
- package/dist/src/cli.js +0 -2
- package/dist/src/engine/after-payment.d.ts +0 -1
- package/dist/src/engine/after-payment.js +0 -1
- package/dist/src/engine/common.d.ts +5 -5
- package/dist/src/engine/common.js +13 -11
- package/dist/src/engine/connect.d.ts +0 -21
- package/dist/src/engine/connect.js +1 -82
- package/dist/src/engine/customers.d.ts +0 -8
- package/dist/src/engine/customers.js +0 -22
- package/dist/src/engine/display.d.ts +0 -3
- package/dist/src/engine/display.js +0 -3
- package/dist/src/engine/files.d.ts +0 -7
- package/dist/src/engine/files.js +0 -10
- package/dist/src/engine/invoices.d.ts +6 -9
- package/dist/src/engine/invoices.js +56 -29
- package/dist/src/engine/issuing.d.ts +6 -8
- package/dist/src/engine/issuing.js +19 -10
- package/dist/src/engine/ledger.d.ts +0 -1
- package/dist/src/engine/ledger.js +0 -1
- package/dist/src/engine/oauth.js +1 -2
- package/dist/src/engine/refunds.js +2 -27
- package/dist/src/engine/stripe.d.ts +2 -7
- package/dist/src/engine/stripe.js +34 -83
- package/dist/src/engine/subscriptions.d.ts +0 -1
- package/dist/src/engine/subscriptions.js +0 -1
- package/dist/src/engine/version.d.ts +0 -2
- package/dist/src/engine/version.js +17 -6
- package/dist/src/fetch.js +2 -2
- package/dist/src/generated/surface.gen.json +1 -1
- package/dist/src/generated/ui.gen.json +1 -1
- package/dist/src/index.js +5 -3
- package/dist/src/manifest.js +348 -220
- package/dist/src/screens/billing-portal.js +5 -5
- package/dist/src/screens/{connect-oauth.d.ts → checkout-js.d.ts} +0 -1
- package/dist/src/screens/checkout-js.js +84 -0
- package/dist/src/screens/connect-onboarding.js +3 -3
- package/dist/src/screens/dashboard.d.ts +1 -1
- package/dist/src/screens/dashboard.js +52 -53
- package/dist/src/screens/stripe-js.js +53 -93
- package/dist/src/semantics/account.d.ts +2 -0
- package/dist/src/semantics/account.js +8 -0
- package/dist/src/semantics/accounts.js +3 -1
- package/dist/src/semantics/around.js +3 -6
- package/dist/src/semantics/billing_portal.d.ts +0 -1
- package/dist/src/semantics/billing_portal.js +1 -7
- package/dist/src/semantics/checkout.d.ts +1 -1
- package/dist/src/semantics/checkout.js +18 -15
- package/dist/src/semantics/clock.js +1 -7
- package/dist/src/semantics/customers.d.ts +1 -2
- package/dist/src/semantics/customers.js +32 -38
- package/dist/src/semantics/entitlements.d.ts +0 -2
- package/dist/src/semantics/entitlements.js +4 -50
- package/dist/src/semantics/events.d.ts +2 -3
- package/dist/src/semantics/events.js +6 -11
- package/dist/src/semantics/index.js +16 -38
- package/dist/src/semantics/invoices.d.ts +3 -8
- package/dist/src/semantics/invoices.js +134 -127
- package/dist/src/semantics/issuing.d.ts +6 -0
- package/dist/src/semantics/issuing.js +77 -0
- package/dist/src/semantics/payment_intents.d.ts +0 -1
- package/dist/src/semantics/payment_intents.js +5 -13
- package/dist/src/semantics/payment_methods.d.ts +0 -2
- package/dist/src/semantics/payment_methods.js +2 -26
- package/dist/src/semantics/payouts.d.ts +1 -0
- package/dist/src/semantics/payouts.js +8 -1
- package/dist/src/semantics/products.d.ts +1 -3
- package/dist/src/semantics/products.js +3 -14
- package/dist/src/semantics/refunds.d.ts +1 -2
- package/dist/src/semantics/refunds.js +1 -5
- package/dist/src/semantics/shared.d.ts +64 -336
- package/dist/src/semantics/shared.js +326 -1336
- package/dist/src/semantics/states.d.ts +20 -89
- package/dist/src/semantics/states.js +116 -334
- package/dist/src/semantics/subscriptions.d.ts +1 -2
- package/dist/src/semantics/subscriptions.js +23 -145
- package/dist/src/semantics/test_helpers.d.ts +2 -5
- package/dist/src/semantics/test_helpers.js +121 -43
- package/dist/src/semantics/webhook_endpoints.d.ts +2 -0
- package/dist/src/semantics/webhook_endpoints.js +26 -0
- package/generated/pack-facts.json +3 -3
- 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 +4 -3
- package/spec/SOURCE.md +5 -1
- package/spec/doc-examples.json +445 -0
- package/spec/sources.json +135 -207
- package/src/cli.ts +0 -3
- package/src/engine/after-payment.ts +0 -2
- package/src/engine/balance.ts +0 -1
- package/src/engine/checkout.ts +0 -1
- package/src/engine/common.ts +19 -17
- package/src/engine/connect.ts +1 -79
- package/src/engine/customers.ts +0 -25
- package/src/engine/display.ts +2 -3
- package/src/engine/files.ts +0 -13
- package/src/engine/invoices.ts +64 -33
- package/src/engine/issuing.ts +16 -11
- package/src/engine/ledger.ts +0 -2
- package/src/engine/oauth.ts +1 -2
- package/src/engine/onboarding.ts +0 -1
- package/src/engine/params.ts +0 -1
- package/src/engine/payment-intents.ts +0 -1
- package/src/engine/payment-methods.ts +0 -1
- package/src/engine/refunds.ts +2 -28
- package/src/engine/renewals.ts +0 -1
- package/src/engine/stripe.ts +35 -83
- package/src/engine/subscriptions.ts +0 -3
- package/src/engine/transfers.ts +0 -1
- package/src/engine/version.ts +15 -7
- package/src/engine/webhooks.ts +0 -2
- package/src/fetch.ts +2 -2
- package/src/generated/surface.gen.json +1 -1
- package/src/generated/ui.gen.json +1 -1
- package/src/index.ts +6 -4
- package/src/manifest.ts +348 -220
- package/src/screens/billing-portal.tsx +5 -7
- package/src/screens/checkout-js.ts +80 -0
- package/src/screens/checkout.tsx +0 -2
- package/src/screens/connect-onboarding.tsx +3 -5
- package/src/screens/dashboard.tsx +53 -73
- package/src/screens/stripe-js.ts +57 -125
- package/src/semantics/account.ts +10 -0
- package/src/semantics/account_links.ts +0 -1
- package/src/semantics/accounts.ts +8 -7
- package/src/semantics/apps.ts +1 -2
- package/src/semantics/around.ts +3 -6
- package/src/semantics/balance.ts +0 -1
- package/src/semantics/balance_transactions.ts +1 -3
- package/src/semantics/billing_portal.ts +1 -7
- package/src/semantics/charges.ts +1 -6
- package/src/semantics/checkout.ts +16 -12
- package/src/semantics/clock.ts +1 -8
- package/src/semantics/coupons.ts +0 -1
- package/src/semantics/customers.ts +32 -35
- package/src/semantics/doors.ts +2 -3
- package/src/semantics/entitlements.ts +1 -45
- package/src/semantics/events.ts +7 -14
- package/src/semantics/index.ts +16 -38
- package/src/semantics/invoice_payments.ts +1 -3
- package/src/semantics/invoices.ts +124 -119
- package/src/semantics/issuing.ts +74 -0
- package/src/semantics/payment_intents.ts +10 -17
- package/src/semantics/payment_methods.ts +2 -25
- package/src/semantics/payouts.ts +9 -3
- package/src/semantics/prices.ts +0 -1
- package/src/semantics/products.ts +4 -14
- package/src/semantics/promotion_codes.ts +0 -1
- package/src/semantics/radar.ts +1 -3
- package/src/semantics/refunds.ts +2 -11
- package/src/semantics/shared.ts +350 -1382
- package/src/semantics/states.ts +109 -330
- package/src/semantics/subscriptions.ts +25 -145
- package/src/semantics/test_helpers.ts +109 -43
- package/src/semantics/transfers.ts +1 -3
- package/src/semantics/webhook_endpoints.ts +27 -0
- package/src/server.ts +0 -1
- package/dist/src/engine/billing.d.ts +0 -5
- package/dist/src/engine/billing.js +0 -6
- package/dist/src/engine/charges.d.ts +0 -6
- package/dist/src/engine/charges.js +0 -13
- package/dist/src/engine/connect-settings.d.ts +0 -16
- package/dist/src/engine/connect-settings.js +0 -26
- package/dist/src/engine/coupons.d.ts +0 -0
- package/dist/src/engine/coupons.js +0 -5
- package/dist/src/engine/credit-notes.d.ts +0 -1
- package/dist/src/engine/credit-notes.js +0 -5
- package/dist/src/engine/disputes.d.ts +0 -0
- package/dist/src/engine/disputes.js +0 -9
- package/dist/src/engine/entitlements.d.ts +0 -1
- package/dist/src/engine/entitlements.js +0 -4
- package/dist/src/engine/ephemeral-keys.d.ts +0 -0
- package/dist/src/engine/ephemeral-keys.js +0 -4
- package/dist/src/engine/front.d.ts +0 -5
- package/dist/src/engine/front.js +0 -25
- package/dist/src/engine/payment-links.d.ts +0 -1
- package/dist/src/engine/payment-links.js +0 -5
- package/dist/src/engine/plans.d.ts +0 -6
- package/dist/src/engine/plans.js +0 -26
- package/dist/src/engine/platform.d.ts +0 -39
- package/dist/src/engine/platform.js +0 -34
- package/dist/src/engine/products.d.ts +0 -0
- package/dist/src/engine/products.js +0 -4
- package/dist/src/engine/setup-intents.d.ts +0 -1
- package/dist/src/engine/setup-intents.js +0 -4
- package/dist/src/engine/subscription-schedules.d.ts +0 -3
- package/dist/src/engine/subscription-schedules.js +0 -1
- package/dist/src/engine/tax.d.ts +0 -7
- package/dist/src/engine/tax.js +0 -28
- package/dist/src/engine/terminal.d.ts +0 -4
- package/dist/src/engine/terminal.js +0 -20
- package/dist/src/engine/test-clocks.d.ts +0 -5
- package/dist/src/engine/test-clocks.js +0 -9
- package/dist/src/engine/tokens.d.ts +0 -7
- package/dist/src/engine/tokens.js +0 -20
- package/dist/src/engine/treasury.d.ts +0 -23
- package/dist/src/engine/treasury.js +0 -45
- package/dist/src/screens/connect-oauth.js +0 -333
- package/dist/src/semantics/disputes.d.ts +0 -2
- package/dist/src/semantics/disputes.js +0 -5
- package/dist/src/semantics/invoiceitems.d.ts +0 -3
- package/dist/src/semantics/invoiceitems.js +0 -59
- package/dist/src/semantics/setup_intents.d.ts +0 -3
- package/dist/src/semantics/setup_intents.js +0 -41
- package/dist/src/semantics/subscription_items.d.ts +0 -5
- package/dist/src/semantics/subscription_items.js +0 -55
- package/dist/src/semantics/subscription_schedules.d.ts +0 -4
- package/dist/src/semantics/subscription_schedules.js +0 -60
- package/src/engine/billing.ts +0 -16
- package/src/engine/charges.ts +0 -19
- package/src/engine/connect-settings.ts +0 -23
- package/src/engine/coupons.ts +0 -5
- package/src/engine/credit-notes.ts +0 -6
- package/src/engine/disputes.ts +0 -9
- package/src/engine/entitlements.ts +0 -5
- package/src/engine/ephemeral-keys.ts +0 -3
- package/src/engine/front.ts +0 -31
- package/src/engine/payment-links.ts +0 -6
- package/src/engine/plans.ts +0 -42
- package/src/engine/platform.ts +0 -47
- package/src/engine/products.ts +0 -3
- package/src/engine/setup-intents.ts +0 -5
- package/src/engine/subscription-schedules.ts +0 -10
- package/src/engine/tax.ts +0 -39
- package/src/engine/terminal.ts +0 -23
- package/src/engine/test-clocks.ts +0 -11
- package/src/engine/tokens.ts +0 -22
- package/src/engine/treasury.ts +0 -47
- package/src/screens/connect-oauth.tsx +0 -376
- package/src/semantics/disputes.ts +0 -12
- package/src/semantics/invoiceitems.ts +0 -59
- package/src/semantics/setup_intents.ts +0 -45
- package/src/semantics/subscription_items.ts +0 -54
- package/src/semantics/subscription_schedules.ts +0 -66
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { CS, sessionMethodTypes } from "../engine/checkout.js";
|
|
2
|
-
import { applyCouponDiscount, lineItemEntries, nowUnix, resolveLineItem } from "../engine/stripe.js";
|
|
3
|
-
import { actingAccount, at, checkoutNoDestination, created, discountOf, fail, finder, noLineItems, sessionMissing, sessionTrialRefused } from "./shared.js";
|
|
2
|
+
import { applyCouponDiscount, lineItemEntries, nowUnix, paginate, resolveLineItem } from "../engine/stripe.js";
|
|
3
|
+
import { actingAccount, at, checkoutNoDestination, created, discountOf, fail, finder, noLineItems, path, sessionMissing, sessionTrialRefused } from "./shared.js";
|
|
4
|
+
export async function GetCheckoutSessionsSessionLineItems(ctx) {
|
|
5
|
+
const s = ctx.get(CS, at(ctx, 'session'));
|
|
6
|
+
if (!s)
|
|
7
|
+
return sessionMissing(ctx, at(ctx, 'session'));
|
|
8
|
+
// source: spec:GetCheckoutSessionsSessionLineItems "There is also a URL where you can retrieve the full (paginated) list of line items."
|
|
9
|
+
const li = s.line_items;
|
|
10
|
+
const { page, hasMore } = paginate(Array.isArray(li?.data) ? li.data : [], ctx.params);
|
|
11
|
+
return ctx.reply({ object: 'list', url: path(ctx), has_more: hasMore, data: page });
|
|
12
|
+
}
|
|
4
13
|
export async function PostCheckoutSessions(ctx) {
|
|
5
14
|
const params = ctx.params;
|
|
6
15
|
const mode = typeof params.mode === 'string' ? params.mode : 'payment';
|
|
@@ -9,8 +18,9 @@ export async function PostCheckoutSessions(ctx) {
|
|
|
9
18
|
const entries = lineItemEntries(params);
|
|
10
19
|
if (mode !== 'setup' && entries.length === 0)
|
|
11
20
|
return noLineItems(ctx);
|
|
12
|
-
//
|
|
13
|
-
|
|
21
|
+
// source: spec:/paths/~1v1~1checkout~1sessions/post/requestBody/content/application~1x-www-form-urlencoded/schema/properties/ui_mode "The UI mode of the Session."
|
|
22
|
+
const custom = params.ui_mode === 'custom';
|
|
23
|
+
if (!custom && (params.success_url === undefined || params.success_url === ''))
|
|
14
24
|
return fail(ctx, 'Missing required param: success_url.', 400, 'parameter_missing');
|
|
15
25
|
const sessionCurrency = typeof params.currency === 'string' ? params.currency : 'usd';
|
|
16
26
|
const resolved = entries.map((e, i) => resolveLineItem(e, i, sessionCurrency, finder(ctx)));
|
|
@@ -32,7 +42,10 @@ export async function PostCheckoutSessions(ctx) {
|
|
|
32
42
|
const fields = {
|
|
33
43
|
mode, status: 'open',
|
|
34
44
|
payment_status: mode === 'setup' ? 'no_payment_required' : 'unpaid',
|
|
35
|
-
|
|
45
|
+
ui_mode: custom ? 'custom' : 'hosted',
|
|
46
|
+
...(custom ? { client_secret: `${id}_secret_${await ctx.secret(`checkout-secret:${id}`)}`, return_url: params.return_url ?? null } : {}),
|
|
47
|
+
allow_promotion_codes: params.allow_promotion_codes === true || params.allow_promotion_codes === 'true',
|
|
48
|
+
url: custom ? null : `https://checkout.stripe.com/c/pay/${id}`, success_url: params.success_url ?? null, cancel_url: params.cancel_url ?? null,
|
|
36
49
|
customer: params.customer ?? null, client_reference_id: params.client_reference_id ?? null,
|
|
37
50
|
customer_email: params.customer_email ?? null,
|
|
38
51
|
// whether paying makes a customer: in payment mode only when asked (`always`), `if_required` by default
|
|
@@ -74,13 +87,3 @@ export async function PostCheckoutSessions(ctx) {
|
|
|
74
87
|
fields._discount = { coupon: String(discount.coupon.id), promotion_code: discount.promotion ?? null };
|
|
75
88
|
return ctx.reply(await created(ctx, CS, { id, ...fields }, {}));
|
|
76
89
|
}
|
|
77
|
-
export async function PostCheckoutSessionsSessionExpire(ctx) {
|
|
78
|
-
const id = at(ctx, 'session');
|
|
79
|
-
const s = ctx.get(CS, id);
|
|
80
|
-
if (!s)
|
|
81
|
-
return sessionMissing(ctx, id);
|
|
82
|
-
const refused = ctx.legal(CS, 'status', 'PostCheckoutSessionsSessionExpire', s.status, undefined, id);
|
|
83
|
-
if (refused)
|
|
84
|
-
return ctx.refuse(refused);
|
|
85
|
-
return ctx.reply(await ctx.write(CS, id, { status: 'expired', url: null }, 'checkout.session.expire'));
|
|
86
|
-
}
|
|
@@ -1,17 +1,11 @@
|
|
|
1
|
-
import { advanceBilling, advancePayouts,
|
|
1
|
+
import { advanceBilling, advancePayouts, lapseCoupons, lapseRealtimeRequests, settleBankDebits, settleHeldRefunds } from "./shared.js";
|
|
2
2
|
export async function clock(ctx) {
|
|
3
|
-
// a test clock advanced by the last request has reached its time
|
|
4
|
-
await finishClockAdvances(ctx);
|
|
5
3
|
// a subscription renews at its period's end, its renewal charged an hour later
|
|
6
4
|
await advanceBilling(ctx);
|
|
7
5
|
// a submitted bank debit settles (in test mode at once)
|
|
8
6
|
await settleBankDebits(ctx);
|
|
9
7
|
// a coupon past its redeem_by is no longer valid
|
|
10
8
|
await lapseCoupons(ctx);
|
|
11
|
-
// a top-up's funds arrive five days after it is made
|
|
12
|
-
await settleTopups(ctx);
|
|
13
|
-
// a report run completes
|
|
14
|
-
await finishReportRuns(ctx);
|
|
15
9
|
// a real-time authorization request no one answered is decided when its window ends
|
|
16
10
|
await lapseRealtimeRequests(ctx);
|
|
17
11
|
// a refund held for want of balance is made when funds cover it, before any payout takes them
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { HandlerContext } from '@volter/world-core';
|
|
2
2
|
export declare function GetCustomersCustomer(ctx: HandlerContext): Promise<Response>;
|
|
3
|
-
export declare function GetCustomersCustomerPaymentMethods(ctx: HandlerContext): Promise<Response>;
|
|
4
3
|
export declare function GetCustomersSearch(ctx: HandlerContext): Promise<Response>;
|
|
5
4
|
export declare function PostCustomers(ctx: HandlerContext): Promise<Response>;
|
|
6
|
-
export declare function
|
|
5
|
+
export declare function PostCustomersCustomer(ctx: HandlerContext): Promise<Response>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { newCustomer } from "../engine/customers.js";
|
|
2
|
-
import {
|
|
2
|
+
import { nowUnix } from "../engine/stripe.js";
|
|
3
|
+
import { at, attachable, attachPaymentMethod, created, customerMissing, expanded, fail, search } from "./shared.js";
|
|
3
4
|
// "If it’s for a deleted Customer, a subset of the customer’s information is returned, including a `deleted` property
|
|
4
5
|
// that’s set to true" (docs.stripe.com/api/customers/retrieve)
|
|
5
6
|
export async function GetCustomersCustomer(ctx) {
|
|
@@ -11,23 +12,10 @@ export async function GetCustomersCustomer(ctx) {
|
|
|
11
12
|
return ctx.reply({ id, object: 'customer', deleted: true });
|
|
12
13
|
return ctx.reply(expanded(ctx, 'customer', ctx.get('customer', id)));
|
|
13
14
|
}
|
|
14
|
-
// the payment methods attached to a customer (customers.listPaymentMethods), optionally by `type`
|
|
15
|
-
export async function GetCustomersCustomerPaymentMethods(ctx) {
|
|
16
|
-
const customer = at(ctx, 'customer');
|
|
17
|
-
if (!ctx.get('customer', customer))
|
|
18
|
-
return customerMissing(ctx, customer);
|
|
19
|
-
const items = where(ctx, newest(ctx, 'payment_method').filter((m) => m.customer === customer), { type: (m, v) => m.type === v });
|
|
20
|
-
return list(ctx, 'payment_method', items);
|
|
21
|
-
}
|
|
22
15
|
export async function GetCustomersSearch(ctx) {
|
|
23
16
|
return search(ctx, 'customer');
|
|
24
17
|
}
|
|
25
18
|
export async function PostCustomers(ctx) {
|
|
26
|
-
// a `coupon` on create materializes the discount object on the customer (the coupon must exist)
|
|
27
|
-
const couponId = typeof ctx.params.coupon === 'string' ? ctx.params.coupon : '';
|
|
28
|
-
const discount = couponId ? customerDiscount(ctx, couponId) : null;
|
|
29
|
-
if (discount instanceof Response)
|
|
30
|
-
return discount;
|
|
31
19
|
// `payment_method` attaches that method to the new customer; it is not a field of the customer
|
|
32
20
|
// (docs.stripe.com/api/customers/create#create_customer-payment_method)
|
|
33
21
|
const pmId = typeof ctx.params.payment_method === 'string' ? ctx.params.payment_method : '';
|
|
@@ -36,34 +24,40 @@ export async function PostCustomers(ctx) {
|
|
|
36
24
|
const given = ctx.params;
|
|
37
25
|
const { coupon: _c, payment_method: _pm, ...rest } = given;
|
|
38
26
|
const id = ctx.mint('customer');
|
|
39
|
-
const customer = await created(ctx, 'customer', { ...rest, id }, { livemode: false, discount:
|
|
40
|
-
|
|
41
|
-
|
|
27
|
+
const customer = await created(ctx, 'customer', { ...rest, id }, { livemode: false, discount: null, ...newCustomer(id) });
|
|
28
|
+
// source: https://docs.stripe.com/billing/customer/balance "Represents the starting value of the customer invoice balance when a customer is created using the API with a non-zero invoice balance."
|
|
29
|
+
if (Number(customer.balance ?? 0) !== 0) {
|
|
30
|
+
await created(ctx, 'customer_balance_transaction', {
|
|
31
|
+
customer: id, amount: Number(customer.balance), ending_balance: Number(customer.balance),
|
|
32
|
+
currency: customer.currency ?? 'usd', type: 'initial', description: null, metadata: {},
|
|
33
|
+
livemode: false, invoice: null, credit_note: null, checkout_session: null, customer_account: null,
|
|
34
|
+
}, {});
|
|
35
|
+
}
|
|
42
36
|
if (pmId)
|
|
43
37
|
await attachPaymentMethod(ctx, pmId, String(customer.id));
|
|
44
38
|
return ctx.reply(customer);
|
|
45
39
|
}
|
|
46
40
|
// ── the credit-balance ledger: a negative amount is a credit; `ending_balance` is the running sum,
|
|
47
41
|
// mirrored onto the customer's `balance` ──
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
return ctx.reply(
|
|
42
|
+
// source: spec:PostCustomersCustomer "Updates the specified customer by setting the values of the parameters passed."
|
|
43
|
+
export async function PostCustomersCustomer(ctx) {
|
|
44
|
+
const id = at(ctx, 'customer');
|
|
45
|
+
const customer = ctx.get('customer', id);
|
|
46
|
+
if (!customer)
|
|
47
|
+
return customerMissing(ctx, id);
|
|
48
|
+
const { customer: _pathCustomer, ...fields } = ctx.params;
|
|
49
|
+
// source: https://docs.stripe.com/billing/customer/balance "All modifications to the invoice balance are recorded as Transactions"
|
|
50
|
+
// source: https://docs.stripe.com/billing/customer/balance "All Transactions created with the API or in the Dashboard have a type value of adjustment"
|
|
51
|
+
if (typeof fields.balance === 'number' && fields.balance !== Number(customer.balance ?? 0)) {
|
|
52
|
+
const balance = fields.balance;
|
|
53
|
+
await created(ctx, 'customer_balance_transaction', {
|
|
54
|
+
customer: id, amount: balance - Number(customer.balance ?? 0), ending_balance: balance,
|
|
55
|
+
// Stripe inherits the customer's billing currency. Where no invoice has set it, this World's invoice currency is USD.
|
|
56
|
+
currency: customer.currency ?? 'usd', type: 'adjustment',
|
|
57
|
+
description: null, metadata: {}, livemode: false,
|
|
58
|
+
invoice: null, credit_note: null, checkout_session: null, customer_account: null,
|
|
59
|
+
created: nowUnix(ctx.occurredAt),
|
|
60
|
+
}, {});
|
|
61
|
+
}
|
|
62
|
+
return ctx.reply(ctx.expand('customer', await ctx.write('customer', id, fields, 'customer.update')));
|
|
69
63
|
}
|
|
@@ -1,50 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
//
|
|
5
|
-
// the subscription's current period began: "When a customer purchases or subscribes to a product with an attached
|
|
6
|
-
// feature, Stripe creates and manages an Active Entitlement for that customer and feature"; "Existing subscriptions will
|
|
7
|
-
// create active entitlements for any product feature changes at the start of the next billing period"
|
|
8
|
-
// (docs.stripe.com/billing/entitlements). Where the documentation stops and the twin decides: a feature removed from a
|
|
9
|
-
// product is kept, the same way, until the next period begins.
|
|
10
|
-
export async function GetEntitlementsActiveEntitlements(ctx) {
|
|
11
|
-
const customer = typeof ctx.params.customer === 'string' ? ctx.params.customer : '';
|
|
12
|
-
if (!customer)
|
|
13
|
-
return fail(ctx, 'Missing required param: customer.', 400, 'parameter_missing');
|
|
14
|
-
if (!ctx.row('customer', customer, { withDeleted: true }))
|
|
15
|
-
return fail(ctx, `No such customer: '${customer}'`, 404, 'resource_missing');
|
|
16
|
-
// each product a live subscription bills, with the start of the period it is billed for
|
|
17
|
-
const productIds = new Map();
|
|
18
|
-
for (const sub of newest(ctx, 'subscription')) {
|
|
19
|
-
// a subscription entitles while it runs: not before its first payment (incomplete), nor once it has ended
|
|
20
|
-
// (docs.stripe.com/billing/entitlements; past_due keeps access during retries — that edge is the twin's reading)
|
|
21
|
-
if (sub.customer !== customer || !['active', 'trialing', 'past_due'].includes(String(sub.status)))
|
|
22
|
-
continue;
|
|
23
|
-
const periodStart = Number(sub.current_period_start ?? sub.start_date ?? sub.created ?? 0);
|
|
24
|
-
for (const it of subscriptionItemPairs(sub)) {
|
|
25
|
-
const price = ctx.get('price', it.price);
|
|
26
|
-
if (price && typeof price.product === 'string')
|
|
27
|
-
productIds.set(price.product, Math.max(productIds.get(price.product) ?? -Infinity, periodStart));
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
const seen = new Set();
|
|
31
|
-
const data = [];
|
|
32
|
-
for (const pf of ctx.rowsRaw('product_feature', { withDeleted: true })) {
|
|
33
|
-
const periodStart = productIds.get(String(pf._product));
|
|
34
|
-
if (periodStart === undefined)
|
|
35
|
-
continue;
|
|
36
|
-
// attached by the period's start, and not removed before it
|
|
37
|
-
if (Number(pf._created ?? 0) > periodStart)
|
|
38
|
-
continue;
|
|
39
|
-
if (pf.deleted && !(Number(pf._removed_at) > periodStart))
|
|
40
|
-
continue;
|
|
41
|
-
const featId = String(pf._feature ?? pf.entitlement_feature?.id ?? pf.entitlement_feature);
|
|
42
|
-
if (seen.has(featId))
|
|
43
|
-
continue;
|
|
44
|
-
seen.add(featId);
|
|
45
|
-
const feat = ctx.get(FEAT, featId);
|
|
46
|
-
if (feat)
|
|
47
|
-
data.push({ id: `ent_twin_${customer}_${featId}`, object: 'entitlements.active_entitlement', feature: featId, lookup_key: feat.lookup_key, livemode: false });
|
|
48
|
-
}
|
|
49
|
-
return ctx.reply({ object: 'list', url: path(ctx), has_more: false, data });
|
|
50
|
-
}
|
|
1
|
+
"use strict";
|
|
2
|
+
// Stripe's entitlements operations (docs/contributing/architecture.md, "What an author writes"): each handler over the
|
|
3
|
+
// handler contract's context, computing with the engine (../engine/).
|
|
4
|
+
// source: spec:PostEntitlementsFeatures "Creates a feature"
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { EventWrite, WriteHookContext } from '@volter/world-core';
|
|
2
|
-
/** An event's `data`: the object the write concerns, as Stripe sends it in the event's API version.
|
|
3
|
-
*
|
|
4
|
-
* the balance notice the drain writes carries the account's Balance. */
|
|
2
|
+
/** An event's `data`: the object the write concerns, as Stripe sends it in the event's API version. An Issuing
|
|
3
|
+
* authorization carries its full card; the balance notice the drain writes carries the account's Balance. */
|
|
5
4
|
export declare function data(ctx: WriteHookContext, write: EventWrite): Record<string, unknown>;
|
|
6
5
|
/** An event's further envelope values: the connected account it is about ("Each event for a connected account contains
|
|
7
6
|
* a top-level `account` property that identifies the connected account", docs.stripe.com/connect/webhooks) — the
|
|
@@ -1,16 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { embedIssuingAuthorizationCard, isValidApiVersion, PLATFORM_ACCOUNT_ID, TWIN_API_VERSION } from "../engine/stripe.js";
|
|
1
|
+
import { isValidApiVersion, PLATFORM_ACCOUNT_ID, TWIN_API_VERSION } from "../engine/stripe.js";
|
|
3
2
|
import { render } from "../engine/version.js";
|
|
4
|
-
import { connectionRevoked, finder } from "./shared.js";
|
|
5
3
|
// ── the events Stripe's writes send (the manifest's `events`: ./shared.ts STRIPE_EVENTS) ──
|
|
6
|
-
/** An event's `data`: the object the write concerns, as Stripe sends it in the event's API version.
|
|
7
|
-
*
|
|
8
|
-
* the balance notice the drain writes carries the account's Balance. */
|
|
4
|
+
/** An event's `data`: the object the write concerns, as Stripe sends it in the event's API version. An Issuing
|
|
5
|
+
* authorization carries its full card; the balance notice the drain writes carries the account's Balance. */
|
|
9
6
|
export function data(ctx, write) {
|
|
10
7
|
const object = write.storedType === '_balance_notice' ? write.body.balance
|
|
11
|
-
: write.storedType === '
|
|
12
|
-
: write.storedType === '
|
|
13
|
-
: write.body;
|
|
8
|
+
: write.storedType === 'issuing_authorization' ? ctx.expand('issuing.authorization', write.body)
|
|
9
|
+
: write.storedType === 'issuing_card' ? ctx.expand('issuing.card', write.body) : ctx.expand(String(write.body.object ?? write.storedType), write.body);
|
|
14
10
|
return { object: render(object, eventVersion(write)) };
|
|
15
11
|
}
|
|
16
12
|
/** An event's further envelope values: the connected account it is about ("Each event for a connected account contains
|
|
@@ -26,8 +22,7 @@ export function values(ctx, write, type) {
|
|
|
26
22
|
?? (write.storedType === 'account' && typeof id === 'string' && id !== PLATFORM_ACCOUNT_ID ? id : undefined)
|
|
27
23
|
?? (write.storedType === '_balance_notice' && typeof write.body.account === 'string' ? write.body.account : undefined)
|
|
28
24
|
?? (typeof kept === 'string' ? kept : undefined);
|
|
29
|
-
|
|
30
|
-
return { $account: account, $version: eventVersion(write), ...(withheld ? { $send: false } : {}) };
|
|
25
|
+
return { $account: account, $version: eventVersion(write) };
|
|
31
26
|
}
|
|
32
27
|
/** The API version an event is rendered in: the one the writing request pinned, when it is one, else the served one. */
|
|
33
28
|
const eventVersion = (write) => {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as account from "./account.js";
|
|
1
2
|
import * as account_links from "./account_links.js";
|
|
2
3
|
import * as accounts from "./accounts.js";
|
|
3
4
|
import * as apps from "./apps.js";
|
|
@@ -8,11 +9,9 @@ import * as charges from "./charges.js";
|
|
|
8
9
|
import * as checkout from "./checkout.js";
|
|
9
10
|
import * as coupons from "./coupons.js";
|
|
10
11
|
import * as customers from "./customers.js";
|
|
11
|
-
import * as disputes from "./disputes.js";
|
|
12
|
-
import * as entitlements from "./entitlements.js";
|
|
13
12
|
import * as invoice_payments from "./invoice_payments.js";
|
|
14
|
-
import * as invoiceitems from "./invoiceitems.js";
|
|
15
13
|
import * as invoices from "./invoices.js";
|
|
14
|
+
import * as issuing from "./issuing.js";
|
|
16
15
|
import * as payment_intents from "./payment_intents.js";
|
|
17
16
|
import * as payment_methods from "./payment_methods.js";
|
|
18
17
|
import * as payouts from "./payouts.js";
|
|
@@ -21,19 +20,14 @@ import * as products from "./products.js";
|
|
|
21
20
|
import * as promotion_codes from "./promotion_codes.js";
|
|
22
21
|
import * as radar from "./radar.js";
|
|
23
22
|
import * as refunds from "./refunds.js";
|
|
24
|
-
import * as setup_intents from "./setup_intents.js";
|
|
25
|
-
import * as subscription_items from "./subscription_items.js";
|
|
26
|
-
import * as subscription_schedules from "./subscription_schedules.js";
|
|
27
23
|
import * as subscriptions from "./subscriptions.js";
|
|
28
24
|
import * as test_helpers from "./test_helpers.js";
|
|
29
25
|
import * as transfers from "./transfers.js";
|
|
26
|
+
import * as webhook_endpoints from "./webhook_endpoints.js";
|
|
30
27
|
export const stripeSemantics = {
|
|
31
|
-
DeleteInvoiceitemsInvoiceitem: invoiceitems.DeleteInvoiceitemsInvoiceitem,
|
|
32
|
-
DeleteInvoicesInvoice: invoices.DeleteInvoicesInvoice,
|
|
33
|
-
DeleteProductsId: products.DeleteProductsId,
|
|
34
|
-
DeleteSubscriptionItemsItem: subscription_items.DeleteSubscriptionItemsItem,
|
|
35
28
|
DeleteSubscriptionsSubscriptionExposedId: subscriptions.DeleteSubscriptionsSubscriptionExposedId,
|
|
36
|
-
|
|
29
|
+
DeleteSubscriptionsSubscriptionExposedIdDiscount: subscriptions.DeleteSubscriptionsSubscriptionExposedIdDiscount,
|
|
30
|
+
GetAccount: account.GetAccount,
|
|
37
31
|
GetAccountsAccountExternalAccounts: accounts.GetAccountsAccountExternalAccounts,
|
|
38
32
|
GetAppsSecretsFind: apps.GetAppsSecretsFind,
|
|
39
33
|
GetBalance: balance.GetBalance,
|
|
@@ -41,25 +35,19 @@ export const stripeSemantics = {
|
|
|
41
35
|
GetBillingPortalConfigurations: billing_portal.GetBillingPortalConfigurations,
|
|
42
36
|
GetCharges: charges.GetCharges,
|
|
43
37
|
GetChargesCharge: charges.GetChargesCharge,
|
|
38
|
+
GetCheckoutSessionsSessionLineItems: checkout.GetCheckoutSessionsSessionLineItems,
|
|
44
39
|
GetCustomersCustomer: customers.GetCustomersCustomer,
|
|
45
|
-
GetCustomersCustomerPaymentMethods: customers.GetCustomersCustomerPaymentMethods,
|
|
46
40
|
GetCustomersSearch: customers.GetCustomersSearch,
|
|
47
|
-
GetDisputesDispute: disputes.GetDisputesDispute,
|
|
48
|
-
GetEntitlementsActiveEntitlements: entitlements.GetEntitlementsActiveEntitlements,
|
|
49
41
|
GetInvoicePayments: invoice_payments.GetInvoicePayments,
|
|
50
42
|
GetInvoicesInvoice: invoices.GetInvoicesInvoice,
|
|
51
|
-
|
|
43
|
+
GetIssuingCardsCard: issuing.GetIssuingCardsCard,
|
|
52
44
|
GetPaymentMethodsPaymentMethod: payment_methods.GetPaymentMethodsPaymentMethod,
|
|
45
|
+
GetPayouts: payouts.GetPayouts,
|
|
53
46
|
GetPrices: prices.GetPrices,
|
|
54
47
|
GetPricesPrice: prices.GetPricesPrice,
|
|
55
48
|
GetProducts: products.GetProducts,
|
|
56
|
-
GetProductsSearch: products.GetProductsSearch,
|
|
57
49
|
GetPromotionCodes: promotion_codes.GetPromotionCodes,
|
|
58
|
-
GetRefundsRefund: refunds.GetRefundsRefund,
|
|
59
|
-
GetSubscriptionItemsItem: subscription_items.GetSubscriptionItemsItem,
|
|
60
|
-
GetSubscriptionSchedulesSchedule: subscription_schedules.GetSubscriptionSchedulesSchedule,
|
|
61
50
|
GetSubscriptions: subscriptions.GetSubscriptions,
|
|
62
|
-
GetSubscriptionsSearch: subscriptions.GetSubscriptionsSearch,
|
|
63
51
|
GetSubscriptionsSubscriptionExposedId: subscriptions.GetSubscriptionsSubscriptionExposedId,
|
|
64
52
|
PostAccountLinks: account_links.PostAccountLinks,
|
|
65
53
|
PostAccounts: accounts.PostAccounts,
|
|
@@ -67,25 +55,21 @@ export const stripeSemantics = {
|
|
|
67
55
|
PostAppsSecrets: apps.PostAppsSecrets,
|
|
68
56
|
PostAppsSecretsDelete: apps.PostAppsSecretsDelete,
|
|
69
57
|
PostBillingPortalConfigurations: billing_portal.PostBillingPortalConfigurations,
|
|
70
|
-
PostBillingPortalConfigurationsConfiguration: billing_portal.PostBillingPortalConfigurationsConfiguration,
|
|
71
58
|
PostBillingPortalSessions: billing_portal.PostBillingPortalSessions,
|
|
72
59
|
PostCheckoutSessions: checkout.PostCheckoutSessions,
|
|
73
|
-
PostCheckoutSessionsSessionExpire: checkout.PostCheckoutSessionsSessionExpire,
|
|
74
60
|
PostCoupons: coupons.PostCoupons,
|
|
75
61
|
PostCustomers: customers.PostCustomers,
|
|
76
|
-
|
|
77
|
-
PostInvoiceitems: invoiceitems.PostInvoiceitems,
|
|
62
|
+
PostCustomersCustomer: customers.PostCustomersCustomer,
|
|
78
63
|
PostInvoices: invoices.PostInvoices,
|
|
79
64
|
PostInvoicesCreatePreview: invoices.PostInvoicesCreatePreview,
|
|
80
|
-
PostInvoicesInvoiceFinalize: invoices.PostInvoicesInvoiceFinalize,
|
|
81
65
|
PostInvoicesInvoicePay: invoices.PostInvoicesInvoicePay,
|
|
82
|
-
PostInvoicesInvoiceSend: invoices.PostInvoicesInvoiceSend,
|
|
83
66
|
PostInvoicesInvoiceVoid: invoices.PostInvoicesInvoiceVoid,
|
|
67
|
+
PostIssuingAuthorizationsAuthorizationApprove: issuing.PostIssuingAuthorizationsAuthorizationApprove,
|
|
68
|
+
PostIssuingAuthorizationsAuthorizationDecline: issuing.PostIssuingAuthorizationsAuthorizationDecline,
|
|
69
|
+
PostIssuingCards: issuing.PostIssuingCards,
|
|
70
|
+
PostIssuingCardsCard: issuing.PostIssuingCardsCard,
|
|
84
71
|
PostPaymentIntents: payment_intents.PostPaymentIntents,
|
|
85
72
|
PostPaymentIntentsIntentCancel: payment_intents.PostPaymentIntentsIntentCancel,
|
|
86
|
-
PostPaymentIntentsIntentConfirm: payment_intents.PostPaymentIntentsIntentConfirm,
|
|
87
|
-
PostPaymentMethods: payment_methods.PostPaymentMethods,
|
|
88
|
-
PostPaymentMethodsPaymentMethodAttach: payment_methods.PostPaymentMethodsPaymentMethodAttach,
|
|
89
73
|
PostPaymentMethodsPaymentMethodDetach: payment_methods.PostPaymentMethodsPaymentMethodDetach,
|
|
90
74
|
PostPayouts: payouts.PostPayouts,
|
|
91
75
|
PostPrices: prices.PostPrices,
|
|
@@ -93,15 +77,9 @@ export const stripeSemantics = {
|
|
|
93
77
|
PostPromotionCodes: promotion_codes.PostPromotionCodes,
|
|
94
78
|
PostRadarValueListItems: radar.PostRadarValueListItems,
|
|
95
79
|
PostRefunds: refunds.PostRefunds,
|
|
96
|
-
PostSetupIntents: setup_intents.PostSetupIntents,
|
|
97
|
-
PostSetupIntentsIntentConfirm: setup_intents.PostSetupIntentsIntentConfirm,
|
|
98
|
-
PostSubscriptionItems: subscription_items.PostSubscriptionItems,
|
|
99
|
-
PostSubscriptionItemsItem: subscription_items.PostSubscriptionItemsItem,
|
|
100
|
-
PostSubscriptionSchedules: subscription_schedules.PostSubscriptionSchedules,
|
|
101
|
-
PostSubscriptionSchedulesScheduleRelease: subscription_schedules.PostSubscriptionSchedulesScheduleRelease,
|
|
102
|
-
PostSubscriptions: subscriptions.PostSubscriptions,
|
|
103
80
|
PostSubscriptionsSubscriptionExposedId: subscriptions.PostSubscriptionsSubscriptionExposedId,
|
|
104
|
-
|
|
105
|
-
|
|
81
|
+
PostTestHelpersIssuingAuthorizations: test_helpers.PostTestHelpersIssuingAuthorizations,
|
|
82
|
+
PostTestHelpersIssuingAuthorizationsAuthorizationCapture: test_helpers.PostTestHelpersIssuingAuthorizationsAuthorizationCapture,
|
|
106
83
|
PostTransfers: transfers.PostTransfers,
|
|
84
|
+
PostWebhookEndpoints: webhook_endpoints.PostWebhookEndpoints,
|
|
107
85
|
};
|
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
import type { HandlerContext } from '@volter/world-core';
|
|
2
|
-
export declare function DeleteInvoicesInvoice(ctx: HandlerContext): Promise<Response>;
|
|
3
2
|
export declare function GetInvoicesInvoice(ctx: HandlerContext): Promise<Response>;
|
|
4
|
-
export declare function
|
|
3
|
+
export declare function PostInvoicesInvoicePay(ctx: HandlerContext): Promise<Response>;
|
|
4
|
+
export declare function PostInvoicesInvoiceVoid(ctx: HandlerContext): Promise<Response>;
|
|
5
5
|
export declare function PostInvoices(ctx: HandlerContext): Promise<Response>;
|
|
6
6
|
/**
|
|
7
7
|
* A preview of the next invoice for a customer or subscription (create_preview), computed and never
|
|
8
8
|
* stored: the subscription's items at their prices, the customer's pending items, the subscription's
|
|
9
|
-
* discount, and
|
|
10
|
-
* charge for the new one (split evenly: there is no clock here to measure the remaining fraction).
|
|
9
|
+
* discount, and an update's unused-time credit and remaining-time charge at the old and new prices.
|
|
11
10
|
*/
|
|
12
11
|
export declare function PostInvoicesCreatePreview(ctx: HandlerContext): Promise<Response>;
|
|
13
|
-
export declare function PostInvoicesInvoiceFinalize(ctx: HandlerContext): Promise<Response>;
|
|
14
|
-
export declare function PostInvoicesInvoicePay(ctx: HandlerContext): Promise<Response>;
|
|
15
|
-
export declare function PostInvoicesInvoiceSend(ctx: HandlerContext): Promise<Response>;
|
|
16
|
-
export declare function PostInvoicesInvoiceVoid(ctx: HandlerContext): Promise<Response>;
|