@waffo/pancake-ts 0.1.5 → 0.1.9

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
@@ -1,14 +1,22 @@
1
1
  interface WaffoPancakeConfig {
2
- /** Merchant ID (X-Merchant-Id header) */
2
+ /** Merchant ID in `MER_{base62}` format (sent as X-Merchant-Id header) */
3
3
  merchantId: string;
4
4
  /** RSA private key in PEM format for request signing */
5
5
  privateKey: string;
6
- /** Base URL override (default: https://waffo-pancake-auth-service.vercel.app) */
6
+ /** Base URL override (default: https://api.waffo.ai) */
7
7
  baseUrl?: string;
8
8
  /** Custom fetch implementation (default: global fetch) */
9
9
  fetch?: typeof fetch;
10
- /** Custom RSA public key (PEM) for webhook signature verification. When set, overrides the built-in Waffo public keys. */
11
- webhookPublicKey?: string;
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;
12
20
  }
13
21
  /**
14
22
  * Single error object within the `errors` array.
@@ -107,10 +115,11 @@ declare enum OnetimeOrderStatus {
107
115
  * Subscription order status.
108
116
  *
109
117
  * State machine:
110
- * - pending -> active, canceled
118
+ * - pending -> active, canceled, closed (PSP CLOSE from never-activated)
111
119
  * - active -> canceling, past_due, canceled, expired
112
120
  * - canceling -> active, canceled
113
121
  * - past_due -> active, canceled
122
+ * - closed -> terminal (never-activated subscription closed by PSP)
114
123
  * - canceled -> terminal
115
124
  * - expired -> terminal
116
125
  *
@@ -120,8 +129,9 @@ declare enum SubscriptionOrderStatus {
120
129
  Pending = "pending",
121
130
  Active = "active",
122
131
  Canceling = "canceling",
123
- Canceled = "canceled",
124
132
  PastDue = "past_due",
133
+ Closed = "closed",
134
+ Canceled = "canceled",
125
135
  Expired = "expired"
126
136
  }
127
137
  /**
@@ -177,8 +187,10 @@ declare enum ErrorLayer {
177
187
  Store = "store",
178
188
  Product = "product",
179
189
  Order = "order",
190
+ Ticket = "ticket",
180
191
  GraphQL = "graphql",
181
192
  Resource = "resource",
193
+ /** SDK-specific layer for email delivery errors (not part of the service-side error layers). */
182
194
  Email = "email"
183
195
  }
184
196
  /**
@@ -281,11 +293,21 @@ interface CreateStoreParams {
281
293
  interface UpdateStoreParams {
282
294
  /** Store ID */
283
295
  id: string;
296
+ /** Store display name */
284
297
  name?: string;
298
+ /** Store status */
285
299
  status?: EntityStatus;
300
+ /** Store logo URL (set to `null` to remove) */
286
301
  logo?: string | null;
302
+ /** Support email address (set to `null` to remove) */
303
+ supportEmail?: string | null;
304
+ /** Store website URL (set to `null` to remove) */
305
+ website?: string | null;
306
+ /** Webhook configuration for test and production environments (set to `null` to remove) */
287
307
  webhookSettings?: WebhookSettings | null;
308
+ /** Notification preferences (set to `null` to remove) */
288
309
  notificationSettings?: NotificationSettings | null;
310
+ /** Checkout page theme configuration (set to `null` to remove) */
289
311
  checkoutSettings?: CheckoutSettings | null;
290
312
  }
291
313
  /** Parameters for deleting (soft-delete) a store. */
