@waffo/pancake-ts 0.1.3 → 0.1.7

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,16 @@ interface WaffoPancakeConfig {
7
7
  baseUrl?: string;
8
8
  /** Custom fetch implementation (default: global fetch) */
9
9
  fetch?: typeof fetch;
10
+ /**
11
+ * Custom RSA public key(s) for webhook signature verification.
12
+ *
13
+ * - `string` — single key used for both test and prod environments
14
+ * - `{ test?, prod? }` — per-environment keys
15
+ *
16
+ * Resolution order per environment: config key → env var → built-in key.
17
+ * @see {@link VerifyWebhookOptions} for per-call overrides
18
+ */
19
+ webhookPublicKey?: WebhookPublicKeys;
10
20
  }
11
21
  /**
12
22
  * Single error object within the `errors` array.
@@ -239,7 +249,6 @@ interface CheckoutThemeSettings {
239
249
  checkoutColorBackground: string;
240
250
  checkoutColorCard: string;
241
251
  checkoutColorText: string;
242
- checkoutColorTextSecondary: string;
243
252
  checkoutBorderRadius: string;
244
253
  }
245
254
  /**
@@ -247,6 +256,7 @@ interface CheckoutThemeSettings {
247
256
  * @see waffo-pancake-store-service/app/lib/types.ts
248
257
  */
249
258
  interface CheckoutSettings {
259
+ defaultDarkMode: boolean;
250
260
  light: CheckoutThemeSettings;
251
261
  dark: CheckoutThemeSettings;
252
262
  }
