@comfyorg/account-core 1.0.0-alpha.1 → 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.
Files changed (76) hide show
  1. package/dist/core/billing/index.d.ts +4 -3
  2. package/dist/core/billing/index.js +2 -1
  3. package/dist/core/billing/operationLifecycle.d.ts +26 -4
  4. package/dist/core/billing/operationLifecycle.js +113 -14
  5. package/dist/core/billing/operationPointer.d.ts +24 -0
  6. package/dist/core/billing/operationPointer.js +14 -1
  7. package/dist/core/billing/operationState.d.ts +135 -1
  8. package/dist/core/billing/operationState.js +15 -2
  9. package/dist/core/billing/paymentFriction.d.ts +17 -0
  10. package/dist/core/billing/paymentFriction.js +41 -0
  11. package/dist/core/billing/subscriptionCommands.d.ts +64 -2
  12. package/dist/core/billing/subscriptionCommands.js +31 -7
  13. package/dist/core/billing/subscriptionDiscount.d.ts +26 -0
  14. package/dist/core/billing/subscriptionDiscount.js +6 -0
  15. package/dist/core/billing/telemetry/billingTelemetryEvent.d.ts +25 -0
  16. package/dist/core/billing/telemetry/billingTelemetryEvent.js +3 -0
  17. package/dist/core/billing/telemetry/cancelEvent.d.ts +19 -0
  18. package/dist/core/billing/telemetry/cancelEvent.js +1 -0
  19. package/dist/core/billing/telemetry/capabilityReadEvent.d.ts +4 -0
  20. package/dist/core/billing/telemetry/capabilityReadEvent.js +1 -0
  21. package/dist/core/billing/telemetry/checkoutChallengeEvent.d.ts +25 -0
  22. package/dist/core/billing/telemetry/checkoutChallengeEvent.js +1 -0
  23. package/dist/core/billing/telemetry/checkoutJourney.d.ts +176 -0
  24. package/dist/core/billing/telemetry/checkoutJourney.js +115 -0
  25. package/dist/core/billing/telemetry/checkoutRedirectEvent.d.ts +30 -0
  26. package/dist/core/billing/telemetry/checkoutRedirectEvent.js +1 -0
  27. package/dist/core/billing/telemetry/downgradeToPersonalEvent.d.ts +14 -0
  28. package/dist/core/billing/telemetry/downgradeToPersonalEvent.js +1 -0
  29. package/dist/core/billing/telemetry/entryEvent.d.ts +16 -0
  30. package/dist/core/billing/telemetry/entryEvent.js +1 -0
  31. package/dist/core/billing/telemetry/eventNames.d.ts +36 -0
  32. package/dist/core/billing/telemetry/eventNames.js +36 -0
  33. package/dist/core/billing/telemetry/index.d.ts +17 -0
  34. package/dist/core/billing/telemetry/index.js +6 -0
  35. package/dist/core/billing/telemetry/operationEvent.d.ts +25 -0
  36. package/dist/core/billing/telemetry/operationEvent.js +1 -0
  37. package/dist/core/billing/telemetry/operationLifecycleEvent.d.ts +9 -0
  38. package/dist/core/billing/telemetry/operationLifecycleEvent.js +79 -0
  39. package/dist/core/billing/telemetry/payload.d.ts +55 -0
  40. package/dist/core/billing/telemetry/payload.js +75 -0
  41. package/dist/core/billing/telemetry/portalEvent.d.ts +23 -0
  42. package/dist/core/billing/telemetry/portalEvent.js +1 -0
  43. package/dist/core/billing/telemetry/resubscribeEvent.d.ts +13 -0
  44. package/dist/core/billing/telemetry/resubscribeEvent.js +1 -0
  45. package/dist/core/billing/telemetry/stages.d.ts +45 -0
  46. package/dist/core/billing/telemetry/stages.js +1 -0
  47. package/dist/core/billing/telemetry/subscriptionCheckoutEvent.d.ts +23 -0
  48. package/dist/core/billing/telemetry/subscriptionCheckoutEvent.js +1 -0
  49. package/dist/core/billing/telemetry/topupEvent.d.ts +30 -0
  50. package/dist/core/billing/telemetry/topupEvent.js +6 -0
  51. package/dist/core/billing/telemetry/vocabulary.d.ts +9 -0
  52. package/dist/core/billing/telemetry/vocabulary.js +1 -0
  53. package/dist/core/billing/telemetry/webEntryEvent.d.ts +27 -0
  54. package/dist/core/billing/telemetry/webEntryEvent.js +1 -0
  55. package/dist/core/billing/telemetry/webHandoffEvent.d.ts +11 -0
  56. package/dist/core/billing/telemetry/webHandoffEvent.js +1 -0
  57. package/dist/core/billing/telemetry/webReturnEvent.d.ts +8 -0
  58. package/dist/core/billing/telemetry/webReturnEvent.js +1 -0
  59. package/dist/core/billing/telemetry/webSessionEvent.d.ts +17 -0
  60. package/dist/core/billing/telemetry/webSessionEvent.js +1 -0
  61. package/dist/core/requestTimeout.d.ts +7 -0
  62. package/dist/core/requestTimeout.js +13 -0
  63. package/dist/core/sessionTokenMint.d.ts +3 -1
  64. package/dist/core/sessionTokenMint.js +28 -11
  65. package/dist/core/webSession.d.ts +6 -3
  66. package/dist/core/webSession.js +31 -23
  67. package/dist/core/webSessionFlag.d.ts +1 -2
  68. package/dist/core/webSessionFlag.js +1 -2
  69. package/dist/core/webSessionIdentity.d.ts +12 -6
  70. package/dist/core/webSessionIdentity.js +17 -4
  71. package/dist/signInSchemas.d.ts +1 -1
  72. package/dist/telemetry.d.ts +26 -0
  73. package/dist/telemetry.js +28 -7
  74. package/dist/testing.d.ts +2 -1
  75. package/dist/testing.js +5 -4
  76. package/package.json +3 -1
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Checkout-journey lifecycle events for the embedded-checkout rollout.
3
+ *
4
+ * These intermediate stages are kept deliberately separate from the terminal
5
+ * billing taxonomy above (`billing.<operation>.<stage>`): entry, preview, and
6
+ * Payment Element observations are client observations of progress, never
7
+ * business success/failure/timeout. They share one frozen journey context so
8
+ * the two rollout arms can be compared on the same denominator.
9
+ */
10
+ export const CHECKOUT_JOURNEY_SCHEMA_VERSION = 1;
11
+ /**
12
+ * The wire name for every phase. Typed as a total `Record` over the phase
13
+ * union, so a phase added to the union without a name here fails to compile —
14
+ * and so the runtime list below can never drift from the emitted names.
15
+ */
16
+ export const CHECKOUT_JOURNEY_EVENT_NAME_BY_PHASE = {
17
+ entered: 'billing.checkout.entered',
18
+ preview_ready: 'billing.checkout.preview_ready',
19
+ preview_failed: 'billing.checkout.preview_failed',
20
+ payment_element_ready: 'billing.checkout.payment_element_ready',
21
+ payment_element_failed: 'billing.checkout.payment_element_failed',
22
+ payment_submit_attempted: 'billing.checkout.payment_submit_attempted',
23
+ payment_submit_failed: 'billing.checkout.payment_submit_failed',
24
+ method_selected: 'billing.checkout.method_selected',
25
+ promo: 'billing.checkout.promo',
26
+ pay_blocked: 'billing.checkout.pay_blocked',
27
+ submitted: 'billing.checkout.submitted',
28
+ operation_linked: 'billing.checkout.operation_linked',
29
+ abandoned: 'billing.checkout.abandoned',
30
+ ended: 'billing.checkout.ended'
31
+ };
32
+ export function getCheckoutJourneyTelemetryEventName(event) {
33
+ return CHECKOUT_JOURNEY_EVENT_NAME_BY_PHASE[event.phase];
34
+ }
35
+ function getContextPayload(event) {
36
+ return {
37
+ schema_version: CHECKOUT_JOURNEY_SCHEMA_VERSION,
38
+ phase: event.phase,
39
+ checkout_journey_id: event.checkout_journey_id,
40
+ checkout_entered_at: event.checkout_entered_at,
41
+ assignment_status: event.assignment_status,
42
+ entry_flow: event.entry_flow,
43
+ entry_source: event.entry_source,
44
+ ...(event.assigned_arm !== undefined && {
45
+ assigned_arm: event.assigned_arm
46
+ }),
47
+ ...(event.ui_mode !== undefined && { ui_mode: event.ui_mode }),
48
+ ...(event.billing_op_id !== undefined && {
49
+ billing_op_id: event.billing_op_id
50
+ })
51
+ };
52
+ }
53
+ function getPreviewPayload(event) {
54
+ return {
55
+ ...('preview_revision' in event &&
56
+ event.preview_revision !== undefined && {
57
+ preview_revision: event.preview_revision
58
+ }),
59
+ ...('failure_category' in event && {
60
+ failure_category: event.failure_category
61
+ }),
62
+ ...('error_code' in event &&
63
+ event.error_code !== undefined && { error_code: event.error_code }),
64
+ ...('denial_reason' in event &&
65
+ event.denial_reason !== undefined && {
66
+ denial_reason: event.denial_reason
67
+ })
68
+ };
69
+ }
70
+ function getPaymentFormPayload(event) {
71
+ return {
72
+ ...('element' in event && { element: event.element }),
73
+ ...('element_phase' in event && { element_phase: event.element_phase }),
74
+ ...('submit_phase' in event && { submit_phase: event.submit_phase })
75
+ };
76
+ }
77
+ function getChoicePayload(event) {
78
+ return {
79
+ ...('payment_intent_source' in event &&
80
+ event.payment_intent_source !== undefined && {
81
+ payment_intent_source: event.payment_intent_source
82
+ }),
83
+ ...('rail' in event && { rail: event.rail }),
84
+ ...('method_kind' in event &&
85
+ event.method_kind !== undefined && { method_kind: event.method_kind }),
86
+ ...('result' in event && { result: event.result }),
87
+ ...('prefilled' in event && { prefilled: event.prefilled }),
88
+ ...('reason' in event && { reason: event.reason })
89
+ };
90
+ }
91
+ function getExitPayload(event) {
92
+ return {
93
+ ...('last_phase' in event && { last_phase: event.last_phase }),
94
+ ...('exit' in event && { exit: event.exit }),
95
+ ...('ending_kind' in event && { ending_kind: event.ending_kind }),
96
+ ...('attribution' in event &&
97
+ event.attribution !== undefined && { attribution: event.attribution })
98
+ };
99
+ }
100
+ export function getCheckoutJourneyTelemetryEventPayload(event) {
101
+ return {
102
+ ...getContextPayload(event),
103
+ ...getPreviewPayload(event),
104
+ ...getPaymentFormPayload(event),
105
+ ...getChoicePayload(event),
106
+ ...getExitPayload(event)
107
+ };
108
+ }
109
+ /** Only the cloud build registers the sinks that call this. */
110
+ export function getCloudAppCheckoutJourneyTelemetryEventPayload(event) {
111
+ return {
112
+ ...getCheckoutJourneyTelemetryEventPayload(event),
113
+ billing_surface: 'cloud_app'
114
+ };
115
+ }
@@ -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,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,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 {};