@@ -334,22 +356,22 @@ interface UpdateRoleResult {
334
356
  /**
335
357
  * Price for a single currency.
336
358
  *
337
- * Amounts are stored in the smallest currency unit (e.g. cents, yen)
338
- * to avoid floating-point precision issues.
359
+ * Amounts are represented as display strings (e.g., "9.99" for USD, "1000" for JPY).
360
+ * The server handles conversion to/from smallest currency units internally.
339
361
  *
340
362
  * @see waffo-pancake-product-service/app/lib/resources/types.ts
341
363
  *
342
364
  * @example
343
365
  * // USD $9.99
344
- * { amount: 999, taxCategory: "saas" }
366
+ * { amount: "9.99", taxCategory: "saas" }
345
367
  *
346
368
  * @example
347
369
  * // JPY ¥1000
348
370
  * { amount: 1000, taxCategory: "software" }
349
371
  */
350
372
  interface PriceInfo {
351
- /** Price amount in smallest currency unit */
352
- amount: number;
373
+ /** Price amount as display string (e.g., "9.99" for USD, "1000" for JPY) */
374
+ amount: string;
353
375
  /** Tax category */
354
376
  taxCategory: TaxCategory;
355
377
  }
@@ -360,7 +382,7 @@ interface PriceInfo {
360
382
  *
361
383
  * @example
362
384
  * {
363
- * "USD": { amount: 999, taxCategory: "saas" },
385
+ * "USD": { amount: "9.99", taxCategory: "saas" },
364
386
  * "EUR": { amount: 899, taxCategory: "saas" }
365
387
  * }
366
388
  */
@@ -620,6 +642,104 @@ interface CheckoutSessionResult {
620
642
  /** Session expiration time (ISO 8601 UTC) */
621
643
  expiresAt: string;
622
644
  }
645
+ /**
646
+ * Parameters for anonymous checkout (visitor → shopper).
647
+ *
648
+ * The buyer enters the checkout page without a session token and fills in
649
+ * billing details manually. No identity is provided upfront.
650
+ *
651
+ * @example
652
+ * const result = await client.checkout.anonymous.create({
653
+ * storeId: "STO_xxx",
654
+ * productId: "PROD_xxx",
655
+ * productType: "onetime",
656
+ * currency: "USD",
657
+ * });
658
+ * // Redirect to result.checkoutUrl
659
+ */
660
+ interface AnonymousCheckoutParams {
661
+ /** Store ID */
662
+ storeId: string;
663
+ /** Product ID */
664
+ productId: string;
665
+ /** Product type */
666
+ productType: `${CheckoutSessionProductType}`;
667
+ /** Currency code (ISO 4217) */
668
+ currency: string;
669
+ /** Optional price snapshot override (reads from DB if omitted) */
670
+ priceSnapshot?: PriceInfo;
671
+ /** Trial toggle override (subscription only) */
672
+ withTrial?: boolean;
673
+ /** Redirect URL after successful payment */
674
+ successUrl?: string;
675
+ /** Session expiration in seconds (default: 45 minutes) */
676
+ expiresInSeconds?: number;
677
+ /** Dark mode override (true=dark, false=light, omit=use store default) */
678
+ darkMode?: boolean;
679
+ /** Custom metadata */
680
+ metadata?: Record<string, string>;
681
+ }
682
+ /**
683
+ * Parameters for authenticated checkout (customer).
684
+ *
685
+ * The merchant provides a buyer identity; the SDK issues a session token
686
+ * and appends it to the checkout URL as a URL fragment.
687
+ *
688
+ * @example
689
+ * const result = await client.checkout.authenticated.create({
690
+ * storeId: "STO_xxx",
691
+ * productId: "PROD_xxx",
692
+ * productType: "onetime",
693
+ * currency: "USD",
694
+ * buyerIdentity: "customer@example.com",
695
+ * });
696
+ * // Redirect to result.checkoutUrl (includes #token=...)
697
+ */
698
+ interface AuthenticatedCheckoutParams {
699
+ /** Store ID */
700
+ storeId: string;
701
+ /** Product ID */
702
+ productId: string;
703
+ /** Product type */
704
+ productType: `${CheckoutSessionProductType}`;
705
+ /** Currency code (ISO 4217) */
706
+ currency: string;
707
+ /** Buyer identity (email or merchant-provided identifier) */
708
+ buyerIdentity: string;
709
+ /** Pre-filled buyer email (defaults to `buyerIdentity` when omitted) */
710
+ buyerEmail?: string;
711
+ /** Pre-filled billing details */
712
+ billingDetail?: BillingDetail;
713
+ /** Optional price snapshot override (reads from DB if omitted) */
714
+ priceSnapshot?: PriceInfo;
715
+ /** Trial toggle override (subscription only) */
716
+ withTrial?: boolean;
717
+ /** Redirect URL after successful payment */
718
+ successUrl?: string;
719
+ /** Session expiration in seconds (default: 45 minutes) */
720
+ expiresInSeconds?: number;
721
+ /** Dark mode override (true=dark, false=light, omit=use store default) */
722
+ darkMode?: boolean;
723
+ /** Custom metadata */
724
+ metadata?: Record<string, string>;
725
+ }
726
+ /**
727
+ * Result of an authenticated checkout creation.
728
+ *
729
+ * Extends the base session result with the issued token details.
730
+ */
731
+ interface AuthenticatedCheckoutResult {
732
+ /** Session ID */
733
+ sessionId: string;
734
+ /** Checkout URL with session token appended as URL fragment (`#token=...`) */
735
+ checkoutUrl: string;
736
+ /** Session expiration time (ISO 8601 UTC) */
737
+ expiresAt: string;
738
+ /** Issued JWT token */
739
+ token: string;
740
+ /** Token expiration time (ISO 8601 UTC) */
741
+ tokenExpiresAt: string;
742
+ }
623
743
  /** Parameters for a GraphQL query. */
624
744
  interface GraphQLParams {
625
745
  /** GraphQL query string */
@@ -673,10 +793,10 @@ interface WebhookEventData {
673
793
  orderId: string;
674
794
  buyerEmail: string;
675
795
  currency: string;
676
- /** Amount in smallest currency unit */
677
- amount: number;
678
- /** Tax amount in smallest currency unit */
679
- taxAmount: number;
796
+ /** Amount as display string (e.g., "9.99" for USD, "1000" for JPY) */
797
+ amount: string;
798
+ /** Tax amount as display string (e.g., "0.91" for USD) */
799
+ taxAmount: string;
680
800
  productName: string;
681
801
  }
682
802
  /**
@@ -689,8 +809,8 @@ interface WebhookEventData {
689
809
  * id: "550e8400-...",
690
810
  * timestamp: "2026-03-10T08:30:00.000Z",
691
811
  * eventType: "order.completed",
692
- * eventId: "pay_660e8400-...",
693
- * storeId: "770e8400-...",
812
+ * eventId: "PAY_5xK9mRtYvWnPqLsJ3hBfDe",
813
+ * storeId: "STO_2aUyqjCzEIiEcYMKj7TZtw",
694
814
  * mode: "prod",
695
815
  * data: { orderId: "...", buyerEmail: "...", currency: "USD", amount: 2900, taxAmount: 290, productName: "Pro Plan" }
696
816
  * }
@@ -711,6 +831,16 @@ interface WebhookEvent<T = WebhookEventData> {
711
831
  /** Event data */
712
832
  data: T;
713
833
  }
834
+ /**
835
+ * Webhook public key configuration.
836
+ *
837
+ * - `string` — single key used for both test and prod environments
838
+ * - `{ test?, prod? }` — per-environment keys
839
+ */
840
+ type WebhookPublicKeys = string | {
841
+ test?: string;
842
+ prod?: string;
843
+ };
714
844
  /** Options for {@link verifyWebhook}. */
715
845
  interface VerifyWebhookOptions {
716
846
  /**
@@ -726,15 +856,31 @@ interface VerifyWebhookOptions {
726
856
  */
727
857
  toleranceMs?: number;
728
858
  /**
729
- * Custom RSA public key (PEM) for signature verification.
730
- * When provided, overrides both built-in keys and the `environment` option.
859
+ * Per-call public key override (highest priority).
860
+ * When provided, skips all other key resolution (config, env vars, built-in).
731
861
  */
732
862
  publicKey?: string;
863
+ /**
864
+ * Config-level public key(s) for the resolution chain.
865
+ * When using `client.webhooks.verify()`, this is set automatically from `WaffoPancakeConfig.webhookPublicKey`.
866
+ * When using the standalone `verifyWebhook()`, you can pass this directly for config-level key injection.
867
+ *
868
+ * Resolution order per environment:
869
+ * 1. `publicKey` (per-call override)
870
+ * 2. `publicKeys[env]` or `publicKeys` (config)
871
+ * 3. `WAFFO_WEBHOOK_{TEST|PROD}_PUBLIC_KEY` (env var)
872
+ * 4. `WAFFO_WEBHOOK_PUBLIC_KEY` (env var)
873
+ * 5. Built-in hardcoded key
874
+ */
875
+ publicKeys?: WebhookPublicKeys;
733
876
  }
734
877
 
735
878
  /**
736
879
  * Internal HTTP client that auto-signs requests and attaches idempotency keys.
737
880
  *
881
+ * The `X-Merchant-Id` header is sent in `MER_{base62}` format as provided by the user.
882
+ * The gateway decodes it to a raw UUID before forwarding to downstream services.
883
+ *
738
884
  * Not exported publicly — used by resource classes via {@link WaffoPancake}.
739
885
  */
740
886
  declare class HttpClient {
@@ -771,27 +917,124 @@ declare class AuthResource {
771
917
  *
772
918
  * @example
773
919
  * const { token, expiresAt } = await client.auth.issueSessionToken({
774
- * storeId: "store_xxx",
920
+ * storeId: "STO_xxx",
775
921
  * buyerIdentity: "customer@example.com",
776
922
  * });
777
923
  */
778
924
  issueSessionToken(params: IssueSessionTokenParams): Promise<SessionToken>;
779
925
  }
780
926
 
781
- /** Checkout resource — create checkout sessions for payments. */
927
+ /**
928
+ * Anonymous checkout — visitor enters without a session token.
929
+ *
930
+ * The buyer fills in billing details manually on the checkout page.
931
+ * Internally creates a checkout session and returns the redirect URL.
932
+ */
933
+ declare class CheckoutAnonymousResource {
934
+ private readonly http;
935
+ constructor(http: HttpClient);
936
+ /**
937
+ * Create an anonymous checkout session.
938
+ *
939
+ * @param params - Checkout parameters (no buyer identity required)
940
+ * @returns Session ID, checkout URL, and expiration
941
+ *
942
+ * @example
943
+ * const result = await client.checkout.anonymous.create({
944
+ * storeId: "STO_xxx",
945
+ * productId: "PROD_xxx",
946
+ * productType: "onetime",
947
+ * currency: "USD",
948
+ * });
949
+ * // Redirect to result.checkoutUrl
950
+ */
951
+ create(params: AnonymousCheckoutParams): Promise<CheckoutSessionResult>;
952
+ }
953
+
954
+ /**
955
+ * Authenticated checkout — merchant provides buyer identity.
956
+ *
957
+ * Issues a session token, creates a checkout session, and returns a
958
+ * checkout URL with the token appended as a URL fragment (`#token=...`).
959
+ * The checkout page reads the fragment to pre-fill buyer information.
960
+ */
961
+ declare class CheckoutAuthenticatedResource {
962
+ private readonly http;
963
+ constructor(http: HttpClient);
964
+ /**
965
+ * Create an authenticated checkout session.
966
+ *
967
+ * Behavior:
968
+ * - Issues a session token via `issue-session-token`
969
+ * - Creates a checkout session via `create-session`
970
+ * - Appends the token to the checkout URL as a URL fragment
971
+ * - Defaults `buyerEmail` to `buyerIdentity` when omitted
972
+ *
973
+ * @param params - Checkout parameters including buyer identity
974
+ * @returns Session details with token-appended checkout URL
975
+ *
976
+ * @example
977
+ * const result = await client.checkout.authenticated.create({
978
+ * storeId: "STO_xxx",
979
+ * productId: "PROD_xxx",
980
+ * productType: "onetime",
981
+ * currency: "USD",
982
+ * buyerIdentity: "customer@example.com",
983
+ * });
984
+ * // Redirect to result.checkoutUrl (includes #token=...)
985
+ */
986
+ create(params: AuthenticatedCheckoutParams): Promise<AuthenticatedCheckoutResult>;
987
+ }
988
+
989
+ /**
990
+ * Checkout resource — create checkout sessions for payments.
991
+ *
992
+ * Provides two convenience sub-resources for the common checkout flows:
993
+ * - `anonymous` — visitor enters without identity (empty form)
994
+ * - `authenticated` — merchant provides buyer identity (pre-filled form + token)
995
+ *
996
+ * The low-level `createSession()` method is still available for full control.
997
+ *
998
+ * @example
999
+ * // Anonymous checkout (visitor → shopper)
1000
+ * const result = await client.checkout.anonymous.create({
1001
+ * storeId: "STO_xxx",
1002
+ * productId: "PROD_xxx",
1003
+ * productType: "onetime",
1004
+ * currency: "USD",
1005
+ * });
1006
+ *
1007
+ * @example
1008
+ * // Authenticated checkout (customer)
1009
+ * const result = await client.checkout.authenticated.create({
1010
+ * storeId: "STO_xxx",
1011
+ * productId: "PROD_xxx",
1012
+ * productType: "onetime",
1013
+ * currency: "USD",
1014
+ * buyerIdentity: "customer@example.com",
1015
+ * });
1016
+ * // result.checkoutUrl includes #token=...
1017
+ */
782
1018
  declare class CheckoutResource {
783
1019
  private readonly http;
1020
+ /** Anonymous checkout — visitor enters without a session token. */
1021
+ readonly anonymous: CheckoutAnonymousResource;
1022
+ /** Authenticated checkout — merchant provides buyer identity. */
1023
+ readonly authenticated: CheckoutAuthenticatedResource;
784
1024
  constructor(http: HttpClient);
785
1025
  /**
786
- * Create a checkout session. Returns a URL to redirect the customer to.
1026
+ * Create a checkout session (low-level). Returns a URL to redirect the customer to.
1027
+ *
1028
+ * For most use cases, prefer `checkout.anonymous.create()` or
1029
+ * `checkout.authenticated.create()` which handle the full flow automatically.
787
1030
  *
788
1031
  * @param params - Checkout session parameters
789
1032
  * @returns Session ID, checkout URL, and expiration
790
1033
  *
791
1034
  * @example
792
1035
  * const session = await client.checkout.createSession({
793
- * storeId: "store_xxx",
794
- * productId: "prod_xxx",
1036
+ * storeId: "STO_xxx",
1037
+ * productId: "PROD_xxx",
795
1038
  * productType: "onetime",
796
1039
  * currency: "USD",
797
1040
  * buyerEmail: "customer@example.com",
@@ -820,7 +1063,7 @@ declare class GraphQLResource {
820
1063
  * @example
821
1064
  * const result = await client.graphql.query({
822
1065
  * query: `query ($id: ID!) { onetimeProduct(id: $id) { id name prices } }`,
823
- * variables: { id: "prod_xxx" },
1066
+ * variables: { id: "PROD_xxx" },
824
1067
  * });
825
1068
  */
826
1069
  query<T = Record<string, unknown>>(params: GraphQLParams): Promise<GraphQLResponse<T>>;
@@ -838,9 +1081,9 @@ declare class OnetimeProductsResource {
838
1081
  *
839
1082
  * @example
840
1083
  * const { product } = await client.onetimeProducts.create({
841
- * storeId: "store_xxx",
1084
+ * storeId: "STO_xxx",
842
1085
  * name: "E-Book",
843
- * prices: { USD: { amount: 2900, taxCategory: "digital_goods" } },
1086
+ * prices: { USD: { amount: "29.00", taxCategory: "digital_goods" } },
844
1087
  * });
845
1088
  */
846
1089
  create(params: CreateOnetimeProductParams): Promise<{
@@ -854,9 +1097,9 @@ declare class OnetimeProductsResource {
854
1097
  *
855
1098
  * @example
856
1099
  * const { product } = await client.onetimeProducts.update({
857
- * id: "prod_xxx",
1100
+ * id: "PROD_xxx",
858
1101
  * name: "E-Book v2",
859
- * prices: { USD: { amount: 3900, taxCategory: "digital_goods" } },
1102
+ * prices: { USD: { amount: "39.00", taxCategory: "digital_goods" } },
860
1103
  * });
861
1104
  */
862
1105
  update(params: UpdateOnetimeProductParams): Promise<{
@@ -869,7 +1112,7 @@ declare class OnetimeProductsResource {
869
1112
  * @returns Published product detail
870
1113
  *
871
1114
  * @example
872
- * const { product } = await client.onetimeProducts.publish({ id: "prod_xxx" });
1115
+ * const { product } = await client.onetimeProducts.publish({ id: "PROD_xxx" });
873
1116
  */
874
1117
  publish(params: PublishOnetimeProductParams): Promise<{
875
1118
  product: OnetimeProductDetail;
@@ -882,7 +1125,7 @@ declare class OnetimeProductsResource {
882
1125
  *
883
1126
  * @example
884
1127
  * const { product } = await client.onetimeProducts.updateStatus({
885
- * id: "prod_xxx",
1128
+ * id: "PROD_xxx",
886
1129
  * status: ProductVersionStatus.Inactive,
887
1130
  * });
888
1131
  */
@@ -906,7 +1149,7 @@ declare class OrdersResource {
906
1149
  *
907
1150
  * @example
908
1151
  * const { orderId, status } = await client.orders.cancelSubscription({
909
- * orderId: "order_xxx",
1152
+ * orderId: "ORD_xxx",
910
1153
  * });
911
1154
  * // status: "canceled" or "canceling"
912
1155
  */
@@ -925,7 +1168,7 @@ declare class StoreMerchantsResource {
925
1168
  *
926
1169
  * @example
927
1170
  * const result = await client.storeMerchants.add({
928
- * storeId: "store_xxx",
1171
+ * storeId: "STO_xxx",
929
1172
  * email: "member@example.com",
930
1173
  * role: "admin",
931
1174
  * });
@@ -939,8 +1182,8 @@ declare class StoreMerchantsResource {
939
1182
  *
940
1183
  * @example
941
1184
  * const result = await client.storeMerchants.remove({
942
- * storeId: "store_xxx",
943
- * merchantId: "merchant_xxx",
1185
+ * storeId: "STO_xxx",
1186
+ * merchantId: "MER_xxx",
944
1187
  * });
945
1188
  */
946
1189
  remove(params: RemoveMerchantParams): Promise<RemoveMerchantResult>;
@@ -952,8 +1195,8 @@ declare class StoreMerchantsResource {
952
1195
  *
953
1196
  * @example
954
1197
  * const result = await client.storeMerchants.updateRole({
955
- * storeId: "store_xxx",
956
- * merchantId: "merchant_xxx",
1198
+ * storeId: "STO_xxx",
1199
+ * merchantId: "MER_xxx",
957
1200
  * role: "member",
958
1201
  * });
959
1202
  */
@@ -984,7 +1227,7 @@ declare class StoresResource {
984
1227
  *
985
1228
  * @example
986
1229
  * const { store } = await client.stores.update({
987
- * id: "store_xxx",
1230
+ * id: "STO_xxx",
988
1231
  * name: "Updated Name",
989
1232
  * });
990
1233
  */
@@ -998,7 +1241,7 @@ declare class StoresResource {
998
1241
  * @returns Deleted store entity (with `deletedAt` set)
999
1242
  *
1000
1243
  * @example
1001
- * const { store } = await client.stores.delete({ id: "store_xxx" });
1244
+ * const { store } = await client.stores.delete({ id: "STO_xxx" });
1002
1245
  */
1003
1246
  delete(params: DeleteStoreParams): Promise<{
1004
1247
  store: Store;
@@ -1017,10 +1260,10 @@ declare class SubscriptionProductGroupsResource {
1017
1260
  *
1018
1261
  * @example
1019
1262
  * const { group } = await client.subscriptionProductGroups.create({
1020
- * storeId: "store_xxx",
1263
+ * storeId: "STO_xxx",
1021
1264
  * name: "Pro Plans",
1022
1265
  * rules: { sharedTrial: true },
1023
- * productIds: ["prod_aaa", "prod_bbb"],
1266
+ * productIds: ["PROD_aaa", "PROD_bbb"],
1024
1267
  * });
1025
1268
  */
1026
1269
  create(params: CreateSubscriptionProductGroupParams): Promise<{
@@ -1034,8 +1277,8 @@ declare class SubscriptionProductGroupsResource {
1034
1277
  *
1035
1278
  * @example
1036
1279
  * const { group } = await client.subscriptionProductGroups.update({
1037
- * id: "group_xxx",
1038
- * productIds: ["prod_aaa", "prod_bbb", "prod_ccc"],
1280
+ * id: "GRP_xxx",
1281
+ * productIds: ["PROD_aaa", "PROD_bbb", "PROD_ccc"],
1039
1282
  * });
1040
1283
  */
1041
1284
  update(params: UpdateSubscriptionProductGroupParams): Promise<{
@@ -1048,7 +1291,7 @@ declare class SubscriptionProductGroupsResource {
1048
1291
  * @returns Deleted group entity
1049
1292
  *
1050
1293
  * @example
1051
- * const { group } = await client.subscriptionProductGroups.delete({ id: "group_xxx" });
1294
+ * const { group } = await client.subscriptionProductGroups.delete({ id: "GRP_xxx" });
1052
1295
  */
1053
1296
  delete(params: DeleteSubscriptionProductGroupParams): Promise<{
1054
1297
  group: SubscriptionProductGroup;
@@ -1060,7 +1303,7 @@ declare class SubscriptionProductGroupsResource {
1060
1303
  * @returns Published group entity
1061
1304
  *
1062
1305
  * @example
1063
- * const { group } = await client.subscriptionProductGroups.publish({ id: "group_xxx" });
1306
+ * const { group } = await client.subscriptionProductGroups.publish({ id: "GRP_xxx" });
1064
1307
  */
1065
1308
  publish(params: PublishSubscriptionProductGroupParams): Promise<{
1066
1309
  group: SubscriptionProductGroup;
@@ -1079,10 +1322,10 @@ declare class SubscriptionProductsResource {
1079
1322
  *
1080
1323
  * @example
1081
1324
  * const { product } = await client.subscriptionProducts.create({
1082
- * storeId: "store_xxx",
1325
+ * storeId: "STO_xxx",
1083
1326
  * name: "Pro Plan",
1084
1327
  * billingPeriod: "monthly",
1085
- * prices: { USD: { amount: 999, taxCategory: "saas" } },
1328
+ * prices: { USD: { amount: "9.99", taxCategory: "saas" } },
1086
1329
  * });
1087
1330
  */
1088
1331
  create(params: CreateSubscriptionProductParams): Promise<{
@@ -1096,10 +1339,10 @@ declare class SubscriptionProductsResource {
1096
1339
  *
1097
1340
  * @example
1098
1341
  * const { product } = await client.subscriptionProducts.update({
1099
- * id: "prod_xxx",
1342
+ * id: "PROD_xxx",
1100
1343
  * name: "Pro Plan v2",
1101
1344
  * billingPeriod: "monthly",
1102
- * prices: { USD: { amount: 1499, taxCategory: "saas" } },
1345
+ * prices: { USD: { amount: "14.99", taxCategory: "saas" } },
1103
1346
  * });
1104
1347
  */
1105
1348
  update(params: UpdateSubscriptionProductParams): Promise<{
@@ -1112,7 +1355,7 @@ declare class SubscriptionProductsResource {
1112
1355
  * @returns Published product detail
1113
1356
  *
1114
1357
  * @example
1115
- * const { product } = await client.subscriptionProducts.publish({ id: "prod_xxx" });
1358
+ * const { product } = await client.subscriptionProducts.publish({ id: "PROD_xxx" });
1116
1359
  */
1117
1360
  publish(params: PublishSubscriptionProductParams): Promise<{
1118
1361
  product: SubscriptionProductDetail;
@@ -1125,7 +1368,7 @@ declare class SubscriptionProductsResource {
1125
1368
  *
1126
1369
  * @example
1127
1370
  * const { product } = await client.subscriptionProducts.updateStatus({
1128
- * id: "prod_xxx",
1371
+ * id: "PROD_xxx",
1129
1372
  * status: ProductVersionStatus.Active,
1130
1373
  * });
1131
1374
  */
@@ -1134,16 +1377,25 @@ declare class SubscriptionProductsResource {
1134
1377
  }>;
1135
1378
  }
1136
1379
 
1137
- /** Webhook signature verification resource. */
1380
+ /**
1381
+ * Webhook signature verification resource.
1382
+ *
1383
+ * Unlike other resources, this does not use HttpClient — webhook verification
1384
+ * is a local cryptographic operation that does not require API calls.
1385
+ */
1138
1386
  declare class WebhooksResource {
1139
- private readonly publicKey;
1140
- /** @param publicKey - Optional custom RSA public key (PEM or raw base64) */
1141
- constructor(publicKey: string | undefined);
1387
+ private readonly publicKeys;
1388
+ /** @param publicKeys - Optional config-level public key(s) from WaffoPancakeConfig */
1389
+ constructor(publicKeys: WebhookPublicKeys | undefined);
1142
1390
  /**
1143
1391
  * Verify and parse an incoming webhook event.
1144
1392
  *
1145
- * When the client was created with a `webhookPublicKey`, that key is used
1146
- * automatically. You can still override per-call via `options.publicKey`.
1393
+ * Key resolution order:
1394
+ * 1. `options.publicKey` per-call override (highest priority)
1395
+ * 2. `config.webhookPublicKey[env]` or `config.webhookPublicKey` (string)
1396
+ * 3. `WAFFO_WEBHOOK_{TEST|PROD}_PUBLIC_KEY` environment variable
1397
+ * 4. `WAFFO_WEBHOOK_PUBLIC_KEY` environment variable
1398
+ * 5. Built-in hardcoded key
1147
1399
  *
1148
1400
  * @param payload - Raw request body string (must be unparsed)
1149
1401
  * @param signatureHeader - Value of the `X-Waffo-Signature` header
@@ -1155,8 +1407,12 @@ declare class WebhooksResource {
1155
1407
  * const event = client.webhooks.verify(rawBody, signatureHeader);
1156
1408
  *
1157
1409
  * @example
1158
- * // Override tolerance per call
1159
- * const event = client.webhooks.verify(rawBody, sig, { toleranceMs: 0 });
1410
+ * // Specify environment
1411
+ * const event = client.webhooks.verify(rawBody, sig, { environment: "test" });
1412
+ *
1413
+ * @example
1414
+ * // Per-call key override
1415
+ * const event = client.webhooks.verify(rawBody, sig, { publicKey: oneOffKey });
1160
1416
  */
1161
1417
  verify<T = Record<string, unknown>>(payload: string, signatureHeader: string | undefined | null, options?: VerifyWebhookOptions): WebhookEvent<T>;
1162
1418
  }
@@ -1171,19 +1427,21 @@ declare class WebhooksResource {
1171
1427
  * import { WaffoPancake } from "@waffo/pancake-ts";
1172
1428
  *
1173
1429
  * const client = new WaffoPancake({
1174
- * merchantId: process.env.WAFFO_MERCHANT_ID!,
1430
+ * merchantId: "MER_2D5F8G3H1K4M6N9P0Q7R8S", // MER_{base62} format
1175
1431
  * privateKey: process.env.WAFFO_PRIVATE_KEY!,
1176
1432
  * });
1177
1433
  *
1178
- * // Create a store
1434
+ * // Create a store — IDs are returned in {prefix}_{base62} format
1179
1435
  * const { store } = await client.stores.create({ name: "My Store" });
1436
+ * // => store.id = "STO_..."
1180
1437
  *
1181
1438
  * // Create a product
1182
1439
  * const { product } = await client.onetimeProducts.create({
1183
- * storeId: store.id,
1440
+ * storeId: store.id, // "STO_..."
1184
1441
  * name: "E-Book",
1185
1442
  * prices: { USD: { amount: 2900, taxCategory: "digital_goods" } },
1186
1443
  * });
1444
+ * // => product.id = "PROD_..."
1187
1445
  *
1188
1446
  * // Create a checkout session
1189
1447
  * const session = await client.checkout.createSession({
@@ -1200,11 +1458,14 @@ declare class WebhooksResource {
1200
1458
  * });
1201
1459
  *
1202
1460
  * @example
1203
- * // Use a custom public key for webhook verification
1461
+ * // Per-environment webhook public keys
1204
1462
  * const client = new WaffoPancake({
1205
1463
  * merchantId: "...",
1206
1464
  * privateKey: "...",
1207
- * webhookPublicKey: myCustomPublicKeyPem,
1465
+ * webhookPublicKey: {
1466
+ * test: process.env.WAFFO_TEST_PUB_KEY!,
1467
+ * prod: process.env.WAFFO_PROD_PUB_KEY!,
1468
+ * },
1208
1469
  * });
1209
1470
  * const event = client.webhooks.verify(rawBody, signatureHeader);
1210
1471
  */
@@ -1245,8 +1506,12 @@ declare class WaffoPancakeError extends Error {
1245
1506
  /**
1246
1507
  * Verify and parse an incoming Waffo Pancake webhook event.
1247
1508
  *
1248
- * Uses built-in Waffo public keys (RSA-SHA256) for signature verification.
1249
- * Test and production environments use different key pairs; both are embedded in the SDK.
1509
+ * Public key resolution (per environment):
1510
+ * 1. `options.publicKey` per-call override (highest priority, skips all other resolution)
1511
+ * 2. `options.publicKeys[env]` or `options.publicKeys` (string) — config-level
1512
+ * 3. `WAFFO_WEBHOOK_{TEST|PROD}_PUBLIC_KEY` environment variable
1513
+ * 4. `WAFFO_WEBHOOK_PUBLIC_KEY` environment variable
1514
+ * 5. Built-in hardcoded key
1250
1515
  *
1251
1516
  * Behavior:
1252
1517
  * - Parses the `X-Waffo-Signature` header (`t=<timestamp>,v1=<base64sig>`)
@@ -1295,4 +1560,4 @@ declare class WaffoPancakeError extends Error {
1295
1560
  */
1296
1561
  declare function verifyWebhook<T = Record<string, unknown>>(payload: string, signatureHeader: string | undefined | null, options?: VerifyWebhookOptions): WebhookEvent<T>;
1297
1562
 
1298
- 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 };
1563
+ export { type AddMerchantParams, type AddMerchantResult, type AnonymousCheckoutParams, type ApiError, type ApiErrorResponse, type ApiResponse, type ApiSuccessResponse, type AuthenticatedCheckoutParams, type AuthenticatedCheckoutResult, 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 };