@402flow/sdk 0.1.0-alpha.2 → 0.1.0-alpha.20

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/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- import { type ParsedChallenge } from './challenge-detection.js';
2
- import { type PaidRequestContext, type PaidRequestTarget, type SdkPaymentDecisionResponse, type SdkReceipt, type SdkReceiptResponse } from './contracts.js';
1
+ import { type DetectedChallenge } from './challenge-detection.js';
2
+ import { type SdkExternalMetadata, type SdkPreparedPaidRequest, type SdkPreparedPaidRequestReady, type PaidRequestContext, type SdkPaymentDecisionResponse, type SdkReceipt, type SdkReceiptResponse } from './contracts.js';
3
+ /** Supported authentication modes for an SDK client. */
3
4
  export type AgentPayAuth = {
4
5
  type: 'bootstrapKey';
5
6
  bootstrapKey: string;
@@ -7,18 +8,34 @@ export type AgentPayAuth = {
7
8
  type: 'runtimeToken';
8
9
  runtimeToken: string;
9
10
  };
11
+ /** Identity bound to a client instance and applied to every paid request. */
12
+ export type AgentPayClientIdentity = Pick<PaidRequestContext, 'organization' | 'agent'>;
13
+ /** Configuration for a client connected to one control plane and one agent identity. */
10
14
  export type AgentPayClientOptions = {
11
15
  controlPlaneBaseUrl: string;
12
16
  auth: AgentPayAuth;
17
+ organization: string;
18
+ agent: string;
13
19
  fetch?: typeof fetch;
14
20
  headers?: Record<string, string>;
15
21
  };
22
+ /** Request-scoped options for the fast fetchPaid() path. */
16
23
  export type FetchPaidOptions = {
17
- target: PaidRequestTarget;
18
- challenge?: ParsedChallenge;
24
+ challenge?: DetectedChallenge;
19
25
  idempotencyKey?: string;
20
26
  };
21
- type PaidProtocol = ParsedChallenge['protocol'];
27
+ /** Optional context for the preparation flow. */
28
+ export type PreparePaidRequestOptions = {
29
+ challenge?: DetectedChallenge;
30
+ externalMetadata?: SdkExternalMetadata;
31
+ };
32
+ /** Execution context accepted when paying a previously prepared request. */
33
+ export type ExecutePreparedRequest = Omit<FetchPaidRequest, 'challenge'>;
34
+ /** Request-scoped control-plane context accepted by fetchPaid(). */
35
+ export type FetchPaidRequest = Omit<PaidRequestContext, keyof AgentPayClientIdentity> & FetchPaidOptions;
36
+ /** Body types the SDK can safely replay through paid prepare/execute flows. */
37
+ export type ReplayableRequestBody = string | URLSearchParams;
38
+ type PaidProtocol = DetectedChallenge['protocol'];
22
39
  type DenyDecision = Extract<SdkPaymentDecisionResponse, {
23
40
  outcome: 'deny';
24
41
  }>;
@@ -37,14 +54,22 @@ type PreflightFailedDecision = Extract<SdkPaymentDecisionResponse, {
37
54
  type PaidFulfillmentFailedDecision = Extract<SdkPaymentDecisionResponse, {
38
55
  outcome: 'paid_fulfillment_failed';
39
56
  }>;
57
+ type RequestFailedDecision = {
58
+ outcome: 'request_failed';
59
+ status: number;
60
+ message: string;
61
+ body?: unknown;
62
+ };
40
63
  type PaidResponseBase = {
41
64
  protocol: PaidProtocol | 'none';
42
65
  response: Response;
43
66
  };
67
+ /** Returned when the merchant did not require payment for the request. */
44
68
  export type PassthroughPaidResponse = PaidResponseBase & {
45
69
  kind: 'passthrough';
46
70
  protocol: 'none';
47
71
  };
72
+ /** Returned when the paid request succeeded and a durable receipt exists. */
48
73
  export type SuccessPaidResponse = PaidResponseBase & {
49
74
  kind: 'success';
50
75
  protocol: PaidProtocol;
@@ -53,6 +78,7 @@ export type SuccessPaidResponse = PaidResponseBase & {
53
78
  receiptId: string;
54
79
  receipt: SdkReceipt;
55
80
  };
81
+ /** Failure result for paid requests that settled but did not fulfill successfully. */
56
82
  export type PaidFulfillmentFailedResponse = PaidResponseBase & {
57
83
  kind: 'paid_fulfillment_failed';
58
84
  protocol: PaidProtocol;
@@ -63,6 +89,7 @@ export type PaidFulfillmentFailedResponse = PaidResponseBase & {
63
89
  reason: string;
64
90
  decision: PaidFulfillmentFailedDecision;
65
91
  };
92
+ /** Failure result for policy denials before paid execution is allowed. */
66
93
  export type DeniedPaidResponse = PaidResponseBase & {
67
94
  kind: 'denied';
68
95
  protocol: PaidProtocol;
@@ -71,6 +98,7 @@ export type DeniedPaidResponse = PaidResponseBase & {
71
98
  decision: DenyDecision;
72
99
  policyReviewEventId?: string;
73
100
  };
101
+ /** Failure result for idempotent retries that are still executing. */
74
102
  export type ExecutionPendingPaidResponse = PaidResponseBase & {
75
103
  kind: 'execution_pending';
76
104
  protocol: PaidProtocol;
@@ -79,6 +107,7 @@ export type ExecutionPendingPaidResponse = PaidResponseBase & {
79
107
  reason: string;
80
108
  decision: ExecutingDecision;
81
109
  };
110
+ /** Failure result when the merchant/control plane could not prove a final outcome. */
82
111
  export type ExecutionInconclusivePaidResponse = PaidResponseBase & {
83
112
  kind: 'execution_inconclusive';
84
113
  protocol: PaidProtocol;
@@ -87,6 +116,7 @@ export type ExecutionInconclusivePaidResponse = PaidResponseBase & {
87
116
  reason: string;
88
117
  decision: InconclusiveDecision;
89
118
  };
119
+ /** Failure result when paid execution started but ended in a hard failure. */
90
120
  export type ExecutionFailedPaidResponse = PaidResponseBase & {
91
121
  kind: 'execution_failed';
92
122
  protocol: PaidProtocol;
@@ -95,6 +125,7 @@ export type ExecutionFailedPaidResponse = PaidResponseBase & {
95
125
  reason: string;
96
126
  decision: ExecutionFailedDecision;
97
127
  };
128
+ /** Failure result when the request could not proceed on the selected payment rail. */
98
129
  export type PreflightFailedPaidResponse = PaidResponseBase & {
99
130
  kind: 'preflight_failed';
100
131
  protocol: PaidProtocol;
@@ -103,16 +134,77 @@ export type PreflightFailedPaidResponse = PaidResponseBase & {
103
134
  reason: string;
104
135
  decision: PreflightFailedDecision;
105
136
  };
106
- export type PaidResponse = PassthroughPaidResponse | SuccessPaidResponse | PaidFulfillmentFailedResponse | DeniedPaidResponse | ExecutionPendingPaidResponse | ExecutionInconclusivePaidResponse | ExecutionFailedPaidResponse | PreflightFailedPaidResponse;
137
+ /** Failure result when the control-plane response itself could not be trusted as valid SDK output. */
138
+ export type RequestFailedPaidResponse = PaidResponseBase & {
139
+ kind: 'request_failed';
140
+ protocol: PaidProtocol;
141
+ reason: string;
142
+ decision: RequestFailedDecision;
143
+ };
144
+ export type FetchPaidFailureResponse = PaidFulfillmentFailedResponse | DeniedPaidResponse | ExecutionPendingPaidResponse | ExecutionInconclusivePaidResponse | ExecutionFailedPaidResponse | PreflightFailedPaidResponse | RequestFailedPaidResponse;
145
+ export type PaidResponse = PassthroughPaidResponse | SuccessPaidResponse;
146
+ /**
147
+ * Thrown for all non-success paid outcomes. The original typed failure payload is
148
+ * preserved on details so callers can branch on kind without reparsing responses.
149
+ */
150
+ export declare class FetchPaidError<TResponse extends FetchPaidFailureResponse = FetchPaidFailureResponse> extends Error {
151
+ readonly details: TResponse;
152
+ readonly kind: TResponse['kind'];
153
+ readonly protocol: TResponse['protocol'];
154
+ readonly response: Response;
155
+ readonly reason: string;
156
+ readonly decision: TResponse['decision'];
157
+ readonly paidRequestId: string | undefined;
158
+ readonly paymentAttemptId: string | undefined;
159
+ readonly receiptId: string | undefined;
160
+ readonly receipt: SdkReceipt | undefined;
161
+ readonly policyReviewEventId: string | undefined;
162
+ constructor(details: TResponse);
163
+ }
164
+ /** Type guard for callers that catch unknown errors around fetchPaid flows. */
165
+ export declare function isFetchPaidError(error: unknown): error is FetchPaidError;
166
+ /** Returns true when a request body can be replayed exactly across paid flows. */
167
+ export declare function isReplayableRequestBody(body: RequestInit['body']): body is ReplayableRequestBody;
168
+ /** Serialize a paid-flow request body into the exact replayable wire representation. */
169
+ export declare function toReplayableRequestBody(body: RequestInit['body']): string | undefined;
170
+ /** Helper for callers that want an explicit JSON-string body for paid flows. */
171
+ export declare function createJsonRequestBody(payload: unknown): string;
172
+ type FormUrlEncodedValue = string | number | boolean;
173
+ type FormUrlEncodedBodyInit = Record<string, FormUrlEncodedValue | readonly FormUrlEncodedValue[]>;
174
+ /** Helper for callers that want a replayable form body for paid flows. */
175
+ export declare function createFormUrlEncodedBody(values: FormUrlEncodedBodyInit): URLSearchParams;
176
+ /**
177
+ * Client bound to one organization/agent identity and one 402flow control plane.
178
+ *
179
+ * Most integrations either call fetchPaid() directly or use the explicit
180
+ * preparePaidRequest() -> executePreparedRequest() flow.
181
+ */
107
182
  export declare class AgentPayClient {
108
183
  private readonly controlPlaneBaseUrl;
109
184
  private readonly auth;
185
+ private readonly identity;
110
186
  private readonly fetchImpl;
111
187
  private readonly headers;
112
188
  private cachedRuntimeToken;
113
189
  private pendingRuntimeToken;
114
190
  constructor(options: AgentPayClientOptions);
115
- fetchPaid(input: string, init: RequestInit | undefined, context: PaidRequestContext, options: FetchPaidOptions): Promise<PaidResponse>;
191
+ /**
192
+ * Probe or reuse a merchant challenge and return a normalized preparation
193
+ * result the caller can inspect before paying.
194
+ */
195
+ preparePaidRequest(input: string, init?: RequestInit, options?: PreparePaidRequestOptions): Promise<SdkPreparedPaidRequest>;
196
+ /**
197
+ * Execute the exact request that was previously prepared, without re-probing
198
+ * the merchant first.
199
+ */
200
+ executePreparedRequest(prepared: SdkPreparedPaidRequestReady, request?: ExecutePreparedRequest): Promise<PaidResponse>;
201
+ /**
202
+ * Fast-path helper that probes when needed, asks the control plane for a paid
203
+ * execution decision, and returns either passthrough or success. All non-success
204
+ * paid outcomes are thrown as FetchPaidError.
205
+ */
206
+ fetchPaid(input: string, init: RequestInit | undefined, request: FetchPaidRequest): Promise<PaidResponse>;
207
+ /** Lookup a durable receipt by id through the control plane. */
116
208
  lookupReceipt(receiptId: string): Promise<SdkReceiptResponse>;
117
209
  private createDecisionRequest;
118
210
  private requestPaymentDecision;
@@ -122,5 +214,10 @@ export declare class AgentPayClient {
122
214
  private requestRuntimeToken;
123
215
  private controlPlaneFetch;
124
216
  }
217
+ /** Small factory wrapper for callers that prefer a function export. */
125
218
  export declare function createAgentPayClient(options: AgentPayClientOptions): AgentPayClient;
126
- export {};
219
+ export * from './agent-harness.js';
220
+ export * from './contracts.js';
221
+ export * from './harness-instructions.js';
222
+ export { detectChallengeFromResponse, type DetectedChallenge } from './challenge-detection.js';
223
+ export { sdkClientVersion, sdkClientVersionHeaderName } from './version.js';