@waffo/pancake-ts 0.17.0 → 0.18.0

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.cts CHANGED
@@ -7,6 +7,21 @@ interface WaffoPancakeConfig {
7
7
  baseUrl?: string;
8
8
  /** Custom fetch implementation (default: global fetch) */
9
9
  fetch?: typeof fetch;
10
+ /**
11
+ * Environment that customer sessions operate in (sent as the `X-Environment`
12
+ * header alongside the session token's Bearer credential).
13
+ *
14
+ * API Key requests do not need this — the gateway derives their environment
15
+ * from the key itself. Session tokens carry no environment, so the gateway
16
+ * requires the header and rejects the request with HTTP 400 without it.
17
+ *
18
+ * There is no default: a wrong guess would route the call to the other
19
+ * environment. Supply it here, or per session via
20
+ * {@link CustomerSessionOptions.environment}.
21
+ *
22
+ * @see {@link WaffoPancake.customer}
23
+ */
24
+ environment?: `${Environment}`;
10
25
  /**
11
26
  * Custom RSA public key(s) for webhook signature verification.
12
27
  *
@@ -18,6 +33,16 @@ interface WaffoPancakeConfig {
18
33
  */
19
34
  webhookPublicKey?: WebhookPublicKeys;
20
35
  }
36
+ /** Options for {@link WaffoPancake.customer}. */
37
+ interface CustomerSessionOptions {
38
+ /**
39
+ * Environment this session operates in, overriding
40
+ * {@link WaffoPancakeConfig.environment} for a single session.
41
+ *
42
+ * Required when the client config omits `environment`.
43
+ */
44
+ environment?: `${Environment}`;
45
+ }
21
46
  /**
22
47
  * Options for {@link HttpClient.post}.
23
48
  * Not exported publicly — used by resource classes.
@@ -1127,11 +1152,27 @@ interface VerifyWebhookOptions {
1127
1152
  */
1128
1153
  environment?: `${Environment}`;
1129
1154
  /**
1130
- * Timestamp tolerance window in milliseconds for replay protection.
1131
- * Set to 0 to skip timestamp checking.
1132
- * @default 300000 (5 minutes)
1155
+ * How far in the past a signature timestamp may be, in milliseconds.
1156
+ * Set to 0 to skip timestamp checking entirely (this also skips
1157
+ * {@link futureToleranceMs}).
1158
+ *
1159
+ * The default covers the full delivery retry schedule: the timestamp is
1160
+ * stamped before the first attempt and retries reuse it, so the last retry
1161
+ * arrives with a timestamp as old as the schedule itself.
1162
+ *
1163
+ * @default 2700000 (45 minutes)
1133
1164
  */
1134
1165
  toleranceMs?: number;
1166
+ /**
1167
+ * How far in the future a signature timestamp may be, in milliseconds.
1168
+ * Only clock skew on the receiving server puts a timestamp ahead of now, so
1169
+ * this stays tight — it matches the gateway's API Key check.
1170
+ *
1171
+ * Ignored when `toleranceMs` is 0.
1172
+ *
1173
+ * @default 60000 (1 minute)
1174
+ */
1175
+ futureToleranceMs?: number;
1135
1176
  /**
1136
1177
  * Per-call public key override (highest priority).
1137
1178
  * When provided, skips all other key resolution (config, env vars, built-in).
@@ -1462,16 +1503,24 @@ declare class ContentSafetyResource {
1462
1503
  * never sends an idempotency key (customer session actions are not protected by
1463
1504
  * gateway idempotency in the current architecture).
1464
1505
  *
1506
+ * Session tokens carry no environment of their own, so every request also sends
1507
+ * `X-Environment`. The gateway treats a Bearer credential without it as an
1508
+ * incomplete JWT header set and answers HTTP 400.
1509
+ *
1465
1510
  * Not exported publicly — used internally by {@link CustomerSession}.
1466
1511
  */