@@ -262,7 +272,6 @@ interface Store {
262
272
  supportEmail: string | null;
263
273
  website: string | null;
264
274
  slug: string | null;
265
- isPublic: boolean;
266
275
  prodEnabled: boolean;
267
276
  webhookSettings: WebhookSettings | null;
268
277
  notificationSettings: NotificationSettings | null;
@@ -283,9 +292,6 @@ interface UpdateStoreParams {
283
292
  name?: string;
284
293
  status?: EntityStatus;
285
294
  logo?: string | null;
286
- supportEmail?: string | null;
287
- website?: string | null;
288
- isPublic?: boolean;
289
295
  webhookSettings?: WebhookSettings | null;
290
296
  notificationSettings?: NotificationSettings | null;
291
297
  checkoutSettings?: CheckoutSettings | null;
@@ -343,17 +349,15 @@ interface UpdateRoleResult {
343
349
  *
344
350
  * @example
345
351
  * // USD $9.99
346
- * { amount: 999, taxIncluded: true, taxCategory: "saas" }
352
+ * { amount: 999, taxCategory: "saas" }
347
353
  *
348
354
  * @example
349
355
  * // JPY ¥1000
350
- * { amount: 1000, taxIncluded: false, taxCategory: "software" }
356
+ * { amount: 1000, taxCategory: "software" }
351
357
  */
352
358
  interface PriceInfo {
353
359
  /** Price amount in smallest currency unit */
354
360
  amount: number;
355
- /** Whether the price is tax-inclusive */
356
- taxIncluded: boolean;
357
361
  /** Tax category */
358
362
  taxCategory: TaxCategory;
359
363
  }
@@ -364,8 +368,8 @@ interface PriceInfo {
364
368
  *
365
369
  * @example
366
370
  * {
367
- * "USD": { amount: 999, taxIncluded: true, taxCategory: "saas" },
368
- * "EUR": { amount: 899, taxIncluded: true, taxCategory: "saas" }
371
+ * "USD": { amount: 999, taxCategory: "saas" },
372
+ * "EUR": { amount: 899, taxCategory: "saas" }
369
373
  * }
370
374
  */
371
375
  type Prices = Record<string, PriceInfo>;
@@ -576,13 +580,13 @@ interface BillingDetail {
576
580
  country: string;
577
581
  /** Whether this is a business purchase */
578
582
  isBusiness: boolean;
579
- /** Postal / ZIP code */
583
+ /** Postal / ZIP code (required for US, at least one of postcode/state for CA) */
580
584
  postcode?: string;
581
- /** State / province code (required for US/CA) */
585
+ /** State / province code (at least one of state/postcode for CA) */
582
586
  state?: string;
583
- /** Business name (required when isBusiness=true) */
587
+ /** Business name (recommended for invoicing, does not affect tax calculation) */
584
588
  businessName?: string;
585
- /** Tax ID (required for EU businesses) */
589
+ /** Tax ID / VAT number (EU businesses: triggers reverse charge 0% when provided) */
586
590
  taxId?: string;
587
591
  }
588
592
  /**
@@ -591,7 +595,7 @@ interface BillingDetail {
591
595
  */
592
596
  interface CreateCheckoutSessionParams {
593
597
  /** Store ID */
594
- storeId?: string;
598
+ storeId: string;
595
599
  /** Product ID */
596
600
  productId: string;
597
601
  /** Product type */
@@ -608,8 +612,10 @@ interface CreateCheckoutSessionParams {
608
612
  billingDetail?: BillingDetail;
609
613
  /** Redirect URL after successful payment */
610
614
  successUrl?: string;
611
- /** Session expiration in seconds (default: 7 days) */
615
+ /** Session expiration in seconds (default: 45 minutes) */
612
616
  expiresInSeconds?: number;
617
+ /** Dark mode override (true=dark, false=light, omit=use store default) */
618
+ darkMode?: boolean;
613
619
  /** Custom metadata */
614
620
  metadata?: Record<string, string>;
615
621
  }
@@ -713,11 +719,22 @@ interface WebhookEvent<T = WebhookEventData> {
713
719
  /** Event data */
714
720
  data: T;
715
721
  }
722
+ /**
723
+ * Webhook public key configuration.
724
+ *
725
+ * - `string` — single key used for both test and prod environments
726
+ * - `{ test?, prod? }` — per-environment keys
727
+ */
728
+ type WebhookPublicKeys = string | {
729
+ test?: string;
730
+ prod?: string;
731
+ };
716
732
  /** Options for {@link verifyWebhook}. */
717
733
  interface VerifyWebhookOptions {
718
734
  /**
719
735
  * Specify which environment's public key to use for verification.
720
736
  * When omitted, both keys are tried automatically (prod first).
737
+ * Ignored when `publicKey` is provided.
721
738
  */
722
739
  environment?: `${Environment}`;
723
740
  /**
@@ -726,6 +743,24 @@ interface VerifyWebhookOptions {
726
743
  * @default 300000 (5 minutes)
727
744
  */
728
745
  toleranceMs?: number;
746
+ /**
747
+ * Per-call public key override (highest priority).
748
+ * When provided, skips all other key resolution (config, env vars, built-in).
749
+ */
750
+ publicKey?: string;
751
+ /**
752
+ * Config-level public key(s) for the resolution chain.
753
+ * When using `client.webhooks.verify()`, this is set automatically from `WaffoPancakeConfig.webhookPublicKey`.
754
+ * When using the standalone `verifyWebhook()`, you can pass this directly for config-level key injection.
755
+ *
756
+ * Resolution order per environment:
757
+ * 1. `publicKey` (per-call override)
758
+ * 2. `publicKeys[env]` or `publicKeys` (config)
759
+ * 3. `WAFFO_WEBHOOK_{TEST|PROD}_PUBLIC_KEY` (env var)
760
+ * 4. `WAFFO_WEBHOOK_PUBLIC_KEY` (env var)
761
+ * 5. Built-in hardcoded key
762
+ */
763
+ publicKeys?: WebhookPublicKeys;
729
764
  }
730
765
 
731
766
  /**
@@ -836,7 +871,7 @@ declare class OnetimeProductsResource {
836
871
  * const { product } = await client.onetimeProducts.create({
837
872
  * storeId: "store_xxx",
838
873
  * name: "E-Book",
839
- * prices: { USD: { amount: 2900, taxIncluded: false, taxCategory: "digital_goods" } },
874
+ * prices: { USD: { amount: 2900, taxCategory: "digital_goods" } },
840
875
  * });
841
876
  */
842
877
  create(params: CreateOnetimeProductParams): Promise<{
@@ -852,7 +887,7 @@ declare class OnetimeProductsResource {
852
887
  * const { product } = await client.onetimeProducts.update({
853
888
  * id: "prod_xxx",
854
889
  * name: "E-Book v2",
855
- * prices: { USD: { amount: 3900, taxIncluded: false, taxCategory: "digital_goods" } },
890
+ * prices: { USD: { amount: 3900, taxCategory: "digital_goods" } },
856
891
  * });
857
892
  */
858
893
  update(params: UpdateOnetimeProductParams): Promise<{
@@ -982,7 +1017,6 @@ declare class StoresResource {
982
1017
  * const { store } = await client.stores.update({
983
1018
  * id: "store_xxx",
984
1019
  * name: "Updated Name",
985
- * supportEmail: "help@example.com",
986
1020
  * });
987
1021
  */
988
1022
  update(params: UpdateStoreParams): Promise<{
@@ -1079,7 +1113,7 @@ declare class SubscriptionProductsResource {
1079
1113
  * storeId: "store_xxx",
1080
1114
  * name: "Pro Plan",
1081
1115
  * billingPeriod: "monthly",
1082
- * prices: { USD: { amount: 999, taxIncluded: false, taxCategory: "saas" } },
1116
+ * prices: { USD: { amount: 999, taxCategory: "saas" } },
1083
1117
  * });
1084
1118
  */
1085
1119
  create(params: CreateSubscriptionProductParams): Promise<{
@@ -1096,7 +1130,7 @@ declare class SubscriptionProductsResource {
1096
1130
  * id: "prod_xxx",
1097
1131
  * name: "Pro Plan v2",
1098
1132
  * billingPeriod: "monthly",
1099
- * prices: { USD: { amount: 1499, taxIncluded: false, taxCategory: "saas" } },
1133
+ * prices: { USD: { amount: 1499, taxCategory: "saas" } },
1100
1134
  * });
1101
1135
  */
1102
1136
  update(params: UpdateSubscriptionProductParams): Promise<{
@@ -1131,6 +1165,46 @@ declare class SubscriptionProductsResource {
1131
1165
  }>;
1132
1166
  }
1133
1167
 
1168
+ /**
1169
+ * Webhook signature verification resource.
1170
+ *
1171
+ * Unlike other resources, this does not use HttpClient — webhook verification
1172
+ * is a local cryptographic operation that does not require API calls.
1173
+ */
1174
+ declare class WebhooksResource {
1175
+ private readonly publicKeys;
1176
+ /** @param publicKeys - Optional config-level public key(s) from WaffoPancakeConfig */
1177
+ constructor(publicKeys: WebhookPublicKeys | undefined);
1178
+ /**
1179
+ * Verify and parse an incoming webhook event.
1180
+ *
1181
+ * Key resolution order:
1182
+ * 1. `options.publicKey` — per-call override (highest priority)
1183
+ * 2. `config.webhookPublicKey[env]` or `config.webhookPublicKey` (string)
1184
+ * 3. `WAFFO_WEBHOOK_{TEST|PROD}_PUBLIC_KEY` environment variable
1185
+ * 4. `WAFFO_WEBHOOK_PUBLIC_KEY` environment variable
1186
+ * 5. Built-in hardcoded key
1187
+ *
1188
+ * @param payload - Raw request body string (must be unparsed)
1189
+ * @param signatureHeader - Value of the `X-Waffo-Signature` header
1190
+ * @param options - Verification options (optional)
1191
+ * @returns Parsed webhook event
1192
+ * @throws Error if signature is invalid, header is malformed, or timestamp is stale
1193
+ *
1194
+ * @example
1195
+ * const event = client.webhooks.verify(rawBody, signatureHeader);
1196
+ *
1197
+ * @example
1198
+ * // Specify environment
1199
+ * const event = client.webhooks.verify(rawBody, sig, { environment: "test" });
1200
+ *
1201
+ * @example
1202
+ * // Per-call key override
1203
+ * const event = client.webhooks.verify(rawBody, sig, { publicKey: oneOffKey });
1204
+ */
1205
+ verify<T = Record<string, unknown>>(payload: string, signatureHeader: string | undefined | null, options?: VerifyWebhookOptions): WebhookEvent<T>;
1206
+ }
1207
+
1134
1208
  /**
1135
1209
  * Waffo Pancake TypeScript SDK client.
1136
1210
  *
@@ -1152,7 +1226,7 @@ declare class SubscriptionProductsResource {
1152
1226
  * const { product } = await client.onetimeProducts.create({
1153
1227
  * storeId: store.id,
1154
1228
  * name: "E-Book",
1155
- * prices: { USD: { amount: 2900, taxIncluded: false, taxCategory: "digital_goods" } },
1229
+ * prices: { USD: { amount: 2900, taxCategory: "digital_goods" } },
1156
1230
  * });
1157
1231
  *
1158
1232
  * // Create a checkout session
@@ -1168,6 +1242,18 @@ declare class SubscriptionProductsResource {
1168
1242
  * const result = await client.graphql.query({
1169
1243
  * query: `query { stores { id name status } }`,
1170
1244
  * });
1245
+ *
1246
+ * @example
1247
+ * // Per-environment webhook public keys
1248
+ * const client = new WaffoPancake({
1249
+ * merchantId: "...",
1250
+ * privateKey: "...",
1251
+ * webhookPublicKey: {
1252
+ * test: process.env.WAFFO_TEST_PUB_KEY!,
1253
+ * prod: process.env.WAFFO_PROD_PUB_KEY!,
1254
+ * },
1255
+ * });
1256
+ * const event = client.webhooks.verify(rawBody, signatureHeader);
1171
1257
  */
1172
1258
  declare class WaffoPancake {
1173
1259
  private readonly http;
@@ -1180,6 +1266,7 @@ declare class WaffoPancake {
1180
1266
  readonly orders: OrdersResource;
1181
1267
  readonly checkout: CheckoutResource;
1182
1268
  readonly graphql: GraphQLResource;
1269
+ readonly webhooks: WebhooksResource;
1183
1270
  constructor(config: WaffoPancakeConfig);
1184
1271
  }
1185
1272
 
@@ -1205,8 +1292,12 @@ declare class WaffoPancakeError extends Error {
1205
1292
  /**
1206
1293
  * Verify and parse an incoming Waffo Pancake webhook event.
1207
1294
  *
1208
- * Uses built-in Waffo public keys (RSA-SHA256) for signature verification.
1209
- * Test and production environments use different key pairs; both are embedded in the SDK.
1295
+ * Public key resolution (per environment):
1296
+ * 1. `options.publicKey` per-call override (highest priority, skips all other resolution)
1297
+ * 2. `options.publicKeys[env]` or `options.publicKeys` (string) — config-level
1298
+ * 3. `WAFFO_WEBHOOK_{TEST|PROD}_PUBLIC_KEY` environment variable
1299
+ * 4. `WAFFO_WEBHOOK_PUBLIC_KEY` environment variable
1300
+ * 5. Built-in hardcoded key
1210
1301
  *
1211
1302
  * Behavior:
1212
1303
  * - Parses the `X-Waffo-Signature` header (`t=<timestamp>,v1=<base64sig>`)
@@ -1255,4 +1346,4 @@ declare class WaffoPancakeError extends Error {
1255
1346
  */
1256
1347
  declare function verifyWebhook<T = Record<string, unknown>>(payload: string, signatureHeader: string | undefined | null, options?: VerifyWebhookOptions): WebhookEvent<T>;
1257
1348
 
1258
- export { type AddMerchantParams, type AddMerchantResult, type ApiError, type ApiErrorResponse, type ApiResponse, type ApiSuccessResponse, type BillingDetail, BillingPeriod, type CancelSubscriptionParams, type CancelSubscriptionResult, CheckoutSessionProductType, type CheckoutSessionResult, type CheckoutSettings, type CheckoutThemeSettings, type CreateCheckoutSessionParams, type CreateOnetimeProductParams, type CreateStoreParams, type CreateSubscriptionProductGroupParams, type CreateSubscriptionProductParams, type DeleteStoreParams, type DeleteSubscriptionProductGroupParams, EntityStatus, Environment, ErrorLayer, type GraphQLParams, type GraphQLResponse, type GroupRules, type IssueSessionTokenParams, type MediaItem, MediaType, type NotificationSettings, OnetimeOrderStatus, type OnetimeProductDetail, PaymentStatus, type PriceInfo, type Prices, ProductVersionStatus, type PublishOnetimeProductParams, type PublishSubscriptionProductGroupParams, type PublishSubscriptionProductParams, RefundStatus, RefundTicketStatus, type RemoveMerchantParams, type RemoveMerchantResult, type SessionToken, type Store, StoreRole, SubscriptionOrderStatus, type SubscriptionProductDetail, type SubscriptionProductGroup, TaxCategory, type UpdateOnetimeProductParams, type UpdateOnetimeStatusParams, type UpdateRoleParams, type UpdateRoleResult, type UpdateStoreParams, type UpdateSubscriptionProductGroupParams, type UpdateSubscriptionProductParams, type UpdateSubscriptionStatusParams, type VerifyWebhookOptions, WaffoPancake, type WaffoPancakeConfig, WaffoPancakeError, type WebhookEvent, type WebhookEventData, WebhookEventType, type WebhookSettings, verifyWebhook };
1349
+ export { type AddMerchantParams, type AddMerchantResult, type ApiError, type ApiErrorResponse, type ApiResponse, type ApiSuccessResponse, type BillingDetail, BillingPeriod, type CancelSubscriptionParams, type CancelSubscriptionResult, CheckoutSessionProductType, type CheckoutSessionResult, type CheckoutSettings, type CheckoutThemeSettings, type CreateCheckoutSessionParams, type CreateOnetimeProductParams, type CreateStoreParams, type CreateSubscriptionProductGroupParams, type CreateSubscriptionProductParams, type DeleteStoreParams, type DeleteSubscriptionProductGroupParams, EntityStatus, Environment, ErrorLayer, type GraphQLParams, type GraphQLResponse, type GroupRules, type IssueSessionTokenParams, type MediaItem, MediaType, type NotificationSettings, OnetimeOrderStatus, type OnetimeProductDetail, PaymentStatus, type PriceInfo, type Prices, ProductVersionStatus, type PublishOnetimeProductParams, type PublishSubscriptionProductGroupParams, type PublishSubscriptionProductParams, RefundStatus, RefundTicketStatus, type RemoveMerchantParams, type RemoveMerchantResult, type SessionToken, type Store, StoreRole, SubscriptionOrderStatus, type SubscriptionProductDetail, type SubscriptionProductGroup, TaxCategory, type UpdateOnetimeProductParams, type UpdateOnetimeStatusParams, type UpdateRoleParams, type UpdateRoleResult, type UpdateStoreParams, type UpdateSubscriptionProductGroupParams, type UpdateSubscriptionProductParams, type UpdateSubscriptionStatusParams, type VerifyWebhookOptions, WaffoPancake, type WaffoPancakeConfig, WaffoPancakeError, type WebhookEvent, type WebhookEventData, WebhookEventType, type WebhookPublicKeys, type WebhookSettings, verifyWebhook };
package/dist/index.d.ts CHANGED
@@ -7,6 +7,16 @@ interface WaffoPancakeConfig {
7
7
  baseUrl?: string;
8
8
  /** Custom fetch implementation (default: global fetch) */
9
9
  fetch?: typeof fetch;
10
+ /**
11
+ * Custom RSA public key(s) for webhook signature verification.
12
+ *
13
+ * - `string` — single key used for both test and prod environments
14
+ * - `{ test?, prod? }` — per-environment keys
15
+ *
16
+ * Resolution order per environment: config key → env var → built-in key.
17
+ * @see {@link VerifyWebhookOptions} for per-call overrides
18
+ */
19
+ webhookPublicKey?: WebhookPublicKeys;
10
20
  }
11
21
  /**
12
22
  * Single error object within the `errors` array.
@@ -239,7 +249,6 @@ interface CheckoutThemeSettings {
239
249
  checkoutColorBackground: string;
240
250
  checkoutColorCard: string;
241
251
  checkoutColorText: string;
242
- checkoutColorTextSecondary: string;
243
252
  checkoutBorderRadius: string;
244
253
  }
245
254
  /**
@@ -247,6 +256,7 @@ interface CheckoutThemeSettings {
247
256
  * @see waffo-pancake-store-service/app/lib/types.ts
248
257
  */
249
258
  interface CheckoutSettings {
259
+ defaultDarkMode: boolean;
250
260
  light: CheckoutThemeSettings;
251
261
  dark: CheckoutThemeSettings;
252
262
  }
@@ -262,7 +272,6 @@ interface Store {
262
272
  supportEmail: string | null;
263
273
  website: string | null;
264
274
  slug: string | null;
265
- isPublic: boolean;
266
275
  prodEnabled: boolean;
267
276
  webhookSettings: WebhookSettings | null;
268
277
  notificationSettings: NotificationSettings | null;
@@ -283,9 +292,6 @@ interface UpdateStoreParams {
283
292
  name?: string;
284
293
  status?: EntityStatus;
285
294
  logo?: string | null;
286
- supportEmail?: string | null;
287
- website?: string | null;
288
- isPublic?: boolean;
289
295
  webhookSettings?: WebhookSettings | null;
290
296
  notificationSettings?: NotificationSettings | null;
291
297
  checkoutSettings?: CheckoutSettings | null;
@@ -343,17 +349,15 @@ interface UpdateRoleResult {
343
349
  *
344
350
  * @example
345
351
  * // USD $9.99
346
- * { amount: 999, taxIncluded: true, taxCategory: "saas" }
352
+ * { amount: 999, taxCategory: "saas" }
347
353
  *
348
354
  * @example
349
355
  * // JPY ¥1000
350
- * { amount: 1000, taxIncluded: false, taxCategory: "software" }
356
+ * { amount: 1000, taxCategory: "software" }
351
357
  */
352
358
  interface PriceInfo {
353
359
  /** Price amount in smallest currency unit */
354
360
  amount: number;
355
- /** Whether the price is tax-inclusive */
356
- taxIncluded: boolean;
357
361
  /** Tax category */
358
362
  taxCategory: TaxCategory;
359
363
  }
@@ -364,8 +368,8 @@ interface PriceInfo {
364
368
  *
365
369
  * @example
366
370
  * {
367
- * "USD": { amount: 999, taxIncluded: true, taxCategory: "saas" },
368
- * "EUR": { amount: 899, taxIncluded: true, taxCategory: "saas" }
371
+ * "USD": { amount: 999, taxCategory: "saas" },
372
+ * "EUR": { amount: 899, taxCategory: "saas" }
369
373
  * }
370
374
  */
371
375
  type Prices = Record<string, PriceInfo>;
@@ -576,13 +580,13 @@ interface BillingDetail {
576
580
  country: string;
577
581
  /** Whether this is a business purchase */
578
582
  isBusiness: boolean;
579
- /** Postal / ZIP code */
583
+ /** Postal / ZIP code (required for US, at least one of postcode/state for CA) */
580
584
  postcode?: string;
581
- /** State / province code (required for US/CA) */
585
+ /** State / province code (at least one of state/postcode for CA) */
582
586
  state?: string;
583
- /** Business name (required when isBusiness=true) */
587
+ /** Business name (recommended for invoicing, does not affect tax calculation) */
584
588
  businessName?: string;
585
- /** Tax ID (required for EU businesses) */
589
+ /** Tax ID / VAT number (EU businesses: triggers reverse charge 0% when provided) */
586
590
  taxId?: string;
587
591
  }
588
592
  /**
@@ -591,7 +595,7 @@ interface BillingDetail {
591
595
  */
592
596
  interface CreateCheckoutSessionParams {
593
597
  /** Store ID */
594
- storeId?: string;
598
+ storeId: string;
595
599
  /** Product ID */
596
600
  productId: string;
597
601
  /** Product type */
@@ -608,8 +612,10 @@ interface CreateCheckoutSessionParams {
608
612
  billingDetail?: BillingDetail;
609
613
  /** Redirect URL after successful payment */
610
614
  successUrl?: string;
611
- /** Session expiration in seconds (default: 7 days) */
615
+ /** Session expiration in seconds (default: 45 minutes) */
612
616
  expiresInSeconds?: number;
617
+ /** Dark mode override (true=dark, false=light, omit=use store default) */
618
+ darkMode?: boolean;
613
619
  /** Custom metadata */
614
620
  metadata?: Record<string, string>;
615
621
  }
@@ -713,11 +719,22 @@ interface WebhookEvent<T = WebhookEventData> {
713
719
  /** Event data */
714
720
  data: T;
715
721
  }
722
+ /**
723
+ * Webhook public key configuration.
724
+ *
725
+ * - `string` — single key used for both test and prod environments
726
+ * - `{ test?, prod? }` — per-environment keys
727
+ */
728
+ type WebhookPublicKeys = string | {
729
+ test?: string;
730
+ prod?: string;
731
+ };
716
732
  /** Options for {@link verifyWebhook}. */
717
733
  interface VerifyWebhookOptions {
718
734
  /**
719
735
  * Specify which environment's public key to use for verification.
720
736
  * When omitted, both keys are tried automatically (prod first).
737
+ * Ignored when `publicKey` is provided.
721
738
  */
722
739
  environment?: `${Environment}`;
723
740
  /**
@@ -726,6 +743,24 @@ interface VerifyWebhookOptions {
726
743
  * @default 300000 (5 minutes)
727
744
  */
728
745
  toleranceMs?: number;
746
+ /**
747
+ * Per-call public key override (highest priority).
748
+ * When provided, skips all other key resolution (config, env vars, built-in).
749
+ */
750
+ publicKey?: string;
751
+ /**
752
+ * Config-level public key(s) for the resolution chain.
753
+ * When using `client.webhooks.verify()`, this is set automatically from `WaffoPancakeConfig.webhookPublicKey`.
754
+ * When using the standalone `verifyWebhook()`, you can pass this directly for config-level key injection.
755
+ *
756
+ * Resolution order per environment:
757
+ * 1. `publicKey` (per-call override)
758
+ * 2. `publicKeys[env]` or `publicKeys` (config)
759
+ * 3. `WAFFO_WEBHOOK_{TEST|PROD}_PUBLIC_KEY` (env var)
760
+ * 4. `WAFFO_WEBHOOK_PUBLIC_KEY` (env var)
761
+ * 5. Built-in hardcoded key
762
+ */
763
+ publicKeys?: WebhookPublicKeys;
729
764
  }
730
765
 
731
766
  /**
@@ -836,7 +871,7 @@ declare class OnetimeProductsResource {
836
871
  * const { product } = await client.onetimeProducts.create({
837
872
  * storeId: "store_xxx",
838
873
  * name: "E-Book",
839
- * prices: { USD: { amount: 2900, taxIncluded: false, taxCategory: "digital_goods" } },
874
+ * prices: { USD: { amount: 2900, taxCategory: "digital_goods" } },
840
875
  * });
841
876
  */
842
877
  create(params: CreateOnetimeProductParams): Promise<{
@@ -852,7 +887,7 @@ declare class OnetimeProductsResource {
852
887
  * const { product } = await client.onetimeProducts.update({
853
888
  * id: "prod_xxx",
854
889
  * name: "E-Book v2",
855
- * prices: { USD: { amount: 3900, taxIncluded: false, taxCategory: "digital_goods" } },
890
+ * prices: { USD: { amount: 3900, taxCategory: "digital_goods" } },
856
891
  * });
857
892
  */
858
893
  update(params: UpdateOnetimeProductParams): Promise<{
@@ -982,7 +1017,6 @@ declare class StoresResource {
982
1017
  * const { store } = await client.stores.update({
983
1018
  * id: "store_xxx",
984
1019
  * name: "Updated Name",
985
- * supportEmail: "help@example.com",
986
1020
  * });
987
1021
  */
988
1022
  update(params: UpdateStoreParams): Promise<{
@@ -1079,7 +1113,7 @@ declare class SubscriptionProductsResource {
1079
1113
  * storeId: "store_xxx",
1080
1114
  * name: "Pro Plan",
1081
1115
  * billingPeriod: "monthly",
1082
- * prices: { USD: { amount: 999, taxIncluded: false, taxCategory: "saas" } },
1116
+ * prices: { USD: { amount: 999, taxCategory: "saas" } },
1083
1117
  * });
1084
1118
  */
1085
1119
  create(params: CreateSubscriptionProductParams): Promise<{
@@ -1096,7 +1130,7 @@ declare class SubscriptionProductsResource {
1096
1130
  * id: "prod_xxx",
1097
1131
  * name: "Pro Plan v2",
1098
1132
  * billingPeriod: "monthly",
1099
- * prices: { USD: { amount: 1499, taxIncluded: false, taxCategory: "saas" } },
1133
+ * prices: { USD: { amount: 1499, taxCategory: "saas" } },
1100
1134
  * });
1101
1135
  */
1102
1136
  update(params: UpdateSubscriptionProductParams): Promise<{
@@ -1131,6 +1165,46 @@ declare class SubscriptionProductsResource {
1131
1165
  }>;
1132
1166
  }
1133
1167
 
1168
+ /**
1169
+ * Webhook signature verification resource.
1170
+ *
1171
+ * Unlike other resources, this does not use HttpClient — webhook verification
1172
+ * is a local cryptographic operation that does not require API calls.
1173
+ */
1174
+ declare class WebhooksResource {
1175
+ private readonly publicKeys;
1176
+ /** @param publicKeys - Optional config-level public key(s) from WaffoPancakeConfig */
1177
+ constructor(publicKeys: WebhookPublicKeys | undefined);
1178
+ /**
1179
+ * Verify and parse an incoming webhook event.
1180
+ *
1181
+ * Key resolution order:
1182
+ * 1. `options.publicKey` — per-call override (highest priority)
1183
+ * 2. `config.webhookPublicKey[env]` or `config.webhookPublicKey` (string)
1184
+ * 3. `WAFFO_WEBHOOK_{TEST|PROD}_PUBLIC_KEY` environment variable
1185
+ * 4. `WAFFO_WEBHOOK_PUBLIC_KEY` environment variable
1186
+ * 5. Built-in hardcoded key
1187
+ *
1188
+ * @param payload - Raw request body string (must be unparsed)
1189
+ * @param signatureHeader - Value of the `X-Waffo-Signature` header
1190
+ * @param options - Verification options (optional)
1191
+ * @returns Parsed webhook event
1192
+ * @throws Error if signature is invalid, header is malformed, or timestamp is stale
1193
+ *
1194
+ * @example
1195
+ * const event = client.webhooks.verify(rawBody, signatureHeader);
1196
+ *
1197
+ * @example
1198
+ * // Specify environment
1199
+ * const event = client.webhooks.verify(rawBody, sig, { environment: "test" });
1200
+ *
1201
+ * @example
1202
+ * // Per-call key override
1203
+ * const event = client.webhooks.verify(rawBody, sig, { publicKey: oneOffKey });
1204
+ */
1205
+ verify<T = Record<string, unknown>>(payload: string, signatureHeader: string | undefined | null, options?: VerifyWebhookOptions): WebhookEvent<T>;
1206
+ }
1207
+
1134
1208
  /**
1135
1209
  * Waffo Pancake TypeScript SDK client.
1136
1210
  *
@@ -1152,7 +1226,7 @@ declare class SubscriptionProductsResource {
1152
1226
  * const { product } = await client.onetimeProducts.create({
1153
1227
  * storeId: store.id,
1154
1228
  * name: "E-Book",
1155
- * prices: { USD: { amount: 2900, taxIncluded: false, taxCategory: "digital_goods" } },
1229
+ * prices: { USD: { amount: 2900, taxCategory: "digital_goods" } },
1156
1230
  * });
1157
1231
  *
1158
1232
  * // Create a checkout session
@@ -1168,6 +1242,18 @@ declare class SubscriptionProductsResource {
1168
1242
  * const result = await client.graphql.query({
1169
1243
  * query: `query { stores { id name status } }`,
1170
1244
  * });
1245
+ *
1246
+ * @example
1247
+ * // Per-environment webhook public keys
1248
+ * const client = new WaffoPancake({
1249
+ * merchantId: "...",
1250
+ * privateKey: "...",
1251
+ * webhookPublicKey: {
1252
+ * test: process.env.WAFFO_TEST_PUB_KEY!,
1253
+ * prod: process.env.WAFFO_PROD_PUB_KEY!,
1254
+ * },
1255
+ * });
1256
+ * const event = client.webhooks.verify(rawBody, signatureHeader);
1171
1257
  */
1172
1258
  declare class WaffoPancake {
1173
1259
  private readonly http;
@@ -1180,6 +1266,7 @@ declare class WaffoPancake {
1180
1266
  readonly orders: OrdersResource;
1181
1267
  readonly checkout: CheckoutResource;
1182
1268
  readonly graphql: GraphQLResource;
1269
+ readonly webhooks: WebhooksResource;
1183
1270
  constructor(config: WaffoPancakeConfig);
1184
1271
  }
1185
1272
 
@@ -1205,8 +1292,12 @@ declare class WaffoPancakeError extends Error {
1205
1292
  /**
1206
1293
  * Verify and parse an incoming Waffo Pancake webhook event.
1207
1294
  *
1208
- * Uses built-in Waffo public keys (RSA-SHA256) for signature verification.
1209
- * Test and production environments use different key pairs; both are embedded in the SDK.
1295
+ * Public key resolution (per environment):
1296
+ * 1. `options.publicKey` per-call override (highest priority, skips all other resolution)
1297
+ * 2. `options.publicKeys[env]` or `options.publicKeys` (string) — config-level
1298
+ * 3. `WAFFO_WEBHOOK_{TEST|PROD}_PUBLIC_KEY` environment variable
1299
+ * 4. `WAFFO_WEBHOOK_PUBLIC_KEY` environment variable
1300
+ * 5. Built-in hardcoded key
1210
1301
  *
1211
1302
  * Behavior:
1212
1303
  * - Parses the `X-Waffo-Signature` header (`t=<timestamp>,v1=<base64sig>`)
@@ -1255,4 +1346,4 @@ declare class WaffoPancakeError extends Error {
1255
1346
  */
1256
1347
  declare function verifyWebhook<T = Record<string, unknown>>(payload: string, signatureHeader: string | undefined | null, options?: VerifyWebhookOptions): WebhookEvent<T>;
1257
1348
 
1258
- export { type AddMerchantParams, type AddMerchantResult, type ApiError, type ApiErrorResponse, type ApiResponse, type ApiSuccessResponse, type BillingDetail, BillingPeriod, type CancelSubscriptionParams, type CancelSubscriptionResult, CheckoutSessionProductType, type CheckoutSessionResult, type CheckoutSettings, type CheckoutThemeSettings, type CreateCheckoutSessionParams, type CreateOnetimeProductParams, type CreateStoreParams, type CreateSubscriptionProductGroupParams, type CreateSubscriptionProductParams, type DeleteStoreParams, type DeleteSubscriptionProductGroupParams, EntityStatus, Environment, ErrorLayer, type GraphQLParams, type GraphQLResponse, type GroupRules, type IssueSessionTokenParams, type MediaItem, MediaType, type NotificationSettings, OnetimeOrderStatus, type OnetimeProductDetail, PaymentStatus, type PriceInfo, type Prices, ProductVersionStatus, type PublishOnetimeProductParams, type PublishSubscriptionProductGroupParams, type PublishSubscriptionProductParams, RefundStatus, RefundTicketStatus, type RemoveMerchantParams, type RemoveMerchantResult, type SessionToken, type Store, StoreRole, SubscriptionOrderStatus, type SubscriptionProductDetail, type SubscriptionProductGroup, TaxCategory, type UpdateOnetimeProductParams, type UpdateOnetimeStatusParams, type UpdateRoleParams, type UpdateRoleResult, type UpdateStoreParams, type UpdateSubscriptionProductGroupParams, type UpdateSubscriptionProductParams, type UpdateSubscriptionStatusParams, type VerifyWebhookOptions, WaffoPancake, type WaffoPancakeConfig, WaffoPancakeError, type WebhookEvent, type WebhookEventData, WebhookEventType, type WebhookSettings, verifyWebhook };
1349
+ export { type AddMerchantParams, type AddMerchantResult, type ApiError, type ApiErrorResponse, type ApiResponse, type ApiSuccessResponse, type BillingDetail, BillingPeriod, type CancelSubscriptionParams, type CancelSubscriptionResult, CheckoutSessionProductType, type CheckoutSessionResult, type CheckoutSettings, type CheckoutThemeSettings, type CreateCheckoutSessionParams, type CreateOnetimeProductParams, type CreateStoreParams, type CreateSubscriptionProductGroupParams, type CreateSubscriptionProductParams, type DeleteStoreParams, type DeleteSubscriptionProductGroupParams, EntityStatus, Environment, ErrorLayer, type GraphQLParams, type GraphQLResponse, type GroupRules, type IssueSessionTokenParams, type MediaItem, MediaType, type NotificationSettings, OnetimeOrderStatus, type OnetimeProductDetail, PaymentStatus, type PriceInfo, type Prices, ProductVersionStatus, type PublishOnetimeProductParams, type PublishSubscriptionProductGroupParams, type PublishSubscriptionProductParams, RefundStatus, RefundTicketStatus, type RemoveMerchantParams, type RemoveMerchantResult, type SessionToken, type Store, StoreRole, SubscriptionOrderStatus, type SubscriptionProductDetail, type SubscriptionProductGroup, TaxCategory, type UpdateOnetimeProductParams, type UpdateOnetimeStatusParams, type UpdateRoleParams, type UpdateRoleResult, type UpdateStoreParams, type UpdateSubscriptionProductGroupParams, type UpdateSubscriptionProductParams, type UpdateSubscriptionStatusParams, type VerifyWebhookOptions, WaffoPancake, type WaffoPancakeConfig, WaffoPancakeError, type WebhookEvent, type WebhookEventData, WebhookEventType, type WebhookPublicKeys, type WebhookSettings, verifyWebhook };