@dodopayments/hono 0.2.1 → 0.2.3

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.cjs CHANGED
@@ -3961,7 +3961,7 @@ const unknownType = ZodUnknown.create;
3961
3961
  ZodNever.create;
3962
3962
  const arrayType = ZodArray.create;
3963
3963
  const objectType = ZodObject.create;
3964
- ZodUnion.create;
3964
+ const unionType = ZodUnion.create;
3965
3965
  const discriminatedUnionType = ZodDiscriminatedUnion.create;
3966
3966
  ZodIntersection.create;
3967
3967
  ZodTuple.create;
@@ -4180,7 +4180,7 @@ const safeJSON = (text) => {
4180
4180
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
4181
4181
  const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
4182
4182
 
4183
- const VERSION = '2.2.0'; // x-release-please-version
4183
+ const VERSION = '2.4.6'; // x-release-please-version
4184
4184
 
4185
4185
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
4186
4186
  /**
@@ -4930,6 +4930,9 @@ class CheckoutSessions extends APIResource {
4930
4930
  create(body, options) {
4931
4931
  return this._client.post('/checkouts', { body, ...options });
4932
4932
  }
4933
+ retrieve(id, options) {
4934
+ return this._client.get(path `/checkouts/${id}`, options);
4935
+ }
4933
4936
  }
4934
4937
 
4935
4938
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
@@ -5608,1519 +5611,325 @@ let Headers$1 = class Headers extends APIResource {
5608
5611
  }
5609
5612
  };
5610
5613
 
5611
- // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
5612
- let Webhooks$1 = class Webhooks extends APIResource {
5613
- constructor() {
5614
- super(...arguments);
5615
- this.headers = new Headers$1(this._client);
5616
- }
5617
- /**
5618
- * Create a new webhook
5619
- */
5620
- create(body, options) {
5621
- return this._client.post('/webhooks', { body, ...options });
5622
- }
5623
- /**
5624
- * Get a webhook by id
5625
- */
5626
- retrieve(webhookID, options) {
5627
- return this._client.get(path `/webhooks/${webhookID}`, options);
5614
+ var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
5615
+
5616
+ var dist = {};
5617
+
5618
+ var timing_safe_equal = {};
5619
+
5620
+ Object.defineProperty(timing_safe_equal, "__esModule", { value: true });
5621
+ timing_safe_equal.timingSafeEqual = void 0;
5622
+ function assert(expr, msg = "") {
5623
+ if (!expr) {
5624
+ throw new Error(msg);
5628
5625
  }
5629
- /**
5630
- * Patch a webhook by id
5631
- */
5632
- update(webhookID, body, options) {
5633
- return this._client.patch(path `/webhooks/${webhookID}`, { body, ...options });
5626
+ }
5627
+ function timingSafeEqual(a, b) {
5628
+ if (a.byteLength !== b.byteLength) {
5629
+ return false;
5634
5630
  }
5635
- /**
5636
- * List all webhooks
5637
- */
5638
- list(query = {}, options) {
5639
- return this._client.getAPIList('/webhooks', (CursorPagePagination), { query, ...options });
5631
+ if (!(a instanceof DataView)) {
5632
+ a = new DataView(ArrayBuffer.isView(a) ? a.buffer : a);
5640
5633
  }
5641
- /**
5642
- * Delete a webhook by id
5643
- */
5644
- delete(webhookID, options) {
5645
- return this._client.delete(path `/webhooks/${webhookID}`, {
5646
- ...options,
5647
- headers: buildHeaders([{ Accept: '*/*' }, options?.headers]),
5648
- });
5634
+ if (!(b instanceof DataView)) {
5635
+ b = new DataView(ArrayBuffer.isView(b) ? b.buffer : b);
5649
5636
  }
5650
- /**
5651
- * Get webhook secret by id
5652
- */
5653
- retrieveSecret(webhookID, options) {
5654
- return this._client.get(path `/webhooks/${webhookID}/secret`, options);
5637
+ assert(a instanceof DataView);
5638
+ assert(b instanceof DataView);
5639
+ const length = a.byteLength;
5640
+ let out = 0;
5641
+ let i = -1;
5642
+ while (++i < length) {
5643
+ out |= a.getUint8(i) ^ b.getUint8(i);
5655
5644
  }
5656
- };
5657
- Webhooks$1.Headers = Headers$1;
5645
+ return out === 0;
5646
+ }
5647
+ timing_safe_equal.timingSafeEqual = timingSafeEqual;
5658
5648
 
5659
- // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
5649
+ var base64$1 = {};
5650
+
5651
+ // Copyright (C) 2016 Dmitry Chestnykh
5652
+ // MIT License. See LICENSE file for details.
5653
+ var __extends = (commonjsGlobal && commonjsGlobal.__extends) || (function () {
5654
+ var extendStatics = function (d, b) {
5655
+ extendStatics = Object.setPrototypeOf ||
5656
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5657
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
5658
+ return extendStatics(d, b);
5659
+ };
5660
+ return function (d, b) {
5661
+ extendStatics(d, b);
5662
+ function __() { this.constructor = d; }
5663
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
5664
+ };
5665
+ })();
5666
+ Object.defineProperty(base64$1, "__esModule", { value: true });
5660
5667
  /**
5661
- * Read an environment variable.
5662
- *
5663
- * Trims beginning and trailing whitespace.
5664
- *
5665
- * Will return undefined if the environment variable doesn't exist or cannot be accessed.
5668
+ * Package base64 implements Base64 encoding and decoding.
5666
5669
  */
5667
- const readEnv = (env) => {
5668
- if (typeof globalThis.process !== 'undefined') {
5669
- return globalThis.process.env?.[env]?.trim() ?? undefined;
5670
- }
5671
- if (typeof globalThis.Deno !== 'undefined') {
5672
- return globalThis.Deno.env?.get?.(env)?.trim();
5673
- }
5674
- return undefined;
5675
- };
5676
-
5677
- // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
5678
- var _DodoPayments_instances, _a, _DodoPayments_encoder, _DodoPayments_baseURLOverridden;
5679
- const environments = {
5680
- live_mode: 'https://live.dodopayments.com',
5681
- test_mode: 'https://test.dodopayments.com',
5682
- };
5670
+ // Invalid character used in decoding to indicate
5671
+ // that the character to decode is out of range of
5672
+ // alphabet and cannot be decoded.
5673
+ var INVALID_BYTE = 256;
5683
5674
  /**
5684
- * API Client for interfacing with the Dodo Payments API.
5675
+ * Implements standard Base64 encoding.
5676
+ *
5677
+ * Operates in constant time.
5685
5678
  */
5686
- class DodoPayments {
5687
- /**
5688
- * API Client for interfacing with the Dodo Payments API.
5689
- *
5690
- * @param {string | undefined} [opts.bearerToken=process.env['DODO_PAYMENTS_API_KEY'] ?? undefined]
5691
- * @param {Environment} [opts.environment=live_mode] - Specifies the environment URL to use for the API.
5692
- * @param {string} [opts.baseURL=process.env['DODO_PAYMENTS_BASE_URL'] ?? https://live.dodopayments.com] - Override the default base URL for the API.
5693
- * @param {number} [opts.timeout=1 minute] - The maximum amount of time (in milliseconds) the client will wait for a response before timing out.
5694
- * @param {MergedRequestInit} [opts.fetchOptions] - Additional `RequestInit` options to be passed to `fetch` calls.
5695
- * @param {Fetch} [opts.fetch] - Specify a custom `fetch` function implementation.
5696
- * @param {number} [opts.maxRetries=2] - The maximum number of times the client will retry a request.
5697
- * @param {HeadersLike} opts.defaultHeaders - Default headers to include with every request to the API.
5698
- * @param {Record<string, string | undefined>} opts.defaultQuery - Default query parameters to include with every request to the API.
5699
- */
5700
- constructor({ baseURL = readEnv('DODO_PAYMENTS_BASE_URL'), bearerToken = readEnv('DODO_PAYMENTS_API_KEY'), ...opts } = {}) {
5701
- _DodoPayments_instances.add(this);
5702
- _DodoPayments_encoder.set(this, void 0);
5703
- this.checkoutSessions = new CheckoutSessions(this);
5704
- this.payments = new Payments(this);
5705
- this.subscriptions = new Subscriptions(this);
5706
- this.invoices = new Invoices(this);
5707
- this.licenses = new Licenses(this);
5708
- this.licenseKeys = new LicenseKeys(this);
5709
- this.licenseKeyInstances = new LicenseKeyInstances(this);
5710
- this.customers = new Customers(this);
5711
- this.refunds = new Refunds(this);
5712
- this.disputes = new Disputes(this);
5713
- this.payouts = new Payouts(this);
5714
- this.webhookEvents = new WebhookEvents(this);
5715
- this.products = new Products(this);
5716
- this.misc = new Misc(this);
5717
- this.discounts = new Discounts(this);
5718
- this.addons = new Addons(this);
5719
- this.brands = new Brands(this);
5720
- this.webhooks = new Webhooks$1(this);
5721
- this.usageEvents = new UsageEvents(this);
5722
- this.meters = new Meters(this);
5723
- if (bearerToken === undefined) {
5724
- throw new DodoPaymentsError("The DODO_PAYMENTS_API_KEY environment variable is missing or empty; either provide it, or instantiate the DodoPayments client with an bearerToken option, like new DodoPayments({ bearerToken: 'My Bearer Token' }).");
5679
+ var Coder = /** @class */ (function () {
5680
+ // TODO(dchest): methods to encode chunk-by-chunk.
5681
+ function Coder(_paddingCharacter) {
5682
+ if (_paddingCharacter === void 0) { _paddingCharacter = "="; }
5683
+ this._paddingCharacter = _paddingCharacter;
5684
+ }
5685
+ Coder.prototype.encodedLength = function (length) {
5686
+ if (!this._paddingCharacter) {
5687
+ return (length * 8 + 5) / 6 | 0;
5725
5688
  }
5726
- const options = {
5727
- bearerToken,
5728
- ...opts,
5729
- baseURL,
5730
- environment: opts.environment ?? 'live_mode',
5731
- };
5732
- if (baseURL && opts.environment) {
5733
- throw new DodoPaymentsError('Ambiguous URL; The `baseURL` option (or DODO_PAYMENTS_BASE_URL env var) and the `environment` option are given. If you want to use the environment you must pass baseURL: null');
5689
+ return (length + 2) / 3 * 4 | 0;
5690
+ };
5691
+ Coder.prototype.encode = function (data) {
5692
+ var out = "";
5693
+ var i = 0;
5694
+ for (; i < data.length - 2; i += 3) {
5695
+ var c = (data[i] << 16) | (data[i + 1] << 8) | (data[i + 2]);
5696
+ out += this._encodeByte((c >>> 3 * 6) & 63);
5697
+ out += this._encodeByte((c >>> 2 * 6) & 63);
5698
+ out += this._encodeByte((c >>> 1 * 6) & 63);
5699
+ out += this._encodeByte((c >>> 0 * 6) & 63);
5734
5700
  }
5735
- this.baseURL = options.baseURL || environments[options.environment || 'live_mode'];
5736
- this.timeout = options.timeout ?? _a.DEFAULT_TIMEOUT /* 1 minute */;
5737
- this.logger = options.logger ?? console;
5738
- const defaultLogLevel = 'warn';
5739
- // Set default logLevel early so that we can log a warning in parseLogLevel.
5740
- this.logLevel = defaultLogLevel;
5741
- this.logLevel =
5742
- parseLogLevel(options.logLevel, 'ClientOptions.logLevel', this) ??
5743
- parseLogLevel(readEnv('DODO_PAYMENTS_LOG'), "process.env['DODO_PAYMENTS_LOG']", this) ??
5744
- defaultLogLevel;
5745
- this.fetchOptions = options.fetchOptions;
5746
- this.maxRetries = options.maxRetries ?? 2;
5747
- this.fetch = options.fetch ?? getDefaultFetch();
5748
- __classPrivateFieldSet(this, _DodoPayments_encoder, FallbackEncoder);
5749
- this._options = options;
5750
- this.bearerToken = bearerToken;
5751
- }
5752
- /**
5753
- * Create a new client instance re-using the same options given to the current client with optional overriding.
5754
- */
5755
- withOptions(options) {
5756
- const client = new this.constructor({
5757
- ...this._options,
5758
- environment: options.environment ? options.environment : undefined,
5759
- baseURL: options.environment ? undefined : this.baseURL,
5760
- maxRetries: this.maxRetries,
5761
- timeout: this.timeout,
5762
- logger: this.logger,
5763
- logLevel: this.logLevel,
5764
- fetch: this.fetch,
5765
- fetchOptions: this.fetchOptions,
5766
- bearerToken: this.bearerToken,
5767
- ...options,
5768
- });
5769
- return client;
5770
- }
5771
- defaultQuery() {
5772
- return this._options.defaultQuery;
5773
- }
5774
- validateHeaders({ values, nulls }) {
5775
- return;
5776
- }
5777
- async authHeaders(opts) {
5778
- return buildHeaders([{ Authorization: `Bearer ${this.bearerToken}` }]);
5779
- }
5780
- /**
5781
- * Basic re-implementation of `qs.stringify` for primitive types.
5782
- */
5783
- stringifyQuery(query) {
5784
- return Object.entries(query)
5785
- .filter(([_, value]) => typeof value !== 'undefined')
5786
- .map(([key, value]) => {
5787
- if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
5788
- return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
5701
+ var left = data.length - i;
5702
+ if (left > 0) {
5703
+ var c = (data[i] << 16) | (left === 2 ? data[i + 1] << 8 : 0);
5704
+ out += this._encodeByte((c >>> 3 * 6) & 63);
5705
+ out += this._encodeByte((c >>> 2 * 6) & 63);
5706
+ if (left === 2) {
5707
+ out += this._encodeByte((c >>> 1 * 6) & 63);
5789
5708
  }
5790
- if (value === null) {
5791
- return `${encodeURIComponent(key)}=`;
5709
+ else {
5710
+ out += this._paddingCharacter || "";
5792
5711
  }
5793
- throw new DodoPaymentsError(`Cannot stringify type ${typeof value}; Expected string, number, boolean, or null. If you need to pass nested query parameters, you can manually encode them, e.g. { query: { 'foo[key1]': value1, 'foo[key2]': value2 } }, and please open a GitHub issue requesting better support for your use case.`);
5794
- })
5795
- .join('&');
5796
- }
5797
- getUserAgent() {
5798
- return `${this.constructor.name}/JS ${VERSION}`;
5799
- }
5800
- defaultIdempotencyKey() {
5801
- return `stainless-node-retry-${uuid4()}`;
5802
- }
5803
- makeStatusError(status, error, message, headers) {
5804
- return APIError.generate(status, error, message, headers);
5805
- }
5806
- buildURL(path, query, defaultBaseURL) {
5807
- const baseURL = (!__classPrivateFieldGet(this, _DodoPayments_instances, "m", _DodoPayments_baseURLOverridden).call(this) && defaultBaseURL) || this.baseURL;
5808
- const url = isAbsoluteURL(path) ?
5809
- new URL(path)
5810
- : new URL(baseURL + (baseURL.endsWith('/') && path.startsWith('/') ? path.slice(1) : path));
5811
- const defaultQuery = this.defaultQuery();
5812
- if (!isEmptyObj(defaultQuery)) {
5813
- query = { ...defaultQuery, ...query };
5814
- }
5815
- if (typeof query === 'object' && query && !Array.isArray(query)) {
5816
- url.search = this.stringifyQuery(query);
5712
+ out += this._paddingCharacter || "";
5817
5713
  }
5818
- return url.toString();
5819
- }
5820
- /**
5821
- * Used as a callback for mutating the given `FinalRequestOptions` object.
5822
- */
5823
- async prepareOptions(options) { }
5824
- /**
5825
- * Used as a callback for mutating the given `RequestInit` object.
5826
- *
5827
- * This is useful for cases where you want to add certain headers based off of
5828
- * the request properties, e.g. `method` or `url`.
5829
- */
5830
- async prepareRequest(request, { url, options }) { }
5831
- get(path, opts) {
5832
- return this.methodRequest('get', path, opts);
5833
- }
5834
- post(path, opts) {
5835
- return this.methodRequest('post', path, opts);
5836
- }
5837
- patch(path, opts) {
5838
- return this.methodRequest('patch', path, opts);
5839
- }
5840
- put(path, opts) {
5841
- return this.methodRequest('put', path, opts);
5842
- }
5843
- delete(path, opts) {
5844
- return this.methodRequest('delete', path, opts);
5845
- }
5846
- methodRequest(method, path, opts) {
5847
- return this.request(Promise.resolve(opts).then((opts) => {
5848
- return { method, path, ...opts };
5849
- }));
5850
- }
5851
- request(options, remainingRetries = null) {
5852
- return new APIPromise(this, this.makeRequest(options, remainingRetries, undefined));
5853
- }
5854
- async makeRequest(optionsInput, retriesRemaining, retryOfRequestLogID) {
5855
- const options = await optionsInput;
5856
- const maxRetries = options.maxRetries ?? this.maxRetries;
5857
- if (retriesRemaining == null) {
5858
- retriesRemaining = maxRetries;
5714
+ return out;
5715
+ };
5716
+ Coder.prototype.maxDecodedLength = function (length) {
5717
+ if (!this._paddingCharacter) {
5718
+ return (length * 6 + 7) / 8 | 0;
5859
5719
  }
5860
- await this.prepareOptions(options);
5861
- const { req, url, timeout } = await this.buildRequest(options, {
5862
- retryCount: maxRetries - retriesRemaining,
5863
- });
5864
- await this.prepareRequest(req, { url, options });
5865
- /** Not an API request ID, just for correlating local log entries. */
5866
- const requestLogID = 'log_' + ((Math.random() * (1 << 24)) | 0).toString(16).padStart(6, '0');
5867
- const retryLogStr = retryOfRequestLogID === undefined ? '' : `, retryOf: ${retryOfRequestLogID}`;
5868
- const startTime = Date.now();
5869
- loggerFor(this).debug(`[${requestLogID}] sending request`, formatRequestDetails({
5870
- retryOfRequestLogID,
5871
- method: options.method,
5872
- url,
5873
- options,
5874
- headers: req.headers,
5875
- }));
5876
- if (options.signal?.aborted) {
5877
- throw new APIUserAbortError();
5720
+ return length / 4 * 3 | 0;
5721
+ };
5722
+ Coder.prototype.decodedLength = function (s) {
5723
+ return this.maxDecodedLength(s.length - this._getPaddingLength(s));
5724
+ };
5725
+ Coder.prototype.decode = function (s) {
5726
+ if (s.length === 0) {
5727
+ return new Uint8Array(0);
5878
5728
  }
5879
- const controller = new AbortController();
5880
- const response = await this.fetchWithTimeout(url, req, timeout, controller).catch(castToError);
5881
- const headersTime = Date.now();
5882
- if (response instanceof globalThis.Error) {
5883
- const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
5884
- if (options.signal?.aborted) {
5885
- throw new APIUserAbortError();
5886
- }
5887
- // detect native connection timeout errors
5888
- // deno throws "TypeError: error sending request for url (https://example/): client error (Connect): tcp connect error: Operation timed out (os error 60): Operation timed out (os error 60)"
5889
- // undici throws "TypeError: fetch failed" with cause "ConnectTimeoutError: Connect Timeout Error (attempted address: example:443, timeout: 1ms)"
5890
- // others do not provide enough information to distinguish timeouts from other connection errors
5891
- const isTimeout = isAbortError(response) ||
5892
- /timed? ?out/i.test(String(response) + ('cause' in response ? String(response.cause) : ''));
5893
- if (retriesRemaining) {
5894
- loggerFor(this).info(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - ${retryMessage}`);
5895
- loggerFor(this).debug(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (${retryMessage})`, formatRequestDetails({
5896
- retryOfRequestLogID,
5897
- url,
5898
- durationMs: headersTime - startTime,
5899
- message: response.message,
5900
- }));
5901
- return this.retryRequest(options, retriesRemaining, retryOfRequestLogID ?? requestLogID);
5902
- }
5903
- loggerFor(this).info(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - error; no more retries left`);
5904
- loggerFor(this).debug(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (error; no more retries left)`, formatRequestDetails({
5905
- retryOfRequestLogID,
5906
- url,
5907
- durationMs: headersTime - startTime,
5908
- message: response.message,
5909
- }));
5910
- if (isTimeout) {
5911
- throw new APIConnectionTimeoutError();
5912
- }
5913
- throw new APIConnectionError({ cause: response });
5729
+ var paddingLength = this._getPaddingLength(s);
5730
+ var length = s.length - paddingLength;
5731
+ var out = new Uint8Array(this.maxDecodedLength(length));
5732
+ var op = 0;
5733
+ var i = 0;
5734
+ var haveBad = 0;
5735
+ var v0 = 0, v1 = 0, v2 = 0, v3 = 0;
5736
+ for (; i < length - 4; i += 4) {
5737
+ v0 = this._decodeChar(s.charCodeAt(i + 0));
5738
+ v1 = this._decodeChar(s.charCodeAt(i + 1));
5739
+ v2 = this._decodeChar(s.charCodeAt(i + 2));
5740
+ v3 = this._decodeChar(s.charCodeAt(i + 3));
5741
+ out[op++] = (v0 << 2) | (v1 >>> 4);
5742
+ out[op++] = (v1 << 4) | (v2 >>> 2);
5743
+ out[op++] = (v2 << 6) | v3;
5744
+ haveBad |= v0 & INVALID_BYTE;
5745
+ haveBad |= v1 & INVALID_BYTE;
5746
+ haveBad |= v2 & INVALID_BYTE;
5747
+ haveBad |= v3 & INVALID_BYTE;
5914
5748
  }
5915
- const responseInfo = `[${requestLogID}${retryLogStr}] ${req.method} ${url} ${response.ok ? 'succeeded' : 'failed'} with status ${response.status} in ${headersTime - startTime}ms`;
5916
- if (!response.ok) {
5917
- const shouldRetry = await this.shouldRetry(response);
5918
- if (retriesRemaining && shouldRetry) {
5919
- const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
5920
- // We don't need the body of this response.
5921
- await CancelReadableStream(response.body);
5922
- loggerFor(this).info(`${responseInfo} - ${retryMessage}`);
5923
- loggerFor(this).debug(`[${requestLogID}] response error (${retryMessage})`, formatRequestDetails({
5924
- retryOfRequestLogID,
5925
- url: response.url,
5926
- status: response.status,
5927
- headers: response.headers,
5928
- durationMs: headersTime - startTime,
5929
- }));
5930
- return this.retryRequest(options, retriesRemaining, retryOfRequestLogID ?? requestLogID, response.headers);
5931
- }
5932
- const retryMessage = shouldRetry ? `error; no more retries left` : `error; not retryable`;
5933
- loggerFor(this).info(`${responseInfo} - ${retryMessage}`);
5934
- const errText = await response.text().catch((err) => castToError(err).message);
5935
- const errJSON = safeJSON(errText);
5936
- const errMessage = errJSON ? undefined : errText;
5937
- loggerFor(this).debug(`[${requestLogID}] response error (${retryMessage})`, formatRequestDetails({
5938
- retryOfRequestLogID,
5939
- url: response.url,
5940
- status: response.status,
5941
- headers: response.headers,
5942
- message: errMessage,
5943
- durationMs: Date.now() - startTime,
5944
- }));
5945
- const err = this.makeStatusError(response.status, errJSON, errMessage, response.headers);
5946
- throw err;
5749
+ if (i < length - 1) {
5750
+ v0 = this._decodeChar(s.charCodeAt(i));
5751
+ v1 = this._decodeChar(s.charCodeAt(i + 1));
5752
+ out[op++] = (v0 << 2) | (v1 >>> 4);
5753
+ haveBad |= v0 & INVALID_BYTE;
5754
+ haveBad |= v1 & INVALID_BYTE;
5947
5755
  }
5948
- loggerFor(this).info(responseInfo);
5949
- loggerFor(this).debug(`[${requestLogID}] response start`, formatRequestDetails({
5950
- retryOfRequestLogID,
5951
- url: response.url,
5952
- status: response.status,
5953
- headers: response.headers,
5954
- durationMs: headersTime - startTime,
5955
- }));
5956
- return { response, options, controller, requestLogID, retryOfRequestLogID, startTime };
5957
- }
5958
- getAPIList(path, Page, opts) {
5959
- return this.requestAPIList(Page, { method: 'get', path, ...opts });
5960
- }
5961
- requestAPIList(Page, options) {
5962
- const request = this.makeRequest(options, null, undefined);
5963
- return new PagePromise(this, request, Page);
5964
- }
5965
- async fetchWithTimeout(url, init, ms, controller) {
5966
- const { signal, method, ...options } = init || {};
5967
- if (signal)
5968
- signal.addEventListener('abort', () => controller.abort());
5969
- const timeout = setTimeout(() => controller.abort(), ms);
5970
- const isReadableBody = (globalThis.ReadableStream && options.body instanceof globalThis.ReadableStream) ||
5971
- (typeof options.body === 'object' && options.body !== null && Symbol.asyncIterator in options.body);
5972
- const fetchOptions = {
5973
- signal: controller.signal,
5974
- ...(isReadableBody ? { duplex: 'half' } : {}),
5975
- method: 'GET',
5976
- ...options,
5977
- };
5978
- if (method) {
5979
- // Custom methods like 'patch' need to be uppercased
5980
- // See https://github.com/nodejs/undici/issues/2294
5981
- fetchOptions.method = method.toUpperCase();
5756
+ if (i < length - 2) {
5757
+ v2 = this._decodeChar(s.charCodeAt(i + 2));
5758
+ out[op++] = (v1 << 4) | (v2 >>> 2);
5759
+ haveBad |= v2 & INVALID_BYTE;
5982
5760
  }
5983
- try {
5984
- // use undefined this binding; fetch errors if bound to something else in browser/cloudflare
5985
- return await this.fetch.call(undefined, url, fetchOptions);
5761
+ if (i < length - 3) {
5762
+ v3 = this._decodeChar(s.charCodeAt(i + 3));
5763
+ out[op++] = (v2 << 6) | v3;
5764
+ haveBad |= v3 & INVALID_BYTE;
5986
5765
  }
5987
- finally {
5988
- clearTimeout(timeout);
5766
+ if (haveBad !== 0) {
5767
+ throw new Error("Base64Coder: incorrect characters for decoding");
5989
5768
  }
5990
- }
5991
- async shouldRetry(response) {
5992
- // Note this is not a standard header.
5993
- const shouldRetryHeader = response.headers.get('x-should-retry');
5994
- // If the server explicitly says whether or not to retry, obey.
5995
- if (shouldRetryHeader === 'true')
5996
- return true;
5997
- if (shouldRetryHeader === 'false')
5998
- return false;
5999
- // Retry on request timeouts.
6000
- if (response.status === 408)
6001
- return true;
6002
- // Retry on lock timeouts.
6003
- if (response.status === 409)
6004
- return true;
6005
- // Retry on rate limits.
6006
- if (response.status === 429)
6007
- return true;
6008
- // Retry internal errors.
6009
- if (response.status >= 500)
6010
- return true;
6011
- return false;
6012
- }
6013
- async retryRequest(options, retriesRemaining, requestLogID, responseHeaders) {
6014
- let timeoutMillis;
6015
- // Note the `retry-after-ms` header may not be standard, but is a good idea and we'd like proactive support for it.
6016
- const retryAfterMillisHeader = responseHeaders?.get('retry-after-ms');
6017
- if (retryAfterMillisHeader) {
6018
- const timeoutMs = parseFloat(retryAfterMillisHeader);
6019
- if (!Number.isNaN(timeoutMs)) {
6020
- timeoutMillis = timeoutMs;
6021
- }
6022
- }
6023
- // About the Retry-After header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
6024
- const retryAfterHeader = responseHeaders?.get('retry-after');
6025
- if (retryAfterHeader && !timeoutMillis) {
6026
- const timeoutSeconds = parseFloat(retryAfterHeader);
6027
- if (!Number.isNaN(timeoutSeconds)) {
6028
- timeoutMillis = timeoutSeconds * 1000;
5769
+ return out;
5770
+ };
5771
+ // Standard encoding have the following encoded/decoded ranges,
5772
+ // which we need to convert between.
5773
+ //
5774
+ // ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 + /
5775
+ // Index: 0 - 25 26 - 51 52 - 61 62 63
5776
+ // ASCII: 65 - 90 97 - 122 48 - 57 43 47
5777
+ //
5778
+ // Encode 6 bits in b into a new character.
5779
+ Coder.prototype._encodeByte = function (b) {
5780
+ // Encoding uses constant time operations as follows:
5781
+ //
5782
+ // 1. Define comparison of A with B using (A - B) >>> 8:
5783
+ // if A > B, then result is positive integer
5784
+ // if A <= B, then result is 0
5785
+ //
5786
+ // 2. Define selection of C or 0 using bitwise AND: X & C:
5787
+ // if X == 0, then result is 0
5788
+ // if X != 0, then result is C
5789
+ //
5790
+ // 3. Start with the smallest comparison (b >= 0), which is always
5791
+ // true, so set the result to the starting ASCII value (65).
5792
+ //
5793
+ // 4. Continue comparing b to higher ASCII values, and selecting
5794
+ // zero if comparison isn't true, otherwise selecting a value
5795
+ // to add to result, which:
5796
+ //
5797
+ // a) undoes the previous addition
5798
+ // b) provides new value to add
5799
+ //
5800
+ var result = b;
5801
+ // b >= 0
5802
+ result += 65;
5803
+ // b > 25
5804
+ result += ((25 - b) >>> 8) & ((0 - 65) - 26 + 97);
5805
+ // b > 51
5806
+ result += ((51 - b) >>> 8) & ((26 - 97) - 52 + 48);
5807
+ // b > 61
5808
+ result += ((61 - b) >>> 8) & ((52 - 48) - 62 + 43);
5809
+ // b > 62
5810
+ result += ((62 - b) >>> 8) & ((62 - 43) - 63 + 47);
5811
+ return String.fromCharCode(result);
5812
+ };
5813
+ // Decode a character code into a byte.
5814
+ // Must return 256 if character is out of alphabet range.
5815
+ Coder.prototype._decodeChar = function (c) {
5816
+ // Decoding works similar to encoding: using the same comparison
5817
+ // function, but now it works on ranges: result is always incremented
5818
+ // by value, but this value becomes zero if the range is not
5819
+ // satisfied.
5820
+ //
5821
+ // Decoding starts with invalid value, 256, which is then
5822
+ // subtracted when the range is satisfied. If none of the ranges
5823
+ // apply, the function returns 256, which is then checked by
5824
+ // the caller to throw error.
5825
+ var result = INVALID_BYTE; // start with invalid character
5826
+ // c == 43 (c > 42 and c < 44)
5827
+ result += (((42 - c) & (c - 44)) >>> 8) & (-INVALID_BYTE + c - 43 + 62);
5828
+ // c == 47 (c > 46 and c < 48)
5829
+ result += (((46 - c) & (c - 48)) >>> 8) & (-INVALID_BYTE + c - 47 + 63);
5830
+ // c > 47 and c < 58
5831
+ result += (((47 - c) & (c - 58)) >>> 8) & (-INVALID_BYTE + c - 48 + 52);
5832
+ // c > 64 and c < 91
5833
+ result += (((64 - c) & (c - 91)) >>> 8) & (-INVALID_BYTE + c - 65 + 0);
5834
+ // c > 96 and c < 123
5835
+ result += (((96 - c) & (c - 123)) >>> 8) & (-INVALID_BYTE + c - 97 + 26);
5836
+ return result;
5837
+ };
5838
+ Coder.prototype._getPaddingLength = function (s) {
5839
+ var paddingLength = 0;
5840
+ if (this._paddingCharacter) {
5841
+ for (var i = s.length - 1; i >= 0; i--) {
5842
+ if (s[i] !== this._paddingCharacter) {
5843
+ break;
5844
+ }
5845
+ paddingLength++;
6029
5846
  }
6030
- else {
6031
- timeoutMillis = Date.parse(retryAfterHeader) - Date.now();
5847
+ if (s.length < 4 || paddingLength > 2) {
5848
+ throw new Error("Base64Coder: incorrect padding");
6032
5849
  }
6033
5850
  }
6034
- // If the API asks us to wait a certain amount of time (and it's a reasonable amount),
6035
- // just do what it says, but otherwise calculate a default
6036
- if (!(timeoutMillis && 0 <= timeoutMillis && timeoutMillis < 60 * 1000)) {
6037
- const maxRetries = options.maxRetries ?? this.maxRetries;
6038
- timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
6039
- }
6040
- await sleep(timeoutMillis);
6041
- return this.makeRequest(options, retriesRemaining - 1, requestLogID);
6042
- }
6043
- calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries) {
6044
- const initialRetryDelay = 0.5;
6045
- const maxRetryDelay = 8.0;
6046
- const numRetries = maxRetries - retriesRemaining;
6047
- // Apply exponential backoff, but not more than the max.
6048
- const sleepSeconds = Math.min(initialRetryDelay * Math.pow(2, numRetries), maxRetryDelay);
6049
- // Apply some jitter, take up to at most 25 percent of the retry time.
6050
- const jitter = 1 - Math.random() * 0.25;
6051
- return sleepSeconds * jitter * 1000;
6052
- }
6053
- async buildRequest(inputOptions, { retryCount = 0 } = {}) {
6054
- const options = { ...inputOptions };
6055
- const { method, path, query, defaultBaseURL } = options;
6056
- const url = this.buildURL(path, query, defaultBaseURL);
6057
- if ('timeout' in options)
6058
- validatePositiveInteger('timeout', options.timeout);
6059
- options.timeout = options.timeout ?? this.timeout;
6060
- const { bodyHeaders, body } = this.buildBody({ options });
6061
- const reqHeaders = await this.buildHeaders({ options: inputOptions, method, bodyHeaders, retryCount });
6062
- const req = {
6063
- method,
6064
- headers: reqHeaders,
6065
- ...(options.signal && { signal: options.signal }),
6066
- ...(globalThis.ReadableStream &&
6067
- body instanceof globalThis.ReadableStream && { duplex: 'half' }),
6068
- ...(body && { body }),
6069
- ...(this.fetchOptions ?? {}),
6070
- ...(options.fetchOptions ?? {}),
6071
- };
6072
- return { req, url, timeout: options.timeout };
6073
- }
6074
- async buildHeaders({ options, method, bodyHeaders, retryCount, }) {
6075
- let idempotencyHeaders = {};
6076
- if (this.idempotencyHeader && method !== 'get') {
6077
- if (!options.idempotencyKey)
6078
- options.idempotencyKey = this.defaultIdempotencyKey();
6079
- idempotencyHeaders[this.idempotencyHeader] = options.idempotencyKey;
6080
- }
6081
- const headers = buildHeaders([
6082
- idempotencyHeaders,
6083
- {
6084
- Accept: 'application/json',
6085
- 'User-Agent': this.getUserAgent(),
6086
- 'X-Stainless-Retry-Count': String(retryCount),
6087
- ...(options.timeout ? { 'X-Stainless-Timeout': String(Math.trunc(options.timeout / 1000)) } : {}),
6088
- ...getPlatformHeaders(),
6089
- },
6090
- await this.authHeaders(options),
6091
- this._options.defaultHeaders,
6092
- bodyHeaders,
6093
- options.headers,
6094
- ]);
6095
- this.validateHeaders(headers);
6096
- return headers.values;
6097
- }
6098
- buildBody({ options: { body, headers: rawHeaders } }) {
6099
- if (!body) {
6100
- return { bodyHeaders: undefined, body: undefined };
6101
- }
6102
- const headers = buildHeaders([rawHeaders]);
6103
- if (
6104
- // Pass raw type verbatim
6105
- ArrayBuffer.isView(body) ||
6106
- body instanceof ArrayBuffer ||
6107
- body instanceof DataView ||
6108
- (typeof body === 'string' &&
6109
- // Preserve legacy string encoding behavior for now
6110
- headers.values.has('content-type')) ||
6111
- // `Blob` is superset of `File`
6112
- (globalThis.Blob && body instanceof globalThis.Blob) ||
6113
- // `FormData` -> `multipart/form-data`
6114
- body instanceof FormData ||
6115
- // `URLSearchParams` -> `application/x-www-form-urlencoded`
6116
- body instanceof URLSearchParams ||
6117
- // Send chunked stream (each chunk has own `length`)
6118
- (globalThis.ReadableStream && body instanceof globalThis.ReadableStream)) {
6119
- return { bodyHeaders: undefined, body: body };
6120
- }
6121
- else if (typeof body === 'object' &&
6122
- (Symbol.asyncIterator in body ||
6123
- (Symbol.iterator in body && 'next' in body && typeof body.next === 'function'))) {
6124
- return { bodyHeaders: undefined, body: ReadableStreamFrom(body) };
6125
- }
6126
- else {
6127
- return __classPrivateFieldGet(this, _DodoPayments_encoder, "f").call(this, { body, headers });
6128
- }
6129
- }
6130
- }
6131
- _a = DodoPayments, _DodoPayments_encoder = new WeakMap(), _DodoPayments_instances = new WeakSet(), _DodoPayments_baseURLOverridden = function _DodoPayments_baseURLOverridden() {
6132
- return this.baseURL !== environments[this._options.environment || 'live_mode'];
6133
- };
6134
- DodoPayments.DodoPayments = _a;
6135
- DodoPayments.DEFAULT_TIMEOUT = 60000; // 1 minute
6136
- DodoPayments.DodoPaymentsError = DodoPaymentsError;
6137
- DodoPayments.APIError = APIError;
6138
- DodoPayments.APIConnectionError = APIConnectionError;
6139
- DodoPayments.APIConnectionTimeoutError = APIConnectionTimeoutError;
6140
- DodoPayments.APIUserAbortError = APIUserAbortError;
6141
- DodoPayments.NotFoundError = NotFoundError;
6142
- DodoPayments.ConflictError = ConflictError;
6143
- DodoPayments.RateLimitError = RateLimitError;
6144
- DodoPayments.BadRequestError = BadRequestError;
6145
- DodoPayments.AuthenticationError = AuthenticationError;
6146
- DodoPayments.InternalServerError = InternalServerError;
6147
- DodoPayments.PermissionDeniedError = PermissionDeniedError;
6148
- DodoPayments.UnprocessableEntityError = UnprocessableEntityError;
6149
- DodoPayments.toFile = toFile;
6150
- DodoPayments.CheckoutSessions = CheckoutSessions;
6151
- DodoPayments.Payments = Payments;
6152
- DodoPayments.Subscriptions = Subscriptions;
6153
- DodoPayments.Invoices = Invoices;
6154
- DodoPayments.Licenses = Licenses;
6155
- DodoPayments.LicenseKeys = LicenseKeys;
6156
- DodoPayments.LicenseKeyInstances = LicenseKeyInstances;
6157
- DodoPayments.Customers = Customers;
6158
- DodoPayments.Refunds = Refunds;
6159
- DodoPayments.Disputes = Disputes;
6160
- DodoPayments.Payouts = Payouts;
6161
- DodoPayments.WebhookEvents = WebhookEvents;
6162
- DodoPayments.Products = Products;
6163
- DodoPayments.Misc = Misc;
6164
- DodoPayments.Discounts = Discounts;
6165
- DodoPayments.Addons = Addons;
6166
- DodoPayments.Brands = Brands;
6167
- DodoPayments.Webhooks = Webhooks$1;
6168
- DodoPayments.UsageEvents = UsageEvents;
6169
- DodoPayments.Meters = Meters;
6170
-
6171
- var __assign = (undefined && undefined.__assign) || function () {
6172
- __assign = Object.assign || function(t) {
6173
- for (var s, i = 1, n = arguments.length; i < n; i++) {
6174
- s = arguments[i];
6175
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6176
- t[p] = s[p];
6177
- }
6178
- return t;
5851
+ return paddingLength;
6179
5852
  };
6180
- return __assign.apply(this, arguments);
6181
- };
6182
- var __awaiter$1 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
6183
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
6184
- return new (P || (P = Promise))(function (resolve, reject) {
6185
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6186
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6187
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
6188
- step((generator = generator.apply(thisArg, _arguments || [])).next());
6189
- });
6190
- };
6191
- var __generator$1 = (undefined && undefined.__generator) || function (thisArg, body) {
6192
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
6193
- return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
6194
- function verb(n) { return function (v) { return step([n, v]); }; }
6195
- function step(op) {
6196
- if (f) throw new TypeError("Generator is already executing.");
6197
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
6198
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
6199
- if (y = 0, t) op = [op[0] & 2, t.value];
6200
- switch (op[0]) {
6201
- case 0: case 1: t = op; break;
6202
- case 4: _.label++; return { value: op[1], done: false };
6203
- case 5: _.label++; y = op[1]; op = [0]; continue;
6204
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
6205
- default:
6206
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
6207
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
6208
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
6209
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
6210
- if (t[2]) _.ops.pop();
6211
- _.trys.pop(); continue;
6212
- }
6213
- op = body.call(thisArg, _);
6214
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
6215
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
6216
- }
6217
- };
6218
- var checkoutQuerySchema = objectType({
6219
- productId: stringType(),
6220
- quantity: stringType().optional(),
6221
- // Customer fields
6222
- fullName: stringType().optional(),
6223
- firstName: stringType().optional(),
6224
- lastName: stringType().optional(),
6225
- email: stringType().optional(),
6226
- country: stringType().optional(),
6227
- addressLine: stringType().optional(),
6228
- city: stringType().optional(),
6229
- state: stringType().optional(),
6230
- zipCode: stringType().optional(),
6231
- // Disable flags
6232
- disableFullName: stringType().optional(),
6233
- disableFirstName: stringType().optional(),
6234
- disableLastName: stringType().optional(),
6235
- disableEmail: stringType().optional(),
6236
- disableCountry: stringType().optional(),
6237
- disableAddressLine: stringType().optional(),
6238
- disableCity: stringType().optional(),
6239
- disableState: stringType().optional(),
6240
- disableZipCode: stringType().optional(),
6241
- // Advanced controls
6242
- paymentCurrency: stringType().optional(),
6243
- showCurrencySelector: stringType().optional(),
6244
- paymentAmount: stringType().optional(),
6245
- showDiscounts: stringType().optional(),
6246
- // Metadata (allow any key starting with metadata_)
6247
- // We'll handle metadata separately in the handler
6248
- })
6249
- .catchall(unknownType());
6250
- // Add Zod schema for dynamic checkout body
6251
- var dynamicCheckoutBodySchema = objectType({
6252
- // For subscription
6253
- product_id: stringType().optional(),
6254
- quantity: numberType().optional(),
6255
- // For one-time payment
6256
- product_cart: arrayType(objectType({
6257
- product_id: stringType(),
6258
- quantity: numberType(),
6259
- }))
6260
- .optional(),
6261
- // Common fields
6262
- billing: objectType({
6263
- city: stringType(),
6264
- country: stringType(),
6265
- state: stringType(),
6266
- street: stringType(),
6267
- zipcode: stringType(),
6268
- }),
6269
- customer: objectType({
6270
- customer_id: stringType().optional(),
6271
- email: stringType().optional(),
6272
- name: stringType().optional(),
6273
- }),
6274
- discount_id: stringType().optional(),
6275
- addons: arrayType(objectType({
6276
- addon_id: stringType(),
6277
- quantity: numberType(),
6278
- }))
6279
- .optional(),
6280
- metadata: recordType(stringType(), stringType()).optional(),
6281
- currency: stringType().optional(),
6282
- // Allow any additional fields (for future compatibility)
6283
- })
6284
- .catchall(unknownType());
6285
- // ========================================
6286
- // CHECKOUT SESSIONS SCHEMAS & TYPES
6287
- // ========================================
6288
- // Product cart item schema for checkout sessions
6289
- var checkoutSessionProductCartItemSchema = objectType({
6290
- product_id: stringType().min(1, "Product ID is required"),
6291
- quantity: numberType().int().positive("Quantity must be a positive integer"),
6292
- });
6293
- // Customer information schema for checkout sessions
6294
- var checkoutSessionCustomerSchema = objectType({
6295
- email: stringType().email().optional(),
6296
- name: stringType().min(1).optional(),
6297
- phone_number: stringType().optional(),
6298
- })
6299
- .optional();
6300
- // Billing address schema for checkout sessions
6301
- var checkoutSessionBillingAddressSchema = objectType({
6302
- street: stringType().optional(),
6303
- city: stringType().optional(),
6304
- state: stringType().optional(),
6305
- country: stringType().length(2, "Country must be a 2-letter ISO code"),
6306
- zipcode: stringType().optional(),
6307
- })
6308
- .optional();
6309
- // Payment method types enum based on Dodo Payments documentation
6310
- var paymentMethodTypeSchema = enumType([
6311
- "credit",
6312
- "debit",
6313
- "upi_collect",
6314
- "upi_intent",
6315
- "apple_pay",
6316
- "google_pay",
6317
- "amazon_pay",
6318
- "klarna",
6319
- "affirm",
6320
- "afterpay_clearpay",
6321
- "sepa",
6322
- "ach",
6323
- ]);
6324
- // Customization options schema
6325
- var checkoutSessionCustomizationSchema = objectType({
6326
- theme: enumType(["light", "dark", "system"]).optional(),
6327
- show_order_details: booleanType().optional(),
6328
- show_on_demand_tag: booleanType().optional(),
6329
- })
6330
- .optional();
6331
- // Feature flags schema
6332
- var checkoutSessionFeatureFlagsSchema = objectType({
6333
- allow_currency_selection: booleanType().optional(),
6334
- allow_discount_code: booleanType().optional(),
6335
- allow_phone_number_collection: booleanType().optional(),
6336
- allow_tax_id: booleanType().optional(),
6337
- always_create_new_customer: booleanType().optional(),
6338
- })
6339
- .optional();
6340
- // Subscription data schema
6341
- var checkoutSessionSubscriptionDataSchema = objectType({
6342
- trial_period_days: numberType().int().nonnegative().optional(),
6343
- })
6344
- .optional();
6345
- // Main checkout session payload schema
6346
- var checkoutSessionPayloadSchema = objectType({
6347
- // Required fields
6348
- product_cart: arrayType(checkoutSessionProductCartItemSchema)
6349
- .min(1, "At least one product is required"),
6350
- // Optional fields
6351
- customer: checkoutSessionCustomerSchema,
6352
- billing_address: checkoutSessionBillingAddressSchema,
6353
- return_url: stringType().url().optional(),
6354
- allowed_payment_method_types: arrayType(paymentMethodTypeSchema).optional(),
6355
- billing_currency: stringType()
6356
- .length(3, "Currency must be a 3-letter ISO code")
6357
- .optional(),
6358
- show_saved_payment_methods: booleanType().optional(),
6359
- confirm: booleanType().optional(),
6360
- discount_code: stringType().optional(),
6361
- metadata: recordType(stringType(), stringType()).optional(),
6362
- customization: checkoutSessionCustomizationSchema,
6363
- feature_flags: checkoutSessionFeatureFlagsSchema,
6364
- subscription_data: checkoutSessionSubscriptionDataSchema,
6365
- });
6366
- // Checkout session response schema
6367
- var checkoutSessionResponseSchema = objectType({
6368
- session_id: stringType().min(1, "Session ID is required"),
6369
- checkout_url: stringType().url("Invalid checkout URL"),
6370
- });
5853
+ return Coder;
5854
+ }());
5855
+ base64$1.Coder = Coder;
5856
+ var stdCoder = new Coder();
5857
+ function encode(data) {
5858
+ return stdCoder.encode(data);
5859
+ }
5860
+ base64$1.encode = encode;
5861
+ function decode(s) {
5862
+ return stdCoder.decode(s);
5863
+ }
5864
+ base64$1.decode = decode;
6371
5865
  /**
6372
- * Creates a new Dodo Payments Checkout Session using the modern /checkouts endpoint.
6373
- * This function provides a clean, type-safe interface to the Checkout Sessions API.
6374
- *
6375
- * @param payload - The checkout session data, validated against CheckoutSessionPayloadSchema
6376
- * @param config - Dodo Payments client configuration (bearerToken, environment)
6377
- * @returns Promise<CheckoutSessionResponse> - The checkout session with session_id and checkout_url
6378
- *
6379
- * @throws {Error} When payload validation fails or API request fails
6380
- *
6381
- * @example
6382
- * ```typescript
6383
- * const session = await createCheckoutSession({
6384
- * product_cart: [{ product_id: 'prod_123', quantity: 1 }],
6385
- * customer: { email: 'customer@example.com' },
6386
- * return_url: 'https://yoursite.com/success'
6387
- * }, {
6388
- * bearerToken: process.env.DODO_PAYMENTS_API_KEY,
6389
- * environment: 'test_mode'
6390
- * });
5866
+ * Implements URL-safe Base64 encoding.
5867
+ * (Same as Base64, but '+' is replaced with '-', and '/' with '_').
6391
5868
  *
6392
- * ```
5869
+ * Operates in constant time.
6393
5870
  */
6394
- var createCheckoutSession = function (payload, config) { return __awaiter$1(void 0, void 0, void 0, function () {
6395
- var validation, dodopayments, sdkPayload, session, responseValidation, error_1;
6396
- return __generator$1(this, function (_a) {
6397
- switch (_a.label) {
6398
- case 0:
6399
- validation = checkoutSessionPayloadSchema.safeParse(payload);
6400
- if (!validation.success) {
6401
- throw new Error("Invalid checkout session payload: ".concat(validation.error.issues
6402
- .map(function (issue) { return "".concat(issue.path.join("."), ": ").concat(issue.message); })
6403
- .join(", ")));
6404
- }
6405
- dodopayments = new DodoPayments({
6406
- bearerToken: config.bearerToken,
6407
- environment: config.environment,
6408
- });
6409
- _a.label = 1;
6410
- case 1:
6411
- _a.trys.push([1, 3, , 4]);
6412
- sdkPayload = __assign(__assign({}, validation.data), (validation.data.billing_address && {
6413
- billing_address: __assign(__assign({}, validation.data.billing_address), { country: validation.data.billing_address.country }),
6414
- }));
6415
- return [4 /*yield*/, dodopayments.checkoutSessions.create(sdkPayload)];
6416
- case 2:
6417
- session = _a.sent();
6418
- responseValidation = checkoutSessionResponseSchema.safeParse(session);
6419
- if (!responseValidation.success) {
6420
- throw new Error("Invalid checkout session response from API: ".concat(responseValidation.error.issues
6421
- .map(function (issue) { return "".concat(issue.path.join("."), ": ").concat(issue.message); })
6422
- .join(", ")));
6423
- }
6424
- return [2 /*return*/, responseValidation.data];
6425
- case 3:
6426
- error_1 = _a.sent();
6427
- if (error_1 instanceof Error) {
6428
- console.error("Dodo Payments Checkout Session API Error:", {
6429
- message: error_1.message,
6430
- payload: validation.data,
6431
- config: {
6432
- environment: config.environment,
6433
- hasBearerToken: !!config.bearerToken,
6434
- },
6435
- });
6436
- // Re-throw with a more user-friendly message
6437
- throw new Error("Failed to create checkout session: ".concat(error_1.message));
6438
- }
6439
- // Handle non-Error objects
6440
- console.error("Unknown error creating checkout session:", error_1);
6441
- throw new Error("Failed to create checkout session due to an unknown error");
6442
- case 4: return [2 /*return*/];
6443
- }
6444
- });
6445
- }); };
6446
- var buildCheckoutUrl = function (_a) { return __awaiter$1(void 0, [_a], void 0, function (_b) {
6447
- var session, inputData, parseResult, success, data, error, _c, productId, quantity_1, fullName, firstName, lastName, email, country, addressLine, city, state, zipCode, disableFullName, disableFirstName, disableLastName, disableEmail, disableCountry, disableAddressLine, disableCity, disableState, disableZipCode, paymentCurrency, showCurrencySelector, paymentAmount, showDiscounts, dodopayments_1, err_1, url, _i, _d, _e, key, value, dyn, product_id, product_cart, quantity, billing, customer, addons, metadata, allowed_payment_method_types, billing_currency, discount_code, on_demand, bodyReturnUrl, show_saved_payment_methods, tax_id, trial_period_days, dodopayments, isSubscription, productIdToFetch, product, err_2, subscriptionPayload, subscription, err_3, cart, paymentPayload, payment, err_4;
6448
- var queryParams = _b.queryParams, body = _b.body, sessionPayload = _b.sessionPayload, returnUrl = _b.returnUrl, bearerToken = _b.bearerToken, environment = _b.environment, _f = _b.type, type = _f === void 0 ? "static" : _f;
6449
- return __generator$1(this, function (_g) {
6450
- switch (_g.label) {
6451
- case 0:
6452
- if (!(type === "session")) return [3 /*break*/, 2];
6453
- if (!sessionPayload) {
6454
- throw new Error("sessionPayload is required when type is 'session'");
6455
- }
6456
- return [4 /*yield*/, createCheckoutSession(sessionPayload, {
6457
- bearerToken: bearerToken,
6458
- environment: environment,
6459
- })];
6460
- case 1:
6461
- session = _g.sent();
6462
- return [2 /*return*/, session.checkout_url];
6463
- case 2:
6464
- inputData = type === "dynamic" ? body : queryParams;
6465
- if (type === "dynamic") {
6466
- parseResult = dynamicCheckoutBodySchema.safeParse(inputData);
6467
- }
6468
- else {
6469
- parseResult = checkoutQuerySchema.safeParse(inputData);
6470
- }
6471
- success = parseResult.success, data = parseResult.data, error = parseResult.error;
6472
- if (!success) {
6473
- throw new Error("Invalid ".concat(type === "dynamic" ? "body" : "query parameters", ".\n ").concat(error.message));
6474
- }
6475
- if (!(type !== "dynamic")) return [3 /*break*/, 7];
6476
- _c = data, productId = _c.productId, quantity_1 = _c.quantity, fullName = _c.fullName, firstName = _c.firstName, lastName = _c.lastName, email = _c.email, country = _c.country, addressLine = _c.addressLine, city = _c.city, state = _c.state, zipCode = _c.zipCode, disableFullName = _c.disableFullName, disableFirstName = _c.disableFirstName, disableLastName = _c.disableLastName, disableEmail = _c.disableEmail, disableCountry = _c.disableCountry, disableAddressLine = _c.disableAddressLine, disableCity = _c.disableCity, disableState = _c.disableState, disableZipCode = _c.disableZipCode, paymentCurrency = _c.paymentCurrency, showCurrencySelector = _c.showCurrencySelector, paymentAmount = _c.paymentAmount, showDiscounts = _c.showDiscounts;
6477
- dodopayments_1 = new DodoPayments({
6478
- bearerToken: bearerToken,
6479
- environment: environment,
6480
- });
6481
- // Check that the product exists for this merchant
6482
- if (!productId)
6483
- throw new Error("Missing required field: productId");
6484
- _g.label = 3;
6485
- case 3:
6486
- _g.trys.push([3, 5, , 6]);
6487
- return [4 /*yield*/, dodopayments_1.products.retrieve(productId)];
6488
- case 4:
6489
- _g.sent();
6490
- return [3 /*break*/, 6];
6491
- case 5:
6492
- err_1 = _g.sent();
6493
- console.error(err_1);
6494
- throw new Error("Product not found");
6495
- case 6:
6496
- url = new URL("".concat(environment === "test_mode" ? "https://test.checkout.dodopayments.com" : "https://checkout.dodopayments.com", "/buy/").concat(productId));
6497
- url.searchParams.set("quantity", quantity_1 ? String(quantity_1) : "1");
6498
- if (returnUrl)
6499
- url.searchParams.set("redirect_url", returnUrl);
6500
- // Customer/billing fields
6501
- if (fullName)
6502
- url.searchParams.set("fullName", String(fullName));
6503
- if (firstName)
6504
- url.searchParams.set("firstName", String(firstName));
6505
- if (lastName)
6506
- url.searchParams.set("lastName", String(lastName));
6507
- if (email)
6508
- url.searchParams.set("email", String(email));
6509
- if (country)
6510
- url.searchParams.set("country", String(country));
6511
- if (addressLine)
6512
- url.searchParams.set("addressLine", String(addressLine));
6513
- if (city)
6514
- url.searchParams.set("city", String(city));
6515
- if (state)
6516
- url.searchParams.set("state", String(state));
6517
- if (zipCode)
6518
- url.searchParams.set("zipCode", String(zipCode));
6519
- // Disable flags (must be set to 'true' to disable)
6520
- if (disableFullName === "true")
6521
- url.searchParams.set("disableFullName", "true");
6522
- if (disableFirstName === "true")
6523
- url.searchParams.set("disableFirstName", "true");
6524
- if (disableLastName === "true")
6525
- url.searchParams.set("disableLastName", "true");
6526
- if (disableEmail === "true")
6527
- url.searchParams.set("disableEmail", "true");
6528
- if (disableCountry === "true")
6529
- url.searchParams.set("disableCountry", "true");
6530
- if (disableAddressLine === "true")
6531
- url.searchParams.set("disableAddressLine", "true");
6532
- if (disableCity === "true")
6533
- url.searchParams.set("disableCity", "true");
6534
- if (disableState === "true")
6535
- url.searchParams.set("disableState", "true");
6536
- if (disableZipCode === "true")
6537
- url.searchParams.set("disableZipCode", "true");
6538
- // Advanced controls
6539
- if (paymentCurrency)
6540
- url.searchParams.set("paymentCurrency", String(paymentCurrency));
6541
- if (showCurrencySelector)
6542
- url.searchParams.set("showCurrencySelector", String(showCurrencySelector));
6543
- if (paymentAmount)
6544
- url.searchParams.set("paymentAmount", String(paymentAmount));
6545
- if (showDiscounts)
6546
- url.searchParams.set("showDiscounts", String(showDiscounts));
6547
- // Metadata: add all query params starting with metadata_
6548
- for (_i = 0, _d = Object.entries(queryParams || {}); _i < _d.length; _i++) {
6549
- _e = _d[_i], key = _e[0], value = _e[1];
6550
- if (key.startsWith("metadata_") && value && typeof value !== "object") {
6551
- url.searchParams.set(key, String(value));
6552
- }
6553
- }
6554
- return [2 /*return*/, url.toString()];
6555
- case 7:
6556
- dyn = data;
6557
- product_id = dyn.product_id, product_cart = dyn.product_cart, quantity = dyn.quantity, billing = dyn.billing, customer = dyn.customer, addons = dyn.addons, metadata = dyn.metadata, allowed_payment_method_types = dyn.allowed_payment_method_types, billing_currency = dyn.billing_currency, discount_code = dyn.discount_code, on_demand = dyn.on_demand, bodyReturnUrl = dyn.return_url, show_saved_payment_methods = dyn.show_saved_payment_methods, tax_id = dyn.tax_id, trial_period_days = dyn.trial_period_days;
6558
- dodopayments = new DodoPayments({
6559
- bearerToken: bearerToken,
6560
- environment: environment,
6561
- });
6562
- isSubscription = false;
6563
- productIdToFetch = product_id;
6564
- if (!product_id && product_cart && product_cart.length > 0) {
6565
- productIdToFetch = product_cart[0].product_id;
6566
- }
6567
- if (!productIdToFetch)
6568
- throw new Error("Missing required field: product_id or product_cart[0].product_id");
6569
- _g.label = 8;
6570
- case 8:
6571
- _g.trys.push([8, 10, , 11]);
6572
- return [4 /*yield*/, dodopayments.products.retrieve(productIdToFetch)];
6573
- case 9:
6574
- product = _g.sent();
6575
- return [3 /*break*/, 11];
6576
- case 10:
6577
- err_2 = _g.sent();
6578
- console.error(err_2);
6579
- throw new Error("Product not found");
6580
- case 11:
6581
- isSubscription = Boolean(product.is_recurring);
6582
- // Required field validation
6583
- if (isSubscription && !product_id)
6584
- throw new Error("Missing required field: product_id for subscription");
6585
- if (!billing)
6586
- throw new Error("Missing required field: billing");
6587
- if (!customer)
6588
- throw new Error("Missing required field: customer");
6589
- if (!isSubscription) return [3 /*break*/, 16];
6590
- subscriptionPayload = {
6591
- billing: billing,
6592
- customer: customer,
6593
- product_id: product_id,
6594
- quantity: quantity ? Number(quantity) : 1,
6595
- };
6596
- if (metadata)
6597
- subscriptionPayload.metadata = metadata;
6598
- if (discount_code)
6599
- subscriptionPayload.discount_code = discount_code;
6600
- if (addons)
6601
- subscriptionPayload.addons = addons;
6602
- if (allowed_payment_method_types)
6603
- subscriptionPayload.allowed_payment_method_types =
6604
- allowed_payment_method_types;
6605
- if (billing_currency)
6606
- subscriptionPayload.billing_currency = billing_currency;
6607
- if (on_demand)
6608
- subscriptionPayload.on_demand = on_demand;
6609
- subscriptionPayload.payment_link = true;
6610
- // Use bodyReturnUrl if present, otherwise use top-level returnUrl
6611
- if (bodyReturnUrl) {
6612
- subscriptionPayload.return_url = bodyReturnUrl;
6613
- }
6614
- else if (returnUrl) {
6615
- subscriptionPayload.return_url = returnUrl;
6616
- }
6617
- if (show_saved_payment_methods)
6618
- subscriptionPayload.show_saved_payment_methods =
6619
- show_saved_payment_methods;
6620
- if (tax_id)
6621
- subscriptionPayload.tax_id = tax_id;
6622
- if (trial_period_days)
6623
- subscriptionPayload.trial_period_days = trial_period_days;
6624
- subscription = void 0;
6625
- _g.label = 12;
6626
- case 12:
6627
- _g.trys.push([12, 14, , 15]);
6628
- return [4 /*yield*/, dodopayments.subscriptions.create(subscriptionPayload)];
6629
- case 13:
6630
- subscription =
6631
- _g.sent();
6632
- return [3 /*break*/, 15];
6633
- case 14:
6634
- err_3 = _g.sent();
6635
- console.error("Error when creating subscription", err_3);
6636
- throw new Error(err_3 instanceof Error ? err_3.message : String(err_3));
6637
- case 15:
6638
- if (!subscription || !subscription.payment_link) {
6639
- throw new Error("No payment link returned from Dodo Payments API (subscription). Make sure to set payment_link as true in payload");
6640
- }
6641
- return [2 /*return*/, subscription.payment_link];
6642
- case 16:
6643
- cart = product_cart;
6644
- if (!cart && product_id) {
6645
- cart = [
6646
- { product_id: product_id, quantity: quantity ? Number(quantity) : 1 },
6647
- ];
6648
- }
6649
- if (!cart || cart.length === 0)
6650
- throw new Error("Missing required field: product_cart or product_id");
6651
- paymentPayload = {
6652
- billing: billing,
6653
- customer: customer,
6654
- product_cart: cart,
6655
- };
6656
- if (metadata)
6657
- paymentPayload.metadata = metadata;
6658
- paymentPayload.payment_link = true;
6659
- if (allowed_payment_method_types)
6660
- paymentPayload.allowed_payment_method_types =
6661
- allowed_payment_method_types;
6662
- if (billing_currency)
6663
- paymentPayload.billing_currency = billing_currency;
6664
- if (discount_code)
6665
- paymentPayload.discount_code = discount_code;
6666
- // Use bodyReturnUrl if present, otherwise use top-level returnUrl
6667
- if (bodyReturnUrl) {
6668
- paymentPayload.return_url = bodyReturnUrl;
6669
- }
6670
- else if (returnUrl) {
6671
- paymentPayload.return_url = returnUrl;
6672
- }
6673
- if (show_saved_payment_methods)
6674
- paymentPayload.show_saved_payment_methods = show_saved_payment_methods;
6675
- if (tax_id)
6676
- paymentPayload.tax_id = tax_id;
6677
- payment = void 0;
6678
- _g.label = 17;
6679
- case 17:
6680
- _g.trys.push([17, 19, , 20]);
6681
- return [4 /*yield*/, dodopayments.payments.create(paymentPayload)];
6682
- case 18:
6683
- payment = _g.sent();
6684
- return [3 /*break*/, 20];
6685
- case 19:
6686
- err_4 = _g.sent();
6687
- console.error("Error when creating payment link", err_4);
6688
- throw new Error(err_4 instanceof Error ? err_4.message : String(err_4));
6689
- case 20:
6690
- if (!payment || !payment.payment_link) {
6691
- throw new Error("No payment link returned from Dodo Payments API. Make sure to set payment_link as true in payload.");
6692
- }
6693
- return [2 /*return*/, payment.payment_link];
6694
- }
6695
- });
6696
- }); };
6697
-
6698
- const Checkout = (config) => {
6699
- const getHandler = async (c) => {
6700
- const queryParams = c.req.query();
6701
- if (!queryParams.productId) {
6702
- return c.text("Please provide productId query parameter", 400);
6703
- }
6704
- const { success, data, error } = checkoutQuerySchema.safeParse(queryParams);
6705
- if (!success) {
6706
- if (error.errors.some((e) => e.path.toString() === "productId")) {
6707
- return c.text("Please provide productId query parameter", 400);
6708
- }
6709
- return c.text(`Invalid query parameters.\n ${error.message}`, 400);
6710
- }
6711
- let url = "";
6712
- try {
6713
- url = await buildCheckoutUrl({ queryParams: data, ...config });
6714
- }
6715
- catch (error) {
6716
- return c.text(error.message, 400);
6717
- }
6718
- return c.json({ checkout_url: url });
6719
- };
6720
- const postHandler = async (c) => {
6721
- let body;
6722
- try {
6723
- body = await c.req.json();
6724
- }
6725
- catch (e) {
6726
- return c.text("Invalid JSON body", 400);
6727
- }
6728
- if (config.type === "dynamic") {
6729
- // Handle dynamic checkout
6730
- const { success, data, error } = dynamicCheckoutBodySchema.safeParse(body);
6731
- if (!success) {
6732
- return c.text(`Invalid request body.\n ${error.message}`, 400);
6733
- }
6734
- let url = "";
6735
- try {
6736
- url = await buildCheckoutUrl({
6737
- body: data,
6738
- ...config,
6739
- type: "dynamic",
6740
- });
6741
- }
6742
- catch (error) {
6743
- return c.text(error.message, 400);
6744
- }
6745
- return c.json({ checkout_url: url });
6746
- }
6747
- else {
6748
- // Handle checkout session
6749
- const { success, data, error } = checkoutSessionPayloadSchema.safeParse(body);
6750
- if (!success) {
6751
- return c.text(`Invalid checkout session payload.\n ${error.message}`, 400);
6752
- }
6753
- let url = "";
6754
- try {
6755
- url = await buildCheckoutUrl({
6756
- sessionPayload: data,
6757
- ...config,
6758
- type: "session",
6759
- });
6760
- }
6761
- catch (error) {
6762
- return c.text(error.message, 400);
6763
- }
6764
- return c.json({ checkout_url: url });
6765
- }
6766
- };
6767
- return (c) => {
6768
- if (c.req.method === "POST") {
6769
- return postHandler(c);
6770
- }
6771
- return getHandler(c);
5871
+ var URLSafeCoder = /** @class */ (function (_super) {
5872
+ __extends(URLSafeCoder, _super);
5873
+ function URLSafeCoder() {
5874
+ return _super !== null && _super.apply(this, arguments) || this;
5875
+ }
5876
+ // URL-safe encoding have the following encoded/decoded ranges:
5877
+ //
5878
+ // ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 - _
5879
+ // Index: 0 - 25 26 - 51 52 - 61 62 63
5880
+ // ASCII: 65 - 90 97 - 122 48 - 57 45 95
5881
+ //
5882
+ URLSafeCoder.prototype._encodeByte = function (b) {
5883
+ var result = b;
5884
+ // b >= 0
5885
+ result += 65;
5886
+ // b > 25
5887
+ result += ((25 - b) >>> 8) & ((0 - 65) - 26 + 97);
5888
+ // b > 51
5889
+ result += ((51 - b) >>> 8) & ((26 - 97) - 52 + 48);
5890
+ // b > 61
5891
+ result += ((61 - b) >>> 8) & ((52 - 48) - 62 + 45);
5892
+ // b > 62
5893
+ result += ((62 - b) >>> 8) & ((62 - 45) - 63 + 95);
5894
+ return String.fromCharCode(result);
6772
5895
  };
6773
- };
6774
-
6775
- const CustomerPortal = ({ bearerToken, environment, }) => {
6776
- const getHandler = async (c) => {
6777
- // Extract customerId from query parameters
6778
- const customerId = c.req.query("customer_id");
6779
- const sendEmail = c.req.query("send_email");
6780
- const params = {
6781
- send_email: false,
6782
- };
6783
- if (sendEmail === "true") {
6784
- params.send_email = true;
6785
- }
6786
- if (!customerId) {
6787
- return c.text("Missing customerId in query parameters", 400);
6788
- }
6789
- const dodopayments = new DodoPayments({
6790
- bearerToken,
6791
- environment,
6792
- });
6793
- try {
6794
- const session = await dodopayments.customers.customerPortal.create(customerId, params);
6795
- return c.redirect(session.link);
6796
- }
6797
- catch (error) {
6798
- console.error("Error creating customer portal session:", error);
6799
- return c.text(`Failed to create customer portal session: ${error.message}`, 500);
6800
- }
5896
+ URLSafeCoder.prototype._decodeChar = function (c) {
5897
+ var result = INVALID_BYTE;
5898
+ // c == 45 (c > 44 and c < 46)
5899
+ result += (((44 - c) & (c - 46)) >>> 8) & (-INVALID_BYTE + c - 45 + 62);
5900
+ // c == 95 (c > 94 and c < 96)
5901
+ result += (((94 - c) & (c - 96)) >>> 8) & (-INVALID_BYTE + c - 95 + 63);
5902
+ // c > 47 and c < 58
5903
+ result += (((47 - c) & (c - 58)) >>> 8) & (-INVALID_BYTE + c - 48 + 52);
5904
+ // c > 64 and c < 91
5905
+ result += (((64 - c) & (c - 91)) >>> 8) & (-INVALID_BYTE + c - 65 + 0);
5906
+ // c > 96 and c < 123
5907
+ result += (((96 - c) & (c - 123)) >>> 8) & (-INVALID_BYTE + c - 97 + 26);
5908
+ return result;
6801
5909
  };
6802
- return getHandler;
6803
- };
6804
-
6805
- var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
6806
-
6807
- var dist = {};
6808
-
6809
- var timing_safe_equal = {};
6810
-
6811
- Object.defineProperty(timing_safe_equal, "__esModule", { value: true });
6812
- timing_safe_equal.timingSafeEqual = void 0;
6813
- function assert(expr, msg = "") {
6814
- if (!expr) {
6815
- throw new Error(msg);
6816
- }
5910
+ return URLSafeCoder;
5911
+ }(Coder));
5912
+ base64$1.URLSafeCoder = URLSafeCoder;
5913
+ var urlSafeCoder = new URLSafeCoder();
5914
+ function encodeURLSafe(data) {
5915
+ return urlSafeCoder.encode(data);
6817
5916
  }
6818
- function timingSafeEqual(a, b) {
6819
- if (a.byteLength !== b.byteLength) {
6820
- return false;
6821
- }
6822
- if (!(a instanceof DataView)) {
6823
- a = new DataView(ArrayBuffer.isView(a) ? a.buffer : a);
6824
- }
6825
- if (!(b instanceof DataView)) {
6826
- b = new DataView(ArrayBuffer.isView(b) ? b.buffer : b);
6827
- }
6828
- assert(a instanceof DataView);
6829
- assert(b instanceof DataView);
6830
- const length = a.byteLength;
6831
- let out = 0;
6832
- let i = -1;
6833
- while (++i < length) {
6834
- out |= a.getUint8(i) ^ b.getUint8(i);
6835
- }
6836
- return out === 0;
5917
+ base64$1.encodeURLSafe = encodeURLSafe;
5918
+ function decodeURLSafe(s) {
5919
+ return urlSafeCoder.decode(s);
6837
5920
  }
6838
- timing_safe_equal.timingSafeEqual = timingSafeEqual;
5921
+ base64$1.decodeURLSafe = decodeURLSafe;
5922
+ base64$1.encodedLength = function (length) {
5923
+ return stdCoder.encodedLength(length);
5924
+ };
5925
+ base64$1.maxDecodedLength = function (length) {
5926
+ return stdCoder.maxDecodedLength(length);
5927
+ };
5928
+ base64$1.decodedLength = function (s) {
5929
+ return stdCoder.decodedLength(s);
5930
+ };
6839
5931
 
6840
- var base64$1 = {};
6841
-
6842
- // Copyright (C) 2016 Dmitry Chestnykh
6843
- // MIT License. See LICENSE file for details.
6844
- var __extends = (commonjsGlobal && commonjsGlobal.__extends) || (function () {
6845
- var extendStatics = function (d, b) {
6846
- extendStatics = Object.setPrototypeOf ||
6847
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6848
- function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
6849
- return extendStatics(d, b);
6850
- };
6851
- return function (d, b) {
6852
- extendStatics(d, b);
6853
- function __() { this.constructor = d; }
6854
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
6855
- };
6856
- })();
6857
- Object.defineProperty(base64$1, "__esModule", { value: true });
6858
- /**
6859
- * Package base64 implements Base64 encoding and decoding.
6860
- */
6861
- // Invalid character used in decoding to indicate
6862
- // that the character to decode is out of range of
6863
- // alphabet and cannot be decoded.
6864
- var INVALID_BYTE = 256;
6865
- /**
6866
- * Implements standard Base64 encoding.
6867
- *
6868
- * Operates in constant time.
6869
- */
6870
- var Coder = /** @class */ (function () {
6871
- // TODO(dchest): methods to encode chunk-by-chunk.
6872
- function Coder(_paddingCharacter) {
6873
- if (_paddingCharacter === void 0) { _paddingCharacter = "="; }
6874
- this._paddingCharacter = _paddingCharacter;
6875
- }
6876
- Coder.prototype.encodedLength = function (length) {
6877
- if (!this._paddingCharacter) {
6878
- return (length * 8 + 5) / 6 | 0;
6879
- }
6880
- return (length + 2) / 3 * 4 | 0;
6881
- };
6882
- Coder.prototype.encode = function (data) {
6883
- var out = "";
6884
- var i = 0;
6885
- for (; i < data.length - 2; i += 3) {
6886
- var c = (data[i] << 16) | (data[i + 1] << 8) | (data[i + 2]);
6887
- out += this._encodeByte((c >>> 3 * 6) & 63);
6888
- out += this._encodeByte((c >>> 2 * 6) & 63);
6889
- out += this._encodeByte((c >>> 1 * 6) & 63);
6890
- out += this._encodeByte((c >>> 0 * 6) & 63);
6891
- }
6892
- var left = data.length - i;
6893
- if (left > 0) {
6894
- var c = (data[i] << 16) | (left === 2 ? data[i + 1] << 8 : 0);
6895
- out += this._encodeByte((c >>> 3 * 6) & 63);
6896
- out += this._encodeByte((c >>> 2 * 6) & 63);
6897
- if (left === 2) {
6898
- out += this._encodeByte((c >>> 1 * 6) & 63);
6899
- }
6900
- else {
6901
- out += this._paddingCharacter || "";
6902
- }
6903
- out += this._paddingCharacter || "";
6904
- }
6905
- return out;
6906
- };
6907
- Coder.prototype.maxDecodedLength = function (length) {
6908
- if (!this._paddingCharacter) {
6909
- return (length * 6 + 7) / 8 | 0;
6910
- }
6911
- return length / 4 * 3 | 0;
6912
- };
6913
- Coder.prototype.decodedLength = function (s) {
6914
- return this.maxDecodedLength(s.length - this._getPaddingLength(s));
6915
- };
6916
- Coder.prototype.decode = function (s) {
6917
- if (s.length === 0) {
6918
- return new Uint8Array(0);
6919
- }
6920
- var paddingLength = this._getPaddingLength(s);
6921
- var length = s.length - paddingLength;
6922
- var out = new Uint8Array(this.maxDecodedLength(length));
6923
- var op = 0;
6924
- var i = 0;
6925
- var haveBad = 0;
6926
- var v0 = 0, v1 = 0, v2 = 0, v3 = 0;
6927
- for (; i < length - 4; i += 4) {
6928
- v0 = this._decodeChar(s.charCodeAt(i + 0));
6929
- v1 = this._decodeChar(s.charCodeAt(i + 1));
6930
- v2 = this._decodeChar(s.charCodeAt(i + 2));
6931
- v3 = this._decodeChar(s.charCodeAt(i + 3));
6932
- out[op++] = (v0 << 2) | (v1 >>> 4);
6933
- out[op++] = (v1 << 4) | (v2 >>> 2);
6934
- out[op++] = (v2 << 6) | v3;
6935
- haveBad |= v0 & INVALID_BYTE;
6936
- haveBad |= v1 & INVALID_BYTE;
6937
- haveBad |= v2 & INVALID_BYTE;
6938
- haveBad |= v3 & INVALID_BYTE;
6939
- }
6940
- if (i < length - 1) {
6941
- v0 = this._decodeChar(s.charCodeAt(i));
6942
- v1 = this._decodeChar(s.charCodeAt(i + 1));
6943
- out[op++] = (v0 << 2) | (v1 >>> 4);
6944
- haveBad |= v0 & INVALID_BYTE;
6945
- haveBad |= v1 & INVALID_BYTE;
6946
- }
6947
- if (i < length - 2) {
6948
- v2 = this._decodeChar(s.charCodeAt(i + 2));
6949
- out[op++] = (v1 << 4) | (v2 >>> 2);
6950
- haveBad |= v2 & INVALID_BYTE;
6951
- }
6952
- if (i < length - 3) {
6953
- v3 = this._decodeChar(s.charCodeAt(i + 3));
6954
- out[op++] = (v2 << 6) | v3;
6955
- haveBad |= v3 & INVALID_BYTE;
6956
- }
6957
- if (haveBad !== 0) {
6958
- throw new Error("Base64Coder: incorrect characters for decoding");
6959
- }
6960
- return out;
6961
- };
6962
- // Standard encoding have the following encoded/decoded ranges,
6963
- // which we need to convert between.
6964
- //
6965
- // ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 + /
6966
- // Index: 0 - 25 26 - 51 52 - 61 62 63
6967
- // ASCII: 65 - 90 97 - 122 48 - 57 43 47
6968
- //
6969
- // Encode 6 bits in b into a new character.
6970
- Coder.prototype._encodeByte = function (b) {
6971
- // Encoding uses constant time operations as follows:
6972
- //
6973
- // 1. Define comparison of A with B using (A - B) >>> 8:
6974
- // if A > B, then result is positive integer
6975
- // if A <= B, then result is 0
6976
- //
6977
- // 2. Define selection of C or 0 using bitwise AND: X & C:
6978
- // if X == 0, then result is 0
6979
- // if X != 0, then result is C
6980
- //
6981
- // 3. Start with the smallest comparison (b >= 0), which is always
6982
- // true, so set the result to the starting ASCII value (65).
6983
- //
6984
- // 4. Continue comparing b to higher ASCII values, and selecting
6985
- // zero if comparison isn't true, otherwise selecting a value
6986
- // to add to result, which:
6987
- //
6988
- // a) undoes the previous addition
6989
- // b) provides new value to add
6990
- //
6991
- var result = b;
6992
- // b >= 0
6993
- result += 65;
6994
- // b > 25
6995
- result += ((25 - b) >>> 8) & ((0 - 65) - 26 + 97);
6996
- // b > 51
6997
- result += ((51 - b) >>> 8) & ((26 - 97) - 52 + 48);
6998
- // b > 61
6999
- result += ((61 - b) >>> 8) & ((52 - 48) - 62 + 43);
7000
- // b > 62
7001
- result += ((62 - b) >>> 8) & ((62 - 43) - 63 + 47);
7002
- return String.fromCharCode(result);
7003
- };
7004
- // Decode a character code into a byte.
7005
- // Must return 256 if character is out of alphabet range.
7006
- Coder.prototype._decodeChar = function (c) {
7007
- // Decoding works similar to encoding: using the same comparison
7008
- // function, but now it works on ranges: result is always incremented
7009
- // by value, but this value becomes zero if the range is not
7010
- // satisfied.
7011
- //
7012
- // Decoding starts with invalid value, 256, which is then
7013
- // subtracted when the range is satisfied. If none of the ranges
7014
- // apply, the function returns 256, which is then checked by
7015
- // the caller to throw error.
7016
- var result = INVALID_BYTE; // start with invalid character
7017
- // c == 43 (c > 42 and c < 44)
7018
- result += (((42 - c) & (c - 44)) >>> 8) & (-INVALID_BYTE + c - 43 + 62);
7019
- // c == 47 (c > 46 and c < 48)
7020
- result += (((46 - c) & (c - 48)) >>> 8) & (-INVALID_BYTE + c - 47 + 63);
7021
- // c > 47 and c < 58
7022
- result += (((47 - c) & (c - 58)) >>> 8) & (-INVALID_BYTE + c - 48 + 52);
7023
- // c > 64 and c < 91
7024
- result += (((64 - c) & (c - 91)) >>> 8) & (-INVALID_BYTE + c - 65 + 0);
7025
- // c > 96 and c < 123
7026
- result += (((96 - c) & (c - 123)) >>> 8) & (-INVALID_BYTE + c - 97 + 26);
7027
- return result;
7028
- };
7029
- Coder.prototype._getPaddingLength = function (s) {
7030
- var paddingLength = 0;
7031
- if (this._paddingCharacter) {
7032
- for (var i = s.length - 1; i >= 0; i--) {
7033
- if (s[i] !== this._paddingCharacter) {
7034
- break;
7035
- }
7036
- paddingLength++;
7037
- }
7038
- if (s.length < 4 || paddingLength > 2) {
7039
- throw new Error("Base64Coder: incorrect padding");
7040
- }
7041
- }
7042
- return paddingLength;
7043
- };
7044
- return Coder;
7045
- }());
7046
- base64$1.Coder = Coder;
7047
- var stdCoder = new Coder();
7048
- function encode(data) {
7049
- return stdCoder.encode(data);
7050
- }
7051
- base64$1.encode = encode;
7052
- function decode(s) {
7053
- return stdCoder.decode(s);
7054
- }
7055
- base64$1.decode = decode;
7056
- /**
7057
- * Implements URL-safe Base64 encoding.
7058
- * (Same as Base64, but '+' is replaced with '-', and '/' with '_').
7059
- *
7060
- * Operates in constant time.
7061
- */
7062
- var URLSafeCoder = /** @class */ (function (_super) {
7063
- __extends(URLSafeCoder, _super);
7064
- function URLSafeCoder() {
7065
- return _super !== null && _super.apply(this, arguments) || this;
7066
- }
7067
- // URL-safe encoding have the following encoded/decoded ranges:
7068
- //
7069
- // ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 - _
7070
- // Index: 0 - 25 26 - 51 52 - 61 62 63
7071
- // ASCII: 65 - 90 97 - 122 48 - 57 45 95
7072
- //
7073
- URLSafeCoder.prototype._encodeByte = function (b) {
7074
- var result = b;
7075
- // b >= 0
7076
- result += 65;
7077
- // b > 25
7078
- result += ((25 - b) >>> 8) & ((0 - 65) - 26 + 97);
7079
- // b > 51
7080
- result += ((51 - b) >>> 8) & ((26 - 97) - 52 + 48);
7081
- // b > 61
7082
- result += ((61 - b) >>> 8) & ((52 - 48) - 62 + 45);
7083
- // b > 62
7084
- result += ((62 - b) >>> 8) & ((62 - 45) - 63 + 95);
7085
- return String.fromCharCode(result);
7086
- };
7087
- URLSafeCoder.prototype._decodeChar = function (c) {
7088
- var result = INVALID_BYTE;
7089
- // c == 45 (c > 44 and c < 46)
7090
- result += (((44 - c) & (c - 46)) >>> 8) & (-INVALID_BYTE + c - 45 + 62);
7091
- // c == 95 (c > 94 and c < 96)
7092
- result += (((94 - c) & (c - 96)) >>> 8) & (-INVALID_BYTE + c - 95 + 63);
7093
- // c > 47 and c < 58
7094
- result += (((47 - c) & (c - 58)) >>> 8) & (-INVALID_BYTE + c - 48 + 52);
7095
- // c > 64 and c < 91
7096
- result += (((64 - c) & (c - 91)) >>> 8) & (-INVALID_BYTE + c - 65 + 0);
7097
- // c > 96 and c < 123
7098
- result += (((96 - c) & (c - 123)) >>> 8) & (-INVALID_BYTE + c - 97 + 26);
7099
- return result;
7100
- };
7101
- return URLSafeCoder;
7102
- }(Coder));
7103
- base64$1.URLSafeCoder = URLSafeCoder;
7104
- var urlSafeCoder = new URLSafeCoder();
7105
- function encodeURLSafe(data) {
7106
- return urlSafeCoder.encode(data);
7107
- }
7108
- base64$1.encodeURLSafe = encodeURLSafe;
7109
- function decodeURLSafe(s) {
7110
- return urlSafeCoder.decode(s);
7111
- }
7112
- base64$1.decodeURLSafe = decodeURLSafe;
7113
- base64$1.encodedLength = function (length) {
7114
- return stdCoder.encodedLength(length);
7115
- };
7116
- base64$1.maxDecodedLength = function (length) {
7117
- return stdCoder.maxDecodedLength(length);
7118
- };
7119
- base64$1.decodedLength = function (s) {
7120
- return stdCoder.decodedLength(s);
7121
- };
7122
-
7123
- var sha256$1 = {exports: {}};
5932
+ var sha256$1 = {exports: {}};
7124
5933
 
7125
5934
  (function (module) {
7126
5935
  (function (root, factory) {
@@ -7547,648 +6356,1670 @@ var sha256$1 = {exports: {}};
7547
6356
  });
7548
6357
  } (sha256$1));
7549
6358
 
7550
- var sha256Exports = sha256$1.exports;
6359
+ var sha256Exports = sha256$1.exports;
6360
+
6361
+ Object.defineProperty(dist, "__esModule", { value: true });
6362
+ var Webhook_1 = dist.Webhook = WebhookVerificationError_1 = dist.WebhookVerificationError = void 0;
6363
+ const timing_safe_equal_1 = timing_safe_equal;
6364
+ const base64 = base64$1;
6365
+ const sha256 = sha256Exports;
6366
+ const WEBHOOK_TOLERANCE_IN_SECONDS = 5 * 60;
6367
+ class ExtendableError extends Error {
6368
+ constructor(message) {
6369
+ super(message);
6370
+ Object.setPrototypeOf(this, ExtendableError.prototype);
6371
+ this.name = "ExtendableError";
6372
+ this.stack = new Error(message).stack;
6373
+ }
6374
+ }
6375
+ class WebhookVerificationError extends ExtendableError {
6376
+ constructor(message) {
6377
+ super(message);
6378
+ Object.setPrototypeOf(this, WebhookVerificationError.prototype);
6379
+ this.name = "WebhookVerificationError";
6380
+ }
6381
+ }
6382
+ var WebhookVerificationError_1 = dist.WebhookVerificationError = WebhookVerificationError;
6383
+ class Webhook {
6384
+ constructor(secret, options) {
6385
+ if (!secret) {
6386
+ throw new Error("Secret can't be empty.");
6387
+ }
6388
+ if ((options === null || options === void 0 ? void 0 : options.format) === "raw") {
6389
+ if (secret instanceof Uint8Array) {
6390
+ this.key = secret;
6391
+ }
6392
+ else {
6393
+ this.key = Uint8Array.from(secret, (c) => c.charCodeAt(0));
6394
+ }
6395
+ }
6396
+ else {
6397
+ if (typeof secret !== "string") {
6398
+ throw new Error("Expected secret to be of type string");
6399
+ }
6400
+ if (secret.startsWith(Webhook.prefix)) {
6401
+ secret = secret.substring(Webhook.prefix.length);
6402
+ }
6403
+ this.key = base64.decode(secret);
6404
+ }
6405
+ }
6406
+ verify(payload, headers_) {
6407
+ const headers = {};
6408
+ for (const key of Object.keys(headers_)) {
6409
+ headers[key.toLowerCase()] = headers_[key];
6410
+ }
6411
+ const msgId = headers["webhook-id"];
6412
+ const msgSignature = headers["webhook-signature"];
6413
+ const msgTimestamp = headers["webhook-timestamp"];
6414
+ if (!msgSignature || !msgId || !msgTimestamp) {
6415
+ throw new WebhookVerificationError("Missing required headers");
6416
+ }
6417
+ const timestamp = this.verifyTimestamp(msgTimestamp);
6418
+ const computedSignature = this.sign(msgId, timestamp, payload);
6419
+ const expectedSignature = computedSignature.split(",")[1];
6420
+ const passedSignatures = msgSignature.split(" ");
6421
+ const encoder = new globalThis.TextEncoder();
6422
+ for (const versionedSignature of passedSignatures) {
6423
+ const [version, signature] = versionedSignature.split(",");
6424
+ if (version !== "v1") {
6425
+ continue;
6426
+ }
6427
+ if ((0, timing_safe_equal_1.timingSafeEqual)(encoder.encode(signature), encoder.encode(expectedSignature))) {
6428
+ return JSON.parse(payload.toString());
6429
+ }
6430
+ }
6431
+ throw new WebhookVerificationError("No matching signature found");
6432
+ }
6433
+ sign(msgId, timestamp, payload) {
6434
+ if (typeof payload === "string") ;
6435
+ else if (payload.constructor.name === "Buffer") {
6436
+ payload = payload.toString();
6437
+ }
6438
+ else {
6439
+ throw new Error("Expected payload to be of type string or Buffer.");
6440
+ }
6441
+ const encoder = new TextEncoder();
6442
+ const timestampNumber = Math.floor(timestamp.getTime() / 1000);
6443
+ const toSign = encoder.encode(`${msgId}.${timestampNumber}.${payload}`);
6444
+ const expectedSignature = base64.encode(sha256.hmac(this.key, toSign));
6445
+ return `v1,${expectedSignature}`;
6446
+ }
6447
+ verifyTimestamp(timestampHeader) {
6448
+ const now = Math.floor(Date.now() / 1000);
6449
+ const timestamp = parseInt(timestampHeader, 10);
6450
+ if (isNaN(timestamp)) {
6451
+ throw new WebhookVerificationError("Invalid Signature Headers");
6452
+ }
6453
+ if (now - timestamp > WEBHOOK_TOLERANCE_IN_SECONDS) {
6454
+ throw new WebhookVerificationError("Message timestamp too old");
6455
+ }
6456
+ if (timestamp > now + WEBHOOK_TOLERANCE_IN_SECONDS) {
6457
+ throw new WebhookVerificationError("Message timestamp too new");
6458
+ }
6459
+ return new Date(timestamp * 1000);
6460
+ }
6461
+ }
6462
+ Webhook_1 = dist.Webhook = Webhook;
6463
+ Webhook.prefix = "whsec_";
6464
+
6465
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
6466
+ let Webhooks$1 = class Webhooks extends APIResource {
6467
+ constructor() {
6468
+ super(...arguments);
6469
+ this.headers = new Headers$1(this._client);
6470
+ }
6471
+ /**
6472
+ * Create a new webhook
6473
+ */
6474
+ create(body, options) {
6475
+ return this._client.post('/webhooks', { body, ...options });
6476
+ }
6477
+ /**
6478
+ * Get a webhook by id
6479
+ */
6480
+ retrieve(webhookID, options) {
6481
+ return this._client.get(path `/webhooks/${webhookID}`, options);
6482
+ }
6483
+ /**
6484
+ * Patch a webhook by id
6485
+ */
6486
+ update(webhookID, body, options) {
6487
+ return this._client.patch(path `/webhooks/${webhookID}`, { body, ...options });
6488
+ }
6489
+ /**
6490
+ * List all webhooks
6491
+ */
6492
+ list(query = {}, options) {
6493
+ return this._client.getAPIList('/webhooks', (CursorPagePagination), { query, ...options });
6494
+ }
6495
+ /**
6496
+ * Delete a webhook by id
6497
+ */
6498
+ delete(webhookID, options) {
6499
+ return this._client.delete(path `/webhooks/${webhookID}`, {
6500
+ ...options,
6501
+ headers: buildHeaders([{ Accept: '*/*' }, options?.headers]),
6502
+ });
6503
+ }
6504
+ /**
6505
+ * Get webhook secret by id
6506
+ */
6507
+ retrieveSecret(webhookID, options) {
6508
+ return this._client.get(path `/webhooks/${webhookID}/secret`, options);
6509
+ }
6510
+ unsafeUnwrap(body) {
6511
+ return JSON.parse(body);
6512
+ }
6513
+ unwrap(body, { headers, key }) {
6514
+ if (headers !== undefined) {
6515
+ const keyStr = key === undefined ? this._client.webhookKey : key;
6516
+ if (keyStr === null)
6517
+ throw new Error('Webhook key must not be null in order to unwrap');
6518
+ const wh = new Webhook_1(keyStr);
6519
+ wh.verify(body, headers);
6520
+ }
6521
+ return JSON.parse(body);
6522
+ }
6523
+ };
6524
+ Webhooks$1.Headers = Headers$1;
6525
+
6526
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
6527
+ /**
6528
+ * Read an environment variable.
6529
+ *
6530
+ * Trims beginning and trailing whitespace.
6531
+ *
6532
+ * Will return undefined if the environment variable doesn't exist or cannot be accessed.
6533
+ */
6534
+ const readEnv = (env) => {
6535
+ if (typeof globalThis.process !== 'undefined') {
6536
+ return globalThis.process.env?.[env]?.trim() ?? undefined;
6537
+ }
6538
+ if (typeof globalThis.Deno !== 'undefined') {
6539
+ return globalThis.Deno.env?.get?.(env)?.trim();
6540
+ }
6541
+ return undefined;
6542
+ };
7551
6543
 
7552
- Object.defineProperty(dist, "__esModule", { value: true });
7553
- var Webhook_1 = dist.Webhook = WebhookVerificationError_1 = dist.WebhookVerificationError = void 0;
7554
- const timing_safe_equal_1 = timing_safe_equal;
7555
- const base64 = base64$1;
7556
- const sha256 = sha256Exports;
7557
- const WEBHOOK_TOLERANCE_IN_SECONDS = 5 * 60;
7558
- class ExtendableError extends Error {
7559
- constructor(message) {
7560
- super(message);
7561
- Object.setPrototypeOf(this, ExtendableError.prototype);
7562
- this.name = "ExtendableError";
7563
- this.stack = new Error(message).stack;
6544
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
6545
+ var _DodoPayments_instances, _a, _DodoPayments_encoder, _DodoPayments_baseURLOverridden;
6546
+ const environments = {
6547
+ live_mode: 'https://live.dodopayments.com',
6548
+ test_mode: 'https://test.dodopayments.com',
6549
+ };
6550
+ /**
6551
+ * API Client for interfacing with the Dodo Payments API.
6552
+ */
6553
+ class DodoPayments {
6554
+ /**
6555
+ * API Client for interfacing with the Dodo Payments API.
6556
+ *
6557
+ * @param {string | undefined} [opts.bearerToken=process.env['DODO_PAYMENTS_API_KEY'] ?? undefined]
6558
+ * @param {string | null | undefined} [opts.webhookKey=process.env['DODO_PAYMENTS_WEBHOOK_KEY'] ?? null]
6559
+ * @param {Environment} [opts.environment=live_mode] - Specifies the environment URL to use for the API.
6560
+ * @param {string} [opts.baseURL=process.env['DODO_PAYMENTS_BASE_URL'] ?? https://live.dodopayments.com] - Override the default base URL for the API.
6561
+ * @param {number} [opts.timeout=1 minute] - The maximum amount of time (in milliseconds) the client will wait for a response before timing out.
6562
+ * @param {MergedRequestInit} [opts.fetchOptions] - Additional `RequestInit` options to be passed to `fetch` calls.
6563
+ * @param {Fetch} [opts.fetch] - Specify a custom `fetch` function implementation.
6564
+ * @param {number} [opts.maxRetries=2] - The maximum number of times the client will retry a request.
6565
+ * @param {HeadersLike} opts.defaultHeaders - Default headers to include with every request to the API.
6566
+ * @param {Record<string, string | undefined>} opts.defaultQuery - Default query parameters to include with every request to the API.
6567
+ */
6568
+ constructor({ baseURL = readEnv('DODO_PAYMENTS_BASE_URL'), bearerToken = readEnv('DODO_PAYMENTS_API_KEY'), webhookKey = readEnv('DODO_PAYMENTS_WEBHOOK_KEY') ?? null, ...opts } = {}) {
6569
+ _DodoPayments_instances.add(this);
6570
+ _DodoPayments_encoder.set(this, void 0);
6571
+ this.checkoutSessions = new CheckoutSessions(this);
6572
+ this.payments = new Payments(this);
6573
+ this.subscriptions = new Subscriptions(this);
6574
+ this.invoices = new Invoices(this);
6575
+ this.licenses = new Licenses(this);
6576
+ this.licenseKeys = new LicenseKeys(this);
6577
+ this.licenseKeyInstances = new LicenseKeyInstances(this);
6578
+ this.customers = new Customers(this);
6579
+ this.refunds = new Refunds(this);
6580
+ this.disputes = new Disputes(this);
6581
+ this.payouts = new Payouts(this);
6582
+ this.products = new Products(this);
6583
+ this.misc = new Misc(this);
6584
+ this.discounts = new Discounts(this);
6585
+ this.addons = new Addons(this);
6586
+ this.brands = new Brands(this);
6587
+ this.webhooks = new Webhooks$1(this);
6588
+ this.webhookEvents = new WebhookEvents(this);
6589
+ this.usageEvents = new UsageEvents(this);
6590
+ this.meters = new Meters(this);
6591
+ if (bearerToken === undefined) {
6592
+ throw new DodoPaymentsError("The DODO_PAYMENTS_API_KEY environment variable is missing or empty; either provide it, or instantiate the DodoPayments client with an bearerToken option, like new DodoPayments({ bearerToken: 'My Bearer Token' }).");
6593
+ }
6594
+ const options = {
6595
+ bearerToken,
6596
+ webhookKey,
6597
+ ...opts,
6598
+ baseURL,
6599
+ environment: opts.environment ?? 'live_mode',
6600
+ };
6601
+ if (baseURL && opts.environment) {
6602
+ throw new DodoPaymentsError('Ambiguous URL; The `baseURL` option (or DODO_PAYMENTS_BASE_URL env var) and the `environment` option are given. If you want to use the environment you must pass baseURL: null');
6603
+ }
6604
+ this.baseURL = options.baseURL || environments[options.environment || 'live_mode'];
6605
+ this.timeout = options.timeout ?? _a.DEFAULT_TIMEOUT /* 1 minute */;
6606
+ this.logger = options.logger ?? console;
6607
+ const defaultLogLevel = 'warn';
6608
+ // Set default logLevel early so that we can log a warning in parseLogLevel.
6609
+ this.logLevel = defaultLogLevel;
6610
+ this.logLevel =
6611
+ parseLogLevel(options.logLevel, 'ClientOptions.logLevel', this) ??
6612
+ parseLogLevel(readEnv('DODO_PAYMENTS_LOG'), "process.env['DODO_PAYMENTS_LOG']", this) ??
6613
+ defaultLogLevel;
6614
+ this.fetchOptions = options.fetchOptions;
6615
+ this.maxRetries = options.maxRetries ?? 2;
6616
+ this.fetch = options.fetch ?? getDefaultFetch();
6617
+ __classPrivateFieldSet(this, _DodoPayments_encoder, FallbackEncoder);
6618
+ this._options = options;
6619
+ this.bearerToken = bearerToken;
6620
+ this.webhookKey = webhookKey;
6621
+ }
6622
+ /**
6623
+ * Create a new client instance re-using the same options given to the current client with optional overriding.
6624
+ */
6625
+ withOptions(options) {
6626
+ const client = new this.constructor({
6627
+ ...this._options,
6628
+ environment: options.environment ? options.environment : undefined,
6629
+ baseURL: options.environment ? undefined : this.baseURL,
6630
+ maxRetries: this.maxRetries,
6631
+ timeout: this.timeout,
6632
+ logger: this.logger,
6633
+ logLevel: this.logLevel,
6634
+ fetch: this.fetch,
6635
+ fetchOptions: this.fetchOptions,
6636
+ bearerToken: this.bearerToken,
6637
+ webhookKey: this.webhookKey,
6638
+ ...options,
6639
+ });
6640
+ return client;
6641
+ }
6642
+ defaultQuery() {
6643
+ return this._options.defaultQuery;
6644
+ }
6645
+ validateHeaders({ values, nulls }) {
6646
+ return;
6647
+ }
6648
+ async authHeaders(opts) {
6649
+ return buildHeaders([{ Authorization: `Bearer ${this.bearerToken}` }]);
6650
+ }
6651
+ /**
6652
+ * Basic re-implementation of `qs.stringify` for primitive types.
6653
+ */
6654
+ stringifyQuery(query) {
6655
+ return Object.entries(query)
6656
+ .filter(([_, value]) => typeof value !== 'undefined')
6657
+ .map(([key, value]) => {
6658
+ if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
6659
+ return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
6660
+ }
6661
+ if (value === null) {
6662
+ return `${encodeURIComponent(key)}=`;
6663
+ }
6664
+ throw new DodoPaymentsError(`Cannot stringify type ${typeof value}; Expected string, number, boolean, or null. If you need to pass nested query parameters, you can manually encode them, e.g. { query: { 'foo[key1]': value1, 'foo[key2]': value2 } }, and please open a GitHub issue requesting better support for your use case.`);
6665
+ })
6666
+ .join('&');
6667
+ }
6668
+ getUserAgent() {
6669
+ return `${this.constructor.name}/JS ${VERSION}`;
6670
+ }
6671
+ defaultIdempotencyKey() {
6672
+ return `stainless-node-retry-${uuid4()}`;
6673
+ }
6674
+ makeStatusError(status, error, message, headers) {
6675
+ return APIError.generate(status, error, message, headers);
6676
+ }
6677
+ buildURL(path, query, defaultBaseURL) {
6678
+ const baseURL = (!__classPrivateFieldGet(this, _DodoPayments_instances, "m", _DodoPayments_baseURLOverridden).call(this) && defaultBaseURL) || this.baseURL;
6679
+ const url = isAbsoluteURL(path) ?
6680
+ new URL(path)
6681
+ : new URL(baseURL + (baseURL.endsWith('/') && path.startsWith('/') ? path.slice(1) : path));
6682
+ const defaultQuery = this.defaultQuery();
6683
+ if (!isEmptyObj(defaultQuery)) {
6684
+ query = { ...defaultQuery, ...query };
6685
+ }
6686
+ if (typeof query === 'object' && query && !Array.isArray(query)) {
6687
+ url.search = this.stringifyQuery(query);
6688
+ }
6689
+ return url.toString();
6690
+ }
6691
+ /**
6692
+ * Used as a callback for mutating the given `FinalRequestOptions` object.
6693
+ */
6694
+ async prepareOptions(options) { }
6695
+ /**
6696
+ * Used as a callback for mutating the given `RequestInit` object.
6697
+ *
6698
+ * This is useful for cases where you want to add certain headers based off of
6699
+ * the request properties, e.g. `method` or `url`.
6700
+ */
6701
+ async prepareRequest(request, { url, options }) { }
6702
+ get(path, opts) {
6703
+ return this.methodRequest('get', path, opts);
6704
+ }
6705
+ post(path, opts) {
6706
+ return this.methodRequest('post', path, opts);
6707
+ }
6708
+ patch(path, opts) {
6709
+ return this.methodRequest('patch', path, opts);
6710
+ }
6711
+ put(path, opts) {
6712
+ return this.methodRequest('put', path, opts);
6713
+ }
6714
+ delete(path, opts) {
6715
+ return this.methodRequest('delete', path, opts);
6716
+ }
6717
+ methodRequest(method, path, opts) {
6718
+ return this.request(Promise.resolve(opts).then((opts) => {
6719
+ return { method, path, ...opts };
6720
+ }));
6721
+ }
6722
+ request(options, remainingRetries = null) {
6723
+ return new APIPromise(this, this.makeRequest(options, remainingRetries, undefined));
6724
+ }
6725
+ async makeRequest(optionsInput, retriesRemaining, retryOfRequestLogID) {
6726
+ const options = await optionsInput;
6727
+ const maxRetries = options.maxRetries ?? this.maxRetries;
6728
+ if (retriesRemaining == null) {
6729
+ retriesRemaining = maxRetries;
6730
+ }
6731
+ await this.prepareOptions(options);
6732
+ const { req, url, timeout } = await this.buildRequest(options, {
6733
+ retryCount: maxRetries - retriesRemaining,
6734
+ });
6735
+ await this.prepareRequest(req, { url, options });
6736
+ /** Not an API request ID, just for correlating local log entries. */
6737
+ const requestLogID = 'log_' + ((Math.random() * (1 << 24)) | 0).toString(16).padStart(6, '0');
6738
+ const retryLogStr = retryOfRequestLogID === undefined ? '' : `, retryOf: ${retryOfRequestLogID}`;
6739
+ const startTime = Date.now();
6740
+ loggerFor(this).debug(`[${requestLogID}] sending request`, formatRequestDetails({
6741
+ retryOfRequestLogID,
6742
+ method: options.method,
6743
+ url,
6744
+ options,
6745
+ headers: req.headers,
6746
+ }));
6747
+ if (options.signal?.aborted) {
6748
+ throw new APIUserAbortError();
6749
+ }
6750
+ const controller = new AbortController();
6751
+ const response = await this.fetchWithTimeout(url, req, timeout, controller).catch(castToError);
6752
+ const headersTime = Date.now();
6753
+ if (response instanceof globalThis.Error) {
6754
+ const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
6755
+ if (options.signal?.aborted) {
6756
+ throw new APIUserAbortError();
6757
+ }
6758
+ // detect native connection timeout errors
6759
+ // deno throws "TypeError: error sending request for url (https://example/): client error (Connect): tcp connect error: Operation timed out (os error 60): Operation timed out (os error 60)"
6760
+ // undici throws "TypeError: fetch failed" with cause "ConnectTimeoutError: Connect Timeout Error (attempted address: example:443, timeout: 1ms)"
6761
+ // others do not provide enough information to distinguish timeouts from other connection errors
6762
+ const isTimeout = isAbortError(response) ||
6763
+ /timed? ?out/i.test(String(response) + ('cause' in response ? String(response.cause) : ''));
6764
+ if (retriesRemaining) {
6765
+ loggerFor(this).info(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - ${retryMessage}`);
6766
+ loggerFor(this).debug(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (${retryMessage})`, formatRequestDetails({
6767
+ retryOfRequestLogID,
6768
+ url,
6769
+ durationMs: headersTime - startTime,
6770
+ message: response.message,
6771
+ }));
6772
+ return this.retryRequest(options, retriesRemaining, retryOfRequestLogID ?? requestLogID);
6773
+ }
6774
+ loggerFor(this).info(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - error; no more retries left`);
6775
+ loggerFor(this).debug(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (error; no more retries left)`, formatRequestDetails({
6776
+ retryOfRequestLogID,
6777
+ url,
6778
+ durationMs: headersTime - startTime,
6779
+ message: response.message,
6780
+ }));
6781
+ if (isTimeout) {
6782
+ throw new APIConnectionTimeoutError();
6783
+ }
6784
+ throw new APIConnectionError({ cause: response });
6785
+ }
6786
+ const responseInfo = `[${requestLogID}${retryLogStr}] ${req.method} ${url} ${response.ok ? 'succeeded' : 'failed'} with status ${response.status} in ${headersTime - startTime}ms`;
6787
+ if (!response.ok) {
6788
+ const shouldRetry = await this.shouldRetry(response);
6789
+ if (retriesRemaining && shouldRetry) {
6790
+ const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
6791
+ // We don't need the body of this response.
6792
+ await CancelReadableStream(response.body);
6793
+ loggerFor(this).info(`${responseInfo} - ${retryMessage}`);
6794
+ loggerFor(this).debug(`[${requestLogID}] response error (${retryMessage})`, formatRequestDetails({
6795
+ retryOfRequestLogID,
6796
+ url: response.url,
6797
+ status: response.status,
6798
+ headers: response.headers,
6799
+ durationMs: headersTime - startTime,
6800
+ }));
6801
+ return this.retryRequest(options, retriesRemaining, retryOfRequestLogID ?? requestLogID, response.headers);
6802
+ }
6803
+ const retryMessage = shouldRetry ? `error; no more retries left` : `error; not retryable`;
6804
+ loggerFor(this).info(`${responseInfo} - ${retryMessage}`);
6805
+ const errText = await response.text().catch((err) => castToError(err).message);
6806
+ const errJSON = safeJSON(errText);
6807
+ const errMessage = errJSON ? undefined : errText;
6808
+ loggerFor(this).debug(`[${requestLogID}] response error (${retryMessage})`, formatRequestDetails({
6809
+ retryOfRequestLogID,
6810
+ url: response.url,
6811
+ status: response.status,
6812
+ headers: response.headers,
6813
+ message: errMessage,
6814
+ durationMs: Date.now() - startTime,
6815
+ }));
6816
+ const err = this.makeStatusError(response.status, errJSON, errMessage, response.headers);
6817
+ throw err;
6818
+ }
6819
+ loggerFor(this).info(responseInfo);
6820
+ loggerFor(this).debug(`[${requestLogID}] response start`, formatRequestDetails({
6821
+ retryOfRequestLogID,
6822
+ url: response.url,
6823
+ status: response.status,
6824
+ headers: response.headers,
6825
+ durationMs: headersTime - startTime,
6826
+ }));
6827
+ return { response, options, controller, requestLogID, retryOfRequestLogID, startTime };
7564
6828
  }
7565
- }
7566
- class WebhookVerificationError extends ExtendableError {
7567
- constructor(message) {
7568
- super(message);
7569
- Object.setPrototypeOf(this, WebhookVerificationError.prototype);
7570
- this.name = "WebhookVerificationError";
6829
+ getAPIList(path, Page, opts) {
6830
+ return this.requestAPIList(Page, { method: 'get', path, ...opts });
6831
+ }
6832
+ requestAPIList(Page, options) {
6833
+ const request = this.makeRequest(options, null, undefined);
6834
+ return new PagePromise(this, request, Page);
6835
+ }
6836
+ async fetchWithTimeout(url, init, ms, controller) {
6837
+ const { signal, method, ...options } = init || {};
6838
+ if (signal)
6839
+ signal.addEventListener('abort', () => controller.abort());
6840
+ const timeout = setTimeout(() => controller.abort(), ms);
6841
+ const isReadableBody = (globalThis.ReadableStream && options.body instanceof globalThis.ReadableStream) ||
6842
+ (typeof options.body === 'object' && options.body !== null && Symbol.asyncIterator in options.body);
6843
+ const fetchOptions = {
6844
+ signal: controller.signal,
6845
+ ...(isReadableBody ? { duplex: 'half' } : {}),
6846
+ method: 'GET',
6847
+ ...options,
6848
+ };
6849
+ if (method) {
6850
+ // Custom methods like 'patch' need to be uppercased
6851
+ // See https://github.com/nodejs/undici/issues/2294
6852
+ fetchOptions.method = method.toUpperCase();
6853
+ }
6854
+ try {
6855
+ // use undefined this binding; fetch errors if bound to something else in browser/cloudflare
6856
+ return await this.fetch.call(undefined, url, fetchOptions);
6857
+ }
6858
+ finally {
6859
+ clearTimeout(timeout);
6860
+ }
6861
+ }
6862
+ async shouldRetry(response) {
6863
+ // Note this is not a standard header.
6864
+ const shouldRetryHeader = response.headers.get('x-should-retry');
6865
+ // If the server explicitly says whether or not to retry, obey.
6866
+ if (shouldRetryHeader === 'true')
6867
+ return true;
6868
+ if (shouldRetryHeader === 'false')
6869
+ return false;
6870
+ // Retry on request timeouts.
6871
+ if (response.status === 408)
6872
+ return true;
6873
+ // Retry on lock timeouts.
6874
+ if (response.status === 409)
6875
+ return true;
6876
+ // Retry on rate limits.
6877
+ if (response.status === 429)
6878
+ return true;
6879
+ // Retry internal errors.
6880
+ if (response.status >= 500)
6881
+ return true;
6882
+ return false;
6883
+ }
6884
+ async retryRequest(options, retriesRemaining, requestLogID, responseHeaders) {
6885
+ let timeoutMillis;
6886
+ // Note the `retry-after-ms` header may not be standard, but is a good idea and we'd like proactive support for it.
6887
+ const retryAfterMillisHeader = responseHeaders?.get('retry-after-ms');
6888
+ if (retryAfterMillisHeader) {
6889
+ const timeoutMs = parseFloat(retryAfterMillisHeader);
6890
+ if (!Number.isNaN(timeoutMs)) {
6891
+ timeoutMillis = timeoutMs;
6892
+ }
6893
+ }
6894
+ // About the Retry-After header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
6895
+ const retryAfterHeader = responseHeaders?.get('retry-after');
6896
+ if (retryAfterHeader && !timeoutMillis) {
6897
+ const timeoutSeconds = parseFloat(retryAfterHeader);
6898
+ if (!Number.isNaN(timeoutSeconds)) {
6899
+ timeoutMillis = timeoutSeconds * 1000;
6900
+ }
6901
+ else {
6902
+ timeoutMillis = Date.parse(retryAfterHeader) - Date.now();
6903
+ }
6904
+ }
6905
+ // If the API asks us to wait a certain amount of time (and it's a reasonable amount),
6906
+ // just do what it says, but otherwise calculate a default
6907
+ if (!(timeoutMillis && 0 <= timeoutMillis && timeoutMillis < 60 * 1000)) {
6908
+ const maxRetries = options.maxRetries ?? this.maxRetries;
6909
+ timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
6910
+ }
6911
+ await sleep(timeoutMillis);
6912
+ return this.makeRequest(options, retriesRemaining - 1, requestLogID);
6913
+ }
6914
+ calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries) {
6915
+ const initialRetryDelay = 0.5;
6916
+ const maxRetryDelay = 8.0;
6917
+ const numRetries = maxRetries - retriesRemaining;
6918
+ // Apply exponential backoff, but not more than the max.
6919
+ const sleepSeconds = Math.min(initialRetryDelay * Math.pow(2, numRetries), maxRetryDelay);
6920
+ // Apply some jitter, take up to at most 25 percent of the retry time.
6921
+ const jitter = 1 - Math.random() * 0.25;
6922
+ return sleepSeconds * jitter * 1000;
6923
+ }
6924
+ async buildRequest(inputOptions, { retryCount = 0 } = {}) {
6925
+ const options = { ...inputOptions };
6926
+ const { method, path, query, defaultBaseURL } = options;
6927
+ const url = this.buildURL(path, query, defaultBaseURL);
6928
+ if ('timeout' in options)
6929
+ validatePositiveInteger('timeout', options.timeout);
6930
+ options.timeout = options.timeout ?? this.timeout;
6931
+ const { bodyHeaders, body } = this.buildBody({ options });
6932
+ const reqHeaders = await this.buildHeaders({ options: inputOptions, method, bodyHeaders, retryCount });
6933
+ const req = {
6934
+ method,
6935
+ headers: reqHeaders,
6936
+ ...(options.signal && { signal: options.signal }),
6937
+ ...(globalThis.ReadableStream &&
6938
+ body instanceof globalThis.ReadableStream && { duplex: 'half' }),
6939
+ ...(body && { body }),
6940
+ ...(this.fetchOptions ?? {}),
6941
+ ...(options.fetchOptions ?? {}),
6942
+ };
6943
+ return { req, url, timeout: options.timeout };
6944
+ }
6945
+ async buildHeaders({ options, method, bodyHeaders, retryCount, }) {
6946
+ let idempotencyHeaders = {};
6947
+ if (this.idempotencyHeader && method !== 'get') {
6948
+ if (!options.idempotencyKey)
6949
+ options.idempotencyKey = this.defaultIdempotencyKey();
6950
+ idempotencyHeaders[this.idempotencyHeader] = options.idempotencyKey;
6951
+ }
6952
+ const headers = buildHeaders([
6953
+ idempotencyHeaders,
6954
+ {
6955
+ Accept: 'application/json',
6956
+ 'User-Agent': this.getUserAgent(),
6957
+ 'X-Stainless-Retry-Count': String(retryCount),
6958
+ ...(options.timeout ? { 'X-Stainless-Timeout': String(Math.trunc(options.timeout / 1000)) } : {}),
6959
+ ...getPlatformHeaders(),
6960
+ },
6961
+ await this.authHeaders(options),
6962
+ this._options.defaultHeaders,
6963
+ bodyHeaders,
6964
+ options.headers,
6965
+ ]);
6966
+ this.validateHeaders(headers);
6967
+ return headers.values;
6968
+ }
6969
+ buildBody({ options: { body, headers: rawHeaders } }) {
6970
+ if (!body) {
6971
+ return { bodyHeaders: undefined, body: undefined };
6972
+ }
6973
+ const headers = buildHeaders([rawHeaders]);
6974
+ if (
6975
+ // Pass raw type verbatim
6976
+ ArrayBuffer.isView(body) ||
6977
+ body instanceof ArrayBuffer ||
6978
+ body instanceof DataView ||
6979
+ (typeof body === 'string' &&
6980
+ // Preserve legacy string encoding behavior for now
6981
+ headers.values.has('content-type')) ||
6982
+ // `Blob` is superset of `File`
6983
+ (globalThis.Blob && body instanceof globalThis.Blob) ||
6984
+ // `FormData` -> `multipart/form-data`
6985
+ body instanceof FormData ||
6986
+ // `URLSearchParams` -> `application/x-www-form-urlencoded`
6987
+ body instanceof URLSearchParams ||
6988
+ // Send chunked stream (each chunk has own `length`)
6989
+ (globalThis.ReadableStream && body instanceof globalThis.ReadableStream)) {
6990
+ return { bodyHeaders: undefined, body: body };
6991
+ }
6992
+ else if (typeof body === 'object' &&
6993
+ (Symbol.asyncIterator in body ||
6994
+ (Symbol.iterator in body && 'next' in body && typeof body.next === 'function'))) {
6995
+ return { bodyHeaders: undefined, body: ReadableStreamFrom(body) };
6996
+ }
6997
+ else {
6998
+ return __classPrivateFieldGet(this, _DodoPayments_encoder, "f").call(this, { body, headers });
6999
+ }
7571
7000
  }
7572
7001
  }
7573
- var WebhookVerificationError_1 = dist.WebhookVerificationError = WebhookVerificationError;
7574
- class Webhook {
7575
- constructor(secret, options) {
7576
- if (!secret) {
7577
- throw new Error("Secret can't be empty.");
7002
+ _a = DodoPayments, _DodoPayments_encoder = new WeakMap(), _DodoPayments_instances = new WeakSet(), _DodoPayments_baseURLOverridden = function _DodoPayments_baseURLOverridden() {
7003
+ return this.baseURL !== environments[this._options.environment || 'live_mode'];
7004
+ };
7005
+ DodoPayments.DodoPayments = _a;
7006
+ DodoPayments.DEFAULT_TIMEOUT = 60000; // 1 minute
7007
+ DodoPayments.DodoPaymentsError = DodoPaymentsError;
7008
+ DodoPayments.APIError = APIError;
7009
+ DodoPayments.APIConnectionError = APIConnectionError;
7010
+ DodoPayments.APIConnectionTimeoutError = APIConnectionTimeoutError;
7011
+ DodoPayments.APIUserAbortError = APIUserAbortError;
7012
+ DodoPayments.NotFoundError = NotFoundError;
7013
+ DodoPayments.ConflictError = ConflictError;
7014
+ DodoPayments.RateLimitError = RateLimitError;
7015
+ DodoPayments.BadRequestError = BadRequestError;
7016
+ DodoPayments.AuthenticationError = AuthenticationError;
7017
+ DodoPayments.InternalServerError = InternalServerError;
7018
+ DodoPayments.PermissionDeniedError = PermissionDeniedError;
7019
+ DodoPayments.UnprocessableEntityError = UnprocessableEntityError;
7020
+ DodoPayments.toFile = toFile;
7021
+ DodoPayments.CheckoutSessions = CheckoutSessions;
7022
+ DodoPayments.Payments = Payments;
7023
+ DodoPayments.Subscriptions = Subscriptions;
7024
+ DodoPayments.Invoices = Invoices;
7025
+ DodoPayments.Licenses = Licenses;
7026
+ DodoPayments.LicenseKeys = LicenseKeys;
7027
+ DodoPayments.LicenseKeyInstances = LicenseKeyInstances;
7028
+ DodoPayments.Customers = Customers;
7029
+ DodoPayments.Refunds = Refunds;
7030
+ DodoPayments.Disputes = Disputes;
7031
+ DodoPayments.Payouts = Payouts;
7032
+ DodoPayments.Products = Products;
7033
+ DodoPayments.Misc = Misc;
7034
+ DodoPayments.Discounts = Discounts;
7035
+ DodoPayments.Addons = Addons;
7036
+ DodoPayments.Brands = Brands;
7037
+ DodoPayments.Webhooks = Webhooks$1;
7038
+ DodoPayments.WebhookEvents = WebhookEvents;
7039
+ DodoPayments.UsageEvents = UsageEvents;
7040
+ DodoPayments.Meters = Meters;
7041
+
7042
+ // src/checkout/checkout.ts
7043
+ var checkoutQuerySchema = objectType({
7044
+ productId: stringType(),
7045
+ quantity: stringType().optional(),
7046
+ // Customer fields
7047
+ fullName: stringType().optional(),
7048
+ firstName: stringType().optional(),
7049
+ lastName: stringType().optional(),
7050
+ email: stringType().optional(),
7051
+ country: stringType().optional(),
7052
+ addressLine: stringType().optional(),
7053
+ city: stringType().optional(),
7054
+ state: stringType().optional(),
7055
+ zipCode: stringType().optional(),
7056
+ // Disable flags
7057
+ disableFullName: stringType().optional(),
7058
+ disableFirstName: stringType().optional(),
7059
+ disableLastName: stringType().optional(),
7060
+ disableEmail: stringType().optional(),
7061
+ disableCountry: stringType().optional(),
7062
+ disableAddressLine: stringType().optional(),
7063
+ disableCity: stringType().optional(),
7064
+ disableState: stringType().optional(),
7065
+ disableZipCode: stringType().optional(),
7066
+ // Advanced controls
7067
+ paymentCurrency: stringType().optional(),
7068
+ showCurrencySelector: stringType().optional(),
7069
+ paymentAmount: stringType().optional(),
7070
+ showDiscounts: stringType().optional()
7071
+ // Metadata (allow any key starting with metadata_)
7072
+ // We'll handle metadata separately in the handler
7073
+ }).catchall(unknownType());
7074
+ var dynamicCheckoutBodySchema = objectType({
7075
+ // For subscription
7076
+ product_id: stringType().optional(),
7077
+ quantity: numberType().optional(),
7078
+ // For one-time payment
7079
+ product_cart: arrayType(
7080
+ objectType({
7081
+ product_id: stringType(),
7082
+ quantity: numberType()
7083
+ })
7084
+ ).optional(),
7085
+ // Common fields
7086
+ billing: objectType({
7087
+ city: stringType(),
7088
+ country: stringType(),
7089
+ state: stringType(),
7090
+ street: stringType(),
7091
+ zipcode: stringType()
7092
+ }),
7093
+ customer: objectType({
7094
+ customer_id: stringType().optional(),
7095
+ email: stringType().optional(),
7096
+ name: stringType().optional()
7097
+ }),
7098
+ discount_id: stringType().optional(),
7099
+ addons: arrayType(
7100
+ objectType({
7101
+ addon_id: stringType(),
7102
+ quantity: numberType()
7103
+ })
7104
+ ).optional(),
7105
+ metadata: recordType(stringType(), stringType()).optional(),
7106
+ currency: stringType().optional()
7107
+ // Allow any additional fields (for future compatibility)
7108
+ }).catchall(unknownType());
7109
+ var checkoutSessionProductCartItemSchema = objectType({
7110
+ product_id: stringType().min(1, "Product ID is required"),
7111
+ quantity: numberType().int().positive("Quantity must be a positive integer"),
7112
+ addons: arrayType(
7113
+ objectType({
7114
+ addon_id: stringType(),
7115
+ quantity: numberType().int().nonnegative()
7116
+ })
7117
+ ).optional(),
7118
+ amount: numberType().int().nonnegative(
7119
+ "Amount must be a non-negative integer (for pay-what-you-want products)"
7120
+ ).optional()
7121
+ });
7122
+ var checkoutSessionCustomerSchema = unionType([
7123
+ objectType({
7124
+ email: stringType().email(),
7125
+ name: stringType().min(1).optional(),
7126
+ phone_number: stringType().optional()
7127
+ }),
7128
+ objectType({
7129
+ customer_id: stringType()
7130
+ })
7131
+ ]).optional();
7132
+ var checkoutSessionBillingAddressSchema = objectType({
7133
+ street: stringType().optional(),
7134
+ city: stringType().optional(),
7135
+ state: stringType().optional(),
7136
+ country: stringType().length(2, "Country must be a 2-letter ISO code"),
7137
+ zipcode: stringType().optional()
7138
+ }).optional();
7139
+ var paymentMethodTypeSchema = enumType([
7140
+ "credit",
7141
+ "debit",
7142
+ "upi_collect",
7143
+ "upi_intent",
7144
+ "apple_pay",
7145
+ "cashapp",
7146
+ "google_pay",
7147
+ "multibanco",
7148
+ "bancontact_card",
7149
+ "eps",
7150
+ "ideal",
7151
+ "przelewy24",
7152
+ "paypal",
7153
+ "affirm",
7154
+ "klarna",
7155
+ "sepa",
7156
+ "ach",
7157
+ "amazon_pay",
7158
+ "afterpay_clearpay"
7159
+ ]);
7160
+ var checkoutSessionCustomizationSchema = objectType({
7161
+ theme: enumType(["light", "dark", "system"]).optional(),
7162
+ show_order_details: booleanType().optional(),
7163
+ show_on_demand_tag: booleanType().optional(),
7164
+ force_language: stringType().optional()
7165
+ }).optional();
7166
+ var checkoutSessionFeatureFlagsSchema = objectType({
7167
+ allow_currency_selection: booleanType().optional(),
7168
+ allow_discount_code: booleanType().optional(),
7169
+ allow_phone_number_collection: booleanType().optional(),
7170
+ allow_tax_id: booleanType().optional(),
7171
+ always_create_new_customer: booleanType().optional()
7172
+ }).optional();
7173
+ var checkoutSessionOnDemandSchema = objectType({
7174
+ mandate_only: booleanType(),
7175
+ product_price: numberType().int().optional(),
7176
+ product_currency: stringType().length(3).optional(),
7177
+ product_description: stringType().optional(),
7178
+ adaptive_currency_fees_inclusive: booleanType().optional()
7179
+ }).optional();
7180
+ var checkoutSessionSubscriptionDataSchema = objectType({
7181
+ trial_period_days: numberType().int().nonnegative().optional(),
7182
+ on_demand: checkoutSessionOnDemandSchema
7183
+ }).optional();
7184
+ var checkoutSessionPayloadSchema = objectType({
7185
+ // Required fields
7186
+ product_cart: arrayType(checkoutSessionProductCartItemSchema).min(1, "At least one product is required"),
7187
+ // Optional fields
7188
+ customer: checkoutSessionCustomerSchema,
7189
+ billing_address: checkoutSessionBillingAddressSchema,
7190
+ return_url: stringType().url().optional(),
7191
+ allowed_payment_method_types: arrayType(paymentMethodTypeSchema).optional(),
7192
+ billing_currency: stringType().length(3, "Currency must be a 3-letter ISO code").optional(),
7193
+ show_saved_payment_methods: booleanType().optional(),
7194
+ confirm: booleanType().optional(),
7195
+ discount_code: stringType().optional(),
7196
+ metadata: recordType(stringType(), stringType()).optional(),
7197
+ customization: checkoutSessionCustomizationSchema,
7198
+ feature_flags: checkoutSessionFeatureFlagsSchema,
7199
+ subscription_data: checkoutSessionSubscriptionDataSchema,
7200
+ force_3ds: booleanType().optional()
7201
+ });
7202
+ var checkoutSessionResponseSchema = objectType({
7203
+ session_id: stringType().min(1, "Session ID is required"),
7204
+ checkout_url: stringType().url("Invalid checkout URL")
7205
+ });
7206
+ var createCheckoutSession = async (payload, config) => {
7207
+ const validation = checkoutSessionPayloadSchema.safeParse(payload);
7208
+ if (!validation.success) {
7209
+ throw new Error(
7210
+ `Invalid checkout session payload: ${validation.error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`).join(", ")}`
7211
+ );
7212
+ }
7213
+ const dodopayments = new DodoPayments({
7214
+ bearerToken: config.bearerToken,
7215
+ environment: config.environment
7216
+ });
7217
+ try {
7218
+ const sdkPayload = {
7219
+ ...validation.data,
7220
+ ...validation.data.billing_address && {
7221
+ billing_address: {
7222
+ ...validation.data.billing_address,
7223
+ country: validation.data.billing_address.country
7224
+ }
7225
+ }
7226
+ };
7227
+ const session = await dodopayments.checkoutSessions.create(
7228
+ sdkPayload
7229
+ );
7230
+ const responseValidation = checkoutSessionResponseSchema.safeParse(session);
7231
+ if (!responseValidation.success) {
7232
+ throw new Error(
7233
+ `Invalid checkout session response from API: ${responseValidation.error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`).join(", ")}`
7234
+ );
7235
+ }
7236
+ return responseValidation.data;
7237
+ } catch (error) {
7238
+ if (error instanceof Error) {
7239
+ console.error("Dodo Payments Checkout Session API Error:", {
7240
+ message: error.message,
7241
+ payload: validation.data,
7242
+ config: {
7243
+ environment: config.environment,
7244
+ hasBearerToken: !!config.bearerToken
7245
+ }
7246
+ });
7247
+ throw new Error(`Failed to create checkout session: ${error.message}`);
7248
+ }
7249
+ console.error("Unknown error creating checkout session:", error);
7250
+ throw new Error(
7251
+ "Failed to create checkout session due to an unknown error"
7252
+ );
7253
+ }
7254
+ };
7255
+ var buildCheckoutUrl = async ({
7256
+ queryParams,
7257
+ body,
7258
+ sessionPayload,
7259
+ returnUrl,
7260
+ bearerToken,
7261
+ environment,
7262
+ type = "static"
7263
+ }) => {
7264
+ if (type === "session") {
7265
+ if (!sessionPayload) {
7266
+ throw new Error("sessionPayload is required when type is 'session'");
7267
+ }
7268
+ const session = await createCheckoutSession(sessionPayload, {
7269
+ bearerToken,
7270
+ environment
7271
+ });
7272
+ return session.checkout_url;
7273
+ }
7274
+ const inputData = type === "dynamic" ? body : queryParams;
7275
+ let parseResult;
7276
+ if (type === "dynamic") {
7277
+ parseResult = dynamicCheckoutBodySchema.safeParse(inputData);
7278
+ } else {
7279
+ parseResult = checkoutQuerySchema.safeParse(inputData);
7280
+ }
7281
+ const { success, data, error } = parseResult;
7282
+ if (!success) {
7283
+ throw new Error(
7284
+ `Invalid ${type === "dynamic" ? "body" : "query parameters"}.
7285
+ ${error.message}`
7286
+ );
7287
+ }
7288
+ if (type !== "dynamic") {
7289
+ const {
7290
+ productId,
7291
+ quantity: quantity2,
7292
+ fullName,
7293
+ firstName,
7294
+ lastName,
7295
+ email,
7296
+ country,
7297
+ addressLine,
7298
+ city,
7299
+ state,
7300
+ zipCode,
7301
+ disableFullName,
7302
+ disableFirstName,
7303
+ disableLastName,
7304
+ disableEmail,
7305
+ disableCountry,
7306
+ disableAddressLine,
7307
+ disableCity,
7308
+ disableState,
7309
+ disableZipCode,
7310
+ paymentCurrency,
7311
+ showCurrencySelector,
7312
+ paymentAmount,
7313
+ showDiscounts
7314
+ // metadata handled below
7315
+ } = data;
7316
+ const dodopayments2 = new DodoPayments({
7317
+ bearerToken,
7318
+ environment
7319
+ });
7320
+ if (!productId) throw new Error("Missing required field: productId");
7321
+ try {
7322
+ await dodopayments2.products.retrieve(productId);
7323
+ } catch (err) {
7324
+ console.error(err);
7325
+ throw new Error("Product not found");
7326
+ }
7327
+ const url = new URL(
7328
+ `${environment === "test_mode" ? "https://test.checkout.dodopayments.com" : "https://checkout.dodopayments.com"}/buy/${productId}`
7329
+ );
7330
+ url.searchParams.set("quantity", quantity2 ? String(quantity2) : "1");
7331
+ if (returnUrl) url.searchParams.set("redirect_url", returnUrl);
7332
+ if (fullName) url.searchParams.set("fullName", String(fullName));
7333
+ if (firstName) url.searchParams.set("firstName", String(firstName));
7334
+ if (lastName) url.searchParams.set("lastName", String(lastName));
7335
+ if (email) url.searchParams.set("email", String(email));
7336
+ if (country) url.searchParams.set("country", String(country));
7337
+ if (addressLine) url.searchParams.set("addressLine", String(addressLine));
7338
+ if (city) url.searchParams.set("city", String(city));
7339
+ if (state) url.searchParams.set("state", String(state));
7340
+ if (zipCode) url.searchParams.set("zipCode", String(zipCode));
7341
+ if (disableFullName === "true")
7342
+ url.searchParams.set("disableFullName", "true");
7343
+ if (disableFirstName === "true")
7344
+ url.searchParams.set("disableFirstName", "true");
7345
+ if (disableLastName === "true")
7346
+ url.searchParams.set("disableLastName", "true");
7347
+ if (disableEmail === "true") url.searchParams.set("disableEmail", "true");
7348
+ if (disableCountry === "true")
7349
+ url.searchParams.set("disableCountry", "true");
7350
+ if (disableAddressLine === "true")
7351
+ url.searchParams.set("disableAddressLine", "true");
7352
+ if (disableCity === "true") url.searchParams.set("disableCity", "true");
7353
+ if (disableState === "true") url.searchParams.set("disableState", "true");
7354
+ if (disableZipCode === "true")
7355
+ url.searchParams.set("disableZipCode", "true");
7356
+ if (paymentCurrency)
7357
+ url.searchParams.set("paymentCurrency", String(paymentCurrency));
7358
+ if (showCurrencySelector)
7359
+ url.searchParams.set(
7360
+ "showCurrencySelector",
7361
+ String(showCurrencySelector)
7362
+ );
7363
+ if (paymentAmount)
7364
+ url.searchParams.set("paymentAmount", String(paymentAmount));
7365
+ if (showDiscounts)
7366
+ url.searchParams.set("showDiscounts", String(showDiscounts));
7367
+ for (const [key, value] of Object.entries(queryParams || {})) {
7368
+ if (key.startsWith("metadata_") && value && typeof value !== "object") {
7369
+ url.searchParams.set(key, String(value));
7370
+ }
7371
+ }
7372
+ return url.toString();
7373
+ }
7374
+ const dyn = data;
7375
+ const {
7376
+ product_id,
7377
+ product_cart,
7378
+ quantity,
7379
+ billing,
7380
+ customer,
7381
+ addons,
7382
+ metadata,
7383
+ allowed_payment_method_types,
7384
+ billing_currency,
7385
+ discount_code,
7386
+ on_demand,
7387
+ return_url: bodyReturnUrl,
7388
+ show_saved_payment_methods,
7389
+ tax_id,
7390
+ trial_period_days
7391
+ } = dyn;
7392
+ const dodopayments = new DodoPayments({
7393
+ bearerToken,
7394
+ environment
7395
+ });
7396
+ let isSubscription = false;
7397
+ let productIdToFetch = product_id;
7398
+ if (!product_id && product_cart && product_cart.length > 0) {
7399
+ productIdToFetch = product_cart[0].product_id;
7400
+ }
7401
+ if (!productIdToFetch)
7402
+ throw new Error(
7403
+ "Missing required field: product_id or product_cart[0].product_id"
7404
+ );
7405
+ let product;
7406
+ try {
7407
+ product = await dodopayments.products.retrieve(productIdToFetch);
7408
+ } catch (err) {
7409
+ console.error(err);
7410
+ throw new Error("Product not found");
7411
+ }
7412
+ isSubscription = Boolean(product.is_recurring);
7413
+ if (isSubscription && !product_id)
7414
+ throw new Error("Missing required field: product_id for subscription");
7415
+ if (!billing) throw new Error("Missing required field: billing");
7416
+ if (!customer) throw new Error("Missing required field: customer");
7417
+ if (isSubscription) {
7418
+ const subscriptionPayload = {
7419
+ billing,
7420
+ customer,
7421
+ product_id,
7422
+ quantity: quantity ? Number(quantity) : 1
7423
+ };
7424
+ if (metadata) subscriptionPayload.metadata = metadata;
7425
+ if (discount_code) subscriptionPayload.discount_code = discount_code;
7426
+ if (addons) subscriptionPayload.addons = addons;
7427
+ if (allowed_payment_method_types)
7428
+ subscriptionPayload.allowed_payment_method_types = allowed_payment_method_types;
7429
+ if (billing_currency)
7430
+ subscriptionPayload.billing_currency = billing_currency;
7431
+ if (on_demand) subscriptionPayload.on_demand = on_demand;
7432
+ subscriptionPayload.payment_link = true;
7433
+ if (bodyReturnUrl) {
7434
+ subscriptionPayload.return_url = bodyReturnUrl;
7435
+ } else if (returnUrl) {
7436
+ subscriptionPayload.return_url = returnUrl;
7437
+ }
7438
+ if (show_saved_payment_methods)
7439
+ subscriptionPayload.show_saved_payment_methods = show_saved_payment_methods;
7440
+ if (tax_id) subscriptionPayload.tax_id = tax_id;
7441
+ if (trial_period_days)
7442
+ subscriptionPayload.trial_period_days = trial_period_days;
7443
+ let subscription;
7444
+ try {
7445
+ subscription = await dodopayments.subscriptions.create(subscriptionPayload);
7446
+ } catch (err) {
7447
+ console.error("Error when creating subscription", err);
7448
+ throw new Error(err instanceof Error ? err.message : String(err));
7449
+ }
7450
+ if (!subscription || !subscription.payment_link) {
7451
+ throw new Error(
7452
+ "No payment link returned from Dodo Payments API (subscription). Make sure to set payment_link as true in payload"
7453
+ );
7454
+ }
7455
+ return subscription.payment_link;
7456
+ } else {
7457
+ let cart = product_cart;
7458
+ if (!cart && product_id) {
7459
+ cart = [
7460
+ { product_id, quantity: quantity ? Number(quantity) : 1 }
7461
+ ];
7462
+ }
7463
+ if (!cart || cart.length === 0)
7464
+ throw new Error("Missing required field: product_cart or product_id");
7465
+ const paymentPayload = {
7466
+ billing,
7467
+ customer,
7468
+ product_cart: cart
7469
+ };
7470
+ if (metadata) paymentPayload.metadata = metadata;
7471
+ paymentPayload.payment_link = true;
7472
+ if (allowed_payment_method_types)
7473
+ paymentPayload.allowed_payment_method_types = allowed_payment_method_types;
7474
+ if (billing_currency) paymentPayload.billing_currency = billing_currency;
7475
+ if (discount_code) paymentPayload.discount_code = discount_code;
7476
+ if (bodyReturnUrl) {
7477
+ paymentPayload.return_url = bodyReturnUrl;
7478
+ } else if (returnUrl) {
7479
+ paymentPayload.return_url = returnUrl;
7480
+ }
7481
+ if (show_saved_payment_methods)
7482
+ paymentPayload.show_saved_payment_methods = show_saved_payment_methods;
7483
+ if (tax_id) paymentPayload.tax_id = tax_id;
7484
+ let payment;
7485
+ try {
7486
+ payment = await dodopayments.payments.create(paymentPayload);
7487
+ } catch (err) {
7488
+ console.error("Error when creating payment link", err);
7489
+ throw new Error(err instanceof Error ? err.message : String(err));
7490
+ }
7491
+ if (!payment || !payment.payment_link) {
7492
+ throw new Error(
7493
+ "No payment link returned from Dodo Payments API. Make sure to set payment_link as true in payload."
7494
+ );
7495
+ }
7496
+ return payment.payment_link;
7497
+ }
7498
+ };
7499
+
7500
+ const Checkout = (config) => {
7501
+ const getHandler = async (c) => {
7502
+ const queryParams = c.req.query();
7503
+ if (!queryParams.productId) {
7504
+ return c.text("Please provide productId query parameter", 400);
7578
7505
  }
7579
- if ((options === null || options === void 0 ? void 0 : options.format) === "raw") {
7580
- if (secret instanceof Uint8Array) {
7581
- this.key = secret;
7582
- }
7583
- else {
7584
- this.key = Uint8Array.from(secret, (c) => c.charCodeAt(0));
7506
+ const { success, data, error } = checkoutQuerySchema.safeParse(queryParams);
7507
+ if (!success) {
7508
+ if (error.errors.some((e) => e.path.toString() === "productId")) {
7509
+ return c.text("Please provide productId query parameter", 400);
7585
7510
  }
7511
+ return c.text(`Invalid query parameters.\n ${error.message}`, 400);
7586
7512
  }
7587
- else {
7588
- if (typeof secret !== "string") {
7589
- throw new Error("Expected secret to be of type string");
7590
- }
7591
- if (secret.startsWith(Webhook.prefix)) {
7592
- secret = secret.substring(Webhook.prefix.length);
7593
- }
7594
- this.key = base64.decode(secret);
7513
+ let url = "";
7514
+ try {
7515
+ url = await buildCheckoutUrl({ queryParams: data, ...config });
7595
7516
  }
7596
- }
7597
- verify(payload, headers_) {
7598
- const headers = {};
7599
- for (const key of Object.keys(headers_)) {
7600
- headers[key.toLowerCase()] = headers_[key];
7517
+ catch (error) {
7518
+ return c.text(error.message, 400);
7601
7519
  }
7602
- const msgId = headers["webhook-id"];
7603
- const msgSignature = headers["webhook-signature"];
7604
- const msgTimestamp = headers["webhook-timestamp"];
7605
- if (!msgSignature || !msgId || !msgTimestamp) {
7606
- throw new WebhookVerificationError("Missing required headers");
7520
+ return c.json({ checkout_url: url });
7521
+ };
7522
+ const postHandler = async (c) => {
7523
+ let body;
7524
+ try {
7525
+ body = await c.req.json();
7607
7526
  }
7608
- const timestamp = this.verifyTimestamp(msgTimestamp);
7609
- const computedSignature = this.sign(msgId, timestamp, payload);
7610
- const expectedSignature = computedSignature.split(",")[1];
7611
- const passedSignatures = msgSignature.split(" ");
7612
- const encoder = new globalThis.TextEncoder();
7613
- for (const versionedSignature of passedSignatures) {
7614
- const [version, signature] = versionedSignature.split(",");
7615
- if (version !== "v1") {
7616
- continue;
7527
+ catch (e) {
7528
+ return c.text("Invalid JSON body", 400);
7529
+ }
7530
+ if (config.type === "dynamic") {
7531
+ // Handle dynamic checkout
7532
+ const { success, data, error } = dynamicCheckoutBodySchema.safeParse(body);
7533
+ if (!success) {
7534
+ return c.text(`Invalid request body.\n ${error.message}`, 400);
7617
7535
  }
7618
- if ((0, timing_safe_equal_1.timingSafeEqual)(encoder.encode(signature), encoder.encode(expectedSignature))) {
7619
- return JSON.parse(payload.toString());
7536
+ let url = "";
7537
+ try {
7538
+ url = await buildCheckoutUrl({
7539
+ body: data,
7540
+ ...config,
7541
+ type: "dynamic",
7542
+ });
7620
7543
  }
7621
- }
7622
- throw new WebhookVerificationError("No matching signature found");
7623
- }
7624
- sign(msgId, timestamp, payload) {
7625
- if (typeof payload === "string") ;
7626
- else if (payload.constructor.name === "Buffer") {
7627
- payload = payload.toString();
7544
+ catch (error) {
7545
+ return c.text(error.message, 400);
7546
+ }
7547
+ return c.json({ checkout_url: url });
7628
7548
  }
7629
7549
  else {
7630
- throw new Error("Expected payload to be of type string or Buffer.");
7550
+ // Handle checkout session
7551
+ const { success, data, error } = checkoutSessionPayloadSchema.safeParse(body);
7552
+ if (!success) {
7553
+ return c.text(`Invalid checkout session payload.\n ${error.message}`, 400);
7554
+ }
7555
+ let url = "";
7556
+ try {
7557
+ url = await buildCheckoutUrl({
7558
+ sessionPayload: data,
7559
+ ...config,
7560
+ type: "session",
7561
+ });
7562
+ }
7563
+ catch (error) {
7564
+ return c.text(error.message, 400);
7565
+ }
7566
+ return c.json({ checkout_url: url });
7631
7567
  }
7632
- const encoder = new TextEncoder();
7633
- const timestampNumber = Math.floor(timestamp.getTime() / 1000);
7634
- const toSign = encoder.encode(`${msgId}.${timestampNumber}.${payload}`);
7635
- const expectedSignature = base64.encode(sha256.hmac(this.key, toSign));
7636
- return `v1,${expectedSignature}`;
7637
- }
7638
- verifyTimestamp(timestampHeader) {
7639
- const now = Math.floor(Date.now() / 1000);
7640
- const timestamp = parseInt(timestampHeader, 10);
7641
- if (isNaN(timestamp)) {
7642
- throw new WebhookVerificationError("Invalid Signature Headers");
7568
+ };
7569
+ return (c) => {
7570
+ if (c.req.method === "POST") {
7571
+ return postHandler(c);
7643
7572
  }
7644
- if (now - timestamp > WEBHOOK_TOLERANCE_IN_SECONDS) {
7645
- throw new WebhookVerificationError("Message timestamp too old");
7573
+ return getHandler(c);
7574
+ };
7575
+ };
7576
+
7577
+ const CustomerPortal = ({ bearerToken, environment, }) => {
7578
+ const getHandler = async (c) => {
7579
+ // Extract customerId from query parameters
7580
+ const customerId = c.req.query("customer_id");
7581
+ const sendEmail = c.req.query("send_email");
7582
+ const params = {
7583
+ send_email: false,
7584
+ };
7585
+ if (sendEmail === "true") {
7586
+ params.send_email = true;
7646
7587
  }
7647
- if (timestamp > now + WEBHOOK_TOLERANCE_IN_SECONDS) {
7648
- throw new WebhookVerificationError("Message timestamp too new");
7588
+ if (!customerId) {
7589
+ return c.text("Missing customerId in query parameters", 400);
7649
7590
  }
7650
- return new Date(timestamp * 1000);
7651
- }
7652
- }
7653
- Webhook_1 = dist.Webhook = Webhook;
7654
- Webhook.prefix = "whsec_";
7591
+ const dodopayments = new DodoPayments({
7592
+ bearerToken,
7593
+ environment,
7594
+ });
7595
+ try {
7596
+ const session = await dodopayments.customers.customerPortal.create(customerId, params);
7597
+ return c.redirect(session.link);
7598
+ }
7599
+ catch (error) {
7600
+ console.error("Error creating customer portal session:", error);
7601
+ return c.text(`Failed to create customer portal session: ${error.message}`, 500);
7602
+ }
7603
+ };
7604
+ return getHandler;
7605
+ };
7655
7606
 
7607
+ // src/schemas/webhook.ts
7656
7608
  var PaymentSchema = objectType({
7657
- payload_type: literalType("Payment"),
7658
- billing: objectType({
7659
- city: stringType().nullable(),
7660
- country: stringType().nullable(),
7661
- state: stringType().nullable(),
7662
- street: stringType().nullable(),
7663
- zipcode: stringType().nullable(),
7664
- }),
7665
- brand_id: stringType(),
7666
- business_id: stringType(),
7667
- card_issuing_country: stringType().nullable(),
7668
- card_last_four: stringType().nullable(),
7669
- card_network: stringType().nullable(),
7670
- card_type: stringType().nullable(),
7671
- created_at: stringType().transform(function (d) { return new Date(d); }),
7672
- currency: stringType(),
7673
- customer: objectType({
7674
- customer_id: stringType(),
7675
- email: stringType(),
7676
- name: stringType().nullable(),
7677
- }),
7678
- digital_products_delivered: booleanType(),
7679
- discount_id: stringType().nullable(),
7680
- disputes: arrayType(objectType({
7681
- amount: stringType(),
7682
- business_id: stringType(),
7683
- created_at: stringType().transform(function (d) { return new Date(d); }),
7684
- currency: stringType(),
7685
- dispute_id: stringType(),
7686
- dispute_stage: enumType([
7687
- "pre_dispute",
7688
- "dispute_opened",
7689
- "dispute_won",
7690
- "dispute_lost",
7691
- ]),
7692
- dispute_status: enumType([
7693
- "dispute_opened",
7694
- "dispute_won",
7695
- "dispute_lost",
7696
- "dispute_accepted",
7697
- "dispute_cancelled",
7698
- "dispute_challenged",
7699
- ]),
7700
- payment_id: stringType(),
7701
- remarks: stringType().nullable(),
7702
- }))
7703
- .nullable(),
7704
- error_code: stringType().nullable(),
7705
- error_message: stringType().nullable(),
7706
- metadata: recordType(anyType()).nullable(),
7707
- payment_id: stringType(),
7708
- payment_link: stringType().nullable(),
7709
- payment_method: stringType().nullable(),
7710
- payment_method_type: stringType().nullable(),
7711
- product_cart: arrayType(objectType({
7712
- product_id: stringType(),
7713
- quantity: numberType(),
7714
- }))
7715
- .nullable(),
7716
- refunds: arrayType(objectType({
7717
- amount: numberType(),
7718
- business_id: stringType(),
7719
- created_at: stringType().transform(function (d) { return new Date(d); }),
7720
- currency: stringType(),
7721
- is_partial: booleanType(),
7722
- payment_id: stringType(),
7723
- reason: stringType().nullable(),
7724
- refund_id: stringType(),
7725
- status: enumType(["succeeded", "failed", "pending"]),
7726
- }))
7727
- .nullable(),
7728
- settlement_amount: numberType(),
7729
- settlement_currency: stringType(),
7730
- settlement_tax: numberType().nullable(),
7731
- status: enumType(["succeeded", "failed", "pending", "processing", "cancelled"]),
7732
- subscription_id: stringType().nullable(),
7733
- tax: numberType().nullable(),
7734
- total_amount: numberType(),
7735
- updated_at: stringType()
7736
- .transform(function (d) { return new Date(d); })
7737
- .nullable(),
7738
- });
7739
- var SubscriptionSchema = objectType({
7740
- payload_type: literalType("Subscription"),
7741
- addons: arrayType(objectType({
7742
- addon_id: stringType(),
7743
- quantity: numberType(),
7744
- }))
7745
- .nullable(),
7746
- billing: objectType({
7747
- city: stringType().nullable(),
7748
- country: stringType().nullable(),
7749
- state: stringType().nullable(),
7750
- street: stringType().nullable(),
7751
- zipcode: stringType().nullable(),
7752
- }),
7753
- cancel_at_next_billing_date: booleanType(),
7754
- cancelled_at: stringType()
7755
- .transform(function (d) { return new Date(d); })
7756
- .nullable(),
7757
- created_at: stringType().transform(function (d) { return new Date(d); }),
7758
- currency: stringType(),
7759
- customer: objectType({
7760
- customer_id: stringType(),
7761
- email: stringType(),
7762
- name: stringType().nullable(),
7763
- }),
7764
- discount_id: stringType().nullable(),
7765
- metadata: recordType(anyType()).nullable(),
7766
- next_billing_date: stringType()
7767
- .transform(function (d) { return new Date(d); })
7768
- .nullable(),
7769
- on_demand: booleanType(),
7770
- payment_frequency_count: numberType(),
7771
- payment_frequency_interval: enumType(["Day", "Week", "Month", "Year"]),
7772
- previous_billing_date: stringType()
7773
- .transform(function (d) { return new Date(d); })
7774
- .nullable(),
7775
- product_id: stringType(),
7776
- quantity: numberType(),
7777
- recurring_pre_tax_amount: numberType(),
7778
- status: enumType([
7779
- "pending",
7780
- "active",
7781
- "on_hold",
7782
- "paused",
7783
- "cancelled",
7784
- "expired",
7785
- "failed",
7786
- ]),
7787
- subscription_id: stringType(),
7788
- subscription_period_count: numberType(),
7789
- subscription_period_interval: enumType(["Day", "Week", "Month", "Year"]),
7790
- tax_inclusive: booleanType(),
7791
- trial_period_days: numberType(),
7792
- });
7793
- var RefundSchema = objectType({
7794
- payload_type: literalType("Refund"),
7795
- amount: numberType(),
7796
- business_id: stringType(),
7797
- created_at: stringType().transform(function (d) { return new Date(d); }),
7798
- currency: stringType(),
7799
- is_partial: booleanType(),
7800
- payment_id: stringType(),
7801
- reason: stringType().nullable(),
7802
- refund_id: stringType(),
7803
- status: enumType(["succeeded", "failed", "pending"]),
7804
- });
7805
- var DisputeSchema = objectType({
7806
- payload_type: literalType("Dispute"),
7807
- amount: stringType(),
7808
- business_id: stringType(),
7809
- created_at: stringType().transform(function (d) { return new Date(d); }),
7810
- currency: stringType(),
7811
- dispute_id: stringType(),
7812
- dispute_stage: enumType([
7609
+ payload_type: literalType("Payment"),
7610
+ billing: objectType({
7611
+ city: stringType().nullable(),
7612
+ country: stringType().nullable(),
7613
+ state: stringType().nullable(),
7614
+ street: stringType().nullable(),
7615
+ zipcode: stringType().nullable()
7616
+ }),
7617
+ brand_id: stringType(),
7618
+ business_id: stringType(),
7619
+ card_issuing_country: stringType().nullable(),
7620
+ card_last_four: stringType().nullable(),
7621
+ card_network: stringType().nullable(),
7622
+ card_type: stringType().nullable(),
7623
+ created_at: stringType().transform((d) => new Date(d)),
7624
+ currency: stringType(),
7625
+ customer: objectType({
7626
+ customer_id: stringType(),
7627
+ email: stringType(),
7628
+ name: stringType().nullable()
7629
+ }),
7630
+ digital_products_delivered: booleanType(),
7631
+ discount_id: stringType().nullable(),
7632
+ disputes: arrayType(
7633
+ objectType({
7634
+ amount: stringType(),
7635
+ business_id: stringType(),
7636
+ created_at: stringType().transform((d) => new Date(d)),
7637
+ currency: stringType(),
7638
+ dispute_id: stringType(),
7639
+ dispute_stage: enumType([
7813
7640
  "pre_dispute",
7814
7641
  "dispute_opened",
7815
7642
  "dispute_won",
7816
- "dispute_lost",
7817
- ]),
7818
- dispute_status: enumType([
7643
+ "dispute_lost"
7644
+ ]),
7645
+ dispute_status: enumType([
7819
7646
  "dispute_opened",
7820
7647
  "dispute_won",
7821
7648
  "dispute_lost",
7822
7649
  "dispute_accepted",
7823
7650
  "dispute_cancelled",
7824
- "dispute_challenged",
7825
- ]),
7826
- payment_id: stringType(),
7827
- remarks: stringType().nullable(),
7651
+ "dispute_challenged"
7652
+ ]),
7653
+ payment_id: stringType(),
7654
+ remarks: stringType().nullable()
7655
+ })
7656
+ ).nullable(),
7657
+ error_code: stringType().nullable(),
7658
+ error_message: stringType().nullable(),
7659
+ metadata: recordType(anyType()).nullable(),
7660
+ payment_id: stringType(),
7661
+ payment_link: stringType().nullable(),
7662
+ payment_method: stringType().nullable(),
7663
+ payment_method_type: stringType().nullable(),
7664
+ product_cart: arrayType(
7665
+ objectType({
7666
+ product_id: stringType(),
7667
+ quantity: numberType()
7668
+ })
7669
+ ).nullable(),
7670
+ refunds: arrayType(
7671
+ objectType({
7672
+ amount: numberType(),
7673
+ business_id: stringType(),
7674
+ created_at: stringType().transform((d) => new Date(d)),
7675
+ currency: stringType(),
7676
+ is_partial: booleanType(),
7677
+ payment_id: stringType(),
7678
+ reason: stringType().nullable(),
7679
+ refund_id: stringType(),
7680
+ status: enumType(["succeeded", "failed", "pending"])
7681
+ })
7682
+ ).nullable(),
7683
+ settlement_amount: numberType(),
7684
+ settlement_currency: stringType(),
7685
+ settlement_tax: numberType().nullable(),
7686
+ status: enumType(["succeeded", "failed", "pending", "processing", "cancelled"]),
7687
+ subscription_id: stringType().nullable(),
7688
+ tax: numberType().nullable(),
7689
+ total_amount: numberType(),
7690
+ updated_at: stringType().transform((d) => new Date(d)).nullable()
7828
7691
  });
7829
- var LicenseKeySchema = objectType({
7830
- payload_type: literalType("LicenseKey"),
7831
- activations_limit: numberType(),
7832
- business_id: stringType(),
7833
- created_at: stringType().transform(function (d) { return new Date(d); }),
7692
+ var SubscriptionSchema = objectType({
7693
+ payload_type: literalType("Subscription"),
7694
+ addons: arrayType(
7695
+ objectType({
7696
+ addon_id: stringType(),
7697
+ quantity: numberType()
7698
+ })
7699
+ ).nullable(),
7700
+ billing: objectType({
7701
+ city: stringType().nullable(),
7702
+ country: stringType().nullable(),
7703
+ state: stringType().nullable(),
7704
+ street: stringType().nullable(),
7705
+ zipcode: stringType().nullable()
7706
+ }),
7707
+ cancel_at_next_billing_date: booleanType(),
7708
+ cancelled_at: stringType().transform((d) => new Date(d)).nullable(),
7709
+ created_at: stringType().transform((d) => new Date(d)),
7710
+ currency: stringType(),
7711
+ customer: objectType({
7834
7712
  customer_id: stringType(),
7835
- expires_at: stringType()
7836
- .transform(function (d) { return new Date(d); })
7837
- .nullable(),
7838
- id: stringType(),
7839
- instances_count: numberType(),
7840
- key: stringType(),
7841
- payment_id: stringType(),
7842
- product_id: stringType(),
7843
- status: enumType(["active", "inactive", "expired"]),
7844
- subscription_id: stringType().nullable(),
7713
+ email: stringType(),
7714
+ name: stringType().nullable()
7715
+ }),
7716
+ discount_id: stringType().nullable(),
7717
+ metadata: recordType(anyType()).nullable(),
7718
+ next_billing_date: stringType().transform((d) => new Date(d)).nullable(),
7719
+ on_demand: booleanType(),
7720
+ payment_frequency_count: numberType(),
7721
+ payment_frequency_interval: enumType(["Day", "Week", "Month", "Year"]),
7722
+ previous_billing_date: stringType().transform((d) => new Date(d)).nullable(),
7723
+ product_id: stringType(),
7724
+ quantity: numberType(),
7725
+ recurring_pre_tax_amount: numberType(),
7726
+ status: enumType([
7727
+ "pending",
7728
+ "active",
7729
+ "on_hold",
7730
+ "paused",
7731
+ "cancelled",
7732
+ "expired",
7733
+ "failed"
7734
+ ]),
7735
+ subscription_id: stringType(),
7736
+ subscription_period_count: numberType(),
7737
+ subscription_period_interval: enumType(["Day", "Week", "Month", "Year"]),
7738
+ tax_inclusive: booleanType(),
7739
+ trial_period_days: numberType()
7740
+ });
7741
+ var RefundSchema = objectType({
7742
+ payload_type: literalType("Refund"),
7743
+ amount: numberType(),
7744
+ business_id: stringType(),
7745
+ created_at: stringType().transform((d) => new Date(d)),
7746
+ currency: stringType(),
7747
+ is_partial: booleanType(),
7748
+ payment_id: stringType(),
7749
+ reason: stringType().nullable(),
7750
+ refund_id: stringType(),
7751
+ status: enumType(["succeeded", "failed", "pending"])
7752
+ });
7753
+ var DisputeSchema = objectType({
7754
+ payload_type: literalType("Dispute"),
7755
+ amount: stringType(),
7756
+ business_id: stringType(),
7757
+ created_at: stringType().transform((d) => new Date(d)),
7758
+ currency: stringType(),
7759
+ dispute_id: stringType(),
7760
+ dispute_stage: enumType([
7761
+ "pre_dispute",
7762
+ "dispute_opened",
7763
+ "dispute_won",
7764
+ "dispute_lost"
7765
+ ]),
7766
+ dispute_status: enumType([
7767
+ "dispute_opened",
7768
+ "dispute_won",
7769
+ "dispute_lost",
7770
+ "dispute_accepted",
7771
+ "dispute_cancelled",
7772
+ "dispute_challenged"
7773
+ ]),
7774
+ payment_id: stringType(),
7775
+ remarks: stringType().nullable()
7776
+ });
7777
+ var LicenseKeySchema = objectType({
7778
+ payload_type: literalType("LicenseKey"),
7779
+ activations_limit: numberType(),
7780
+ business_id: stringType(),
7781
+ created_at: stringType().transform((d) => new Date(d)),
7782
+ customer_id: stringType(),
7783
+ expires_at: stringType().transform((d) => new Date(d)).nullable(),
7784
+ id: stringType(),
7785
+ instances_count: numberType(),
7786
+ key: stringType(),
7787
+ payment_id: stringType(),
7788
+ product_id: stringType(),
7789
+ status: enumType(["active", "inactive", "expired"]),
7790
+ subscription_id: stringType().nullable()
7845
7791
  });
7846
7792
  var PaymentSucceededPayloadSchema = objectType({
7847
- business_id: stringType(),
7848
- type: literalType("payment.succeeded"),
7849
- timestamp: stringType().transform(function (d) { return new Date(d); }),
7850
- data: PaymentSchema,
7793
+ business_id: stringType(),
7794
+ type: literalType("payment.succeeded"),
7795
+ timestamp: stringType().transform((d) => new Date(d)),
7796
+ data: PaymentSchema
7851
7797
  });
7852
7798
  var PaymentFailedPayloadSchema = objectType({
7853
- business_id: stringType(),
7854
- type: literalType("payment.failed"),
7855
- timestamp: stringType().transform(function (d) { return new Date(d); }),
7856
- data: PaymentSchema,
7799
+ business_id: stringType(),
7800
+ type: literalType("payment.failed"),
7801
+ timestamp: stringType().transform((d) => new Date(d)),
7802
+ data: PaymentSchema
7857
7803
  });
7858
7804
  var PaymentProcessingPayloadSchema = objectType({
7859
- business_id: stringType(),
7860
- type: literalType("payment.processing"),
7861
- timestamp: stringType().transform(function (d) { return new Date(d); }),
7862
- data: PaymentSchema,
7805
+ business_id: stringType(),
7806
+ type: literalType("payment.processing"),
7807
+ timestamp: stringType().transform((d) => new Date(d)),
7808
+ data: PaymentSchema
7863
7809
  });
7864
7810
  var PaymentCancelledPayloadSchema = objectType({
7865
- business_id: stringType(),
7866
- type: literalType("payment.cancelled"),
7867
- timestamp: stringType().transform(function (d) { return new Date(d); }),
7868
- data: PaymentSchema,
7811
+ business_id: stringType(),
7812
+ type: literalType("payment.cancelled"),
7813
+ timestamp: stringType().transform((d) => new Date(d)),
7814
+ data: PaymentSchema
7869
7815
  });
7870
7816
  var RefundSucceededPayloadSchema = objectType({
7871
- business_id: stringType(),
7872
- type: literalType("refund.succeeded"),
7873
- timestamp: stringType().transform(function (d) { return new Date(d); }),
7874
- data: RefundSchema,
7817
+ business_id: stringType(),
7818
+ type: literalType("refund.succeeded"),
7819
+ timestamp: stringType().transform((d) => new Date(d)),
7820
+ data: RefundSchema
7875
7821
  });
7876
7822
  var RefundFailedPayloadSchema = objectType({
7877
- business_id: stringType(),
7878
- type: literalType("refund.failed"),
7879
- timestamp: stringType().transform(function (d) { return new Date(d); }),
7880
- data: RefundSchema,
7823
+ business_id: stringType(),
7824
+ type: literalType("refund.failed"),
7825
+ timestamp: stringType().transform((d) => new Date(d)),
7826
+ data: RefundSchema
7881
7827
  });
7882
7828
  var DisputeOpenedPayloadSchema = objectType({
7883
- business_id: stringType(),
7884
- type: literalType("dispute.opened"),
7885
- timestamp: stringType().transform(function (d) { return new Date(d); }),
7886
- data: DisputeSchema,
7829
+ business_id: stringType(),
7830
+ type: literalType("dispute.opened"),
7831
+ timestamp: stringType().transform((d) => new Date(d)),
7832
+ data: DisputeSchema
7887
7833
  });
7888
7834
  var DisputeExpiredPayloadSchema = objectType({
7889
- business_id: stringType(),
7890
- type: literalType("dispute.expired"),
7891
- timestamp: stringType().transform(function (d) { return new Date(d); }),
7892
- data: DisputeSchema,
7835
+ business_id: stringType(),
7836
+ type: literalType("dispute.expired"),
7837
+ timestamp: stringType().transform((d) => new Date(d)),
7838
+ data: DisputeSchema
7893
7839
  });
7894
7840
  var DisputeAcceptedPayloadSchema = objectType({
7895
- business_id: stringType(),
7896
- type: literalType("dispute.accepted"),
7897
- timestamp: stringType().transform(function (d) { return new Date(d); }),
7898
- data: DisputeSchema,
7841
+ business_id: stringType(),
7842
+ type: literalType("dispute.accepted"),
7843
+ timestamp: stringType().transform((d) => new Date(d)),
7844
+ data: DisputeSchema
7899
7845
  });
7900
7846
  var DisputeCancelledPayloadSchema = objectType({
7901
- business_id: stringType(),
7902
- type: literalType("dispute.cancelled"),
7903
- timestamp: stringType().transform(function (d) { return new Date(d); }),
7904
- data: DisputeSchema,
7847
+ business_id: stringType(),
7848
+ type: literalType("dispute.cancelled"),
7849
+ timestamp: stringType().transform((d) => new Date(d)),
7850
+ data: DisputeSchema
7905
7851
  });
7906
7852
  var DisputeChallengedPayloadSchema = objectType({
7907
- business_id: stringType(),
7908
- type: literalType("dispute.challenged"),
7909
- timestamp: stringType().transform(function (d) { return new Date(d); }),
7910
- data: DisputeSchema,
7853
+ business_id: stringType(),
7854
+ type: literalType("dispute.challenged"),
7855
+ timestamp: stringType().transform((d) => new Date(d)),
7856
+ data: DisputeSchema
7911
7857
  });
7912
7858
  var DisputeWonPayloadSchema = objectType({
7913
- business_id: stringType(),
7914
- type: literalType("dispute.won"),
7915
- timestamp: stringType().transform(function (d) { return new Date(d); }),
7916
- data: DisputeSchema,
7859
+ business_id: stringType(),
7860
+ type: literalType("dispute.won"),
7861
+ timestamp: stringType().transform((d) => new Date(d)),
7862
+ data: DisputeSchema
7917
7863
  });
7918
7864
  var DisputeLostPayloadSchema = objectType({
7919
- business_id: stringType(),
7920
- type: literalType("dispute.lost"),
7921
- timestamp: stringType().transform(function (d) { return new Date(d); }),
7922
- data: DisputeSchema,
7865
+ business_id: stringType(),
7866
+ type: literalType("dispute.lost"),
7867
+ timestamp: stringType().transform((d) => new Date(d)),
7868
+ data: DisputeSchema
7923
7869
  });
7924
7870
  var SubscriptionActivePayloadSchema = objectType({
7925
- business_id: stringType(),
7926
- type: literalType("subscription.active"),
7927
- timestamp: stringType().transform(function (d) { return new Date(d); }),
7928
- data: SubscriptionSchema,
7871
+ business_id: stringType(),
7872
+ type: literalType("subscription.active"),
7873
+ timestamp: stringType().transform((d) => new Date(d)),
7874
+ data: SubscriptionSchema
7929
7875
  });
7930
7876
  var SubscriptionOnHoldPayloadSchema = objectType({
7931
- business_id: stringType(),
7932
- type: literalType("subscription.on_hold"),
7933
- timestamp: stringType().transform(function (d) { return new Date(d); }),
7934
- data: SubscriptionSchema,
7877
+ business_id: stringType(),
7878
+ type: literalType("subscription.on_hold"),
7879
+ timestamp: stringType().transform((d) => new Date(d)),
7880
+ data: SubscriptionSchema
7935
7881
  });
7936
7882
  var SubscriptionRenewedPayloadSchema = objectType({
7937
- business_id: stringType(),
7938
- type: literalType("subscription.renewed"),
7939
- timestamp: stringType().transform(function (d) { return new Date(d); }),
7940
- data: SubscriptionSchema,
7883
+ business_id: stringType(),
7884
+ type: literalType("subscription.renewed"),
7885
+ timestamp: stringType().transform((d) => new Date(d)),
7886
+ data: SubscriptionSchema
7941
7887
  });
7942
7888
  var SubscriptionPausedPayloadSchema = objectType({
7943
- business_id: stringType(),
7944
- type: literalType("subscription.paused"),
7945
- timestamp: stringType().transform(function (d) { return new Date(d); }),
7946
- data: SubscriptionSchema,
7889
+ business_id: stringType(),
7890
+ type: literalType("subscription.paused"),
7891
+ timestamp: stringType().transform((d) => new Date(d)),
7892
+ data: SubscriptionSchema
7947
7893
  });
7948
7894
  var SubscriptionPlanChangedPayloadSchema = objectType({
7949
- business_id: stringType(),
7950
- type: literalType("subscription.plan_changed"),
7951
- timestamp: stringType().transform(function (d) { return new Date(d); }),
7952
- data: SubscriptionSchema,
7895
+ business_id: stringType(),
7896
+ type: literalType("subscription.plan_changed"),
7897
+ timestamp: stringType().transform((d) => new Date(d)),
7898
+ data: SubscriptionSchema
7953
7899
  });
7954
7900
  var SubscriptionCancelledPayloadSchema = objectType({
7955
- business_id: stringType(),
7956
- type: literalType("subscription.cancelled"),
7957
- timestamp: stringType().transform(function (d) { return new Date(d); }),
7958
- data: SubscriptionSchema,
7901
+ business_id: stringType(),
7902
+ type: literalType("subscription.cancelled"),
7903
+ timestamp: stringType().transform((d) => new Date(d)),
7904
+ data: SubscriptionSchema
7959
7905
  });
7960
7906
  var SubscriptionFailedPayloadSchema = objectType({
7961
- business_id: stringType(),
7962
- type: literalType("subscription.failed"),
7963
- timestamp: stringType().transform(function (d) { return new Date(d); }),
7964
- data: SubscriptionSchema,
7907
+ business_id: stringType(),
7908
+ type: literalType("subscription.failed"),
7909
+ timestamp: stringType().transform((d) => new Date(d)),
7910
+ data: SubscriptionSchema
7965
7911
  });
7966
7912
  var SubscriptionExpiredPayloadSchema = objectType({
7967
- business_id: stringType(),
7968
- type: literalType("subscription.expired"),
7969
- timestamp: stringType().transform(function (d) { return new Date(d); }),
7970
- data: SubscriptionSchema,
7913
+ business_id: stringType(),
7914
+ type: literalType("subscription.expired"),
7915
+ timestamp: stringType().transform((d) => new Date(d)),
7916
+ data: SubscriptionSchema
7971
7917
  });
7972
7918
  var LicenseKeyCreatedPayloadSchema = objectType({
7973
- business_id: stringType(),
7974
- type: literalType("license_key.created"),
7975
- timestamp: stringType().transform(function (d) { return new Date(d); }),
7976
- data: LicenseKeySchema,
7919
+ business_id: stringType(),
7920
+ type: literalType("license_key.created"),
7921
+ timestamp: stringType().transform((d) => new Date(d)),
7922
+ data: LicenseKeySchema
7977
7923
  });
7978
7924
  var WebhookPayloadSchema = discriminatedUnionType("type", [
7979
- PaymentSucceededPayloadSchema,
7980
- PaymentFailedPayloadSchema,
7981
- PaymentProcessingPayloadSchema,
7982
- PaymentCancelledPayloadSchema,
7983
- RefundSucceededPayloadSchema,
7984
- RefundFailedPayloadSchema,
7985
- DisputeOpenedPayloadSchema,
7986
- DisputeExpiredPayloadSchema,
7987
- DisputeAcceptedPayloadSchema,
7988
- DisputeCancelledPayloadSchema,
7989
- DisputeChallengedPayloadSchema,
7990
- DisputeWonPayloadSchema,
7991
- DisputeLostPayloadSchema,
7992
- SubscriptionActivePayloadSchema,
7993
- SubscriptionOnHoldPayloadSchema,
7994
- SubscriptionRenewedPayloadSchema,
7995
- SubscriptionPausedPayloadSchema,
7996
- SubscriptionPlanChangedPayloadSchema,
7997
- SubscriptionCancelledPayloadSchema,
7998
- SubscriptionFailedPayloadSchema,
7999
- SubscriptionExpiredPayloadSchema,
8000
- LicenseKeyCreatedPayloadSchema,
7925
+ PaymentSucceededPayloadSchema,
7926
+ PaymentFailedPayloadSchema,
7927
+ PaymentProcessingPayloadSchema,
7928
+ PaymentCancelledPayloadSchema,
7929
+ RefundSucceededPayloadSchema,
7930
+ RefundFailedPayloadSchema,
7931
+ DisputeOpenedPayloadSchema,
7932
+ DisputeExpiredPayloadSchema,
7933
+ DisputeAcceptedPayloadSchema,
7934
+ DisputeCancelledPayloadSchema,
7935
+ DisputeChallengedPayloadSchema,
7936
+ DisputeWonPayloadSchema,
7937
+ DisputeLostPayloadSchema,
7938
+ SubscriptionActivePayloadSchema,
7939
+ SubscriptionOnHoldPayloadSchema,
7940
+ SubscriptionRenewedPayloadSchema,
7941
+ SubscriptionPausedPayloadSchema,
7942
+ SubscriptionPlanChangedPayloadSchema,
7943
+ SubscriptionCancelledPayloadSchema,
7944
+ SubscriptionFailedPayloadSchema,
7945
+ SubscriptionExpiredPayloadSchema,
7946
+ LicenseKeyCreatedPayloadSchema
8001
7947
  ]);
8002
7948
 
8003
- var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
8004
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
8005
- return new (P || (P = Promise))(function (resolve, reject) {
8006
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
8007
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
8008
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8009
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8010
- });
8011
- };
8012
- var __generator = (undefined && undefined.__generator) || function (thisArg, body) {
8013
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
8014
- return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
8015
- function verb(n) { return function (v) { return step([n, v]); }; }
8016
- function step(op) {
8017
- if (f) throw new TypeError("Generator is already executing.");
8018
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
8019
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
8020
- if (y = 0, t) op = [op[0] & 2, t.value];
8021
- switch (op[0]) {
8022
- case 0: case 1: t = op; break;
8023
- case 4: _.label++; return { value: op[1], done: false };
8024
- case 5: _.label++; y = op[1]; op = [0]; continue;
8025
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
8026
- default:
8027
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
8028
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
8029
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
8030
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
8031
- if (t[2]) _.ops.pop();
8032
- _.trys.pop(); continue;
8033
- }
8034
- op = body.call(thisArg, _);
8035
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
8036
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
8037
- }
8038
- };
8039
- // Implementation
8040
- function handleWebhookPayload(payload, config, context) {
8041
- return __awaiter(this, void 0, void 0, function () {
8042
- var callHandler;
8043
- return __generator(this, function (_a) {
8044
- switch (_a.label) {
8045
- case 0:
8046
- callHandler = function (handler, payload) {
8047
- if (!handler)
8048
- return;
8049
- return handler(payload);
8050
- };
8051
- if (!config.onPayload) return [3 /*break*/, 2];
8052
- return [4 /*yield*/, callHandler(config.onPayload, payload)];
8053
- case 1:
8054
- _a.sent();
8055
- _a.label = 2;
8056
- case 2:
8057
- if (!(payload.type === "payment.succeeded")) return [3 /*break*/, 4];
8058
- return [4 /*yield*/, callHandler(config.onPaymentSucceeded, payload)];
8059
- case 3:
8060
- _a.sent();
8061
- _a.label = 4;
8062
- case 4:
8063
- if (!(payload.type === "payment.failed")) return [3 /*break*/, 6];
8064
- return [4 /*yield*/, callHandler(config.onPaymentFailed, payload)];
8065
- case 5:
8066
- _a.sent();
8067
- _a.label = 6;
8068
- case 6:
8069
- if (!(payload.type === "payment.processing")) return [3 /*break*/, 8];
8070
- return [4 /*yield*/, callHandler(config.onPaymentProcessing, payload)];
8071
- case 7:
8072
- _a.sent();
8073
- _a.label = 8;
8074
- case 8:
8075
- if (!(payload.type === "payment.cancelled")) return [3 /*break*/, 10];
8076
- return [4 /*yield*/, callHandler(config.onPaymentCancelled, payload)];
8077
- case 9:
8078
- _a.sent();
8079
- _a.label = 10;
8080
- case 10:
8081
- if (!(payload.type === "refund.succeeded")) return [3 /*break*/, 12];
8082
- return [4 /*yield*/, callHandler(config.onRefundSucceeded, payload)];
8083
- case 11:
8084
- _a.sent();
8085
- _a.label = 12;
8086
- case 12:
8087
- if (!(payload.type === "refund.failed")) return [3 /*break*/, 14];
8088
- return [4 /*yield*/, callHandler(config.onRefundFailed, payload)];
8089
- case 13:
8090
- _a.sent();
8091
- _a.label = 14;
8092
- case 14:
8093
- if (!(payload.type === "dispute.opened")) return [3 /*break*/, 16];
8094
- return [4 /*yield*/, callHandler(config.onDisputeOpened, payload)];
8095
- case 15:
8096
- _a.sent();
8097
- _a.label = 16;
8098
- case 16:
8099
- if (!(payload.type === "dispute.expired")) return [3 /*break*/, 18];
8100
- return [4 /*yield*/, callHandler(config.onDisputeExpired, payload)];
8101
- case 17:
8102
- _a.sent();
8103
- _a.label = 18;
8104
- case 18:
8105
- if (!(payload.type === "dispute.accepted")) return [3 /*break*/, 20];
8106
- return [4 /*yield*/, callHandler(config.onDisputeAccepted, payload)];
8107
- case 19:
8108
- _a.sent();
8109
- _a.label = 20;
8110
- case 20:
8111
- if (!(payload.type === "dispute.cancelled")) return [3 /*break*/, 22];
8112
- return [4 /*yield*/, callHandler(config.onDisputeCancelled, payload)];
8113
- case 21:
8114
- _a.sent();
8115
- _a.label = 22;
8116
- case 22:
8117
- if (!(payload.type === "dispute.challenged")) return [3 /*break*/, 24];
8118
- return [4 /*yield*/, callHandler(config.onDisputeChallenged, payload)];
8119
- case 23:
8120
- _a.sent();
8121
- _a.label = 24;
8122
- case 24:
8123
- if (!(payload.type === "dispute.won")) return [3 /*break*/, 26];
8124
- return [4 /*yield*/, callHandler(config.onDisputeWon, payload)];
8125
- case 25:
8126
- _a.sent();
8127
- _a.label = 26;
8128
- case 26:
8129
- if (!(payload.type === "dispute.lost")) return [3 /*break*/, 28];
8130
- return [4 /*yield*/, callHandler(config.onDisputeLost, payload)];
8131
- case 27:
8132
- _a.sent();
8133
- _a.label = 28;
8134
- case 28:
8135
- if (!(payload.type === "subscription.active")) return [3 /*break*/, 30];
8136
- return [4 /*yield*/, callHandler(config.onSubscriptionActive, payload)];
8137
- case 29:
8138
- _a.sent();
8139
- _a.label = 30;
8140
- case 30:
8141
- if (!(payload.type === "subscription.on_hold")) return [3 /*break*/, 32];
8142
- return [4 /*yield*/, callHandler(config.onSubscriptionOnHold, payload)];
8143
- case 31:
8144
- _a.sent();
8145
- _a.label = 32;
8146
- case 32:
8147
- if (!(payload.type === "subscription.renewed")) return [3 /*break*/, 34];
8148
- return [4 /*yield*/, callHandler(config.onSubscriptionRenewed, payload)];
8149
- case 33:
8150
- _a.sent();
8151
- _a.label = 34;
8152
- case 34:
8153
- if (!(payload.type === "subscription.paused")) return [3 /*break*/, 36];
8154
- return [4 /*yield*/, callHandler(config.onSubscriptionPaused, payload)];
8155
- case 35:
8156
- _a.sent();
8157
- _a.label = 36;
8158
- case 36:
8159
- if (!(payload.type === "subscription.plan_changed")) return [3 /*break*/, 38];
8160
- return [4 /*yield*/, callHandler(config.onSubscriptionPlanChanged, payload)];
8161
- case 37:
8162
- _a.sent();
8163
- _a.label = 38;
8164
- case 38:
8165
- if (!(payload.type === "subscription.cancelled")) return [3 /*break*/, 40];
8166
- return [4 /*yield*/, callHandler(config.onSubscriptionCancelled, payload)];
8167
- case 39:
8168
- _a.sent();
8169
- _a.label = 40;
8170
- case 40:
8171
- if (!(payload.type === "subscription.failed")) return [3 /*break*/, 42];
8172
- return [4 /*yield*/, callHandler(config.onSubscriptionFailed, payload)];
8173
- case 41:
8174
- _a.sent();
8175
- _a.label = 42;
8176
- case 42:
8177
- if (!(payload.type === "subscription.expired")) return [3 /*break*/, 44];
8178
- return [4 /*yield*/, callHandler(config.onSubscriptionExpired, payload)];
8179
- case 43:
8180
- _a.sent();
8181
- _a.label = 44;
8182
- case 44:
8183
- if (!(payload.type === "license_key.created")) return [3 /*break*/, 46];
8184
- return [4 /*yield*/, callHandler(config.onLicenseKeyCreated, payload)];
8185
- case 45:
8186
- _a.sent();
8187
- _a.label = 46;
8188
- case 46: return [2 /*return*/];
8189
- }
8190
- });
8191
- });
7949
+ async function handleWebhookPayload(payload, config, context) {
7950
+ const callHandler = (handler, payload2) => {
7951
+ if (!handler) return;
7952
+ return handler(payload2);
7953
+ };
7954
+ if (config.onPayload) {
7955
+ await callHandler(config.onPayload, payload);
7956
+ }
7957
+ if (payload.type === "payment.succeeded") {
7958
+ await callHandler(config.onPaymentSucceeded, payload);
7959
+ }
7960
+ if (payload.type === "payment.failed") {
7961
+ await callHandler(config.onPaymentFailed, payload);
7962
+ }
7963
+ if (payload.type === "payment.processing") {
7964
+ await callHandler(config.onPaymentProcessing, payload);
7965
+ }
7966
+ if (payload.type === "payment.cancelled") {
7967
+ await callHandler(config.onPaymentCancelled, payload);
7968
+ }
7969
+ if (payload.type === "refund.succeeded") {
7970
+ await callHandler(config.onRefundSucceeded, payload);
7971
+ }
7972
+ if (payload.type === "refund.failed") {
7973
+ await callHandler(config.onRefundFailed, payload);
7974
+ }
7975
+ if (payload.type === "dispute.opened") {
7976
+ await callHandler(config.onDisputeOpened, payload);
7977
+ }
7978
+ if (payload.type === "dispute.expired") {
7979
+ await callHandler(config.onDisputeExpired, payload);
7980
+ }
7981
+ if (payload.type === "dispute.accepted") {
7982
+ await callHandler(config.onDisputeAccepted, payload);
7983
+ }
7984
+ if (payload.type === "dispute.cancelled") {
7985
+ await callHandler(config.onDisputeCancelled, payload);
7986
+ }
7987
+ if (payload.type === "dispute.challenged") {
7988
+ await callHandler(config.onDisputeChallenged, payload);
7989
+ }
7990
+ if (payload.type === "dispute.won") {
7991
+ await callHandler(config.onDisputeWon, payload);
7992
+ }
7993
+ if (payload.type === "dispute.lost") {
7994
+ await callHandler(config.onDisputeLost, payload);
7995
+ }
7996
+ if (payload.type === "subscription.active") {
7997
+ await callHandler(config.onSubscriptionActive, payload);
7998
+ }
7999
+ if (payload.type === "subscription.on_hold") {
8000
+ await callHandler(config.onSubscriptionOnHold, payload);
8001
+ }
8002
+ if (payload.type === "subscription.renewed") {
8003
+ await callHandler(config.onSubscriptionRenewed, payload);
8004
+ }
8005
+ if (payload.type === "subscription.paused") {
8006
+ await callHandler(config.onSubscriptionPaused, payload);
8007
+ }
8008
+ if (payload.type === "subscription.plan_changed") {
8009
+ await callHandler(config.onSubscriptionPlanChanged, payload);
8010
+ }
8011
+ if (payload.type === "subscription.cancelled") {
8012
+ await callHandler(config.onSubscriptionCancelled, payload);
8013
+ }
8014
+ if (payload.type === "subscription.failed") {
8015
+ await callHandler(config.onSubscriptionFailed, payload);
8016
+ }
8017
+ if (payload.type === "subscription.expired") {
8018
+ await callHandler(config.onSubscriptionExpired, payload);
8019
+ }
8020
+ if (payload.type === "license_key.created") {
8021
+ await callHandler(config.onLicenseKeyCreated, payload);
8022
+ }
8192
8023
  }
8193
8024
 
8194
8025
  const Webhooks = ({ webhookKey, ...eventHandlers }) => {