1467
1512
  declare class CustomerHttpClient {
1468
1513
  private readonly token;
1514
+ private readonly environment;
1469
1515
  private readonly baseUrl;
1470
1516
  private readonly _fetch;
1471
- constructor(token: string, config: Pick<WaffoPancakeConfig, "baseUrl" | "fetch">);
1517
+ constructor(token: string, environment: `${Environment}`, config: Pick<WaffoPancakeConfig, "baseUrl" | "fetch">);
1472
1518
  /**
1473
1519
  * Send a Bearer-authenticated POST and return the full envelope plus HTTP status.
1474
1520
  *
1521
+ * Sends `Authorization: Bearer <token>` and `X-Environment` — the gateway
1522
+ * requires both to accept a session token.
1523
+ *
1475
1524
  * Does NOT throw on `errors[]` or non-2xx status — caller inspects the result.
1476
1525
  * Throws {@link WaffoPancakeError} only when the response body is not valid JSON.
1477
1526
  */
@@ -2174,22 +2223,34 @@ declare class WaffoPancake {
2174
2223
  * methods for order cancellation, subscription management, refund tickets,
2175
2224
  * and scoped GraphQL queries.
2176
2225
  *
2226
+ * Session tokens expire 5 minutes after issuance, so issue one right before
2227
+ * use rather than caching it.
2228
+ *
2177
2229
  * @param token - Session token from `client.auth.issueSessionToken()`
2230
+ * @param options - Per-session overrides
2178
2231
  * @returns A customer session with self-service methods
2232
+ * @throws {WaffoPancakeError} When no environment is available from either
2233
+ * `options.environment` or `WaffoPancakeConfig.environment`
2179
2234
  *
2180
2235
  * @example
2181
2236
  * const { token } = await client.auth.issueSessionToken({
2182
2237
  * storeId: "STO_xxx",
2183
2238
  * buyerIdentity: "customer@example.com",
2184
2239
  * });
2185
- * const customer = client.customer(token);
2240
+ * const customer = client.customer(token, { environment: "test" });
2186
2241
  * await customer.cancelSubscription({ orderId: "ORD_xxx" });
2242
+ *
2243
+ * @example
2244
+ * // Set the environment once on the client instead
2245
+ * const client = new WaffoPancake({ merchantId, privateKey, environment: "test" });
2246
+ * const customer = client.customer(token);
2187
2247
  */
2188
- customer(token: string): CustomerSession;
2248
+ customer(token: string, options?: CustomerSessionOptions): CustomerSession;
2189
2249
  /**
2190
2250
  * Create a customer session for self-service operations.
2191
2251
  *
2192
2252
  * @param token - Session token from `client.auth.issueSessionToken()`
2253
+ * @param options - Per-session overrides
2193
2254
  * @returns A customer session with self-service methods
2194
2255
  *
2195
2256
  * @example
@@ -2199,7 +2260,7 @@ declare class WaffoPancake {
2199
2260
  *
2200
2261
  * @deprecated Use {@link WaffoPancake.customer} instead.
2201
2262
  */
2202
- buyer(token: string): CustomerSession;
2263
+ buyer(token: string, options?: CustomerSessionOptions): CustomerSession;
2203
2264
  }
2204
2265
 
2205
2266
  /**
@@ -2278,4 +2339,4 @@ declare class WaffoPancakeError extends Error {
2278
2339
  */
2279
2340
  declare function verifyWebhook<T = Record<string, unknown>>(payload: string, signatureHeader: string | undefined | null, options?: VerifyWebhookOptions): WebhookEvent<T>;
2280
2341
 
2281
- export { type AddMerchantParams, type AddMerchantResult, type AddWebhookParams, type AnonymousCheckoutParams, type ApiError, type AuthenticatedCheckoutParams, type AuthenticatedCheckoutResult, type BillingDetail, BillingPeriod, type CancelOnetimeOrderParams, type CancelOnetimeOrderResult, type CancelSubscriptionParams, type CancelSubscriptionResult, type CashierLanguage, type CheckoutSessionResult, type CheckoutSettings, type CheckoutThemeSettings, type CreateCheckoutSessionParams, type CreateOnetimeProductParams, type CreateRefundTicketParams, type CreateStoreParams, type CreateSubscriptionProductGroupParams, type CreateSubscriptionProductParams, type DeleteStoreParams, type DeleteSubscriptionProductGroupParams, EntityStatus, type Envelope, Environment, ErrorLayer, type GraphQLParams, type GraphQLResponse, type GroupRules, type IssueSessionTokenParams, type MediaItem, MediaType, type MerchantWritableNotificationSettings, type Notice, type NotificationSettings, OnetimeOrderStatus, type OnetimeProductDetail, type PaymentMethod, PaymentStatus, type PostResult, type PriceInfo, type Prices, ProductVersionStatus, type PublishOnetimeProductParams, type PublishSubscriptionProductGroupParams, type PublishSubscriptionProductParams, type ReactivateSubscriptionParams, type ReactivateSubscriptionResult, RefundStatus, type RefundTicket, RefundTicketStatus, type RefundTicketVersionData, type RemoveMerchantParams, type RemoveMerchantResult, type RemoveWebhookParams, type RequestedAmount, type ResubmitRefundTicketParams, ScanAction, ScanPolicyCategory, type ScanPromptParams, ScanReasonCode, type ScanResult, ScanSemanticMode, ScanSemanticStatus, type SessionToken, type Store, StoreRole, type StoreWebhook, SubscriptionOrderStatus, type SubscriptionProductDetail, type SubscriptionProductGroup, TaxCategory, type UpdateOnetimeProductParams, type UpdateOnetimeStatusParams, type UpdateRoleParams, type UpdateRoleResult, type UpdateStoreParams, type UpdateSubscriptionProductGroupParams, type UpdateSubscriptionProductParams, type UpdateSubscriptionStatusParams, type UpdateWebhookParams, type VerifyWebhookOptions, WaffoPancake, type WaffoPancakeConfig, WaffoPancakeError, type WebhookChannel, type WebhookEvent, type WebhookEventData, WebhookEventType, type WebhookPublicKeys, verifyWebhook };
2342
+ export { type AddMerchantParams, type AddMerchantResult, type AddWebhookParams, type AnonymousCheckoutParams, type ApiError, type AuthenticatedCheckoutParams, type AuthenticatedCheckoutResult, type BillingDetail, BillingPeriod, type CancelOnetimeOrderParams, type CancelOnetimeOrderResult, type CancelSubscriptionParams, type CancelSubscriptionResult, type CashierLanguage, type CheckoutSessionResult, type CheckoutSettings, type CheckoutThemeSettings, type CreateCheckoutSessionParams, type CreateOnetimeProductParams, type CreateRefundTicketParams, type CreateStoreParams, type CreateSubscriptionProductGroupParams, type CreateSubscriptionProductParams, type CustomerSessionOptions, type DeleteStoreParams, type DeleteSubscriptionProductGroupParams, EntityStatus, type Envelope, Environment, ErrorLayer, type GraphQLParams, type GraphQLResponse, type GroupRules, type IssueSessionTokenParams, type MediaItem, MediaType, type MerchantWritableNotificationSettings, type Notice, type NotificationSettings, OnetimeOrderStatus, type OnetimeProductDetail, type PaymentMethod, PaymentStatus, type PostResult, type PriceInfo, type Prices, ProductVersionStatus, type PublishOnetimeProductParams, type PublishSubscriptionProductGroupParams, type PublishSubscriptionProductParams, type ReactivateSubscriptionParams, type ReactivateSubscriptionResult, RefundStatus, type RefundTicket, RefundTicketStatus, type RefundTicketVersionData, type RemoveMerchantParams, type RemoveMerchantResult, type RemoveWebhookParams, type RequestedAmount, type ResubmitRefundTicketParams, ScanAction, ScanPolicyCategory, type ScanPromptParams, ScanReasonCode, type ScanResult, ScanSemanticMode, ScanSemanticStatus, type SessionToken, type Store, StoreRole, type StoreWebhook, SubscriptionOrderStatus, type SubscriptionProductDetail, type SubscriptionProductGroup, TaxCategory, type UpdateOnetimeProductParams, type UpdateOnetimeStatusParams, type UpdateRoleParams, type UpdateRoleResult, type UpdateStoreParams, type UpdateSubscriptionProductGroupParams, type UpdateSubscriptionProductParams, type UpdateSubscriptionStatusParams, type UpdateWebhookParams, type VerifyWebhookOptions, WaffoPancake, type WaffoPancakeConfig, WaffoPancakeError, type WebhookChannel, type WebhookEvent, type WebhookEventData, WebhookEventType, type WebhookPublicKeys, verifyWebhook };
package/dist/index.d.ts CHANGED
@@ -7,6 +7,21 @@ interface WaffoPancakeConfig {
7
7
  baseUrl?: string;
8
8
  /** Custom fetch implementation (default: global fetch) */
9
9
  fetch?: typeof fetch;
10
+ /**
11
+ * Environment that customer sessions operate in (sent as the `X-Environment`
12
+ * header alongside the session token's Bearer credential).
13
+ *
14
+ * API Key requests do not need this — the gateway derives their environment
15
+ * from the key itself. Session tokens carry no environment, so the gateway
16
+ * requires the header and rejects the request with HTTP 400 without it.
17
+ *
18
+ * There is no default: a wrong guess would route the call to the other
19
+ * environment. Supply it here, or per session via
20
+ * {@link CustomerSessionOptions.environment}.
21
+ *
22
+ * @see {@link WaffoPancake.customer}
23
+ */
24
+ environment?: `${Environment}`;
10
25
  /**
11
26
  * Custom RSA public key(s) for webhook signature verification.
12
27
  *
@@ -18,6 +33,16 @@ interface WaffoPancakeConfig {
18
33
  */
19
34
  webhookPublicKey?: WebhookPublicKeys;
20
35
  }
36
+ /** Options for {@link WaffoPancake.customer}. */
37
+ interface CustomerSessionOptions {
38
+ /**
39
+ * Environment this session operates in, overriding
40
+ * {@link WaffoPancakeConfig.environment} for a single session.
41
+ *
42
+ * Required when the client config omits `environment`.
43
+ */
44
+ environment?: `${Environment}`;
45
+ }
21
46
  /**
22
47
  * Options for {@link HttpClient.post}.
23
48
  * Not exported publicly — used by resource classes.
@@ -1127,11 +1152,27 @@ interface VerifyWebhookOptions {
1127
1152
  */
1128
1153
  environment?: `${Environment}`;
1129
1154
  /**
1130
- * Timestamp tolerance window in milliseconds for replay protection.
1131
- * Set to 0 to skip timestamp checking.
1132
- * @default 300000 (5 minutes)
1155
+ * How far in the past a signature timestamp may be, in milliseconds.
1156
+ * Set to 0 to skip timestamp checking entirely (this also skips
1157
+ * {@link futureToleranceMs}).
1158
+ *
1159
+ * The default covers the full delivery retry schedule: the timestamp is
1160
+ * stamped before the first attempt and retries reuse it, so the last retry
1161
+ * arrives with a timestamp as old as the schedule itself.
1162
+ *
1163
+ * @default 2700000 (45 minutes)
1133
1164
  */
1134
1165
  toleranceMs?: number;
1166
+ /**
1167
+ * How far in the future a signature timestamp may be, in milliseconds.
1168
+ * Only clock skew on the receiving server puts a timestamp ahead of now, so
1169
+ * this stays tight — it matches the gateway's API Key check.
1170
+ *
1171
+ * Ignored when `toleranceMs` is 0.
1172
+ *
1173
+ * @default 60000 (1 minute)
1174
+ */
1175
+ futureToleranceMs?: number;
1135
1176
  /**
1136
1177
  * Per-call public key override (highest priority).
1137
1178
  * When provided, skips all other key resolution (config, env vars, built-in).
@@ -1462,16 +1503,24 @@ declare class ContentSafetyResource {
1462
1503
  * never sends an idempotency key (customer session actions are not protected by
1463
1504
  * gateway idempotency in the current architecture).
1464
1505
  *
1506
+ * Session tokens carry no environment of their own, so every request also sends
1507
+ * `X-Environment`. The gateway treats a Bearer credential without it as an
1508
+ * incomplete JWT header set and answers HTTP 400.
1509
+ *
1465
1510
  * Not exported publicly — used internally by {@link CustomerSession}.
1466
1511
  */
1467
1512
  declare class CustomerHttpClient {
1468
1513
  private readonly token;
1514
+ private readonly environment;
1469
1515
  private readonly baseUrl;
1470
1516
  private readonly _fetch;
1471
- constructor(token: string, config: Pick<WaffoPancakeConfig, "baseUrl" | "fetch">);
1517
+ constructor(token: string, environment: `${Environment}`, config: Pick<WaffoPancakeConfig, "baseUrl" | "fetch">);
1472
1518
  /**
1473
1519
  * Send a Bearer-authenticated POST and return the full envelope plus HTTP status.
1474
1520
  *
1521
+ * Sends `Authorization: Bearer <token>` and `X-Environment` — the gateway
1522
+ * requires both to accept a session token.
1523
+ *
1475
1524
  * Does NOT throw on `errors[]` or non-2xx status — caller inspects the result.
1476
1525
  * Throws {@link WaffoPancakeError} only when the response body is not valid JSON.
1477
1526
  */
@@ -2174,22 +2223,34 @@ declare class WaffoPancake {
2174
2223
  * methods for order cancellation, subscription management, refund tickets,
2175
2224
  * and scoped GraphQL queries.
2176
2225
  *
2226
+ * Session tokens expire 5 minutes after issuance, so issue one right before
2227
+ * use rather than caching it.
2228
+ *
2177
2229
  * @param token - Session token from `client.auth.issueSessionToken()`
2230
+ * @param options - Per-session overrides
2178
2231
  * @returns A customer session with self-service methods
2232
+ * @throws {WaffoPancakeError} When no environment is available from either
2233
+ * `options.environment` or `WaffoPancakeConfig.environment`
2179
2234
  *
2180
2235
  * @example
2181
2236
  * const { token } = await client.auth.issueSessionToken({
2182
2237
  * storeId: "STO_xxx",
2183
2238
  * buyerIdentity: "customer@example.com",
2184
2239
  * });
2185
- * const customer = client.customer(token);
2240
+ * const customer = client.customer(token, { environment: "test" });
2186
2241
  * await customer.cancelSubscription({ orderId: "ORD_xxx" });
2242
+ *
2243
+ * @example
2244
+ * // Set the environment once on the client instead
2245
+ * const client = new WaffoPancake({ merchantId, privateKey, environment: "test" });
2246
+ * const customer = client.customer(token);
2187
2247
  */
2188
- customer(token: string): CustomerSession;
2248
+ customer(token: string, options?: CustomerSessionOptions): CustomerSession;
2189
2249
  /**
2190
2250
  * Create a customer session for self-service operations.
2191
2251
  *
2192
2252
  * @param token - Session token from `client.auth.issueSessionToken()`
2253
+ * @param options - Per-session overrides
2193
2254
  * @returns A customer session with self-service methods
2194
2255
  *
2195
2256
  * @example
@@ -2199,7 +2260,7 @@ declare class WaffoPancake {
2199
2260
  *
2200
2261
  * @deprecated Use {@link WaffoPancake.customer} instead.
2201
2262
  */
2202
- buyer(token: string): CustomerSession;
2263
+ buyer(token: string, options?: CustomerSessionOptions): CustomerSession;
2203
2264
  }
2204
2265
 
2205
2266
  /**
@@ -2278,4 +2339,4 @@ declare class WaffoPancakeError extends Error {
2278
2339
  */
2279
2340
  declare function verifyWebhook<T = Record<string, unknown>>(payload: string, signatureHeader: string | undefined | null, options?: VerifyWebhookOptions): WebhookEvent<T>;
2280
2341
 
2281
- export { type AddMerchantParams, type AddMerchantResult, type AddWebhookParams, type AnonymousCheckoutParams, type ApiError, type AuthenticatedCheckoutParams, type AuthenticatedCheckoutResult, type BillingDetail, BillingPeriod, type CancelOnetimeOrderParams, type CancelOnetimeOrderResult, type CancelSubscriptionParams, type CancelSubscriptionResult, type CashierLanguage, type CheckoutSessionResult, type CheckoutSettings, type CheckoutThemeSettings, type CreateCheckoutSessionParams, type CreateOnetimeProductParams, type CreateRefundTicketParams, type CreateStoreParams, type CreateSubscriptionProductGroupParams, type CreateSubscriptionProductParams, type DeleteStoreParams, type DeleteSubscriptionProductGroupParams, EntityStatus, type Envelope, Environment, ErrorLayer, type GraphQLParams, type GraphQLResponse, type GroupRules, type IssueSessionTokenParams, type MediaItem, MediaType, type MerchantWritableNotificationSettings, type Notice, type NotificationSettings, OnetimeOrderStatus, type OnetimeProductDetail, type PaymentMethod, PaymentStatus, type PostResult, type PriceInfo, type Prices, ProductVersionStatus, type PublishOnetimeProductParams, type PublishSubscriptionProductGroupParams, type PublishSubscriptionProductParams, type ReactivateSubscriptionParams, type ReactivateSubscriptionResult, RefundStatus, type RefundTicket, RefundTicketStatus, type RefundTicketVersionData, type RemoveMerchantParams, type RemoveMerchantResult, type RemoveWebhookParams, type RequestedAmount, type ResubmitRefundTicketParams, ScanAction, ScanPolicyCategory, type ScanPromptParams, ScanReasonCode, type ScanResult, ScanSemanticMode, ScanSemanticStatus, type SessionToken, type Store, StoreRole, type StoreWebhook, SubscriptionOrderStatus, type SubscriptionProductDetail, type SubscriptionProductGroup, TaxCategory, type UpdateOnetimeProductParams, type UpdateOnetimeStatusParams, type UpdateRoleParams, type UpdateRoleResult, type UpdateStoreParams, type UpdateSubscriptionProductGroupParams, type UpdateSubscriptionProductParams, type UpdateSubscriptionStatusParams, type UpdateWebhookParams, type VerifyWebhookOptions, WaffoPancake, type WaffoPancakeConfig, WaffoPancakeError, type WebhookChannel, type WebhookEvent, type WebhookEventData, WebhookEventType, type WebhookPublicKeys, verifyWebhook };
2342
+ export { type AddMerchantParams, type AddMerchantResult, type AddWebhookParams, type AnonymousCheckoutParams, type ApiError, type AuthenticatedCheckoutParams, type AuthenticatedCheckoutResult, type BillingDetail, BillingPeriod, type CancelOnetimeOrderParams, type CancelOnetimeOrderResult, type CancelSubscriptionParams, type CancelSubscriptionResult, type CashierLanguage, type CheckoutSessionResult, type CheckoutSettings, type CheckoutThemeSettings, type CreateCheckoutSessionParams, type CreateOnetimeProductParams, type CreateRefundTicketParams, type CreateStoreParams, type CreateSubscriptionProductGroupParams, type CreateSubscriptionProductParams, type CustomerSessionOptions, type DeleteStoreParams, type DeleteSubscriptionProductGroupParams, EntityStatus, type Envelope, Environment, ErrorLayer, type GraphQLParams, type GraphQLResponse, type GroupRules, type IssueSessionTokenParams, type MediaItem, MediaType, type MerchantWritableNotificationSettings, type Notice, type NotificationSettings, OnetimeOrderStatus, type OnetimeProductDetail, type PaymentMethod, PaymentStatus, type PostResult, type PriceInfo, type Prices, ProductVersionStatus, type PublishOnetimeProductParams, type PublishSubscriptionProductGroupParams, type PublishSubscriptionProductParams, type ReactivateSubscriptionParams, type ReactivateSubscriptionResult, RefundStatus, type RefundTicket, RefundTicketStatus, type RefundTicketVersionData, type RemoveMerchantParams, type RemoveMerchantResult, type RemoveWebhookParams, type RequestedAmount, type ResubmitRefundTicketParams, ScanAction, ScanPolicyCategory, type ScanPromptParams, ScanReasonCode, type ScanResult, ScanSemanticMode, ScanSemanticStatus, type SessionToken, type Store, StoreRole, type StoreWebhook, SubscriptionOrderStatus, type SubscriptionProductDetail, type SubscriptionProductGroup, TaxCategory, type UpdateOnetimeProductParams, type UpdateOnetimeStatusParams, type UpdateRoleParams, type UpdateRoleResult, type UpdateStoreParams, type UpdateSubscriptionProductGroupParams, type UpdateSubscriptionProductParams, type UpdateSubscriptionStatusParams, type UpdateWebhookParams, type VerifyWebhookOptions, WaffoPancake, type WaffoPancakeConfig, WaffoPancakeError, type WebhookChannel, type WebhookEvent, type WebhookEventData, WebhookEventType, type WebhookPublicKeys, verifyWebhook };
package/dist/index.js CHANGED
@@ -15,16 +15,21 @@ var WaffoPancakeError = class extends Error {
15
15
  var DEFAULT_BASE_URL = "https://api.waffo.ai";
16
16
  var CustomerHttpClient = class {
17
17
  token;
18
+ environment;
18
19
  baseUrl;
19
20
  _fetch;
20
- constructor(token, config) {
21
+ constructor(token, environment, config) {
21
22
  this.token = token;
23
+ this.environment = environment;
22
24
  this.baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
23
25
  this._fetch = config.fetch ?? globalThis.fetch.bind(globalThis);
24
26
  }
25
27
  /**
26
28
  * Send a Bearer-authenticated POST and return the full envelope plus HTTP status.
27
29
  *
30
+ * Sends `Authorization: Bearer <token>` and `X-Environment` — the gateway
31
+ * requires both to accept a session token.
32
+ *
28
33
  * Does NOT throw on `errors[]` or non-2xx status — caller inspects the result.
29
34
  * Throws {@link WaffoPancakeError} only when the response body is not valid JSON.
30
35
  */
@@ -33,7 +38,8 @@ var CustomerHttpClient = class {
33
38
  method: "POST",
34
39
  headers: {
35
40
  "Content-Type": "application/json",
36
- Authorization: `Bearer ${this.token}`
41
+ Authorization: `Bearer ${this.token}`,
42
+ "X-Environment": this.environment
37
43
  },
38
44
  body: JSON.stringify(body)
39
45
  });
@@ -1073,7 +1079,8 @@ var SubscriptionProductsResource = class {
1073
1079
 
1074
1080
  // src/webhooks.ts
1075
1081
  import { createVerify } from "crypto";
1076
- var DEFAULT_TOLERANCE_MS = 5 * 60 * 1e3;
1082
+ var DEFAULT_TOLERANCE_MS = 45 * 60 * 1e3;
1083
+ var DEFAULT_FUTURE_TOLERANCE_MS = 60 * 1e3;
1077
1084
  var TEST_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
1078
1085
  MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxnmRY6yMMA3lVqmAU6ZG
1079
1086
  b1sjL/+r/z6E+ZjkXaDAKiqOhk9rpazni0bNsGXwmftTPk9jy2wn+j6JHODD/WH/
@@ -1141,7 +1148,9 @@ function verifyWebhook(payload, signatureHeader, options) {
1141
1148
  if (Number.isNaN(timestampMs)) {
1142
1149
  throw new Error("Invalid timestamp in X-Waffo-Signature header");
1143
1150
  }
1144
- if (Math.abs(Date.now() - timestampMs) > toleranceMs) {
1151
+ const futureToleranceMs = options?.futureToleranceMs ?? DEFAULT_FUTURE_TOLERANCE_MS;
1152
+ const ageMs = Date.now() - timestampMs;
1153
+ if (ageMs > toleranceMs || ageMs < -futureToleranceMs) {
1145
1154
  throw new Error("Webhook timestamp outside tolerance window (possible replay attack)");
1146
1155
  }
1147
1156
  }
@@ -1334,19 +1343,40 @@ var WaffoPancake = class {
1334
1343
  * methods for order cancellation, subscription management, refund tickets,
1335
1344
  * and scoped GraphQL queries.
1336
1345
  *
1346
+ * Session tokens expire 5 minutes after issuance, so issue one right before
1347
+ * use rather than caching it.
1348
+ *
1337
1349
  * @param token - Session token from `client.auth.issueSessionToken()`
1350
+ * @param options - Per-session overrides
1338
1351
  * @returns A customer session with self-service methods
1352
+ * @throws {WaffoPancakeError} When no environment is available from either
1353
+ * `options.environment` or `WaffoPancakeConfig.environment`
1339
1354
  *
1340
1355
  * @example
1341
1356
  * const { token } = await client.auth.issueSessionToken({
1342
1357
  * storeId: "STO_xxx",
1343
1358
  * buyerIdentity: "customer@example.com",
1344
1359
  * });
1345
- * const customer = client.customer(token);
1360
+ * const customer = client.customer(token, { environment: "test" });
1346
1361
  * await customer.cancelSubscription({ orderId: "ORD_xxx" });
1362
+ *
1363
+ * @example
1364
+ * // Set the environment once on the client instead
1365
+ * const client = new WaffoPancake({ merchantId, privateKey, environment: "test" });
1366
+ * const customer = client.customer(token);
1347
1367
  */
1348
- customer(token) {
1349
- const customerHttp = new CustomerHttpClient(token, {
1368
+ customer(token, options) {
1369
+ const environment = options?.environment ?? this.config.environment;
1370
+ if (environment === void 0) {
1371
+ throw new WaffoPancakeError(400, [
1372
+ {
1373
+ message: "Missing required field: environment \u2014 set it on the client config or pass client.customer(token, { environment: 'test' | 'prod' })",
1374
+ layer: "sdk"
1375
+ }
1376
+ ]);
1377
+ }
1378
+ validateEnum("environment", environment, ["test", "prod"]);
1379
+ const customerHttp = new CustomerHttpClient(token, environment, {
1350
1380
  baseUrl: this.config.baseUrl,
1351
1381
  fetch: this.config.fetch
1352
1382
  });
@@ -1356,6 +1386,7 @@ var WaffoPancake = class {
1356
1386
  * Create a customer session for self-service operations.
1357
1387
  *
1358
1388
  * @param token - Session token from `client.auth.issueSessionToken()`
1389
+ * @param options - Per-session overrides
1359
1390
  * @returns A customer session with self-service methods
1360
1391
  *
1361
1392
  * @example
@@ -1365,8 +1396,8 @@ var WaffoPancake = class {
1365
1396
  *
1366
1397
  * @deprecated Use {@link WaffoPancake.customer} instead.
1367
1398
  */
1368
- buyer(token) {
1369
- return this.customer(token);
1399
+ buyer(token, options) {
1400
+ return this.customer(token, options);
1370
1401
  }
1371
1402
  };
1372
1403