UNPKG

@sumup/sdk

Version:

The official TypeScript SDK for the SumUp API

863 lines (862 loc) 27.6 kB
class APIResource { _client; constructor(client){ this._client = client; } } class SumUpError extends Error { } class APIError extends SumUpError { status; error; response; constructor(status, error, response){ const message = "string" == typeof error ? error : JSON.stringify(error); super(`${status}: ${message}`); this.status = status; this.error = error; this.response = response; } } async function parseResponse(res) { if (204 === res.status || 205 === res.status) return; const contentLength = res.headers.get("content-length"); if ("0" === contentLength) return; const contentType = res.headers.get("content-type"); const isJSON = contentType?.includes("json"); if (!isJSON) throw new SumUpError("Unexpected non-json response."); return await res.json(); } const UNKNOWN = "unknown"; const normalizeArch = (arch)=>{ const lower = arch.toLowerCase(); if ("x64" === lower || "x86_64" === lower || "amd64" === lower) return "x86_64"; if ("ia32" === lower || "x86" === lower || "x32" === lower) return "x86"; if ("aarch64" === lower || "arm64" === lower) return "arm64"; if ("arm" === lower) return "arm"; return lower || UNKNOWN; }; let cachedRuntimeInfo; function getRuntimeInfo() { if (cachedRuntimeInfo) return cachedRuntimeInfo; const isVercel = "u" > typeof process && "1" === process.env.VERCEL; const globalAny = globalThis; if (globalAny.Bun?.version) { cachedRuntimeInfo = { runtime: "bun", runtimeVersion: globalAny.Bun.version || UNKNOWN, os: globalAny.process?.platform || UNKNOWN, arch: normalizeArch(globalAny.process?.arch || "") }; return cachedRuntimeInfo; } if (globalAny.Deno?.version?.deno) { cachedRuntimeInfo = { runtime: "deno", runtimeVersion: globalAny.Deno.version.deno || UNKNOWN, os: globalAny.Deno.build?.os || UNKNOWN, arch: normalizeArch(globalAny.Deno.build?.arch || "") }; return cachedRuntimeInfo; } if (globalAny.process?.versions?.node) { cachedRuntimeInfo = { runtime: isVercel ? "vercel" : "node", runtimeVersion: globalAny.process.version || UNKNOWN, os: globalAny.process.platform || UNKNOWN, arch: normalizeArch(globalAny.process.arch || "") }; return cachedRuntimeInfo; } if (globalAny.EdgeRuntime) { cachedRuntimeInfo = { runtime: isVercel ? "vercel-edge" : "edge", runtimeVersion: globalAny.process?.version || UNKNOWN, os: UNKNOWN, arch: `${globalAny.EdgeRuntime}` }; return cachedRuntimeInfo; } if (globalAny.navigator) { const userAgent = globalAny.navigator.userAgent || ""; if (userAgent.includes("Cloudflare-Workers")) { cachedRuntimeInfo = { runtime: "cloudflare-workers", runtimeVersion: userAgent, os: UNKNOWN, arch: UNKNOWN }; return cachedRuntimeInfo; } const platform = globalAny.navigator.userAgentData?.platform || globalAny.navigator.platform || ""; cachedRuntimeInfo = { runtime: "browser", runtimeVersion: UNKNOWN, os: platform || UNKNOWN, arch: UNKNOWN }; return cachedRuntimeInfo; } cachedRuntimeInfo = { runtime: UNKNOWN, runtimeVersion: UNKNOWN, os: UNKNOWN, arch: UNKNOWN }; return cachedRuntimeInfo; } function buildRuntimeHeaders() { const { runtime, runtimeVersion, os, arch } = getRuntimeInfo(); return { "X-Sumup-Api-Version": "1.0.0", "X-Sumup-Lang": "javascript", "X-Sumup-Package-Version": "0.1.6", "X-Sumup-Os": os, "X-Sumup-Arch": arch, "X-Sumup-Runtime": runtime, "X-Sumup-Runtime-Version": runtimeVersion }; } class HTTPClient { host; apiKey; baseParams; constructor({ apiKey, host = "https://api.sumup.com", baseParams = {}, maxRetries = 0, timeout } = {}){ this.host = host; this.apiKey = apiKey; const headers = new Headers({ Accept: "application/problem+json, application/json", "Content-Type": "application/json", "User-Agent": "sumup-ts/v0.1.6", ...buildRuntimeHeaders() }); if (apiKey) headers.append("Authorization", `Bearer ${apiKey}`); this.baseParams = mergeParams({ headers, maxRetries, timeout }, baseParams); } get({ ...params }) { return this.request({ method: "GET", ...params }); } getWithResponse({ ...params }) { return this.requestWithResponse({ method: "GET", ...params }); } post({ ...params }) { return this.request({ method: "POST", ...params }); } postWithResponse({ ...params }) { return this.requestWithResponse({ method: "POST", ...params }); } put({ ...params }) { return this.request({ method: "PUT", ...params }); } putWithResponse({ ...params }) { return this.requestWithResponse({ method: "PUT", ...params }); } patch({ ...params }) { return this.request({ method: "PATCH", ...params }); } patchWithResponse({ ...params }) { return this.requestWithResponse({ method: "PATCH", ...params }); } delete({ ...params }) { return this.request({ method: "DELETE", ...params }); } deleteWithResponse({ ...params }) { return this.requestWithResponse({ method: "DELETE", ...params }); } request({ ...params }) { return this.requestWithResponse(params).then(({ data })=>data); } async requestWithResponse({ body, path, query, host: hostOverride, ...requestOptions }) { const host = hostOverride || this.host; const url = new URL(host + (host.endsWith("/") && path.startsWith("/") ? path.slice(1) : path)); if ("object" == typeof query && query && !Array.isArray(query)) url.search = this.stringifyQuery(query); const mergedOptions = mergeParams(this.baseParams, requestOptions); const { maxRetries, timeout, ...fetchParams } = mergedOptions; const init = { ...fetchParams, body: JSON.stringify(body) }; const response = await this.do(url, init, { maxRetries, signal: fetchParams.signal, timeout }); const data = await parseResponse(response.clone()); return { data, response }; } async do(input, init, options) { const maxRetries = options.maxRetries ?? 0; for(let attempt = 0;; attempt++){ const { cleanup, didTimeout, signal } = withTimeoutSignal(options.signal, options.timeout); try { const res = await fetch(input, { ...init, signal }); if (!res.ok) { if (attempt < maxRetries && isRetryableStatus(res.status)) continue; const contentType = res.headers.get("content-type"); const isJSON = contentType?.includes("json"); throw new APIError(res.status, isJSON ? await res.json() : await res.text(), res); } return res; } catch (error) { if (attempt < maxRetries && isRetryableError(error, options.signal)) continue; if (didTimeout()) throw new SumUpError(`Request timed out after ${options.timeout}ms.`); throw error; } finally{ cleanup(); } } } stringifyQuery(query) { return Object.entries(query).filter(([_, value])=>void 0 !== value).map(([key, value])=>{ if ("string" == typeof value || "number" == typeof value || "boolean" == typeof value) return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`; if (null === value) return `${encodeURIComponent(key)}=`; if (Array.isArray(value)) return value.map((v)=>`${encodeURIComponent(key)}=${encodeURIComponent(v)}`).join("&"); throw new Error(`Cannot stringify type ${typeof value}; Expected string, number, boolean, or null.`); }).join("&"); } } function mergeParams(a, b) { const { authorization: defaultAuthorization, headers: defaultHeaders, ...defaultParams } = a; const { authorization: overrideAuthorization, headers: overrideHeaders, ...overrideParams } = b; const headers = new Headers(defaultHeaders); for (const [key, value] of new Headers(overrideHeaders).entries())headers.set(key, value); const authorization = overrideAuthorization ?? defaultAuthorization; if (authorization) headers.set("Authorization", authorization); return { ...defaultParams, ...overrideParams, headers }; } function isRetryableStatus(status) { return 408 === status || 409 === status || 429 === status || status >= 500; } function isRetryableError(error, signal) { if (signal?.aborted) return false; return error instanceof TypeError || isAbortError(error); } function isAbortError(error) { return error instanceof DOMException ? "AbortError" === error.name : error instanceof Error && "AbortError" === error.name; } function withTimeoutSignal(signal, timeout) { if (!signal && void 0 === timeout) return { cleanup: ()=>{}, didTimeout: ()=>false, signal: void 0 }; const controller = new AbortController(); let timedOut = false; const onAbort = ()=>{ controller.abort(signal?.reason); }; if (signal) if (signal.aborted) onAbort(); else signal.addEventListener("abort", onAbort, { once: true }); const timeoutId = "number" == typeof timeout ? setTimeout(()=>{ timedOut = true; controller.abort(new SumUpError(`Request timed out after ${timeout}ms.`)); }, timeout) : void 0; return { cleanup: ()=>{ if (void 0 !== timeoutId) clearTimeout(timeoutId); signal?.removeEventListener("abort", onAbort); }, didTimeout: ()=>timedOut, signal: controller.signal }; } class Checkouts extends APIResource { listAvailablePaymentMethods(merchantCode, query, options) { return this._client.get({ path: `/v0.1/merchants/${merchantCode}/payment-methods`, query, ...options }); } listAvailablePaymentMethodsWithResponse(merchantCode, query, options) { return this._client.getWithResponse({ path: `/v0.1/merchants/${merchantCode}/payment-methods`, query, ...options }); } list(query, options) { return this._client.get({ path: "/v0.1/checkouts", query, ...options }); } listWithResponse(query, options) { return this._client.getWithResponse({ path: "/v0.1/checkouts", query, ...options }); } create(body, options) { return this._client.post({ path: "/v0.1/checkouts", body, ...options }); } createWithResponse(body, options) { return this._client.postWithResponse({ path: "/v0.1/checkouts", body, ...options }); } get(id, options) { return this._client.get({ path: `/v0.1/checkouts/${id}`, ...options }); } getWithResponse(id, options) { return this._client.getWithResponse({ path: `/v0.1/checkouts/${id}`, ...options }); } process(id, body, options) { return this._client.put({ path: `/v0.1/checkouts/${id}`, body, ...options }); } processWithResponse(id, body, options) { return this._client.putWithResponse({ path: `/v0.1/checkouts/${id}`, body, ...options }); } deactivate(id, options) { return this._client.delete({ path: `/v0.1/checkouts/${id}`, ...options }); } deactivateWithResponse(id, options) { return this._client.deleteWithResponse({ path: `/v0.1/checkouts/${id}`, ...options }); } createApplePaySession(id, body, options) { return this._client.put({ path: `/v0.2/checkouts/${id}/apple-pay-session`, body, ...options }); } createApplePaySessionWithResponse(id, body, options) { return this._client.putWithResponse({ path: `/v0.2/checkouts/${id}/apple-pay-session`, body, ...options }); } } class Customers extends APIResource { create(body, options) { return this._client.post({ path: "/v0.1/customers", body, ...options }); } createWithResponse(body, options) { return this._client.postWithResponse({ path: "/v0.1/customers", body, ...options }); } get(customerId, options) { return this._client.get({ path: `/v0.1/customers/${customerId}`, ...options }); } getWithResponse(customerId, options) { return this._client.getWithResponse({ path: `/v0.1/customers/${customerId}`, ...options }); } update(customerId, body, options) { return this._client.put({ path: `/v0.1/customers/${customerId}`, body, ...options }); } updateWithResponse(customerId, body, options) { return this._client.putWithResponse({ path: `/v0.1/customers/${customerId}`, body, ...options }); } listPaymentInstruments(customerId, options) { return this._client.get({ path: `/v0.1/customers/${customerId}/payment-instruments`, ...options }); } listPaymentInstrumentsWithResponse(customerId, options) { return this._client.getWithResponse({ path: `/v0.1/customers/${customerId}/payment-instruments`, ...options }); } deactivatePaymentInstrument(customerId, token, options) { return this._client.delete({ path: `/v0.1/customers/${customerId}/payment-instruments/${token}`, ...options }); } deactivatePaymentInstrumentWithResponse(customerId, token, options) { return this._client.deleteWithResponse({ path: `/v0.1/customers/${customerId}/payment-instruments/${token}`, ...options }); } } class Members extends APIResource { list(merchantCode, query, options) { return this._client.get({ path: `/v0.1/merchants/${merchantCode}/members`, query, ...options }); } listWithResponse(merchantCode, query, options) { return this._client.getWithResponse({ path: `/v0.1/merchants/${merchantCode}/members`, query, ...options }); } create(merchantCode, body, options) { return this._client.post({ path: `/v0.1/merchants/${merchantCode}/members`, body, ...options }); } createWithResponse(merchantCode, body, options) { return this._client.postWithResponse({ path: `/v0.1/merchants/${merchantCode}/members`, body, ...options }); } get(merchantCode, memberId, options) { return this._client.get({ path: `/v0.1/merchants/${merchantCode}/members/${memberId}`, ...options }); } getWithResponse(merchantCode, memberId, options) { return this._client.getWithResponse({ path: `/v0.1/merchants/${merchantCode}/members/${memberId}`, ...options }); } update(merchantCode, memberId, body, options) { return this._client.put({ path: `/v0.1/merchants/${merchantCode}/members/${memberId}`, body, ...options }); } updateWithResponse(merchantCode, memberId, body, options) { return this._client.putWithResponse({ path: `/v0.1/merchants/${merchantCode}/members/${memberId}`, body, ...options }); } delete(merchantCode, memberId, options) { return this._client.delete({ path: `/v0.1/merchants/${merchantCode}/members/${memberId}`, ...options }); } deleteWithResponse(merchantCode, memberId, options) { return this._client.deleteWithResponse({ path: `/v0.1/merchants/${merchantCode}/members/${memberId}`, ...options }); } } class Memberships extends APIResource { list(query, options) { return this._client.get({ path: "/v0.1/memberships", query, ...options }); } listWithResponse(query, options) { return this._client.getWithResponse({ path: "/v0.1/memberships", query, ...options }); } } class Merchants extends APIResource { get(merchantCode, query, options) { return this._client.get({ path: `/v1/merchants/${merchantCode}`, query, ...options }); } getWithResponse(merchantCode, query, options) { return this._client.getWithResponse({ path: `/v1/merchants/${merchantCode}`, query, ...options }); } listPersons(merchantCode, query, options) { return this._client.get({ path: `/v1/merchants/${merchantCode}/persons`, query, ...options }); } listPersonsWithResponse(merchantCode, query, options) { return this._client.getWithResponse({ path: `/v1/merchants/${merchantCode}/persons`, query, ...options }); } getPerson(merchantCode, personId, query, options) { return this._client.get({ path: `/v1/merchants/${merchantCode}/persons/${personId}`, query, ...options }); } getPersonWithResponse(merchantCode, personId, query, options) { return this._client.getWithResponse({ path: `/v1/merchants/${merchantCode}/persons/${personId}`, query, ...options }); } } class Payouts extends APIResource { list(merchantCode, query, options) { return this._client.get({ path: `/v1.0/merchants/${merchantCode}/payouts`, query, ...options }); } listWithResponse(merchantCode, query, options) { return this._client.getWithResponse({ path: `/v1.0/merchants/${merchantCode}/payouts`, query, ...options }); } } class Readers extends APIResource { list(merchantCode, options) { return this._client.get({ path: `/v0.1/merchants/${merchantCode}/readers`, ...options }); } listWithResponse(merchantCode, options) { return this._client.getWithResponse({ path: `/v0.1/merchants/${merchantCode}/readers`, ...options }); } create(merchantCode, body, options) { return this._client.post({ path: `/v0.1/merchants/${merchantCode}/readers`, body, ...options }); } createWithResponse(merchantCode, body, options) { return this._client.postWithResponse({ path: `/v0.1/merchants/${merchantCode}/readers`, body, ...options }); } get(merchantCode, id, options) { return this._client.get({ path: `/v0.1/merchants/${merchantCode}/readers/${id}`, ...options }); } getWithResponse(merchantCode, id, options) { return this._client.getWithResponse({ path: `/v0.1/merchants/${merchantCode}/readers/${id}`, ...options }); } delete(merchantCode, id, options) { return this._client.delete({ path: `/v0.1/merchants/${merchantCode}/readers/${id}`, ...options }); } deleteWithResponse(merchantCode, id, options) { return this._client.deleteWithResponse({ path: `/v0.1/merchants/${merchantCode}/readers/${id}`, ...options }); } update(merchantCode, id, body, options) { return this._client.patch({ path: `/v0.1/merchants/${merchantCode}/readers/${id}`, body, ...options }); } updateWithResponse(merchantCode, id, body, options) { return this._client.patchWithResponse({ path: `/v0.1/merchants/${merchantCode}/readers/${id}`, body, ...options }); } createCheckout(merchantCode, readerId, body, options) { return this._client.post({ path: `/v0.1/merchants/${merchantCode}/readers/${readerId}/checkout`, body, ...options }); } createCheckoutWithResponse(merchantCode, readerId, body, options) { return this._client.postWithResponse({ path: `/v0.1/merchants/${merchantCode}/readers/${readerId}/checkout`, body, ...options }); } getStatus(merchantCode, readerId, options) { return this._client.get({ path: `/v0.1/merchants/${merchantCode}/readers/${readerId}/status`, ...options }); } getStatusWithResponse(merchantCode, readerId, options) { return this._client.getWithResponse({ path: `/v0.1/merchants/${merchantCode}/readers/${readerId}/status`, ...options }); } terminateCheckout(merchantCode, readerId, body, options) { return this._client.post({ path: `/v0.1/merchants/${merchantCode}/readers/${readerId}/terminate`, body, ...options }); } terminateCheckoutWithResponse(merchantCode, readerId, body, options) { return this._client.postWithResponse({ path: `/v0.1/merchants/${merchantCode}/readers/${readerId}/terminate`, body, ...options }); } } class Receipts extends APIResource { get(id, query, options) { return this._client.get({ path: `/v1.1/receipts/${id}`, query, ...options }); } getWithResponse(id, query, options) { return this._client.getWithResponse({ path: `/v1.1/receipts/${id}`, query, ...options }); } } class Roles extends APIResource { list(merchantCode, options) { return this._client.get({ path: `/v0.1/merchants/${merchantCode}/roles`, ...options }); } listWithResponse(merchantCode, options) { return this._client.getWithResponse({ path: `/v0.1/merchants/${merchantCode}/roles`, ...options }); } create(merchantCode, body, options) { return this._client.post({ path: `/v0.1/merchants/${merchantCode}/roles`, body, ...options }); } createWithResponse(merchantCode, body, options) { return this._client.postWithResponse({ path: `/v0.1/merchants/${merchantCode}/roles`, body, ...options }); } get(merchantCode, roleId, options) { return this._client.get({ path: `/v0.1/merchants/${merchantCode}/roles/${roleId}`, ...options }); } getWithResponse(merchantCode, roleId, options) { return this._client.getWithResponse({ path: `/v0.1/merchants/${merchantCode}/roles/${roleId}`, ...options }); } delete(merchantCode, roleId, options) { return this._client.delete({ path: `/v0.1/merchants/${merchantCode}/roles/${roleId}`, ...options }); } deleteWithResponse(merchantCode, roleId, options) { return this._client.deleteWithResponse({ path: `/v0.1/merchants/${merchantCode}/roles/${roleId}`, ...options }); } update(merchantCode, roleId, body, options) { return this._client.patch({ path: `/v0.1/merchants/${merchantCode}/roles/${roleId}`, body, ...options }); } updateWithResponse(merchantCode, roleId, body, options) { return this._client.patchWithResponse({ path: `/v0.1/merchants/${merchantCode}/roles/${roleId}`, body, ...options }); } } class Transactions extends APIResource { refund(merchantCode, id, body, options) { return this._client.post({ path: `/v1.0/merchants/${merchantCode}/payments/${id}/refunds`, body, ...options }); } refundWithResponse(merchantCode, id, body, options) { return this._client.postWithResponse({ path: `/v1.0/merchants/${merchantCode}/payments/${id}/refunds`, body, ...options }); } get(merchantCode, query, options) { return this._client.get({ path: `/v2.1/merchants/${merchantCode}/transactions`, query, ...options }); } getWithResponse(merchantCode, query, options) { return this._client.getWithResponse({ path: `/v2.1/merchants/${merchantCode}/transactions`, query, ...options }); } list(merchantCode, query, options) { return this._client.get({ path: `/v2.1/merchants/${merchantCode}/transactions/history`, query, ...options }); } listWithResponse(merchantCode, query, options) { return this._client.getWithResponse({ path: `/v2.1/merchants/${merchantCode}/transactions/history`, query, ...options }); } } class SumUp extends HTTPClient { checkouts = new Checkouts(this); customers = new Customers(this); members = new Members(this); memberships = new Memberships(this); merchants = new Merchants(this); payouts = new Payouts(this); readers = new Readers(this); receipts = new Receipts(this); roles = new Roles(this); transactions = new Transactions(this); } const src = SumUp; export default src; export { APIError, Checkouts, Customers, Members, Memberships, Merchants, Payouts, Readers, Receipts, Roles, SumUp, SumUpError, Transactions }; //# sourceMappingURL=index.js.map