@comfyorg/account-core 1.0.0-alpha.2 → 1.0.0-alpha.3
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/dist/core/billing/index.d.ts +4 -3
- package/dist/core/billing/index.js +2 -1
- package/dist/core/billing/operationLifecycle.d.ts +26 -4
- package/dist/core/billing/operationLifecycle.js +113 -14
- package/dist/core/billing/operationPointer.d.ts +24 -0
- package/dist/core/billing/operationPointer.js +14 -1
- package/dist/core/billing/operationState.d.ts +18 -6
- package/dist/core/billing/operationState.js +13 -15
- package/dist/core/billing/paymentFriction.d.ts +17 -0
- package/dist/core/billing/paymentFriction.js +41 -0
- package/dist/core/billing/subscriptionCommands.d.ts +38 -2
- package/dist/core/billing/subscriptionCommands.js +27 -7
- package/dist/core/billing/subscriptionDiscount.d.ts +26 -0
- package/dist/core/billing/subscriptionDiscount.js +6 -0
- package/dist/core/billing/telemetry/billingTelemetryEvent.d.ts +25 -0
- package/dist/core/billing/telemetry/billingTelemetryEvent.js +3 -0
- package/dist/core/billing/telemetry/cancelEvent.d.ts +19 -0
- package/dist/core/billing/telemetry/cancelEvent.js +1 -0
- package/dist/core/billing/telemetry/capabilityReadEvent.d.ts +4 -0
- package/dist/core/billing/telemetry/capabilityReadEvent.js +1 -0
- package/dist/core/billing/telemetry/checkoutChallengeEvent.d.ts +25 -0
- package/dist/core/billing/telemetry/checkoutChallengeEvent.js +1 -0
- package/dist/core/billing/telemetry/checkoutJourney.d.ts +176 -0
- package/dist/core/billing/telemetry/checkoutJourney.js +115 -0
- package/dist/core/billing/telemetry/checkoutRedirectEvent.d.ts +30 -0
- package/dist/core/billing/telemetry/checkoutRedirectEvent.js +1 -0
- package/dist/core/billing/telemetry/downgradeToPersonalEvent.d.ts +14 -0
- package/dist/core/billing/telemetry/downgradeToPersonalEvent.js +1 -0
- package/dist/core/billing/telemetry/entryEvent.d.ts +16 -0
- package/dist/core/billing/telemetry/entryEvent.js +1 -0
- package/dist/core/billing/telemetry/eventNames.d.ts +36 -0
- package/dist/core/billing/telemetry/eventNames.js +36 -0
- package/dist/core/billing/telemetry/index.d.ts +17 -0
- package/dist/core/billing/telemetry/index.js +6 -0
- package/dist/core/billing/telemetry/operationEvent.d.ts +25 -0
- package/dist/core/billing/telemetry/operationEvent.js +1 -0
- package/dist/core/billing/telemetry/operationLifecycleEvent.d.ts +9 -0
- package/dist/core/billing/telemetry/operationLifecycleEvent.js +79 -0
- package/dist/core/billing/telemetry/payload.d.ts +55 -0
- package/dist/core/billing/telemetry/payload.js +75 -0
- package/dist/core/billing/telemetry/portalEvent.d.ts +23 -0
- package/dist/core/billing/telemetry/portalEvent.js +1 -0
- package/dist/core/billing/telemetry/resubscribeEvent.d.ts +13 -0
- package/dist/core/billing/telemetry/resubscribeEvent.js +1 -0
- package/dist/core/billing/telemetry/stages.d.ts +45 -0
- package/dist/core/billing/telemetry/stages.js +1 -0
- package/dist/core/billing/telemetry/subscriptionCheckoutEvent.d.ts +23 -0
- package/dist/core/billing/telemetry/subscriptionCheckoutEvent.js +1 -0
- package/dist/core/billing/telemetry/topupEvent.d.ts +30 -0
- package/dist/core/billing/telemetry/topupEvent.js +6 -0
- package/dist/core/billing/telemetry/vocabulary.d.ts +9 -0
- package/dist/core/billing/telemetry/vocabulary.js +1 -0
- package/dist/core/billing/telemetry/webEntryEvent.d.ts +27 -0
- package/dist/core/billing/telemetry/webEntryEvent.js +1 -0
- package/dist/core/billing/telemetry/webHandoffEvent.d.ts +11 -0
- package/dist/core/billing/telemetry/webHandoffEvent.js +1 -0
- package/dist/core/billing/telemetry/webReturnEvent.d.ts +8 -0
- package/dist/core/billing/telemetry/webReturnEvent.js +1 -0
- package/dist/core/billing/telemetry/webSessionEvent.d.ts +17 -0
- package/dist/core/billing/telemetry/webSessionEvent.js +1 -0
- package/dist/core/webSession.d.ts +4 -3
- package/dist/core/webSession.js +6 -5
- package/dist/core/webSessionIdentity.d.ts +6 -6
- package/dist/signInSchemas.d.ts +1 -1
- package/dist/telemetry.d.ts +26 -0
- package/dist/telemetry.js +28 -7
- package/dist/testing.d.ts +2 -1
- package/dist/testing.js +5 -4
- package/package.json +3 -1
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { BillingOperationKind, BillingPresentation, HostedBillingDestination } from '../operationState.js';
|
|
2
|
+
import type { CheckoutMethodKind } from './checkoutJourney.js';
|
|
3
|
+
/** What the hosted page asks of the customer, from what the server waits on. */
|
|
4
|
+
export type CheckoutHostedStep = 'authentication' | 'payment_method' | 'invoice_payment' | 'checkout';
|
|
5
|
+
/** The hosted page replaced this page, or opened beside it. */
|
|
6
|
+
export type CheckoutRedirectNavigation = 'redirect' | 'new_tab';
|
|
7
|
+
/**
|
|
8
|
+
* A hosted step this tab handed the customer to, and the customer back on the
|
|
9
|
+
* tab that handed it. Neither settles the operation; the pair joins on
|
|
10
|
+
* `billing_op_id`, and a start with no return is a customer who did not come
|
|
11
|
+
* back.
|
|
12
|
+
*/
|
|
13
|
+
export type CheckoutRedirectBillingEvent = {
|
|
14
|
+
operation: 'checkout';
|
|
15
|
+
outcome: 'pending';
|
|
16
|
+
billing_op_id: string;
|
|
17
|
+
operation_type: BillingOperationKind;
|
|
18
|
+
presentation: BillingPresentation;
|
|
19
|
+
/** True when this tab reattached to an operation it did not issue. */
|
|
20
|
+
resumed?: boolean;
|
|
21
|
+
destination: HostedBillingDestination;
|
|
22
|
+
step: CheckoutHostedStep;
|
|
23
|
+
navigation: CheckoutRedirectNavigation;
|
|
24
|
+
/** The method the customer chose, when the host knows it. */
|
|
25
|
+
method_kind?: CheckoutMethodKind;
|
|
26
|
+
} & ({
|
|
27
|
+
stage: 'redirect_started';
|
|
28
|
+
} | {
|
|
29
|
+
stage: 'returned';
|
|
30
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { BillingFailed, BillingStarted, BillingSucceeded } from './stages.js';
|
|
2
|
+
import type { BillingTierKey, PaymentIntentSource } from './vocabulary.js';
|
|
3
|
+
export type DowngradeToPersonalBillingEvent = {
|
|
4
|
+
operation: 'downgrade_to_personal';
|
|
5
|
+
member_removal_count: number;
|
|
6
|
+
member_removal_failures: number;
|
|
7
|
+
target_tier?: BillingTierKey;
|
|
8
|
+
payment_intent_source?: PaymentIntentSource;
|
|
9
|
+
/**
|
|
10
|
+
* Client-observed end-to-end wall time from this attempt's canonical
|
|
11
|
+
* `started` event through to this terminal event.
|
|
12
|
+
*/
|
|
13
|
+
duration_ms?: number;
|
|
14
|
+
} & (BillingStarted | BillingSucceeded | BillingFailed);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { PaymentIntentSource, SubscriptionCheckoutTier } from './vocabulary.js';
|
|
2
|
+
/**
|
|
3
|
+
* A cloud entry point that leads to billing. A client journey observation: it
|
|
4
|
+
* has no backend operation counterpart and never claims an operation outcome.
|
|
5
|
+
*/
|
|
6
|
+
export type EntryBillingEvent = {
|
|
7
|
+
operation: 'entry';
|
|
8
|
+
outcome: 'pending';
|
|
9
|
+
payment_intent_source?: PaymentIntentSource;
|
|
10
|
+
} & ({
|
|
11
|
+
stage: 'paywall_shown';
|
|
12
|
+
/** The plan the customer is on when the paywall opens; absent when unknown. */
|
|
13
|
+
current_tier?: SubscriptionCheckoutTier;
|
|
14
|
+
} | {
|
|
15
|
+
stage: 'add_credits_clicked';
|
|
16
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export declare const BILLING_TELEMETRY_EVENTS: {
|
|
2
|
+
readonly BILLING_SUBSCRIPTION_CHECKOUT_RECEIVED: "billing.subscription_checkout.checkout_received";
|
|
3
|
+
readonly BILLING_TOPUP_CHECKOUT_RECEIVED: "billing.topup.checkout_received";
|
|
4
|
+
readonly BILLING_SUBSCRIPTION_CHECKOUT_REQUEST_SENT: "billing.subscription_checkout.request_sent";
|
|
5
|
+
readonly BILLING_TOPUP_REQUEST_SENT: "billing.topup.request_sent";
|
|
6
|
+
readonly BILLING_SUBSCRIPTION_CHECKOUT_INTENT: "billing.subscription_checkout.intent";
|
|
7
|
+
readonly BILLING_TOPUP_INTENT: "billing.topup.intent";
|
|
8
|
+
readonly BILLING_SUBSCRIPTION_CHECKOUT_STARTED: "billing.subscription_checkout.started";
|
|
9
|
+
readonly BILLING_SUBSCRIPTION_CHECKOUT_SUCCEEDED: "billing.subscription_checkout.succeeded";
|
|
10
|
+
readonly BILLING_SUBSCRIPTION_CHECKOUT_FAILED: "billing.subscription_checkout.failed";
|
|
11
|
+
readonly BILLING_SUBSCRIPTION_CHECKOUT_TIMEOUT: "billing.subscription_checkout.timeout";
|
|
12
|
+
readonly BILLING_OPERATION_STARTED: "billing.operation.started";
|
|
13
|
+
readonly BILLING_CAPABILITY_READ_SUCCEEDED: "billing.capability_read.succeeded";
|
|
14
|
+
readonly BILLING_CAPABILITY_READ_FAILED: "billing.capability_read.failed";
|
|
15
|
+
readonly BILLING_OPERATION_SUCCEEDED: "billing.operation.succeeded";
|
|
16
|
+
readonly BILLING_OPERATION_FAILED: "billing.operation.failed";
|
|
17
|
+
readonly BILLING_OPERATION_TIMEOUT: "billing.operation.timeout";
|
|
18
|
+
readonly BILLING_RESUBSCRIBE_STARTED: "billing.resubscribe.started";
|
|
19
|
+
readonly BILLING_RESUBSCRIBE_SUCCEEDED: "billing.resubscribe.succeeded";
|
|
20
|
+
readonly BILLING_RESUBSCRIBE_FAILED: "billing.resubscribe.failed";
|
|
21
|
+
readonly BILLING_TOPUP_STARTED: "billing.topup.started";
|
|
22
|
+
readonly BILLING_TOPUP_SUCCEEDED: "billing.topup.succeeded";
|
|
23
|
+
readonly BILLING_TOPUP_FAILED: "billing.topup.failed";
|
|
24
|
+
readonly BILLING_DOWNGRADE_TO_PERSONAL_STARTED: "billing.downgrade_to_personal.started";
|
|
25
|
+
readonly BILLING_DOWNGRADE_TO_PERSONAL_SUCCEEDED: "billing.downgrade_to_personal.succeeded";
|
|
26
|
+
readonly BILLING_DOWNGRADE_TO_PERSONAL_FAILED: "billing.downgrade_to_personal.failed";
|
|
27
|
+
readonly BILLING_WEB_HANDOFF_OPENED: "billing.web_handoff.opened";
|
|
28
|
+
readonly BILLING_ENTRY_PAYWALL_SHOWN: "billing.entry.paywall_shown";
|
|
29
|
+
readonly BILLING_ENTRY_ADD_CREDITS_CLICKED: "billing.entry.add_credits_clicked";
|
|
30
|
+
readonly BILLING_CANCEL_INTENT: "billing.cancel.intent";
|
|
31
|
+
readonly BILLING_CANCEL_ABANDONED: "billing.cancel.abandoned";
|
|
32
|
+
readonly BILLING_CANCEL_FAILED: "billing.cancel.failed";
|
|
33
|
+
readonly BILLING_PORTAL_OPENED: "billing.portal.opened";
|
|
34
|
+
readonly BILLING_PORTAL_FAILED: "billing.portal.failed";
|
|
35
|
+
readonly BILLING_PORTAL_RETURNED: "billing.portal.returned";
|
|
36
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export const BILLING_TELEMETRY_EVENTS = {
|
|
2
|
+
BILLING_SUBSCRIPTION_CHECKOUT_RECEIVED: 'billing.subscription_checkout.checkout_received',
|
|
3
|
+
BILLING_TOPUP_CHECKOUT_RECEIVED: 'billing.topup.checkout_received',
|
|
4
|
+
BILLING_SUBSCRIPTION_CHECKOUT_REQUEST_SENT: 'billing.subscription_checkout.request_sent',
|
|
5
|
+
BILLING_TOPUP_REQUEST_SENT: 'billing.topup.request_sent',
|
|
6
|
+
BILLING_SUBSCRIPTION_CHECKOUT_INTENT: 'billing.subscription_checkout.intent',
|
|
7
|
+
BILLING_TOPUP_INTENT: 'billing.topup.intent',
|
|
8
|
+
BILLING_SUBSCRIPTION_CHECKOUT_STARTED: 'billing.subscription_checkout.started',
|
|
9
|
+
BILLING_SUBSCRIPTION_CHECKOUT_SUCCEEDED: 'billing.subscription_checkout.succeeded',
|
|
10
|
+
BILLING_SUBSCRIPTION_CHECKOUT_FAILED: 'billing.subscription_checkout.failed',
|
|
11
|
+
BILLING_SUBSCRIPTION_CHECKOUT_TIMEOUT: 'billing.subscription_checkout.timeout',
|
|
12
|
+
BILLING_OPERATION_STARTED: 'billing.operation.started',
|
|
13
|
+
BILLING_CAPABILITY_READ_SUCCEEDED: 'billing.capability_read.succeeded',
|
|
14
|
+
BILLING_CAPABILITY_READ_FAILED: 'billing.capability_read.failed',
|
|
15
|
+
BILLING_OPERATION_SUCCEEDED: 'billing.operation.succeeded',
|
|
16
|
+
BILLING_OPERATION_FAILED: 'billing.operation.failed',
|
|
17
|
+
BILLING_OPERATION_TIMEOUT: 'billing.operation.timeout',
|
|
18
|
+
BILLING_RESUBSCRIBE_STARTED: 'billing.resubscribe.started',
|
|
19
|
+
BILLING_RESUBSCRIBE_SUCCEEDED: 'billing.resubscribe.succeeded',
|
|
20
|
+
BILLING_RESUBSCRIBE_FAILED: 'billing.resubscribe.failed',
|
|
21
|
+
BILLING_TOPUP_STARTED: 'billing.topup.started',
|
|
22
|
+
BILLING_TOPUP_SUCCEEDED: 'billing.topup.succeeded',
|
|
23
|
+
BILLING_TOPUP_FAILED: 'billing.topup.failed',
|
|
24
|
+
BILLING_DOWNGRADE_TO_PERSONAL_STARTED: 'billing.downgrade_to_personal.started',
|
|
25
|
+
BILLING_DOWNGRADE_TO_PERSONAL_SUCCEEDED: 'billing.downgrade_to_personal.succeeded',
|
|
26
|
+
BILLING_DOWNGRADE_TO_PERSONAL_FAILED: 'billing.downgrade_to_personal.failed',
|
|
27
|
+
BILLING_WEB_HANDOFF_OPENED: 'billing.web_handoff.opened',
|
|
28
|
+
BILLING_ENTRY_PAYWALL_SHOWN: 'billing.entry.paywall_shown',
|
|
29
|
+
BILLING_ENTRY_ADD_CREDITS_CLICKED: 'billing.entry.add_credits_clicked',
|
|
30
|
+
BILLING_CANCEL_INTENT: 'billing.cancel.intent',
|
|
31
|
+
BILLING_CANCEL_ABANDONED: 'billing.cancel.abandoned',
|
|
32
|
+
BILLING_CANCEL_FAILED: 'billing.cancel.failed',
|
|
33
|
+
BILLING_PORTAL_OPENED: 'billing.portal.opened',
|
|
34
|
+
BILLING_PORTAL_FAILED: 'billing.portal.failed',
|
|
35
|
+
BILLING_PORTAL_RETURNED: 'billing.portal.returned'
|
|
36
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type { BillingOperationTerminal, BillingTelemetryErrorCode, BillingTelemetryFailure, BillingTelemetryFailureCategory } from './stages.js';
|
|
2
|
+
export type { BillingClient, BillingSurface, BillingTelemetryEvent, BillingTelemetryEventName } from './billingTelemetryEvent.js';
|
|
3
|
+
export { getBillingTelemetryEventName } from './billingTelemetryEvent.js';
|
|
4
|
+
export { getBillingTelemetryEventPayload, getBillingWebTelemetryEventPayload, getCloudAppBillingTelemetryEventPayload } from './payload.js';
|
|
5
|
+
export { BILLING_TELEMETRY_EVENTS } from './eventNames.js';
|
|
6
|
+
export { toBillingTelemetryEvent } from './operationLifecycleEvent.js';
|
|
7
|
+
export type { CheckoutHostedStep, CheckoutRedirectNavigation } from './checkoutRedirectEvent.js';
|
|
8
|
+
export type { BillingPortalTarget } from './portalEvent.js';
|
|
9
|
+
export type { SubscriptionCheckoutUi } from './subscriptionCheckoutEvent.js';
|
|
10
|
+
export type { WebEntryBillingEvent, WebEntryBounceReason, WebEntryBounceTarget, WebEntryErrorCode, WebEntryProduct } from './webEntryEvent.js';
|
|
11
|
+
export type { WebReturnBillingEvent, WebReturnControl } from './webReturnEvent.js';
|
|
12
|
+
export type { WebSessionBillingEvent, WebSessionMode } from './webSessionEvent.js';
|
|
13
|
+
export type { CheckoutAssignmentStatus, CheckoutEndingAttribution, CheckoutEndingKind, CheckoutEntryFlow, CheckoutExit, CheckoutEntrySource, CheckoutJourneyArm, CheckoutJourneyContext, CheckoutJourneyPhase, CheckoutJourneyPhaseEvent, CheckoutJourneyTelemetryEvent, CheckoutJourneyTelemetryEventName, CheckoutJourneyTelemetryEventPayload, CheckoutMethodKind, CheckoutUiMode } from './checkoutJourney.js';
|
|
14
|
+
export { CHECKOUT_JOURNEY_EVENT_NAME_BY_PHASE, CHECKOUT_JOURNEY_SCHEMA_VERSION, getCheckoutJourneyTelemetryEventName, getCheckoutJourneyTelemetryEventPayload, getCloudAppCheckoutJourneyTelemetryEventPayload } from './checkoutJourney.js';
|
|
15
|
+
export type { TopupAmountPreset } from './topupEvent.js';
|
|
16
|
+
export { getTopupAmountPreset, TOPUP_AMOUNT_PRESETS_USD } from './topupEvent.js';
|
|
17
|
+
export type { BillingCycle, BillingTierKey, HostedBillingIntent, PaymentIntentSource, ResubscribeSource, SubscriptionCheckoutTier, SubscriptionCheckoutType } from './vocabulary.js';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { getBillingTelemetryEventName } from './billingTelemetryEvent.js';
|
|
2
|
+
export { getBillingTelemetryEventPayload, getBillingWebTelemetryEventPayload, getCloudAppBillingTelemetryEventPayload } from './payload.js';
|
|
3
|
+
export { BILLING_TELEMETRY_EVENTS } from './eventNames.js';
|
|
4
|
+
export { toBillingTelemetryEvent } from './operationLifecycleEvent.js';
|
|
5
|
+
export { CHECKOUT_JOURNEY_EVENT_NAME_BY_PHASE, CHECKOUT_JOURNEY_SCHEMA_VERSION, getCheckoutJourneyTelemetryEventName, getCheckoutJourneyTelemetryEventPayload, getCloudAppCheckoutJourneyTelemetryEventPayload } from './checkoutJourney.js';
|
|
6
|
+
export { getTopupAmountPreset, TOPUP_AMOUNT_PRESETS_USD } from './topupEvent.js';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { BillingPresentation } from '../operationState.js';
|
|
2
|
+
import type { BillingOperationTerminal, BillingStarted } from './stages.js';
|
|
3
|
+
import type { BillingCycle, PaymentIntentSource, SubscriptionCheckoutTier, SubscriptionCheckoutType } from './vocabulary.js';
|
|
4
|
+
export type BillingOperationBillingEvent = {
|
|
5
|
+
operation: 'operation';
|
|
6
|
+
/** Absent when the initiating call itself failed, before the backend returned one to poll. */
|
|
7
|
+
billing_op_id?: string;
|
|
8
|
+
operation_type: 'subscription' | 'topup' | 'cancel';
|
|
9
|
+
/** Set by the billing SDK rail, as is `resumed`; the poller never sets either. */
|
|
10
|
+
presentation?: BillingPresentation;
|
|
11
|
+
/** True when this tab reattached to an operation it did not issue. */
|
|
12
|
+
resumed?: boolean;
|
|
13
|
+
tier?: SubscriptionCheckoutTier;
|
|
14
|
+
cycle?: BillingCycle;
|
|
15
|
+
checkout_type?: SubscriptionCheckoutType;
|
|
16
|
+
payment_intent_source?: PaymentIntentSource;
|
|
17
|
+
/**
|
|
18
|
+
* Client-observed end-to-end wall time from this attempt's canonical
|
|
19
|
+
* `started` event through to this terminal event, including the
|
|
20
|
+
* initiating API call's latency (not just the poll-observation window).
|
|
21
|
+
* On `timeout` this is how long the client watched, not the operation's
|
|
22
|
+
* true duration.
|
|
23
|
+
*/
|
|
24
|
+
duration_ms?: number;
|
|
25
|
+
} & (BillingStarted | BillingOperationTerminal);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { BillingOperationTelemetryEvent } from '../operationLifecycle.js';
|
|
2
|
+
import type { BillingTelemetryEvent } from './billingTelemetryEvent.js';
|
|
3
|
+
import type { PaymentIntentSource } from './vocabulary.js';
|
|
4
|
+
/**
|
|
5
|
+
* The lifecycle's event onto the poller's `billing.operation.*` stages, so
|
|
6
|
+
* both rails count in one funnel; only this rail sets `presentation` and
|
|
7
|
+
* `resumed`. Friction inside the operation maps onto `billing.checkout.*`.
|
|
8
|
+
*/
|
|
9
|
+
export declare function toBillingTelemetryEvent(event: BillingOperationTelemetryEvent, paymentIntentSource?: PaymentIntentSource): BillingTelemetryEvent;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { BILLING_CHECKOUT_FRICTION_TELEMETRY_EVENT, BILLING_OPERATION_TELEMETRY_EVENT } from '../../../telemetry.js';
|
|
2
|
+
/**
|
|
3
|
+
* The lifecycle's event onto the poller's `billing.operation.*` stages, so
|
|
4
|
+
* both rails count in one funnel; only this rail sets `presentation` and
|
|
5
|
+
* `resumed`. Friction inside the operation maps onto `billing.checkout.*`.
|
|
6
|
+
*/
|
|
7
|
+
export function toBillingTelemetryEvent(event, paymentIntentSource) {
|
|
8
|
+
const friction = {
|
|
9
|
+
operation: 'checkout',
|
|
10
|
+
outcome: 'pending',
|
|
11
|
+
billing_client: 'sdk',
|
|
12
|
+
operation_type: event.operation_type,
|
|
13
|
+
billing_op_id: event.billing_op_id,
|
|
14
|
+
presentation: event.presentation,
|
|
15
|
+
resumed: event.resumed
|
|
16
|
+
};
|
|
17
|
+
if (event.name === BILLING_CHECKOUT_FRICTION_TELEMETRY_EVENT.redirectStarted ||
|
|
18
|
+
event.name === BILLING_CHECKOUT_FRICTION_TELEMETRY_EVENT.returned) {
|
|
19
|
+
return {
|
|
20
|
+
...friction,
|
|
21
|
+
stage: event.name === BILLING_CHECKOUT_FRICTION_TELEMETRY_EVENT.returned
|
|
22
|
+
? 'returned'
|
|
23
|
+
: 'redirect_started',
|
|
24
|
+
destination: event.destination,
|
|
25
|
+
step: event.step,
|
|
26
|
+
navigation: event.navigation,
|
|
27
|
+
...(event.method_kind === undefined
|
|
28
|
+
? {}
|
|
29
|
+
: { method_kind: event.method_kind })
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const shared = {
|
|
33
|
+
operation: 'operation',
|
|
34
|
+
billing_client: 'sdk',
|
|
35
|
+
operation_type: event.operation_type,
|
|
36
|
+
billing_op_id: event.billing_op_id,
|
|
37
|
+
presentation: event.presentation,
|
|
38
|
+
resumed: event.resumed,
|
|
39
|
+
...(paymentIntentSource === undefined
|
|
40
|
+
? {}
|
|
41
|
+
: { payment_intent_source: paymentIntentSource }),
|
|
42
|
+
...('duration_ms' in event && event.duration_ms !== undefined
|
|
43
|
+
? { duration_ms: event.duration_ms }
|
|
44
|
+
: {})
|
|
45
|
+
};
|
|
46
|
+
switch (event.name) {
|
|
47
|
+
case BILLING_OPERATION_TELEMETRY_EVENT.started:
|
|
48
|
+
return { ...shared, stage: 'started', outcome: 'pending' };
|
|
49
|
+
case BILLING_OPERATION_TELEMETRY_EVENT.succeeded:
|
|
50
|
+
return { ...shared, stage: 'succeeded', outcome: 'success' };
|
|
51
|
+
case BILLING_OPERATION_TELEMETRY_EVENT.timeout:
|
|
52
|
+
return {
|
|
53
|
+
...shared,
|
|
54
|
+
stage: 'timeout',
|
|
55
|
+
outcome: 'failure',
|
|
56
|
+
failure_category: 'poll_timeout'
|
|
57
|
+
};
|
|
58
|
+
case BILLING_OPERATION_TELEMETRY_EVENT.failed:
|
|
59
|
+
return {
|
|
60
|
+
...shared,
|
|
61
|
+
stage: 'failed',
|
|
62
|
+
outcome: 'failure',
|
|
63
|
+
failure_category: event.failure_category ?? 'provider_decline',
|
|
64
|
+
decline_reason: event.decline_reason
|
|
65
|
+
};
|
|
66
|
+
case BILLING_CHECKOUT_FRICTION_TELEMETRY_EVENT.challengeRequired:
|
|
67
|
+
return { ...friction, stage: 'challenge_required' };
|
|
68
|
+
case BILLING_CHECKOUT_FRICTION_TELEMETRY_EVENT.challengeCompleted:
|
|
69
|
+
return { ...friction, stage: 'challenge_completed' };
|
|
70
|
+
case BILLING_CHECKOUT_FRICTION_TELEMETRY_EVENT.challengeFailed:
|
|
71
|
+
return {
|
|
72
|
+
...friction,
|
|
73
|
+
stage: 'challenge_failed',
|
|
74
|
+
...(event.decline_reason === undefined
|
|
75
|
+
? {}
|
|
76
|
+
: { decline_reason: event.decline_reason })
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { BillingSurface, BillingTelemetryEvent } from './billingTelemetryEvent.js';
|
|
2
|
+
type BillingTelemetryPayload = Record<string, unknown>;
|
|
3
|
+
type KeysOfUnion<T> = T extends unknown ? keyof T : never;
|
|
4
|
+
export type BillingPayloadFieldHandling<Event = BillingTelemetryEvent> = Record<Exclude<KeysOfUnion<Event>, 'operation' | 'stage' | 'outcome'>, 'optional' | 'required'>;
|
|
5
|
+
export declare const BILLING_PAYLOAD_FIELD_HANDLING: {
|
|
6
|
+
readonly checkout_status: "required";
|
|
7
|
+
readonly control: "required";
|
|
8
|
+
readonly correlation_id: "required";
|
|
9
|
+
readonly destination: "required";
|
|
10
|
+
readonly failure_category: "required";
|
|
11
|
+
readonly has_plan: "required";
|
|
12
|
+
readonly intent: "required";
|
|
13
|
+
readonly member_removal_count: "required";
|
|
14
|
+
readonly member_removal_failures: "required";
|
|
15
|
+
readonly mode: "required";
|
|
16
|
+
readonly navigation: "required";
|
|
17
|
+
readonly operation_type: "required";
|
|
18
|
+
readonly origin: "required";
|
|
19
|
+
readonly product: "required";
|
|
20
|
+
readonly reason: "required";
|
|
21
|
+
readonly result: "required";
|
|
22
|
+
readonly source: "required";
|
|
23
|
+
readonly step: "required";
|
|
24
|
+
readonly target: "required";
|
|
25
|
+
readonly to: "required";
|
|
26
|
+
readonly amount_cents: "optional";
|
|
27
|
+
readonly amount_preset: "optional";
|
|
28
|
+
readonly billing_client: "optional";
|
|
29
|
+
readonly billing_op_id: "optional";
|
|
30
|
+
readonly checkout_attempt_id: "optional";
|
|
31
|
+
readonly checkout_type: "optional";
|
|
32
|
+
readonly checkout_ui: "optional";
|
|
33
|
+
readonly current_tier: "optional";
|
|
34
|
+
readonly cycle: "optional";
|
|
35
|
+
readonly decline_reason: "optional";
|
|
36
|
+
readonly duration_ms: "optional";
|
|
37
|
+
readonly error_code: "optional";
|
|
38
|
+
readonly method_kind: "optional";
|
|
39
|
+
readonly payment_intent_source: "optional";
|
|
40
|
+
readonly presentation: "optional";
|
|
41
|
+
readonly recovery_outcome: "optional";
|
|
42
|
+
readonly resumed: "optional";
|
|
43
|
+
readonly target_tier: "optional";
|
|
44
|
+
readonly tier: "optional";
|
|
45
|
+
};
|
|
46
|
+
export declare function getBillingTelemetryEventPayload(event: BillingTelemetryEvent): BillingTelemetryPayload;
|
|
47
|
+
/** Only the cloud build registers the sinks that call this; the desktop host sink claims no surface. */
|
|
48
|
+
export declare function getCloudAppBillingTelemetryEventPayload(event: BillingTelemetryEvent): BillingTelemetryPayload & {
|
|
49
|
+
billing_surface: BillingSurface;
|
|
50
|
+
};
|
|
51
|
+
/** The payload billing web reports: the same allowlist, claiming the billing web surface. */
|
|
52
|
+
export declare function getBillingWebTelemetryEventPayload(event: BillingTelemetryEvent): BillingTelemetryPayload & {
|
|
53
|
+
billing_surface: BillingSurface;
|
|
54
|
+
};
|
|
55
|
+
export {};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
export const BILLING_PAYLOAD_FIELD_HANDLING = {
|
|
2
|
+
checkout_status: 'required',
|
|
3
|
+
control: 'required',
|
|
4
|
+
correlation_id: 'required',
|
|
5
|
+
destination: 'required',
|
|
6
|
+
failure_category: 'required',
|
|
7
|
+
has_plan: 'required',
|
|
8
|
+
intent: 'required',
|
|
9
|
+
member_removal_count: 'required',
|
|
10
|
+
member_removal_failures: 'required',
|
|
11
|
+
mode: 'required',
|
|
12
|
+
navigation: 'required',
|
|
13
|
+
operation_type: 'required',
|
|
14
|
+
origin: 'required',
|
|
15
|
+
product: 'required',
|
|
16
|
+
reason: 'required',
|
|
17
|
+
result: 'required',
|
|
18
|
+
source: 'required',
|
|
19
|
+
step: 'required',
|
|
20
|
+
target: 'required',
|
|
21
|
+
to: 'required',
|
|
22
|
+
amount_cents: 'optional',
|
|
23
|
+
amount_preset: 'optional',
|
|
24
|
+
billing_client: 'optional',
|
|
25
|
+
billing_op_id: 'optional',
|
|
26
|
+
checkout_attempt_id: 'optional',
|
|
27
|
+
checkout_type: 'optional',
|
|
28
|
+
checkout_ui: 'optional',
|
|
29
|
+
current_tier: 'optional',
|
|
30
|
+
cycle: 'optional',
|
|
31
|
+
decline_reason: 'optional',
|
|
32
|
+
duration_ms: 'optional',
|
|
33
|
+
error_code: 'optional',
|
|
34
|
+
method_kind: 'optional',
|
|
35
|
+
payment_intent_source: 'optional',
|
|
36
|
+
presentation: 'optional',
|
|
37
|
+
recovery_outcome: 'optional',
|
|
38
|
+
resumed: 'optional',
|
|
39
|
+
target_tier: 'optional',
|
|
40
|
+
tier: 'optional'
|
|
41
|
+
};
|
|
42
|
+
const OPTIONAL_BILLING_PAYLOAD_FIELDS = Object.entries(BILLING_PAYLOAD_FIELD_HANDLING).flatMap(([field, handling]) => (handling === 'optional' ? [field] : []));
|
|
43
|
+
const REQUIRED_BILLING_PAYLOAD_FIELDS = Object.entries(BILLING_PAYLOAD_FIELD_HANDLING).flatMap(([field, handling]) => (handling === 'required' ? [field] : []));
|
|
44
|
+
const optionalBillingPayloadFields = new Set(OPTIONAL_BILLING_PAYLOAD_FIELDS);
|
|
45
|
+
const requiredBillingPayloadFields = new Set(REQUIRED_BILLING_PAYLOAD_FIELDS);
|
|
46
|
+
export function getBillingTelemetryEventPayload(event) {
|
|
47
|
+
const payload = {
|
|
48
|
+
operation: event.operation,
|
|
49
|
+
stage: event.stage,
|
|
50
|
+
outcome: event.outcome
|
|
51
|
+
};
|
|
52
|
+
for (const [field, value] of Object.entries(event)) {
|
|
53
|
+
if (requiredBillingPayloadFields.has(field)) {
|
|
54
|
+
payload[field] = value;
|
|
55
|
+
}
|
|
56
|
+
else if (optionalBillingPayloadFields.has(field) && value !== undefined) {
|
|
57
|
+
payload[field] = value;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return payload;
|
|
61
|
+
}
|
|
62
|
+
/** Only the cloud build registers the sinks that call this; the desktop host sink claims no surface. */
|
|
63
|
+
export function getCloudAppBillingTelemetryEventPayload(event) {
|
|
64
|
+
return {
|
|
65
|
+
...getBillingTelemetryEventPayload(event),
|
|
66
|
+
billing_surface: 'cloud_app'
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/** The payload billing web reports: the same allowlist, claiming the billing web surface. */
|
|
70
|
+
export function getBillingWebTelemetryEventPayload(event) {
|
|
71
|
+
return {
|
|
72
|
+
...getBillingTelemetryEventPayload(event),
|
|
73
|
+
billing_surface: 'billing_web'
|
|
74
|
+
};
|
|
75
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { BillingFailed } from './stages.js';
|
|
2
|
+
/**
|
|
3
|
+
* The part of the provider's hosted portal the customer was sent to.
|
|
4
|
+
* `payment_recovery` is a checkout that stopped on a failed or outstanding
|
|
5
|
+
* payment and sent the customer to settle it.
|
|
6
|
+
*/
|
|
7
|
+
export type BillingPortalTarget = 'payment_methods' | 'invoices' | 'manage_subscription' | 'payment_recovery';
|
|
8
|
+
/**
|
|
9
|
+
* A trip to the provider's hosted portal. What the customer does there (adding,
|
|
10
|
+
* removing or picking a default method, reading invoices) never reaches the
|
|
11
|
+
* browser, so the trip only records leaving for the portal, failing to, and
|
|
12
|
+
* coming back.
|
|
13
|
+
*/
|
|
14
|
+
export type PortalBillingEvent = {
|
|
15
|
+
operation: 'portal';
|
|
16
|
+
target: BillingPortalTarget;
|
|
17
|
+
} & ({
|
|
18
|
+
stage: 'opened';
|
|
19
|
+
outcome: 'pending';
|
|
20
|
+
} | BillingFailed | {
|
|
21
|
+
stage: 'returned';
|
|
22
|
+
outcome: 'pending';
|
|
23
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { BillingDeclineReason } from '../operationState.js';
|
|
2
|
+
import type { BillingFailed, BillingRecoveredSucceeded, BillingStarted } from './stages.js';
|
|
3
|
+
import type { PaymentIntentSource, ResubscribeSource } from './vocabulary.js';
|
|
4
|
+
export type ResubscribeBillingEvent = {
|
|
5
|
+
operation: 'resubscribe';
|
|
6
|
+
source: ResubscribeSource;
|
|
7
|
+
billing_op_id?: string;
|
|
8
|
+
checkout_attempt_id?: string;
|
|
9
|
+
payment_intent_source?: PaymentIntentSource;
|
|
10
|
+
duration_ms?: number;
|
|
11
|
+
} & (BillingStarted | BillingRecoveredSucceeded | (BillingFailed & {
|
|
12
|
+
decline_reason?: BillingDeclineReason;
|
|
13
|
+
}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { BillingDeclineReason } from '../operationState.js';
|
|
2
|
+
export type BillingTelemetryFailureCategory = 'validation' | 'network' | 'api_rejected' | 'provider_decline' | 'redirect' | 'poll_timeout' | 'reconciliation_needed' | 'stale_operation' | 'rendering' | 'unknown';
|
|
3
|
+
export type BillingTelemetryErrorCode = 'conflicting_payment_method' | 'downgrade_not_allowed' | 'invalid_request' | 'member_removal_failed' | 'missing_checkout_response' | 'missing_payment_method_url' | 'operation_already_pending' | 'payment_popup_blocked' | 'quote_stale' | 'reactivation_not_confirmed' | 'reactivation_amount_changed';
|
|
4
|
+
export interface BillingTelemetryFailure {
|
|
5
|
+
failure_category: BillingTelemetryFailureCategory;
|
|
6
|
+
error_code?: BillingTelemetryErrorCode;
|
|
7
|
+
}
|
|
8
|
+
export type BillingIntent = {
|
|
9
|
+
stage: 'intent';
|
|
10
|
+
outcome: 'pending';
|
|
11
|
+
};
|
|
12
|
+
export type BillingRequestSent = {
|
|
13
|
+
stage: 'request_sent';
|
|
14
|
+
outcome: 'pending';
|
|
15
|
+
};
|
|
16
|
+
export type BillingCheckoutReceived<Status extends string> = {
|
|
17
|
+
stage: 'checkout_received';
|
|
18
|
+
outcome: 'pending';
|
|
19
|
+
billing_op_id: string;
|
|
20
|
+
checkout_status: Status;
|
|
21
|
+
};
|
|
22
|
+
export type BillingStarted = {
|
|
23
|
+
stage: 'started';
|
|
24
|
+
outcome: 'pending';
|
|
25
|
+
};
|
|
26
|
+
export type BillingSucceeded = {
|
|
27
|
+
stage: 'succeeded';
|
|
28
|
+
outcome: 'success';
|
|
29
|
+
};
|
|
30
|
+
export type BillingRecoveredSucceeded = BillingSucceeded & {
|
|
31
|
+
recovery_outcome?: 'late_success';
|
|
32
|
+
};
|
|
33
|
+
export type BillingFailed = BillingTelemetryFailure & {
|
|
34
|
+
stage: 'failed';
|
|
35
|
+
outcome: 'failure';
|
|
36
|
+
};
|
|
37
|
+
export type BillingTimedOut = {
|
|
38
|
+
stage: 'timeout';
|
|
39
|
+
outcome: 'failure';
|
|
40
|
+
failure_category: 'poll_timeout';
|
|
41
|
+
};
|
|
42
|
+
/** The stage one attempt at a billing operation settled on. */
|
|
43
|
+
export type BillingOperationTerminal = BillingSucceeded | (BillingFailed & {
|
|
44
|
+
decline_reason?: BillingDeclineReason;
|
|
45
|
+
}) | BillingTimedOut;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { SubscribeResponse } from '@comfyorg/ingest-types';
|
|
2
|
+
import type { BillingDeclineReason } from '../operationState.js';
|
|
3
|
+
import type { BillingCheckoutReceived, BillingFailed, BillingIntent, BillingRecoveredSucceeded, BillingRequestSent, BillingStarted, BillingTimedOut } from './stages.js';
|
|
4
|
+
import type { BillingCycle, PaymentIntentSource, SubscriptionCheckoutTier, SubscriptionCheckoutType } from './vocabulary.js';
|
|
5
|
+
/** The two checkouts billing web serves; the cloud app's events name neither. */
|
|
6
|
+
export type SubscriptionCheckoutUi = 'embedded' | 'full_page';
|
|
7
|
+
export type SubscriptionCheckoutBillingEvent = {
|
|
8
|
+
operation: 'subscription_checkout';
|
|
9
|
+
billing_op_id?: string;
|
|
10
|
+
checkout_attempt_id?: string;
|
|
11
|
+
tier?: SubscriptionCheckoutTier;
|
|
12
|
+
cycle?: BillingCycle;
|
|
13
|
+
checkout_type?: SubscriptionCheckoutType;
|
|
14
|
+
checkout_ui?: SubscriptionCheckoutUi;
|
|
15
|
+
payment_intent_source?: PaymentIntentSource;
|
|
16
|
+
/**
|
|
17
|
+
* Client-observed end-to-end wall time from this attempt's canonical
|
|
18
|
+
* `started` event through to this terminal event.
|
|
19
|
+
*/
|
|
20
|
+
duration_ms?: number;
|
|
21
|
+
} & (BillingIntent | BillingCheckoutReceived<SubscribeResponse['status']> | BillingRequestSent | BillingStarted | BillingRecoveredSucceeded | (BillingFailed & {
|
|
22
|
+
decline_reason?: BillingDeclineReason;
|
|
23
|
+
}) | BillingTimedOut);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { CreateTopupResponse } from '@comfyorg/ingest-types';
|
|
2
|
+
import type { BillingCheckoutReceived, BillingFailed, BillingIntent, BillingRequestSent, BillingStarted, BillingSucceeded } from './stages.js';
|
|
3
|
+
import type { PaymentIntentSource } from './vocabulary.js';
|
|
4
|
+
/** The fixed amounts, in USD, a top-up dialog offers as one-click choices. */
|
|
5
|
+
export declare const TOPUP_AMOUNT_PRESETS_USD: readonly [10, 25, 50, 100];
|
|
6
|
+
/** The preset the customer picked, or `custom` for any typed amount. */
|
|
7
|
+
export type TopupAmountPreset = `${(typeof TOPUP_AMOUNT_PRESETS_USD)[number]}` | 'custom';
|
|
8
|
+
export declare function getTopupAmountPreset(pickedPresetUsd: number | null): TopupAmountPreset;
|
|
9
|
+
type TopupStarted = BillingStarted & {
|
|
10
|
+
/** The amount being bought, in whole cents. */
|
|
11
|
+
amount_cents?: number;
|
|
12
|
+
amount_preset?: TopupAmountPreset;
|
|
13
|
+
};
|
|
14
|
+
export type TopupBillingEvent = {
|
|
15
|
+
operation: 'topup';
|
|
16
|
+
billing_op_id?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Surface the top-up was opened from. Absent when the caller named none,
|
|
19
|
+
* exactly as on the subscription rail's events — absent is no claim, never
|
|
20
|
+
* an implied default. Named `payment_intent_source` to match its siblings
|
|
21
|
+
* above; the journey's own `entry_source` is a separate, smaller enum.
|
|
22
|
+
*/
|
|
23
|
+
payment_intent_source?: PaymentIntentSource;
|
|
24
|
+
/**
|
|
25
|
+
* Client-observed end-to-end wall time from this attempt's canonical
|
|
26
|
+
* `started` event through to this terminal event.
|
|
27
|
+
*/
|
|
28
|
+
duration_ms?: number;
|
|
29
|
+
} & (BillingIntent | BillingCheckoutReceived<CreateTopupResponse['status']> | BillingRequestSent | TopupStarted | BillingSucceeded | BillingFailed);
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** The fixed amounts, in USD, a top-up dialog offers as one-click choices. */
|
|
2
|
+
export const TOPUP_AMOUNT_PRESETS_USD = [10, 25, 50, 100];
|
|
3
|
+
export function getTopupAmountPreset(pickedPresetUsd) {
|
|
4
|
+
const preset = TOPUP_AMOUNT_PRESETS_USD.find((usd) => usd === pickedPresetUsd);
|
|
5
|
+
return preset === undefined ? 'custom' : `${preset}`;
|
|
6
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type BillingTierKey = 'free' | 'standard' | 'creator' | 'pro' | 'founder';
|
|
2
|
+
export type BillingCycle = 'monthly' | 'yearly';
|
|
3
|
+
export type SubscriptionCheckoutType = 'new' | 'change';
|
|
4
|
+
export type SubscriptionCheckoutTier = BillingTierKey | 'team';
|
|
5
|
+
export type ResubscribeSource = 'pricing_dialog' | 'settings_billing_panel' | 'billing_web_subscription';
|
|
6
|
+
/** Mirrors `BillingSource` in `@comfyorg/billing-contract`; a type test there fails when the two drift. */
|
|
7
|
+
export type PaymentIntentSource = 'subscription_required' | 'out_of_credits' | 'top_up_blocked' | 'deep_link' | 'subscribe_to_run' | 'subscribe_now_button' | 'upgrade_to_add_credits' | 'settings_billing_panel' | 'avatar_menu_plans' | 'team_members_panel' | 'invite_member_upsell' | 'upload_model_upgrade' | 'team_upgrade_resume' | 'free_tier_quota' | 'agent_paywall';
|
|
8
|
+
/** Mirrors `BillingIntent` in `@comfyorg/billing-contract`; a type test there fails when the two drift. */
|
|
9
|
+
export type HostedBillingIntent = 'pricing' | 'checkout' | 'top-up' | 'subscription' | 'payment-methods' | 'invoices' | 'result';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { HostedBillingIntent, PaymentIntentSource } from './vocabulary.js';
|
|
2
|
+
/** Mirrors `BillingProduct` in `@comfyorg/billing-contract`; a type test there fails when the two drift. */
|
|
3
|
+
export type WebEntryProduct = 'comfyui' | 'platform' | 'workshop' | 'models';
|
|
4
|
+
/** Mirrors `BillingEntryErrorCode` in `@comfyorg/billing-contract`; a type test there fails when the two drift. */
|
|
5
|
+
export type WebEntryErrorCode = 'UNSUPPORTED_VERSION' | 'UNKNOWN_INTENT' | 'UNKNOWN_PRODUCT' | 'UNKNOWN_RETURN_TARGET' | 'INVALID_AMOUNT' | 'INVALID_PLAN' | 'INVALID_CORRELATION_ID' | 'INVALID_WORKSPACE_ID' | 'INVALID_TEAM_CREDIT_STOP_ID' | 'INVALID_PROMOTION_CODE';
|
|
6
|
+
export type WebEntryBounceReason = 'pricing_link' | 'planless_checkout' | 'return_target_rewritten';
|
|
7
|
+
/** A `ReturnTarget` of `@comfyorg/billing-contract` (a type test there pins them) or the host's pricing table. */
|
|
8
|
+
export type WebEntryBounceTarget = 'comfyui_workspace' | 'comfyui_credits' | 'platform_account' | 'platform_billing' | 'pricing_table';
|
|
9
|
+
export type WebEntryBillingEvent = {
|
|
10
|
+
operation: 'web_entry';
|
|
11
|
+
outcome: 'pending';
|
|
12
|
+
} & ({
|
|
13
|
+
stage: 'received';
|
|
14
|
+
intent: HostedBillingIntent;
|
|
15
|
+
product: WebEntryProduct;
|
|
16
|
+
has_plan: boolean;
|
|
17
|
+
payment_intent_source?: PaymentIntentSource;
|
|
18
|
+
/** The cloud journey id the entry link carries; links from other products carry none. */
|
|
19
|
+
correlation_id?: string;
|
|
20
|
+
} | {
|
|
21
|
+
stage: 'rejected';
|
|
22
|
+
error_code: WebEntryErrorCode;
|
|
23
|
+
} | {
|
|
24
|
+
stage: 'bounced';
|
|
25
|
+
reason: WebEntryBounceReason;
|
|
26
|
+
to: WebEntryBounceTarget;
|
|
27
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|