@ozura/elements 0.1.0-beta.1
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/LICENSE +21 -0
- package/README.md +717 -0
- package/dist/frame/element-frame.html +22 -0
- package/dist/frame/element-frame.js +731 -0
- package/dist/frame/element-frame.js.map +1 -0
- package/dist/frame/tokenizer-frame.html +11 -0
- package/dist/frame/tokenizer-frame.js +328 -0
- package/dist/frame/tokenizer-frame.js.map +1 -0
- package/dist/oz-elements.esm.js +1190 -0
- package/dist/oz-elements.esm.js.map +1 -0
- package/dist/oz-elements.umd.js +1202 -0
- package/dist/oz-elements.umd.js.map +1 -0
- package/dist/react/frame/elementFrame.d.ts +8 -0
- package/dist/react/frame/tokenizerFrame.d.ts +13 -0
- package/dist/react/index.cjs.js +1407 -0
- package/dist/react/index.cjs.js.map +1 -0
- package/dist/react/index.esm.js +1400 -0
- package/dist/react/index.esm.js.map +1 -0
- package/dist/react/react/index.d.ts +214 -0
- package/dist/react/sdk/OzElement.d.ts +65 -0
- package/dist/react/sdk/OzVault.d.ts +106 -0
- package/dist/react/sdk/errors.d.ts +55 -0
- package/dist/react/sdk/index.d.ts +5 -0
- package/dist/react/server/index.d.ts +140 -0
- package/dist/react/types/index.d.ts +432 -0
- package/dist/react/utils/appearance.d.ts +13 -0
- package/dist/react/utils/billingUtils.d.ts +60 -0
- package/dist/react/utils/cardUtils.d.ts +37 -0
- package/dist/server/frame/elementFrame.d.ts +8 -0
- package/dist/server/frame/tokenizerFrame.d.ts +13 -0
- package/dist/server/index.cjs.js +294 -0
- package/dist/server/index.cjs.js.map +1 -0
- package/dist/server/index.esm.js +290 -0
- package/dist/server/index.esm.js.map +1 -0
- package/dist/server/sdk/OzElement.d.ts +65 -0
- package/dist/server/sdk/OzVault.d.ts +106 -0
- package/dist/server/sdk/errors.d.ts +55 -0
- package/dist/server/sdk/index.d.ts +5 -0
- package/dist/server/server/index.d.ts +140 -0
- package/dist/server/types/index.d.ts +432 -0
- package/dist/server/utils/appearance.d.ts +13 -0
- package/dist/server/utils/billingUtils.d.ts +60 -0
- package/dist/server/utils/cardUtils.d.ts +37 -0
- package/dist/types/frame/elementFrame.d.ts +8 -0
- package/dist/types/frame/tokenizerFrame.d.ts +13 -0
- package/dist/types/sdk/OzElement.d.ts +65 -0
- package/dist/types/sdk/OzVault.d.ts +106 -0
- package/dist/types/sdk/errors.d.ts +55 -0
- package/dist/types/sdk/index.d.ts +5 -0
- package/dist/types/server/index.d.ts +140 -0
- package/dist/types/types/index.d.ts +432 -0
- package/dist/types/utils/appearance.d.ts +13 -0
- package/dist/types/utils/billingUtils.d.ts +60 -0
- package/dist/types/utils/cardUtils.d.ts +37 -0
- package/package.json +97 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* tokenizerFrame.ts — runs inside a hidden <iframe> served from Ozura's domain.
|
|
3
|
+
*
|
|
4
|
+
* Collects raw card field values sent by element frames (same-origin),
|
|
5
|
+
* assembles the vault tokenization payload, and POSTs it directly to the
|
|
6
|
+
* vault API. The merchant page never sees raw card data.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Returns true when the given URL's origin is in the compile-time allowlist.
|
|
10
|
+
* For localhost entries, any port is accepted (dev-server port varies).
|
|
11
|
+
* Exported for unit testing only — not part of the public SDK API.
|
|
12
|
+
*/
|
|
13
|
+
export declare function isAllowedVaultOrigin(apiUrl: string): boolean;
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @ozura/server — Server-side SDK for the Ozura Pay API.
|
|
5
|
+
*
|
|
6
|
+
* Wraps cardSale and transaction query endpoints with typed methods,
|
|
7
|
+
* automatic field mapping, retry logic, and error handling.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { Ozura } from 'oz-elements/server';
|
|
12
|
+
*
|
|
13
|
+
* const ozura = new Ozura({
|
|
14
|
+
* merchantId: process.env.MERCHANT_ID!,
|
|
15
|
+
* apiKey: process.env.MERCHANT_API_KEY!,
|
|
16
|
+
* vaultKey: process.env.VAULT_API_KEY!,
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* const result = await ozura.cardSale({
|
|
20
|
+
* token: tokenResponse.token,
|
|
21
|
+
* cvcSession: tokenResponse.cvcSession,
|
|
22
|
+
* amount: '49.00',
|
|
23
|
+
* currency: 'USD',
|
|
24
|
+
* billing: tokenResponse.billing,
|
|
25
|
+
* clientIpAddress: req.ip,
|
|
26
|
+
* });
|
|
27
|
+
*
|
|
28
|
+
* console.log(result.transactionId);
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
// ─── Configuration ───────────────────────────────────────────────────────────
|
|
32
|
+
const DEFAULT_API_URL = "https://ozurapay-pay-api-v2-staging-c8abbdfhfbd3c5em.eastus-01.azurewebsites.net";
|
|
33
|
+
const DEFAULT_TIMEOUT = 30000;
|
|
34
|
+
// ─── Error ───────────────────────────────────────────────────────────────────
|
|
35
|
+
class OzuraError extends Error {
|
|
36
|
+
constructor(message, statusCode, raw, retryAfter) {
|
|
37
|
+
super(message);
|
|
38
|
+
this.name = 'OzuraError';
|
|
39
|
+
this.statusCode = statusCode;
|
|
40
|
+
this.raw = raw !== null && raw !== void 0 ? raw : message;
|
|
41
|
+
this.retryAfter = retryAfter;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// ─── Retry helper ─────────────────────────────────────────────────────────────
|
|
45
|
+
const DEFAULT_RETRIES = 2;
|
|
46
|
+
function isRetryable(status) {
|
|
47
|
+
return status >= 500 && status < 600;
|
|
48
|
+
}
|
|
49
|
+
async function sleep(ms) {
|
|
50
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
51
|
+
}
|
|
52
|
+
// ─── Main class ──────────────────────────────────────────────────────────────
|
|
53
|
+
class Ozura {
|
|
54
|
+
constructor(config) {
|
|
55
|
+
var _a, _b;
|
|
56
|
+
if (!config.merchantId)
|
|
57
|
+
throw new OzuraError('merchantId is required', 0);
|
|
58
|
+
if (!config.apiKey)
|
|
59
|
+
throw new OzuraError('apiKey is required', 0);
|
|
60
|
+
if (!config.vaultKey)
|
|
61
|
+
throw new OzuraError('vaultKey is required', 0);
|
|
62
|
+
this.merchantId = config.merchantId;
|
|
63
|
+
this.apiKey = config.apiKey;
|
|
64
|
+
this.vaultKey = config.vaultKey;
|
|
65
|
+
this.apiUrl = config.apiUrl || DEFAULT_API_URL;
|
|
66
|
+
this.timeoutMs = (_a = config.timeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_TIMEOUT;
|
|
67
|
+
this.retries = (_b = config.retries) !== null && _b !== void 0 ? _b : DEFAULT_RETRIES;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Charge a tokenized card. Maps the friendly `CardSaleInput` shape to the
|
|
71
|
+
* Pay API's flat field format and handles headers, defaults, and errors.
|
|
72
|
+
*
|
|
73
|
+
* Rate limit: 100 requests/minute per merchant.
|
|
74
|
+
*/
|
|
75
|
+
async cardSale(input) {
|
|
76
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
77
|
+
const billing = input.billing;
|
|
78
|
+
const body = {
|
|
79
|
+
merchantId: this.merchantId,
|
|
80
|
+
amount: input.amount,
|
|
81
|
+
currency: input.currency || 'USD',
|
|
82
|
+
ozuraCardToken: input.token,
|
|
83
|
+
ozuraCvcSession: input.cvcSession,
|
|
84
|
+
billingFirstName: billing.firstName,
|
|
85
|
+
billingLastName: billing.lastName,
|
|
86
|
+
billingEmail: billing.email || '',
|
|
87
|
+
billingPhone: billing.phone || '',
|
|
88
|
+
billingAddress1: ((_a = billing.address) === null || _a === void 0 ? void 0 : _a.line1) || '',
|
|
89
|
+
billingCity: ((_b = billing.address) === null || _b === void 0 ? void 0 : _b.city) || '',
|
|
90
|
+
billingState: ((_c = billing.address) === null || _c === void 0 ? void 0 : _c.state) || '',
|
|
91
|
+
billingZipcode: ((_d = billing.address) === null || _d === void 0 ? void 0 : _d.zip) || '',
|
|
92
|
+
billingCountry: ((_e = billing.address) === null || _e === void 0 ? void 0 : _e.country) || 'US',
|
|
93
|
+
clientIpAddress: input.clientIpAddress,
|
|
94
|
+
salesTaxExempt: (_f = input.salesTaxExempt) !== null && _f !== void 0 ? _f : false,
|
|
95
|
+
surchargePercent: (_g = input.surchargePercent) !== null && _g !== void 0 ? _g : '0.00',
|
|
96
|
+
tipAmount: (_h = input.tipAmount) !== null && _h !== void 0 ? _h : '0.00',
|
|
97
|
+
};
|
|
98
|
+
if ((_j = billing.address) === null || _j === void 0 ? void 0 : _j.line2) {
|
|
99
|
+
body.billingAddress2 = billing.address.line2;
|
|
100
|
+
}
|
|
101
|
+
if (input.processor) {
|
|
102
|
+
body.processor = input.processor;
|
|
103
|
+
}
|
|
104
|
+
return this.post('/api/v1/cardSale', body, true);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Retrieve a single transaction by ID.
|
|
108
|
+
*
|
|
109
|
+
* **Known issue:** The Pay API requires the API key as a query parameter
|
|
110
|
+
* (`access_token`), which means it can appear in server logs, CDN caches,
|
|
111
|
+
* and HTTP Referer headers. This is a Pay API design issue — the SDK will
|
|
112
|
+
* switch to header-based auth once the backend supports it.
|
|
113
|
+
*
|
|
114
|
+
* Rate limit: 100 requests/minute per merchant.
|
|
115
|
+
*/
|
|
116
|
+
async getTransaction(transactionId) {
|
|
117
|
+
const qs = new URLSearchParams({ access_token: this.apiKey });
|
|
118
|
+
return this.get(`/api/v1/transactions/${encodeURIComponent(transactionId)}?${qs}`);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* List transactions by date range with pagination.
|
|
122
|
+
*
|
|
123
|
+
* Rate limit: 200 requests/minute per merchant.
|
|
124
|
+
*/
|
|
125
|
+
async listTransactions(input = {}) {
|
|
126
|
+
const params = { merchantId: this.merchantId };
|
|
127
|
+
if (input.dateFrom)
|
|
128
|
+
params.dateFrom = input.dateFrom;
|
|
129
|
+
if (input.dateTo)
|
|
130
|
+
params.dateTo = input.dateTo;
|
|
131
|
+
if (input.transactionType)
|
|
132
|
+
params.transactionType = input.transactionType;
|
|
133
|
+
if (input.page)
|
|
134
|
+
params.page = String(input.page);
|
|
135
|
+
if (input.limit)
|
|
136
|
+
params.limit = String(input.limit);
|
|
137
|
+
if (input.fields)
|
|
138
|
+
params.fields = input.fields;
|
|
139
|
+
if (input.sortBy)
|
|
140
|
+
params.sortBy = input.sortBy;
|
|
141
|
+
if (input.sortOrder)
|
|
142
|
+
params.sortOrder = input.sortOrder;
|
|
143
|
+
const qs = new URLSearchParams(params);
|
|
144
|
+
const raw = await this.getRaw(`/api/v1/transQuery?${qs}`);
|
|
145
|
+
return { transactions: raw.data, pagination: raw.pagination };
|
|
146
|
+
}
|
|
147
|
+
// ─── HTTP helpers ────────────────────────────────────────────────────────
|
|
148
|
+
/**
|
|
149
|
+
* Execute a fetch with retry on 5xx / network errors.
|
|
150
|
+
* 4xx errors (including 429) are never retried — they require caller action.
|
|
151
|
+
*/
|
|
152
|
+
async fetchWithRetry(url, init) {
|
|
153
|
+
let lastError;
|
|
154
|
+
for (let attempt = 0; attempt <= this.retries; attempt++) {
|
|
155
|
+
try {
|
|
156
|
+
const res = await fetch(url, Object.assign(Object.assign({}, init), { signal: AbortSignal.timeout(this.timeoutMs) }));
|
|
157
|
+
if (isRetryable(res.status) && attempt < this.retries) {
|
|
158
|
+
// Consume/cancel body so the connection is released (undici holds socket until body is drained)
|
|
159
|
+
if (res.body) {
|
|
160
|
+
try {
|
|
161
|
+
await res.body.cancel();
|
|
162
|
+
}
|
|
163
|
+
catch (_a) {
|
|
164
|
+
/* ignore */
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
const backoff = Math.min(1000 * 2 ** attempt, 8000);
|
|
168
|
+
await sleep(backoff);
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
return res;
|
|
172
|
+
}
|
|
173
|
+
catch (err) {
|
|
174
|
+
lastError = err;
|
|
175
|
+
if (attempt < this.retries) {
|
|
176
|
+
const backoff = Math.min(1000 * 2 ** attempt, 8000);
|
|
177
|
+
await sleep(backoff);
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// All attempts exhausted — wrap the raw error in OzuraError
|
|
183
|
+
if (lastError instanceof Error) {
|
|
184
|
+
if (lastError.name === 'TimeoutError' || lastError.name === 'AbortError') {
|
|
185
|
+
throw new OzuraError(`Request timed out after ${this.timeoutMs}ms`, 0, lastError.message);
|
|
186
|
+
}
|
|
187
|
+
throw new OzuraError(`Network error: ${lastError.message}`, 0, lastError.message);
|
|
188
|
+
}
|
|
189
|
+
throw new OzuraError('Network error', 0);
|
|
190
|
+
}
|
|
191
|
+
async post(path, body, includeVaultKey) {
|
|
192
|
+
const headers = {
|
|
193
|
+
'Content-Type': 'application/json',
|
|
194
|
+
'x-api-key': this.apiKey,
|
|
195
|
+
};
|
|
196
|
+
if (includeVaultKey) {
|
|
197
|
+
headers['vault-api-key'] = this.vaultKey;
|
|
198
|
+
}
|
|
199
|
+
const res = await this.fetchWithRetry(`${this.apiUrl}${path}`, {
|
|
200
|
+
method: 'POST',
|
|
201
|
+
headers,
|
|
202
|
+
body: JSON.stringify(body),
|
|
203
|
+
});
|
|
204
|
+
return this.handleResponse(res);
|
|
205
|
+
}
|
|
206
|
+
async get(path) {
|
|
207
|
+
const res = await this.fetchWithRetry(`${this.apiUrl}${path}`, {
|
|
208
|
+
method: 'GET',
|
|
209
|
+
headers: { 'x-api-key': this.apiKey },
|
|
210
|
+
});
|
|
211
|
+
return this.handleResponse(res);
|
|
212
|
+
}
|
|
213
|
+
async getRaw(path) {
|
|
214
|
+
const res = await this.fetchWithRetry(`${this.apiUrl}${path}`, {
|
|
215
|
+
method: 'GET',
|
|
216
|
+
headers: { 'x-api-key': this.apiKey },
|
|
217
|
+
});
|
|
218
|
+
const json = await res.json().catch(() => ({ error: res.statusText }));
|
|
219
|
+
if (!res.ok) {
|
|
220
|
+
const retryAfter = res.status === 429
|
|
221
|
+
? Number(res.headers.get('retry-after') || json.retryAfter) || undefined
|
|
222
|
+
: undefined;
|
|
223
|
+
throw new OzuraError(json.error || `HTTP ${res.status}`, res.status, json.error, retryAfter);
|
|
224
|
+
}
|
|
225
|
+
if (json.success === false) {
|
|
226
|
+
throw new OzuraError(json.error || 'Request was not successful', res.status, json.error);
|
|
227
|
+
}
|
|
228
|
+
return json;
|
|
229
|
+
}
|
|
230
|
+
async handleResponse(res) {
|
|
231
|
+
var _a;
|
|
232
|
+
const json = await res.json().catch(() => ({ error: res.statusText }));
|
|
233
|
+
if (!res.ok) {
|
|
234
|
+
const retryAfter = res.status === 429
|
|
235
|
+
? Number(res.headers.get('retry-after') || json.retryAfter) || undefined
|
|
236
|
+
: undefined;
|
|
237
|
+
throw new OzuraError(json.error || `HTTP ${res.status}`, res.status, json.error, retryAfter);
|
|
238
|
+
}
|
|
239
|
+
if (json.success === false) {
|
|
240
|
+
throw new OzuraError(json.error || 'Request was not successful', res.status, json.error);
|
|
241
|
+
}
|
|
242
|
+
return ((_a = json.data) !== null && _a !== void 0 ? _a : json);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
// ─── Utilities ────────────────────────────────────────────────────────────────
|
|
246
|
+
/**
|
|
247
|
+
* Extract the client IP address from a server request object.
|
|
248
|
+
* Works with Express (`req.ip`), Fastify (`request.ip`), Next.js App Router
|
|
249
|
+
* (`req.headers.get('x-forwarded-for')`), and raw Node.js `IncomingMessage`.
|
|
250
|
+
*
|
|
251
|
+
* @example
|
|
252
|
+
* // Express / Fastify
|
|
253
|
+
* clientIpAddress: getClientIp(req)
|
|
254
|
+
*
|
|
255
|
+
* // Next.js App Router
|
|
256
|
+
* clientIpAddress: getClientIp(req)
|
|
257
|
+
*/
|
|
258
|
+
function getClientIp(req) {
|
|
259
|
+
// Express / Fastify: req.ip
|
|
260
|
+
if (typeof req.ip === 'string' && req.ip)
|
|
261
|
+
return req.ip;
|
|
262
|
+
// Next.js App Router: req.headers.get('x-forwarded-for')
|
|
263
|
+
const headers = req.headers;
|
|
264
|
+
if (headers && typeof headers.get === 'function') {
|
|
265
|
+
const xff = headers.get('x-forwarded-for');
|
|
266
|
+
if (xff)
|
|
267
|
+
return xff.split(',')[0].trim();
|
|
268
|
+
const realIp = headers.get('x-real-ip');
|
|
269
|
+
if (realIp)
|
|
270
|
+
return realIp;
|
|
271
|
+
}
|
|
272
|
+
// Node.js IncomingMessage: req.headers['x-forwarded-for']
|
|
273
|
+
if (headers && typeof headers === 'object') {
|
|
274
|
+
const h = headers;
|
|
275
|
+
const xff = h['x-forwarded-for'];
|
|
276
|
+
if (typeof xff === 'string' && xff)
|
|
277
|
+
return xff.split(',')[0].trim();
|
|
278
|
+
if (Array.isArray(xff) && xff[0])
|
|
279
|
+
return xff[0].split(',')[0].trim();
|
|
280
|
+
const realIp = h['x-real-ip'];
|
|
281
|
+
if (typeof realIp === 'string' && realIp)
|
|
282
|
+
return realIp;
|
|
283
|
+
}
|
|
284
|
+
// Raw Node.js socket
|
|
285
|
+
const socket = req.socket;
|
|
286
|
+
if (socket === null || socket === void 0 ? void 0 : socket.remoteAddress)
|
|
287
|
+
return socket.remoteAddress;
|
|
288
|
+
return '0.0.0.0';
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
exports.Ozura = Ozura;
|
|
292
|
+
exports.OzuraError = OzuraError;
|
|
293
|
+
exports.getClientIp = getClientIp;
|
|
294
|
+
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../../src/server/index.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ozura/server — Server-side SDK for the Ozura Pay API.
|
|
3
|
+
*
|
|
4
|
+
* Wraps cardSale and transaction query endpoints with typed methods,
|
|
5
|
+
* automatic field mapping, retry logic, and error handling.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { Ozura } from 'oz-elements/server';
|
|
10
|
+
*
|
|
11
|
+
* const ozura = new Ozura({
|
|
12
|
+
* merchantId: process.env.MERCHANT_ID!,
|
|
13
|
+
* apiKey: process.env.MERCHANT_API_KEY!,
|
|
14
|
+
* vaultKey: process.env.VAULT_API_KEY!,
|
|
15
|
+
* });
|
|
16
|
+
*
|
|
17
|
+
* const result = await ozura.cardSale({
|
|
18
|
+
* token: tokenResponse.token,
|
|
19
|
+
* cvcSession: tokenResponse.cvcSession,
|
|
20
|
+
* amount: '49.00',
|
|
21
|
+
* currency: 'USD',
|
|
22
|
+
* billing: tokenResponse.billing,
|
|
23
|
+
* clientIpAddress: req.ip,
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* console.log(result.transactionId);
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
// ─── Configuration ───────────────────────────────────────────────────────────
|
|
30
|
+
const DEFAULT_API_URL = "https://ozurapay-pay-api-v2-staging-c8abbdfhfbd3c5em.eastus-01.azurewebsites.net";
|
|
31
|
+
const DEFAULT_TIMEOUT = 30000;
|
|
32
|
+
// ─── Error ───────────────────────────────────────────────────────────────────
|
|
33
|
+
class OzuraError extends Error {
|
|
34
|
+
constructor(message, statusCode, raw, retryAfter) {
|
|
35
|
+
super(message);
|
|
36
|
+
this.name = 'OzuraError';
|
|
37
|
+
this.statusCode = statusCode;
|
|
38
|
+
this.raw = raw !== null && raw !== void 0 ? raw : message;
|
|
39
|
+
this.retryAfter = retryAfter;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// ─── Retry helper ─────────────────────────────────────────────────────────────
|
|
43
|
+
const DEFAULT_RETRIES = 2;
|
|
44
|
+
function isRetryable(status) {
|
|
45
|
+
return status >= 500 && status < 600;
|
|
46
|
+
}
|
|
47
|
+
async function sleep(ms) {
|
|
48
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
49
|
+
}
|
|
50
|
+
// ─── Main class ──────────────────────────────────────────────────────────────
|
|
51
|
+
class Ozura {
|
|
52
|
+
constructor(config) {
|
|
53
|
+
var _a, _b;
|
|
54
|
+
if (!config.merchantId)
|
|
55
|
+
throw new OzuraError('merchantId is required', 0);
|
|
56
|
+
if (!config.apiKey)
|
|
57
|
+
throw new OzuraError('apiKey is required', 0);
|
|
58
|
+
if (!config.vaultKey)
|
|
59
|
+
throw new OzuraError('vaultKey is required', 0);
|
|
60
|
+
this.merchantId = config.merchantId;
|
|
61
|
+
this.apiKey = config.apiKey;
|
|
62
|
+
this.vaultKey = config.vaultKey;
|
|
63
|
+
this.apiUrl = config.apiUrl || DEFAULT_API_URL;
|
|
64
|
+
this.timeoutMs = (_a = config.timeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_TIMEOUT;
|
|
65
|
+
this.retries = (_b = config.retries) !== null && _b !== void 0 ? _b : DEFAULT_RETRIES;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Charge a tokenized card. Maps the friendly `CardSaleInput` shape to the
|
|
69
|
+
* Pay API's flat field format and handles headers, defaults, and errors.
|
|
70
|
+
*
|
|
71
|
+
* Rate limit: 100 requests/minute per merchant.
|
|
72
|
+
*/
|
|
73
|
+
async cardSale(input) {
|
|
74
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
75
|
+
const billing = input.billing;
|
|
76
|
+
const body = {
|
|
77
|
+
merchantId: this.merchantId,
|
|
78
|
+
amount: input.amount,
|
|
79
|
+
currency: input.currency || 'USD',
|
|
80
|
+
ozuraCardToken: input.token,
|
|
81
|
+
ozuraCvcSession: input.cvcSession,
|
|
82
|
+
billingFirstName: billing.firstName,
|
|
83
|
+
billingLastName: billing.lastName,
|
|
84
|
+
billingEmail: billing.email || '',
|
|
85
|
+
billingPhone: billing.phone || '',
|
|
86
|
+
billingAddress1: ((_a = billing.address) === null || _a === void 0 ? void 0 : _a.line1) || '',
|
|
87
|
+
billingCity: ((_b = billing.address) === null || _b === void 0 ? void 0 : _b.city) || '',
|
|
88
|
+
billingState: ((_c = billing.address) === null || _c === void 0 ? void 0 : _c.state) || '',
|
|
89
|
+
billingZipcode: ((_d = billing.address) === null || _d === void 0 ? void 0 : _d.zip) || '',
|
|
90
|
+
billingCountry: ((_e = billing.address) === null || _e === void 0 ? void 0 : _e.country) || 'US',
|
|
91
|
+
clientIpAddress: input.clientIpAddress,
|
|
92
|
+
salesTaxExempt: (_f = input.salesTaxExempt) !== null && _f !== void 0 ? _f : false,
|
|
93
|
+
surchargePercent: (_g = input.surchargePercent) !== null && _g !== void 0 ? _g : '0.00',
|
|
94
|
+
tipAmount: (_h = input.tipAmount) !== null && _h !== void 0 ? _h : '0.00',
|
|
95
|
+
};
|
|
96
|
+
if ((_j = billing.address) === null || _j === void 0 ? void 0 : _j.line2) {
|
|
97
|
+
body.billingAddress2 = billing.address.line2;
|
|
98
|
+
}
|
|
99
|
+
if (input.processor) {
|
|
100
|
+
body.processor = input.processor;
|
|
101
|
+
}
|
|
102
|
+
return this.post('/api/v1/cardSale', body, true);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Retrieve a single transaction by ID.
|
|
106
|
+
*
|
|
107
|
+
* **Known issue:** The Pay API requires the API key as a query parameter
|
|
108
|
+
* (`access_token`), which means it can appear in server logs, CDN caches,
|
|
109
|
+
* and HTTP Referer headers. This is a Pay API design issue — the SDK will
|
|
110
|
+
* switch to header-based auth once the backend supports it.
|
|
111
|
+
*
|
|
112
|
+
* Rate limit: 100 requests/minute per merchant.
|
|
113
|
+
*/
|
|
114
|
+
async getTransaction(transactionId) {
|
|
115
|
+
const qs = new URLSearchParams({ access_token: this.apiKey });
|
|
116
|
+
return this.get(`/api/v1/transactions/${encodeURIComponent(transactionId)}?${qs}`);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* List transactions by date range with pagination.
|
|
120
|
+
*
|
|
121
|
+
* Rate limit: 200 requests/minute per merchant.
|
|
122
|
+
*/
|
|
123
|
+
async listTransactions(input = {}) {
|
|
124
|
+
const params = { merchantId: this.merchantId };
|
|
125
|
+
if (input.dateFrom)
|
|
126
|
+
params.dateFrom = input.dateFrom;
|
|
127
|
+
if (input.dateTo)
|
|
128
|
+
params.dateTo = input.dateTo;
|
|
129
|
+
if (input.transactionType)
|
|
130
|
+
params.transactionType = input.transactionType;
|
|
131
|
+
if (input.page)
|
|
132
|
+
params.page = String(input.page);
|
|
133
|
+
if (input.limit)
|
|
134
|
+
params.limit = String(input.limit);
|
|
135
|
+
if (input.fields)
|
|
136
|
+
params.fields = input.fields;
|
|
137
|
+
if (input.sortBy)
|
|
138
|
+
params.sortBy = input.sortBy;
|
|
139
|
+
if (input.sortOrder)
|
|
140
|
+
params.sortOrder = input.sortOrder;
|
|
141
|
+
const qs = new URLSearchParams(params);
|
|
142
|
+
const raw = await this.getRaw(`/api/v1/transQuery?${qs}`);
|
|
143
|
+
return { transactions: raw.data, pagination: raw.pagination };
|
|
144
|
+
}
|
|
145
|
+
// ─── HTTP helpers ────────────────────────────────────────────────────────
|
|
146
|
+
/**
|
|
147
|
+
* Execute a fetch with retry on 5xx / network errors.
|
|
148
|
+
* 4xx errors (including 429) are never retried — they require caller action.
|
|
149
|
+
*/
|
|
150
|
+
async fetchWithRetry(url, init) {
|
|
151
|
+
let lastError;
|
|
152
|
+
for (let attempt = 0; attempt <= this.retries; attempt++) {
|
|
153
|
+
try {
|
|
154
|
+
const res = await fetch(url, Object.assign(Object.assign({}, init), { signal: AbortSignal.timeout(this.timeoutMs) }));
|
|
155
|
+
if (isRetryable(res.status) && attempt < this.retries) {
|
|
156
|
+
// Consume/cancel body so the connection is released (undici holds socket until body is drained)
|
|
157
|
+
if (res.body) {
|
|
158
|
+
try {
|
|
159
|
+
await res.body.cancel();
|
|
160
|
+
}
|
|
161
|
+
catch (_a) {
|
|
162
|
+
/* ignore */
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const backoff = Math.min(1000 * 2 ** attempt, 8000);
|
|
166
|
+
await sleep(backoff);
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
return res;
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
lastError = err;
|
|
173
|
+
if (attempt < this.retries) {
|
|
174
|
+
const backoff = Math.min(1000 * 2 ** attempt, 8000);
|
|
175
|
+
await sleep(backoff);
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// All attempts exhausted — wrap the raw error in OzuraError
|
|
181
|
+
if (lastError instanceof Error) {
|
|
182
|
+
if (lastError.name === 'TimeoutError' || lastError.name === 'AbortError') {
|
|
183
|
+
throw new OzuraError(`Request timed out after ${this.timeoutMs}ms`, 0, lastError.message);
|
|
184
|
+
}
|
|
185
|
+
throw new OzuraError(`Network error: ${lastError.message}`, 0, lastError.message);
|
|
186
|
+
}
|
|
187
|
+
throw new OzuraError('Network error', 0);
|
|
188
|
+
}
|
|
189
|
+
async post(path, body, includeVaultKey) {
|
|
190
|
+
const headers = {
|
|
191
|
+
'Content-Type': 'application/json',
|
|
192
|
+
'x-api-key': this.apiKey,
|
|
193
|
+
};
|
|
194
|
+
if (includeVaultKey) {
|
|
195
|
+
headers['vault-api-key'] = this.vaultKey;
|
|
196
|
+
}
|
|
197
|
+
const res = await this.fetchWithRetry(`${this.apiUrl}${path}`, {
|
|
198
|
+
method: 'POST',
|
|
199
|
+
headers,
|
|
200
|
+
body: JSON.stringify(body),
|
|
201
|
+
});
|
|
202
|
+
return this.handleResponse(res);
|
|
203
|
+
}
|
|
204
|
+
async get(path) {
|
|
205
|
+
const res = await this.fetchWithRetry(`${this.apiUrl}${path}`, {
|
|
206
|
+
method: 'GET',
|
|
207
|
+
headers: { 'x-api-key': this.apiKey },
|
|
208
|
+
});
|
|
209
|
+
return this.handleResponse(res);
|
|
210
|
+
}
|
|
211
|
+
async getRaw(path) {
|
|
212
|
+
const res = await this.fetchWithRetry(`${this.apiUrl}${path}`, {
|
|
213
|
+
method: 'GET',
|
|
214
|
+
headers: { 'x-api-key': this.apiKey },
|
|
215
|
+
});
|
|
216
|
+
const json = await res.json().catch(() => ({ error: res.statusText }));
|
|
217
|
+
if (!res.ok) {
|
|
218
|
+
const retryAfter = res.status === 429
|
|
219
|
+
? Number(res.headers.get('retry-after') || json.retryAfter) || undefined
|
|
220
|
+
: undefined;
|
|
221
|
+
throw new OzuraError(json.error || `HTTP ${res.status}`, res.status, json.error, retryAfter);
|
|
222
|
+
}
|
|
223
|
+
if (json.success === false) {
|
|
224
|
+
throw new OzuraError(json.error || 'Request was not successful', res.status, json.error);
|
|
225
|
+
}
|
|
226
|
+
return json;
|
|
227
|
+
}
|
|
228
|
+
async handleResponse(res) {
|
|
229
|
+
var _a;
|
|
230
|
+
const json = await res.json().catch(() => ({ error: res.statusText }));
|
|
231
|
+
if (!res.ok) {
|
|
232
|
+
const retryAfter = res.status === 429
|
|
233
|
+
? Number(res.headers.get('retry-after') || json.retryAfter) || undefined
|
|
234
|
+
: undefined;
|
|
235
|
+
throw new OzuraError(json.error || `HTTP ${res.status}`, res.status, json.error, retryAfter);
|
|
236
|
+
}
|
|
237
|
+
if (json.success === false) {
|
|
238
|
+
throw new OzuraError(json.error || 'Request was not successful', res.status, json.error);
|
|
239
|
+
}
|
|
240
|
+
return ((_a = json.data) !== null && _a !== void 0 ? _a : json);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
// ─── Utilities ────────────────────────────────────────────────────────────────
|
|
244
|
+
/**
|
|
245
|
+
* Extract the client IP address from a server request object.
|
|
246
|
+
* Works with Express (`req.ip`), Fastify (`request.ip`), Next.js App Router
|
|
247
|
+
* (`req.headers.get('x-forwarded-for')`), and raw Node.js `IncomingMessage`.
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* // Express / Fastify
|
|
251
|
+
* clientIpAddress: getClientIp(req)
|
|
252
|
+
*
|
|
253
|
+
* // Next.js App Router
|
|
254
|
+
* clientIpAddress: getClientIp(req)
|
|
255
|
+
*/
|
|
256
|
+
function getClientIp(req) {
|
|
257
|
+
// Express / Fastify: req.ip
|
|
258
|
+
if (typeof req.ip === 'string' && req.ip)
|
|
259
|
+
return req.ip;
|
|
260
|
+
// Next.js App Router: req.headers.get('x-forwarded-for')
|
|
261
|
+
const headers = req.headers;
|
|
262
|
+
if (headers && typeof headers.get === 'function') {
|
|
263
|
+
const xff = headers.get('x-forwarded-for');
|
|
264
|
+
if (xff)
|
|
265
|
+
return xff.split(',')[0].trim();
|
|
266
|
+
const realIp = headers.get('x-real-ip');
|
|
267
|
+
if (realIp)
|
|
268
|
+
return realIp;
|
|
269
|
+
}
|
|
270
|
+
// Node.js IncomingMessage: req.headers['x-forwarded-for']
|
|
271
|
+
if (headers && typeof headers === 'object') {
|
|
272
|
+
const h = headers;
|
|
273
|
+
const xff = h['x-forwarded-for'];
|
|
274
|
+
if (typeof xff === 'string' && xff)
|
|
275
|
+
return xff.split(',')[0].trim();
|
|
276
|
+
if (Array.isArray(xff) && xff[0])
|
|
277
|
+
return xff[0].split(',')[0].trim();
|
|
278
|
+
const realIp = h['x-real-ip'];
|
|
279
|
+
if (typeof realIp === 'string' && realIp)
|
|
280
|
+
return realIp;
|
|
281
|
+
}
|
|
282
|
+
// Raw Node.js socket
|
|
283
|
+
const socket = req.socket;
|
|
284
|
+
if (socket === null || socket === void 0 ? void 0 : socket.remoteAddress)
|
|
285
|
+
return socket.remoteAddress;
|
|
286
|
+
return '0.0.0.0';
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
export { Ozura, OzuraError, getClientIp };
|
|
290
|
+
//# sourceMappingURL=index.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../../src/server/index.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|