@proxy-checkout/server-js 0.0.7 → 0.0.8-prx-109.80.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 CHANGED
@@ -35,7 +35,11 @@ const proxy = createProxyCheckoutServerClient({
35
35
 
36
36
  const handoff = await proxy.sessions.createHandoff({
37
37
  amountMinor: 5000,
38
+ // Stable, non-PII entitlement owner reference. For pre-account flows,
39
+ // use a pending entitlement id instead of an email address.
38
40
  buyerReference: "buyer_123",
41
+ // Optional beneficiary contact for the person receiving access.
42
+ beneficiaryContact: { email: "student@example.com" },
39
43
  currency: "usd",
40
44
  cartSnapshot: {
41
45
  items: [{ product_id: "prod_123", quantity: 1 }],
@@ -70,6 +74,27 @@ For delegated checkout, prefer the high-level flow:
70
74
 
71
75
  Use `payerHandoff`, `payerOpened`, raw event construction, or manual provisioning acknowledgements only for custom integrations that cannot use the default helpers.
72
76
 
77
+ `proxy.webhooks.handle(...)` automatically marks successful initial provisioning as provisioned after `onResolved` completes. Return a fulfillment reference and/or metadata from `onResolved` when you want that acknowledgement to record the merchant-side access row:
78
+
79
+ ```ts
80
+ await proxy.webhooks.handle(request, {
81
+ secret: process.env.PROXY_WEBHOOK_SIGNING_SECRET!,
82
+ async onResolved(resolved) {
83
+ if (resolved.kind !== "initial_provision") {
84
+ return;
85
+ }
86
+
87
+ const entitlement = await grantOrMarkPending(resolved.session);
88
+ return {
89
+ fulfillmentReference: entitlement.id,
90
+ metadata: { claim_status: entitlement.profileId ? "claimed" : "pending_account_claim" },
91
+ };
92
+ },
93
+ });
94
+ ```
95
+
96
+ For pre-account purchases, create a durable pending entitlement before `sessions.createHandoff(...)`, use that pending entitlement id as `buyerReference`, pass the future student's contact as `beneficiaryContact`, and claim the entitlement after signup/login with your own high-entropy claim token. Treat `proxy_session_id` as public correlation, not as a claim secret.
97
+
73
98
  Verify and parse outbound webhooks with the exact raw request body:
74
99
 
75
100
  ```ts
@@ -9,5 +9,5 @@ export { type MerchantProxySubscription, ProxySubscriptionsResource, type ProxyS
9
9
  export type { JsonObject, JsonPrimitive, JsonValue, ProxyCheckoutFetch, ProxyCheckoutServerClientOptions, ProxyCheckoutServerRequestOptions, } from "./types.js";
10
10
  export { proxyCheckoutServerSdkName, proxyCheckoutServerSdkUserAgent, proxyCheckoutServerSdkVersion, } from "./version.js";
11
11
  export { isProxyPaymentAttemptEvent, isProxySessionEvent, isProxySubscriptionEvent, PROXY_WEBHOOK_EVENT_TYPES, type ProxyWebhookEventType, } from "./webhook-events.js";
12
- export { PROXY_WEBHOOK_RETRY_AFTER_SECONDS, type ProxyWebhookClaimResult, type ProxyWebhookHandlerOptions, type ProxyWebhookOutcome, type ProxyWebhookPayloadInput, type ProxyWebhookProcessRecord, type ProxyWebhookProcessResult, type ProxyWebhookProvisioningFailure, type ProxyWebhookRequestInput, type ProxyWebhookStore, ProxyWebhooksResource, } from "./webhook-handler.js";
12
+ export { PROXY_WEBHOOK_RETRY_AFTER_SECONDS, type ProxyWebhookClaimResult, type ProxyWebhookHandlerOptions, type ProxyWebhookOutcome, type ProxyWebhookPayloadInput, type ProxyWebhookProcessRecord, type ProxyWebhookProcessResult, type ProxyWebhookProvisioningFailure, type ProxyWebhookProvisioningSuccess, type ProxyWebhookProvisioningSuccessResult, type ProxyWebhookRequestInput, type ProxyWebhookStore, ProxyWebhooksResource, } from "./webhook-handler.js";
13
13
  export { type ConstructProxyWebhookEventInput, type CreateWebhookEndpointInput, constructProxyWebhookEvent, PROXY_SIGNATURE_HEADER, ProxyWebhookEndpointsResource, type ProxyWebhookEvent, ProxyWebhookSignatureVerificationError, proxyCheckoutWebhookEndpointEndpoints, type RotateWebhookEndpointSecretInput, type UpdateWebhookEndpointInput, type VerifyProxyWebhookSignatureInput, verifyProxyWebhookSignature, type WebhookEndpoint, type WebhookEndpointSecretResult, } from "./webhooks.js";
@@ -9,5 +9,5 @@ export { type MerchantProxySubscription, ProxySubscriptionsResource, type ProxyS
9
9
  export type { JsonObject, JsonPrimitive, JsonValue, ProxyCheckoutFetch, ProxyCheckoutServerClientOptions, ProxyCheckoutServerRequestOptions, } from "./types.js";
10
10
  export { proxyCheckoutServerSdkName, proxyCheckoutServerSdkUserAgent, proxyCheckoutServerSdkVersion, } from "./version.js";
11
11
  export { isProxyPaymentAttemptEvent, isProxySessionEvent, isProxySubscriptionEvent, PROXY_WEBHOOK_EVENT_TYPES, type ProxyWebhookEventType, } from "./webhook-events.js";
12
- export { PROXY_WEBHOOK_RETRY_AFTER_SECONDS, type ProxyWebhookClaimResult, type ProxyWebhookHandlerOptions, type ProxyWebhookOutcome, type ProxyWebhookPayloadInput, type ProxyWebhookProcessRecord, type ProxyWebhookProcessResult, type ProxyWebhookProvisioningFailure, type ProxyWebhookRequestInput, type ProxyWebhookStore, ProxyWebhooksResource, } from "./webhook-handler.js";
12
+ export { PROXY_WEBHOOK_RETRY_AFTER_SECONDS, type ProxyWebhookClaimResult, type ProxyWebhookHandlerOptions, type ProxyWebhookOutcome, type ProxyWebhookPayloadInput, type ProxyWebhookProcessRecord, type ProxyWebhookProcessResult, type ProxyWebhookProvisioningFailure, type ProxyWebhookProvisioningSuccess, type ProxyWebhookProvisioningSuccessResult, type ProxyWebhookRequestInput, type ProxyWebhookStore, ProxyWebhooksResource, } from "./webhook-handler.js";
13
13
  export { type ConstructProxyWebhookEventInput, type CreateWebhookEndpointInput, constructProxyWebhookEvent, PROXY_SIGNATURE_HEADER, ProxyWebhookEndpointsResource, type ProxyWebhookEvent, ProxyWebhookSignatureVerificationError, proxyCheckoutWebhookEndpointEndpoints, type RotateWebhookEndpointSecretInput, type UpdateWebhookEndpointInput, type VerifyProxyWebhookSignatureInput, verifyProxyWebhookSignature, type WebhookEndpoint, type WebhookEndpointSecretResult, } from "./webhooks.js";
@@ -6,6 +6,10 @@ export interface CreateProxySessionOptions extends ProxyCheckoutServerRequestOpt
6
6
  }
7
7
  export interface CreateProxySessionInput extends CreateProxySessionOptions {
8
8
  readonly amountMinor: number;
9
+ readonly beneficiaryContact?: {
10
+ readonly email?: string;
11
+ readonly phone?: string;
12
+ };
9
13
  readonly buyerReference: string;
10
14
  readonly cartSnapshot: JsonObject;
11
15
  readonly currency: string;
@@ -34,6 +38,10 @@ export interface ProxySessionHandoff extends ProxySession {
34
38
  }
35
39
  export interface MerchantProxySession {
36
40
  readonly amountMinor: number;
41
+ readonly beneficiaryContact: {
42
+ readonly email: string | null;
43
+ readonly phone: string | null;
44
+ } | null;
37
45
  readonly buyerReference: string;
38
46
  readonly cartSnapshot: JsonObject;
39
47
  readonly cartVersion: number;
@@ -6,6 +6,10 @@ export interface CreateProxySessionOptions extends ProxyCheckoutServerRequestOpt
6
6
  }
7
7
  export interface CreateProxySessionInput extends CreateProxySessionOptions {
8
8
  readonly amountMinor: number;
9
+ readonly beneficiaryContact?: {
10
+ readonly email?: string;
11
+ readonly phone?: string;
12
+ };
9
13
  readonly buyerReference: string;
10
14
  readonly cartSnapshot: JsonObject;
11
15
  readonly currency: string;
@@ -34,6 +38,10 @@ export interface ProxySessionHandoff extends ProxySession {
34
38
  }
35
39
  export interface MerchantProxySession {
36
40
  readonly amountMinor: number;
41
+ readonly beneficiaryContact: {
42
+ readonly email: string | null;
43
+ readonly phone: string | null;
44
+ } | null;
37
45
  readonly buyerReference: string;
38
46
  readonly cartSnapshot: JsonObject;
39
47
  readonly cartVersion: number;
@@ -196,6 +196,12 @@ function toCreateProxySessionBody(input) {
196
196
  cart_snapshot: input.cartSnapshot,
197
197
  currency: input.currency,
198
198
  };
199
+ if (input.beneficiaryContact !== undefined) {
200
+ body.beneficiary_contact = removeUndefinedValues({
201
+ email: input.beneficiaryContact.email,
202
+ phone: input.beneficiaryContact.phone,
203
+ });
204
+ }
199
205
  if (input.expiresAt !== undefined) {
200
206
  body.expires_at =
201
207
  input.expiresAt instanceof Date ? input.expiresAt.toISOString() : input.expiresAt;
@@ -256,6 +262,7 @@ function toMerchantProxySession(response) {
256
262
  const body = (0, response_validators_js_1.requireJsonObject)(response, "sessions.retrieve");
257
263
  return {
258
264
  amountMinor: (0, response_validators_js_1.requireInteger)(body.amount_minor, "sessions.retrieve.amountMinor"),
265
+ beneficiaryContact: requireNullableContact(body.beneficiary_contact, "sessions.retrieve.beneficiaryContact"),
259
266
  buyerReference: (0, response_validators_js_1.requireString)(body.buyer_reference, "sessions.retrieve.buyerReference"),
260
267
  cartSnapshot: (0, response_validators_js_1.requireJsonObject)(body.cart_snapshot, "sessions.retrieve.cartSnapshot"),
261
268
  cartVersion: (0, response_validators_js_1.requireInteger)(body.cart_version, "sessions.retrieve.cartVersion"),
@@ -266,7 +273,7 @@ function toMerchantProxySession(response) {
266
273
  idempotencyKey: (0, response_validators_js_1.requireNullableString)(body.idempotency_key, "sessions.retrieve.idempotencyKey"),
267
274
  integrationMode: (0, response_validators_js_1.requireString)(body.integration_mode, "sessions.retrieve.integrationMode"),
268
275
  metadata: (0, response_validators_js_1.requireJsonObject)(body.metadata, "sessions.retrieve.metadata"),
269
- payerContact: requireNullablePayerContact(body.payer_contact),
276
+ payerContact: requireNullableContact(body.payer_contact, "sessions.retrieve.payerContact"),
270
277
  payerDestinationUrl: (0, response_validators_js_1.requireNullableString)(body.payer_destination_url, "sessions.retrieve.payerDestinationUrl"),
271
278
  providerCheckoutSessionId: (0, response_validators_js_1.requireNullableString)(body.provider_checkout_session_id, "sessions.retrieve.providerCheckoutSessionId"),
272
279
  providerCheckoutSessionPsp: (0, response_validators_js_1.requireNullableString)(body.provider_checkout_session_psp, "sessions.retrieve.providerCheckoutSessionPsp"),
@@ -282,6 +289,7 @@ function toPayerOpenedResult(response) {
282
289
  }
283
290
  return {
284
291
  amountMinor: (0, response_validators_js_1.requireInteger)(body.amount_minor, "sessions.payerOpened.amountMinor"),
292
+ beneficiaryContact: requireNullableContact(body.beneficiary_contact, "sessions.payerOpened.beneficiaryContact"),
285
293
  buyerReference: (0, response_validators_js_1.requireString)(body.buyer_reference, "sessions.payerOpened.buyerReference"),
286
294
  cartSnapshot: (0, response_validators_js_1.requireJsonObject)(body.cart_snapshot, "sessions.payerOpened.cartSnapshot"),
287
295
  cartVersion: (0, response_validators_js_1.requireInteger)(body.cart_version, "sessions.payerOpened.cartVersion"),
@@ -292,7 +300,7 @@ function toPayerOpenedResult(response) {
292
300
  idempotencyKey: (0, response_validators_js_1.requireNullableString)(body.idempotency_key, "sessions.payerOpened.idempotencyKey"),
293
301
  integrationMode: (0, response_validators_js_1.requireString)(body.integration_mode, "sessions.payerOpened.integrationMode"),
294
302
  metadata: (0, response_validators_js_1.requireJsonObject)(body.metadata, "sessions.payerOpened.metadata"),
295
- payerContact: requireNullablePayerContact(body.payer_contact, "sessions.payerOpened"),
303
+ payerContact: requireNullableContact(body.payer_contact, "sessions.payerOpened.payerContact"),
296
304
  payerDestinationUrl: (0, response_validators_js_1.requireNullableString)(body.payer_destination_url, "sessions.payerOpened.payerDestinationUrl"),
297
305
  providerCheckoutSessionId: (0, response_validators_js_1.requireNullableString)(body.provider_checkout_session_id, "sessions.payerOpened.providerCheckoutSessionId"),
298
306
  providerCheckoutSessionPsp: (0, response_validators_js_1.requireNullableString)(body.provider_checkout_session_psp, "sessions.payerOpened.providerCheckoutSessionPsp"),
@@ -300,14 +308,14 @@ function toPayerOpenedResult(response) {
300
308
  updatedAt: (0, response_validators_js_1.requireString)(body.updated_at, "sessions.payerOpened.updatedAt"),
301
309
  };
302
310
  }
303
- function requireNullablePayerContact(value, operation = "sessions.retrieve") {
304
- if (value === null) {
311
+ function requireNullableContact(value, field) {
312
+ if (value === null || value === undefined) {
305
313
  return null;
306
314
  }
307
- const contact = (0, response_validators_js_1.requireJsonObject)(value, `${operation}.payerContact`);
315
+ const contact = (0, response_validators_js_1.requireJsonObject)(value, field);
308
316
  return {
309
- email: (0, response_validators_js_1.requireNullableString)(contact.email, `${operation}.payerContact.email`),
310
- phone: (0, response_validators_js_1.requireNullableString)(contact.phone, `${operation}.payerContact.phone`),
317
+ email: (0, response_validators_js_1.requireNullableString)(contact.email, `${field}.email`),
318
+ phone: (0, response_validators_js_1.requireNullableString)(contact.phone, `${field}.phone`),
311
319
  };
312
320
  }
313
321
  function requirePayerHandoffStatus(value) {
@@ -1,3 +1,3 @@
1
1
  export declare const proxyCheckoutServerSdkName = "@proxy-checkout/server-js";
2
- export declare const proxyCheckoutServerSdkVersion = "0.0.7";
3
- export declare const proxyCheckoutServerSdkUserAgent = "@proxy-checkout/server-js/0.0.7";
2
+ export declare const proxyCheckoutServerSdkVersion = "0.0.8-prx-109.80.1";
3
+ export declare const proxyCheckoutServerSdkUserAgent = "@proxy-checkout/server-js/0.0.8-prx-109.80.1";
@@ -1,3 +1,3 @@
1
1
  export declare const proxyCheckoutServerSdkName = "@proxy-checkout/server-js";
2
- export declare const proxyCheckoutServerSdkVersion = "0.0.7";
3
- export declare const proxyCheckoutServerSdkUserAgent = "@proxy-checkout/server-js/0.0.7";
2
+ export declare const proxyCheckoutServerSdkVersion = "0.0.8-prx-109.80.1";
3
+ export declare const proxyCheckoutServerSdkUserAgent = "@proxy-checkout/server-js/0.0.8-prx-109.80.1";
@@ -2,5 +2,5 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.proxyCheckoutServerSdkUserAgent = exports.proxyCheckoutServerSdkVersion = exports.proxyCheckoutServerSdkName = void 0;
4
4
  exports.proxyCheckoutServerSdkName = "@proxy-checkout/server-js";
5
- exports.proxyCheckoutServerSdkVersion = "0.0.7";
5
+ exports.proxyCheckoutServerSdkVersion = "0.0.8-prx-109.80.1";
6
6
  exports.proxyCheckoutServerSdkUserAgent = `${exports.proxyCheckoutServerSdkName}/${exports.proxyCheckoutServerSdkVersion}`;
@@ -40,6 +40,11 @@ export interface ProxyWebhookProvisioningFailure {
40
40
  readonly errorMessage: string;
41
41
  readonly metadata?: JsonObject;
42
42
  }
43
+ export interface ProxyWebhookProvisioningSuccess {
44
+ readonly fulfillmentReference?: string;
45
+ readonly metadata?: JsonObject;
46
+ }
47
+ export type ProxyWebhookProvisioningSuccessResult = ProxyWebhookProvisioningSuccess | null | undefined;
43
48
  export interface ProxyWebhookPayloadInput {
44
49
  readonly body: Buffer | string;
45
50
  readonly signature?: string | null;
@@ -56,8 +61,12 @@ export interface ProxyWebhookHandlerOptions {
56
61
  * failure payload only after the merchant knows retrying cannot grant access.
57
62
  */
58
63
  readonly classifyProvisioningFailure?: (error: unknown, resolved: ResolvedProxyEvent) => Promise<ProxyWebhookProvisioningFailure | null | undefined> | ProxyWebhookProvisioningFailure | null | undefined;
59
- /** Merchant entitlement callback, invoked once per claimed event after current-state resolution. */
60
- readonly onResolved: (resolved: ResolvedProxyEvent) => Promise<void> | void;
64
+ /**
65
+ * Merchant entitlement callback, invoked once per claimed event after
66
+ * current-state resolution. For initial provisioning, return a fulfillment
67
+ * reference and/or metadata to record on Proxy's provisioned acknowledgement.
68
+ */
69
+ readonly onResolved: (resolved: ResolvedProxyEvent) => Promise<ProxyWebhookProvisioningSuccessResult> | ProxyWebhookProvisioningSuccessResult;
61
70
  /** Optional request id forwarded to the current-state retrieval calls. */
62
71
  readonly requestId?: string;
63
72
  /** Endpoint signing secret. */
@@ -40,6 +40,11 @@ export interface ProxyWebhookProvisioningFailure {
40
40
  readonly errorMessage: string;
41
41
  readonly metadata?: JsonObject;
42
42
  }
43
+ export interface ProxyWebhookProvisioningSuccess {
44
+ readonly fulfillmentReference?: string;
45
+ readonly metadata?: JsonObject;
46
+ }
47
+ export type ProxyWebhookProvisioningSuccessResult = ProxyWebhookProvisioningSuccess | null | undefined;
43
48
  export interface ProxyWebhookPayloadInput {
44
49
  readonly body: Buffer | string;
45
50
  readonly signature?: string | null;
@@ -56,8 +61,12 @@ export interface ProxyWebhookHandlerOptions {
56
61
  * failure payload only after the merchant knows retrying cannot grant access.
57
62
  */
58
63
  readonly classifyProvisioningFailure?: (error: unknown, resolved: ResolvedProxyEvent) => Promise<ProxyWebhookProvisioningFailure | null | undefined> | ProxyWebhookProvisioningFailure | null | undefined;
59
- /** Merchant entitlement callback, invoked once per claimed event after current-state resolution. */
60
- readonly onResolved: (resolved: ResolvedProxyEvent) => Promise<void> | void;
64
+ /**
65
+ * Merchant entitlement callback, invoked once per claimed event after
66
+ * current-state resolution. For initial provisioning, return a fulfillment
67
+ * reference and/or metadata to record on Proxy's provisioned acknowledgement.
68
+ */
69
+ readonly onResolved: (resolved: ResolvedProxyEvent) => Promise<ProxyWebhookProvisioningSuccessResult> | ProxyWebhookProvisioningSuccessResult;
61
70
  /** Optional request id forwarded to the current-state retrieval calls. */
62
71
  readonly requestId?: string;
63
72
  /** Endpoint signing secret. */
@@ -64,9 +64,11 @@ class ProxyWebhooksResource {
64
64
  let resolved;
65
65
  try {
66
66
  resolved = await this.events.resolveCurrentState(event, { requestId: options.requestId });
67
- const provisioningFailed = await this.runResolvedHandler(resolved, options);
68
- if (!provisioningFailed && resolved.kind === "initial_provision") {
67
+ const provisioning = await this.runResolvedHandler(resolved, options);
68
+ if (!provisioning.failed && resolved.kind === "initial_provision") {
69
69
  await this.requireSessionsResource("mark provisioned").markProvisioned(resolved.session.id, {
70
+ fulfillmentReference: provisioning.success?.fulfillmentReference,
71
+ metadata: provisioning.success?.metadata,
70
72
  requestId: options.requestId,
71
73
  });
72
74
  }
@@ -130,8 +132,11 @@ class ProxyWebhooksResource {
130
132
  }
131
133
  async runResolvedHandler(resolved, options) {
132
134
  try {
133
- await options.onResolved(resolved);
134
- return false;
135
+ const success = await options.onResolved(resolved);
136
+ return {
137
+ failed: false,
138
+ success: normalizeProvisioningSuccess(success),
139
+ };
135
140
  }
136
141
  catch (error) {
137
142
  if (resolved.kind !== "initial_provision" || !options.classifyProvisioningFailure) {
@@ -147,7 +152,7 @@ class ProxyWebhooksResource {
147
152
  metadata: failure.metadata,
148
153
  requestId: options.requestId,
149
154
  });
150
- return true;
155
+ return { failed: true };
151
156
  }
152
157
  }
153
158
  requireSessionsResource(operation) {
@@ -160,6 +165,21 @@ class ProxyWebhooksResource {
160
165
  }
161
166
  }
162
167
  exports.ProxyWebhooksResource = ProxyWebhooksResource;
168
+ function normalizeProvisioningSuccess(value) {
169
+ if (value == null) {
170
+ return undefined;
171
+ }
172
+ const success = {};
173
+ if (value.fulfillmentReference !== undefined) {
174
+ success.fulfillmentReference = value.fulfillmentReference;
175
+ }
176
+ if (value.metadata !== undefined) {
177
+ success.metadata = value.metadata;
178
+ }
179
+ return success.fulfillmentReference === undefined && success.metadata === undefined
180
+ ? undefined
181
+ : success;
182
+ }
163
183
  function toWebhookResponse(result) {
164
184
  const headers = { "content-type": "application/json" };
165
185
  if (result.retryable) {
@@ -9,5 +9,5 @@ export { type MerchantProxySubscription, ProxySubscriptionsResource, type ProxyS
9
9
  export type { JsonObject, JsonPrimitive, JsonValue, ProxyCheckoutFetch, ProxyCheckoutServerClientOptions, ProxyCheckoutServerRequestOptions, } from "./types.js";
10
10
  export { proxyCheckoutServerSdkName, proxyCheckoutServerSdkUserAgent, proxyCheckoutServerSdkVersion, } from "./version.js";
11
11
  export { isProxyPaymentAttemptEvent, isProxySessionEvent, isProxySubscriptionEvent, PROXY_WEBHOOK_EVENT_TYPES, type ProxyWebhookEventType, } from "./webhook-events.js";
12
- export { PROXY_WEBHOOK_RETRY_AFTER_SECONDS, type ProxyWebhookClaimResult, type ProxyWebhookHandlerOptions, type ProxyWebhookOutcome, type ProxyWebhookPayloadInput, type ProxyWebhookProcessRecord, type ProxyWebhookProcessResult, type ProxyWebhookProvisioningFailure, type ProxyWebhookRequestInput, type ProxyWebhookStore, ProxyWebhooksResource, } from "./webhook-handler.js";
12
+ export { PROXY_WEBHOOK_RETRY_AFTER_SECONDS, type ProxyWebhookClaimResult, type ProxyWebhookHandlerOptions, type ProxyWebhookOutcome, type ProxyWebhookPayloadInput, type ProxyWebhookProcessRecord, type ProxyWebhookProcessResult, type ProxyWebhookProvisioningFailure, type ProxyWebhookProvisioningSuccess, type ProxyWebhookProvisioningSuccessResult, type ProxyWebhookRequestInput, type ProxyWebhookStore, ProxyWebhooksResource, } from "./webhook-handler.js";
13
13
  export { type ConstructProxyWebhookEventInput, type CreateWebhookEndpointInput, constructProxyWebhookEvent, PROXY_SIGNATURE_HEADER, ProxyWebhookEndpointsResource, type ProxyWebhookEvent, ProxyWebhookSignatureVerificationError, proxyCheckoutWebhookEndpointEndpoints, type RotateWebhookEndpointSecretInput, type UpdateWebhookEndpointInput, type VerifyProxyWebhookSignatureInput, verifyProxyWebhookSignature, type WebhookEndpoint, type WebhookEndpointSecretResult, } from "./webhooks.js";
@@ -6,6 +6,10 @@ export interface CreateProxySessionOptions extends ProxyCheckoutServerRequestOpt
6
6
  }
7
7
  export interface CreateProxySessionInput extends CreateProxySessionOptions {
8
8
  readonly amountMinor: number;
9
+ readonly beneficiaryContact?: {
10
+ readonly email?: string;
11
+ readonly phone?: string;
12
+ };
9
13
  readonly buyerReference: string;
10
14
  readonly cartSnapshot: JsonObject;
11
15
  readonly currency: string;
@@ -34,6 +38,10 @@ export interface ProxySessionHandoff extends ProxySession {
34
38
  }
35
39
  export interface MerchantProxySession {
36
40
  readonly amountMinor: number;
41
+ readonly beneficiaryContact: {
42
+ readonly email: string | null;
43
+ readonly phone: string | null;
44
+ } | null;
37
45
  readonly buyerReference: string;
38
46
  readonly cartSnapshot: JsonObject;
39
47
  readonly cartVersion: number;
@@ -191,6 +191,12 @@ function toCreateProxySessionBody(input) {
191
191
  cart_snapshot: input.cartSnapshot,
192
192
  currency: input.currency,
193
193
  };
194
+ if (input.beneficiaryContact !== undefined) {
195
+ body.beneficiary_contact = removeUndefinedValues({
196
+ email: input.beneficiaryContact.email,
197
+ phone: input.beneficiaryContact.phone,
198
+ });
199
+ }
194
200
  if (input.expiresAt !== undefined) {
195
201
  body.expires_at =
196
202
  input.expiresAt instanceof Date ? input.expiresAt.toISOString() : input.expiresAt;
@@ -251,6 +257,7 @@ function toMerchantProxySession(response) {
251
257
  const body = requireJsonObject(response, "sessions.retrieve");
252
258
  return {
253
259
  amountMinor: requireInteger(body.amount_minor, "sessions.retrieve.amountMinor"),
260
+ beneficiaryContact: requireNullableContact(body.beneficiary_contact, "sessions.retrieve.beneficiaryContact"),
254
261
  buyerReference: requireString(body.buyer_reference, "sessions.retrieve.buyerReference"),
255
262
  cartSnapshot: requireJsonObject(body.cart_snapshot, "sessions.retrieve.cartSnapshot"),
256
263
  cartVersion: requireInteger(body.cart_version, "sessions.retrieve.cartVersion"),
@@ -261,7 +268,7 @@ function toMerchantProxySession(response) {
261
268
  idempotencyKey: requireNullableString(body.idempotency_key, "sessions.retrieve.idempotencyKey"),
262
269
  integrationMode: requireString(body.integration_mode, "sessions.retrieve.integrationMode"),
263
270
  metadata: requireJsonObject(body.metadata, "sessions.retrieve.metadata"),
264
- payerContact: requireNullablePayerContact(body.payer_contact),
271
+ payerContact: requireNullableContact(body.payer_contact, "sessions.retrieve.payerContact"),
265
272
  payerDestinationUrl: requireNullableString(body.payer_destination_url, "sessions.retrieve.payerDestinationUrl"),
266
273
  providerCheckoutSessionId: requireNullableString(body.provider_checkout_session_id, "sessions.retrieve.providerCheckoutSessionId"),
267
274
  providerCheckoutSessionPsp: requireNullableString(body.provider_checkout_session_psp, "sessions.retrieve.providerCheckoutSessionPsp"),
@@ -277,6 +284,7 @@ function toPayerOpenedResult(response) {
277
284
  }
278
285
  return {
279
286
  amountMinor: requireInteger(body.amount_minor, "sessions.payerOpened.amountMinor"),
287
+ beneficiaryContact: requireNullableContact(body.beneficiary_contact, "sessions.payerOpened.beneficiaryContact"),
280
288
  buyerReference: requireString(body.buyer_reference, "sessions.payerOpened.buyerReference"),
281
289
  cartSnapshot: requireJsonObject(body.cart_snapshot, "sessions.payerOpened.cartSnapshot"),
282
290
  cartVersion: requireInteger(body.cart_version, "sessions.payerOpened.cartVersion"),
@@ -287,7 +295,7 @@ function toPayerOpenedResult(response) {
287
295
  idempotencyKey: requireNullableString(body.idempotency_key, "sessions.payerOpened.idempotencyKey"),
288
296
  integrationMode: requireString(body.integration_mode, "sessions.payerOpened.integrationMode"),
289
297
  metadata: requireJsonObject(body.metadata, "sessions.payerOpened.metadata"),
290
- payerContact: requireNullablePayerContact(body.payer_contact, "sessions.payerOpened"),
298
+ payerContact: requireNullableContact(body.payer_contact, "sessions.payerOpened.payerContact"),
291
299
  payerDestinationUrl: requireNullableString(body.payer_destination_url, "sessions.payerOpened.payerDestinationUrl"),
292
300
  providerCheckoutSessionId: requireNullableString(body.provider_checkout_session_id, "sessions.payerOpened.providerCheckoutSessionId"),
293
301
  providerCheckoutSessionPsp: requireNullableString(body.provider_checkout_session_psp, "sessions.payerOpened.providerCheckoutSessionPsp"),
@@ -295,14 +303,14 @@ function toPayerOpenedResult(response) {
295
303
  updatedAt: requireString(body.updated_at, "sessions.payerOpened.updatedAt"),
296
304
  };
297
305
  }
298
- function requireNullablePayerContact(value, operation = "sessions.retrieve") {
299
- if (value === null) {
306
+ function requireNullableContact(value, field) {
307
+ if (value === null || value === undefined) {
300
308
  return null;
301
309
  }
302
- const contact = requireJsonObject(value, `${operation}.payerContact`);
310
+ const contact = requireJsonObject(value, field);
303
311
  return {
304
- email: requireNullableString(contact.email, `${operation}.payerContact.email`),
305
- phone: requireNullableString(contact.phone, `${operation}.payerContact.phone`),
312
+ email: requireNullableString(contact.email, `${field}.email`),
313
+ phone: requireNullableString(contact.phone, `${field}.phone`),
306
314
  };
307
315
  }
308
316
  function requirePayerHandoffStatus(value) {
@@ -1,3 +1,3 @@
1
1
  export declare const proxyCheckoutServerSdkName = "@proxy-checkout/server-js";
2
- export declare const proxyCheckoutServerSdkVersion = "0.0.7";
3
- export declare const proxyCheckoutServerSdkUserAgent = "@proxy-checkout/server-js/0.0.7";
2
+ export declare const proxyCheckoutServerSdkVersion = "0.0.8-prx-109.80.1";
3
+ export declare const proxyCheckoutServerSdkUserAgent = "@proxy-checkout/server-js/0.0.8-prx-109.80.1";
@@ -1,3 +1,3 @@
1
1
  export const proxyCheckoutServerSdkName = "@proxy-checkout/server-js";
2
- export const proxyCheckoutServerSdkVersion = "0.0.7";
2
+ export const proxyCheckoutServerSdkVersion = "0.0.8-prx-109.80.1";
3
3
  export const proxyCheckoutServerSdkUserAgent = `${proxyCheckoutServerSdkName}/${proxyCheckoutServerSdkVersion}`;
@@ -40,6 +40,11 @@ export interface ProxyWebhookProvisioningFailure {
40
40
  readonly errorMessage: string;
41
41
  readonly metadata?: JsonObject;
42
42
  }
43
+ export interface ProxyWebhookProvisioningSuccess {
44
+ readonly fulfillmentReference?: string;
45
+ readonly metadata?: JsonObject;
46
+ }
47
+ export type ProxyWebhookProvisioningSuccessResult = ProxyWebhookProvisioningSuccess | null | undefined;
43
48
  export interface ProxyWebhookPayloadInput {
44
49
  readonly body: Buffer | string;
45
50
  readonly signature?: string | null;
@@ -56,8 +61,12 @@ export interface ProxyWebhookHandlerOptions {
56
61
  * failure payload only after the merchant knows retrying cannot grant access.
57
62
  */
58
63
  readonly classifyProvisioningFailure?: (error: unknown, resolved: ResolvedProxyEvent) => Promise<ProxyWebhookProvisioningFailure | null | undefined> | ProxyWebhookProvisioningFailure | null | undefined;
59
- /** Merchant entitlement callback, invoked once per claimed event after current-state resolution. */
60
- readonly onResolved: (resolved: ResolvedProxyEvent) => Promise<void> | void;
64
+ /**
65
+ * Merchant entitlement callback, invoked once per claimed event after
66
+ * current-state resolution. For initial provisioning, return a fulfillment
67
+ * reference and/or metadata to record on Proxy's provisioned acknowledgement.
68
+ */
69
+ readonly onResolved: (resolved: ResolvedProxyEvent) => Promise<ProxyWebhookProvisioningSuccessResult> | ProxyWebhookProvisioningSuccessResult;
61
70
  /** Optional request id forwarded to the current-state retrieval calls. */
62
71
  readonly requestId?: string;
63
72
  /** Endpoint signing secret. */
@@ -61,9 +61,11 @@ export class ProxyWebhooksResource {
61
61
  let resolved;
62
62
  try {
63
63
  resolved = await this.events.resolveCurrentState(event, { requestId: options.requestId });
64
- const provisioningFailed = await this.runResolvedHandler(resolved, options);
65
- if (!provisioningFailed && resolved.kind === "initial_provision") {
64
+ const provisioning = await this.runResolvedHandler(resolved, options);
65
+ if (!provisioning.failed && resolved.kind === "initial_provision") {
66
66
  await this.requireSessionsResource("mark provisioned").markProvisioned(resolved.session.id, {
67
+ fulfillmentReference: provisioning.success?.fulfillmentReference,
68
+ metadata: provisioning.success?.metadata,
67
69
  requestId: options.requestId,
68
70
  });
69
71
  }
@@ -127,8 +129,11 @@ export class ProxyWebhooksResource {
127
129
  }
128
130
  async runResolvedHandler(resolved, options) {
129
131
  try {
130
- await options.onResolved(resolved);
131
- return false;
132
+ const success = await options.onResolved(resolved);
133
+ return {
134
+ failed: false,
135
+ success: normalizeProvisioningSuccess(success),
136
+ };
132
137
  }
133
138
  catch (error) {
134
139
  if (resolved.kind !== "initial_provision" || !options.classifyProvisioningFailure) {
@@ -144,7 +149,7 @@ export class ProxyWebhooksResource {
144
149
  metadata: failure.metadata,
145
150
  requestId: options.requestId,
146
151
  });
147
- return true;
152
+ return { failed: true };
148
153
  }
149
154
  }
150
155
  requireSessionsResource(operation) {
@@ -156,6 +161,21 @@ export class ProxyWebhooksResource {
156
161
  });
157
162
  }
158
163
  }
164
+ function normalizeProvisioningSuccess(value) {
165
+ if (value == null) {
166
+ return undefined;
167
+ }
168
+ const success = {};
169
+ if (value.fulfillmentReference !== undefined) {
170
+ success.fulfillmentReference = value.fulfillmentReference;
171
+ }
172
+ if (value.metadata !== undefined) {
173
+ success.metadata = value.metadata;
174
+ }
175
+ return success.fulfillmentReference === undefined && success.metadata === undefined
176
+ ? undefined
177
+ : success;
178
+ }
159
179
  function toWebhookResponse(result) {
160
180
  const headers = { "content-type": "application/json" };
161
181
  if (result.retryable) {
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "sideEffects": false,
8
8
  "type": "module",
9
9
  "types": "./dist/esm/index.d.ts",
10
- "version": "0.0.7",
10
+ "version": "0.0.8-prx-109.80.1",
11
11
  "devDependencies": {
12
12
  "@types/node": "^24.12.4",
13
13
  "@vitest/coverage-v8": "4.1.7",