@nile-squad/nylonpay-ts 1.0.4 → 1.0.6
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 +284 -76
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +62 -13
- package/dist/index.d.ts +62 -13
- package/dist/index.js +285 -78
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -55,21 +55,6 @@ function createEmitter() {
|
|
|
55
55
|
const emitter = { on, once, off, emit, clear, listenerCount };
|
|
56
56
|
return emitter;
|
|
57
57
|
}
|
|
58
|
-
function generateFingerprint() {
|
|
59
|
-
const components = [
|
|
60
|
-
`type:${os.type()}`,
|
|
61
|
-
`platform:${os.platform()}`,
|
|
62
|
-
`arch:${os.arch()}`,
|
|
63
|
-
`release:${os.release()}`,
|
|
64
|
-
`hostname:${os.hostname()}`,
|
|
65
|
-
`node:${process.versions.node}`,
|
|
66
|
-
`v8:${process.versions.v8}`
|
|
67
|
-
].join("|");
|
|
68
|
-
return crypto.createHash("sha256").update(components).digest("hex");
|
|
69
|
-
}
|
|
70
|
-
function generateNonce(length = 16) {
|
|
71
|
-
return crypto.randomBytes(length).toString("hex");
|
|
72
|
-
}
|
|
73
58
|
|
|
74
59
|
// src/sdk.config.ts
|
|
75
60
|
var DEFAULT_BASE_URL = "https://api.nylonpay.nilesquad.com/api/services";
|
|
@@ -78,6 +63,9 @@ var DEFAULT_MAX_RETRIES = 3;
|
|
|
78
63
|
var DEFAULT_MAX_POLL_INTERVAL_MS = 2e3;
|
|
79
64
|
var DEFAULT_MAX_POLL_DURATION_MS = 3e5;
|
|
80
65
|
var DEFAULT_MAX_POLL_ATTEMPTS = 150;
|
|
66
|
+
var DEFAULT_STREAMING = true;
|
|
67
|
+
var STREAM_PATH = "/sse/transaction";
|
|
68
|
+
var MAX_STREAM_RECONNECTS = 2;
|
|
81
69
|
var SDK_SERVICE = "sdk";
|
|
82
70
|
var SDK_ACTIONS = {
|
|
83
71
|
collectPayment: "sdk-collect-payment",
|
|
@@ -90,6 +78,21 @@ var SDK_ACTIONS = {
|
|
|
90
78
|
createInvoice: "sdk-create-invoice"
|
|
91
79
|
};
|
|
92
80
|
var RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([408, 429, 500, 502, 503, 504]);
|
|
81
|
+
function generateFingerprint() {
|
|
82
|
+
const components = [
|
|
83
|
+
`type:${os.type()}`,
|
|
84
|
+
`platform:${os.platform()}`,
|
|
85
|
+
`arch:${os.arch()}`,
|
|
86
|
+
`release:${os.release()}`,
|
|
87
|
+
`hostname:${os.hostname()}`,
|
|
88
|
+
`node:${process.versions.node}`,
|
|
89
|
+
`v8:${process.versions.v8}`
|
|
90
|
+
].join("|");
|
|
91
|
+
return crypto.createHash("sha256").update(components).digest("hex");
|
|
92
|
+
}
|
|
93
|
+
function generateNonce(length = 16) {
|
|
94
|
+
return crypto.randomBytes(length).toString("hex");
|
|
95
|
+
}
|
|
93
96
|
function sortValue(value) {
|
|
94
97
|
if (Array.isArray(value)) {
|
|
95
98
|
return value.map((entry) => sortValue(entry));
|
|
@@ -120,6 +123,42 @@ function createSignature(input) {
|
|
|
120
123
|
function createTimestamp() {
|
|
121
124
|
return Date.now().toString();
|
|
122
125
|
}
|
|
126
|
+
|
|
127
|
+
// src/sse-parse.ts
|
|
128
|
+
function parseBlock(block) {
|
|
129
|
+
let event = "message";
|
|
130
|
+
const dataLines = [];
|
|
131
|
+
for (const rawLine of block.split("\n")) {
|
|
132
|
+
const line = rawLine.replace(/\r$/, "");
|
|
133
|
+
if (line.startsWith(":")) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
if (line.startsWith("event:")) {
|
|
137
|
+
event = line.slice("event:".length).trim();
|
|
138
|
+
} else if (line.startsWith("data:")) {
|
|
139
|
+
dataLines.push(line.slice("data:".length).trim());
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (dataLines.length === 0) {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
return { event, data: dataLines.join("\n") };
|
|
146
|
+
}
|
|
147
|
+
function parseSseBuffer(buffer) {
|
|
148
|
+
const messages = [];
|
|
149
|
+
let rest = buffer;
|
|
150
|
+
let separator = rest.indexOf("\n\n");
|
|
151
|
+
while (separator !== -1) {
|
|
152
|
+
const block = rest.slice(0, separator);
|
|
153
|
+
rest = rest.slice(separator + 2);
|
|
154
|
+
const message = parseBlock(block);
|
|
155
|
+
if (message) {
|
|
156
|
+
messages.push(message);
|
|
157
|
+
}
|
|
158
|
+
separator = rest.indexOf("\n\n");
|
|
159
|
+
}
|
|
160
|
+
return { messages, rest };
|
|
161
|
+
}
|
|
123
162
|
function verifyResponseSignature(data, signature, secret) {
|
|
124
163
|
const expectedSignature = crypto.createHmac("sha256", secret).update(createCanonicalPayload(data)).digest("hex");
|
|
125
164
|
const providedBuffer = Buffer.from(signature, "hex");
|
|
@@ -132,6 +171,55 @@ function verifyResponseSignature(data, signature, secret) {
|
|
|
132
171
|
|
|
133
172
|
// src/transport.ts
|
|
134
173
|
var CACHED_FINGERPRINT = generateFingerprint();
|
|
174
|
+
function streamUrl(baseUrl) {
|
|
175
|
+
try {
|
|
176
|
+
return new URL(baseUrl).origin + STREAM_PATH;
|
|
177
|
+
} catch {
|
|
178
|
+
return baseUrl.replace(/\/api\/services\/?$/u, "") + STREAM_PATH;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
var KNOWN_CATEGORIES = /* @__PURE__ */ new Set([
|
|
182
|
+
"auth",
|
|
183
|
+
"validation",
|
|
184
|
+
"limit",
|
|
185
|
+
"rate_limit",
|
|
186
|
+
"account",
|
|
187
|
+
"provider",
|
|
188
|
+
"not_found",
|
|
189
|
+
"internal",
|
|
190
|
+
"network",
|
|
191
|
+
"timeout"
|
|
192
|
+
]);
|
|
193
|
+
var STATUS_CATEGORY = {
|
|
194
|
+
408: "timeout",
|
|
195
|
+
429: "rate_limit"
|
|
196
|
+
};
|
|
197
|
+
var ERROR_TYPE_SUFFIX = /^(.*?)\s*--\s*error-type:\s*([a-z_]+)\s*$/is;
|
|
198
|
+
function parseCategoryFromMessage(message) {
|
|
199
|
+
const match = ERROR_TYPE_SUFFIX.exec(message);
|
|
200
|
+
if (match?.[2] && KNOWN_CATEGORIES.has(match[2])) {
|
|
201
|
+
return {
|
|
202
|
+
category: match[2],
|
|
203
|
+
message: match[1] ?? message
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
return { category: null, message };
|
|
207
|
+
}
|
|
208
|
+
function buildHttpError(params) {
|
|
209
|
+
const parsed = parseCategoryFromMessage(params.message);
|
|
210
|
+
const category = parsed.category ?? STATUS_CATEGORY[params.statusCode] ?? (params.statusCode >= 500 ? "internal" : "validation");
|
|
211
|
+
return {
|
|
212
|
+
category,
|
|
213
|
+
message: parsed.message,
|
|
214
|
+
retryable: RETRYABLE_STATUS_CODES.has(params.statusCode)
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
function createSdkError(error) {
|
|
218
|
+
return Object.assign(new Error(error.message), {
|
|
219
|
+
category: error.category,
|
|
220
|
+
retryable: error.retryable
|
|
221
|
+
});
|
|
222
|
+
}
|
|
135
223
|
function calculateBackoff(attempt) {
|
|
136
224
|
const base = 2 ** attempt * 1e3;
|
|
137
225
|
const jitter = Math.random() * 500;
|
|
@@ -234,21 +322,19 @@ function createTransport({
|
|
|
234
322
|
await delay(calculateBackoff(currentAttempt));
|
|
235
323
|
return attempt(currentAttempt + 1);
|
|
236
324
|
}
|
|
237
|
-
const sdkError = {
|
|
238
|
-
code: `HTTP_${statusCode}`,
|
|
239
|
-
message: errorMessage,
|
|
240
|
-
statusCode,
|
|
241
|
-
retryable
|
|
242
|
-
};
|
|
243
325
|
cleanup();
|
|
244
|
-
return slangTs.Err(
|
|
326
|
+
return slangTs.Err(
|
|
327
|
+
JSON.stringify(
|
|
328
|
+
buildHttpError({ message: errorMessage, statusCode })
|
|
329
|
+
)
|
|
330
|
+
);
|
|
245
331
|
}
|
|
246
332
|
const responseBody = await response.json();
|
|
247
333
|
if (!responseBody || typeof responseBody !== "object" || !("status" in responseBody)) {
|
|
248
334
|
cleanup();
|
|
249
335
|
return slangTs.Err(
|
|
250
336
|
JSON.stringify({
|
|
251
|
-
|
|
337
|
+
category: "internal",
|
|
252
338
|
message: "Response missing status field",
|
|
253
339
|
retryable: false
|
|
254
340
|
})
|
|
@@ -267,7 +353,7 @@ function createTransport({
|
|
|
267
353
|
cleanup();
|
|
268
354
|
return slangTs.Err(
|
|
269
355
|
JSON.stringify({
|
|
270
|
-
|
|
356
|
+
category: "internal",
|
|
271
357
|
message: "Response signature verification failed",
|
|
272
358
|
retryable: false
|
|
273
359
|
})
|
|
@@ -284,7 +370,7 @@ function createTransport({
|
|
|
284
370
|
cleanup();
|
|
285
371
|
const isAbort = error instanceof DOMException && error.name === "AbortError";
|
|
286
372
|
const sdkError = {
|
|
287
|
-
|
|
373
|
+
category: isAbort ? "timeout" : "network",
|
|
288
374
|
message: isAbort ? `Request timed out after ${timeoutMs}ms` : String(error),
|
|
289
375
|
retryable: true
|
|
290
376
|
};
|
|
@@ -297,17 +383,105 @@ function createTransport({
|
|
|
297
383
|
}
|
|
298
384
|
return attempt(0);
|
|
299
385
|
}
|
|
300
|
-
|
|
386
|
+
function openStream(input) {
|
|
387
|
+
const controller = new AbortController();
|
|
388
|
+
let closed = false;
|
|
389
|
+
const close = () => {
|
|
390
|
+
if (closed) {
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
closed = true;
|
|
394
|
+
controller.abort();
|
|
395
|
+
};
|
|
396
|
+
const payload = {
|
|
397
|
+
reference: input.reference,
|
|
398
|
+
_fingerprint: CACHED_FINGERPRINT
|
|
399
|
+
};
|
|
400
|
+
const headers = buildAuthHeaders({ apiKey, apiSecret, payload });
|
|
401
|
+
const url = streamUrl(baseUrl);
|
|
402
|
+
const run = async () => {
|
|
403
|
+
const fetchResult = await slangTs.safeTry(
|
|
404
|
+
() => fetchImpl(url, {
|
|
405
|
+
method: "POST",
|
|
406
|
+
headers,
|
|
407
|
+
body: JSON.stringify(payload),
|
|
408
|
+
signal: controller.signal
|
|
409
|
+
})
|
|
410
|
+
);
|
|
411
|
+
if (fetchResult.isErr) {
|
|
412
|
+
if (!closed) {
|
|
413
|
+
input.onError(fetchResult.error);
|
|
414
|
+
}
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
const response = fetchResult.value;
|
|
418
|
+
if (!response.ok || !response.body) {
|
|
419
|
+
const textResult = await slangTs.safeTry(() => response.text());
|
|
420
|
+
const message = textResult.isOk ? textResult.value : `HTTP ${response.status}`;
|
|
421
|
+
if (!closed) {
|
|
422
|
+
input.onError(message || `HTTP ${response.status}`);
|
|
423
|
+
}
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
const reader = response.body.getReader();
|
|
427
|
+
const decoder = new TextDecoder();
|
|
428
|
+
let buffer = "";
|
|
429
|
+
while (!closed) {
|
|
430
|
+
const chunkResult = await slangTs.safeTry(() => reader.read());
|
|
431
|
+
if (chunkResult.isErr) {
|
|
432
|
+
if (!closed) {
|
|
433
|
+
input.onError(chunkResult.error);
|
|
434
|
+
}
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
const chunk = chunkResult.value;
|
|
438
|
+
if (chunk.done) {
|
|
439
|
+
break;
|
|
440
|
+
}
|
|
441
|
+
buffer += decoder.decode(chunk.value, { stream: true });
|
|
442
|
+
const { messages, rest } = parseSseBuffer(buffer);
|
|
443
|
+
buffer = rest;
|
|
444
|
+
for (const message of messages) {
|
|
445
|
+
if (message.event === "status") {
|
|
446
|
+
const statusResult = await slangTs.safeTry(
|
|
447
|
+
() => JSON.parse(message.data)
|
|
448
|
+
);
|
|
449
|
+
if (statusResult.isOk) {
|
|
450
|
+
input.onStatus(statusResult.value);
|
|
451
|
+
}
|
|
452
|
+
} else if (message.event === "error") {
|
|
453
|
+
const errDataResult = await slangTs.safeTry(
|
|
454
|
+
() => JSON.parse(message.data)
|
|
455
|
+
);
|
|
456
|
+
const text = errDataResult.isOk ? errDataResult.value.message ?? message.data : message.data;
|
|
457
|
+
close();
|
|
458
|
+
input.onError(text);
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
if (!closed) {
|
|
464
|
+
input.onClose();
|
|
465
|
+
}
|
|
466
|
+
};
|
|
467
|
+
void run();
|
|
468
|
+
return { close };
|
|
469
|
+
}
|
|
470
|
+
return { send, openStream, parseError };
|
|
301
471
|
}
|
|
302
472
|
function parseError(error) {
|
|
303
473
|
try {
|
|
304
474
|
const parsed = JSON.parse(error);
|
|
305
|
-
if (parsed && typeof parsed === "object" && "
|
|
475
|
+
if (parsed && typeof parsed === "object" && "category" in parsed && "message" in parsed && typeof parsed.category === "string" && typeof parsed.message === "string") {
|
|
306
476
|
return parsed;
|
|
307
477
|
}
|
|
308
478
|
} catch {
|
|
309
479
|
}
|
|
310
|
-
|
|
480
|
+
const fromSuffix = parseCategoryFromMessage(error);
|
|
481
|
+
return {
|
|
482
|
+
category: fromSuffix.category ?? "internal",
|
|
483
|
+
message: fromSuffix.message
|
|
484
|
+
};
|
|
311
485
|
}
|
|
312
486
|
|
|
313
487
|
// src/payment.ts
|
|
@@ -343,11 +517,15 @@ function createPaymentInstance(initialResponse, deps) {
|
|
|
343
517
|
fetchTransaction: deps.fetchTransaction,
|
|
344
518
|
pollIntervalMs: deps.pollIntervalMs ?? 2e3,
|
|
345
519
|
maxPollDuration: deps.maxPollDuration ?? 3e5,
|
|
346
|
-
maxPollAttempts: deps.maxPollAttempts ?? 150
|
|
520
|
+
maxPollAttempts: deps.maxPollAttempts ?? 150,
|
|
521
|
+
streaming: deps.streaming ?? false,
|
|
522
|
+
openStream: deps.openStream,
|
|
523
|
+
streamHandle: null,
|
|
524
|
+
streamReconnects: 0
|
|
347
525
|
};
|
|
348
526
|
function resolveWithError(error) {
|
|
349
527
|
state.resolved = true;
|
|
350
|
-
|
|
528
|
+
stopUpdates();
|
|
351
529
|
emitEvent("error", parseError(error).message);
|
|
352
530
|
}
|
|
353
531
|
function emitEvent(event, error) {
|
|
@@ -374,7 +552,7 @@ function createPaymentInstance(initialResponse, deps) {
|
|
|
374
552
|
emitEvent("error", `Failed to fetch transaction: ${txResult.error}`);
|
|
375
553
|
}
|
|
376
554
|
state.resolved = true;
|
|
377
|
-
|
|
555
|
+
stopUpdates();
|
|
378
556
|
}
|
|
379
557
|
async function handleStatusUpdate(response) {
|
|
380
558
|
if (response.reference !== state.reference) {
|
|
@@ -398,13 +576,13 @@ function createPaymentInstance(initialResponse, deps) {
|
|
|
398
576
|
}
|
|
399
577
|
}
|
|
400
578
|
function handlePollError(error) {
|
|
401
|
-
const
|
|
402
|
-
if (
|
|
579
|
+
const parsed = parseError(error);
|
|
580
|
+
if (parsed.category === "not_found") {
|
|
403
581
|
return;
|
|
404
582
|
}
|
|
405
|
-
emitEvent("error",
|
|
583
|
+
emitEvent("error", parsed.message);
|
|
406
584
|
state.resolved = true;
|
|
407
|
-
|
|
585
|
+
stopUpdates();
|
|
408
586
|
}
|
|
409
587
|
function scheduleNextPoll() {
|
|
410
588
|
if (state.resolved || state.pollingTimer) {
|
|
@@ -417,7 +595,7 @@ function createPaymentInstance(initialResponse, deps) {
|
|
|
417
595
|
}
|
|
418
596
|
async function pollStatus() {
|
|
419
597
|
if (state.resolved) {
|
|
420
|
-
|
|
598
|
+
stopUpdates();
|
|
421
599
|
return;
|
|
422
600
|
}
|
|
423
601
|
if (state.pollAttempts >= state.maxPollAttempts) {
|
|
@@ -436,25 +614,66 @@ function createPaymentInstance(initialResponse, deps) {
|
|
|
436
614
|
handlePollError(result.error);
|
|
437
615
|
}
|
|
438
616
|
if (state.resolved) {
|
|
439
|
-
|
|
617
|
+
stopUpdates();
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
620
|
+
scheduleNextPoll();
|
|
621
|
+
}
|
|
622
|
+
function closeStream() {
|
|
623
|
+
if (state.streamHandle) {
|
|
624
|
+
state.streamHandle.close();
|
|
625
|
+
state.streamHandle = null;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
function startStream() {
|
|
629
|
+
if (state.resolved || !state.openStream) {
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
632
|
+
state.streamHandle = state.openStream({
|
|
633
|
+
reference: state.reference,
|
|
634
|
+
onStatus: (status) => {
|
|
635
|
+
void handleStatusUpdate(status);
|
|
636
|
+
},
|
|
637
|
+
onError: () => handleStreamFailure(),
|
|
638
|
+
onClose: () => handleStreamFailure()
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
function handleStreamFailure() {
|
|
642
|
+
closeStream();
|
|
643
|
+
if (state.resolved) {
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
646
|
+
if (state.streamReconnects < MAX_STREAM_RECONNECTS) {
|
|
647
|
+
state.streamReconnects += 1;
|
|
648
|
+
const backoff = 500 * 2 ** (state.streamReconnects - 1) + Math.random() * 250;
|
|
649
|
+
setTimeout(() => {
|
|
650
|
+
if (!state.resolved) {
|
|
651
|
+
startStream();
|
|
652
|
+
}
|
|
653
|
+
}, backoff);
|
|
440
654
|
return;
|
|
441
655
|
}
|
|
442
656
|
scheduleNextPoll();
|
|
443
657
|
}
|
|
444
|
-
function
|
|
445
|
-
if (TERMINAL_STATES.has(state.status
|
|
658
|
+
function startUpdates() {
|
|
659
|
+
if (TERMINAL_STATES.has(state.status)) {
|
|
446
660
|
setTimeout(() => {
|
|
447
661
|
void handleTerminalState(state.status);
|
|
448
662
|
}, 0);
|
|
449
663
|
return;
|
|
450
664
|
}
|
|
665
|
+
if (state.streaming && state.openStream) {
|
|
666
|
+
startStream();
|
|
667
|
+
return;
|
|
668
|
+
}
|
|
451
669
|
scheduleNextPoll();
|
|
452
670
|
}
|
|
453
|
-
function
|
|
671
|
+
function stopUpdates() {
|
|
454
672
|
if (state.pollingTimer) {
|
|
455
673
|
clearTimeout(state.pollingTimer);
|
|
456
674
|
state.pollingTimer = null;
|
|
457
675
|
}
|
|
676
|
+
closeStream();
|
|
458
677
|
}
|
|
459
678
|
function on(event, handler) {
|
|
460
679
|
state.emitter.on(event, handler);
|
|
@@ -516,7 +735,7 @@ function createPaymentInstance(initialResponse, deps) {
|
|
|
516
735
|
off,
|
|
517
736
|
wait
|
|
518
737
|
};
|
|
519
|
-
|
|
738
|
+
startUpdates();
|
|
520
739
|
return paymentInstance;
|
|
521
740
|
}
|
|
522
741
|
function verifyWebhookSignature(input) {
|
|
@@ -534,14 +753,17 @@ function verifyWebhookSignature(input) {
|
|
|
534
753
|
function generateReference() {
|
|
535
754
|
return crypto.randomBytes(16).toString("hex").slice(0, 15);
|
|
536
755
|
}
|
|
756
|
+
function throwValidation(message) {
|
|
757
|
+
throw createSdkError({ category: "validation", message });
|
|
758
|
+
}
|
|
537
759
|
function validateAmount(amount) {
|
|
538
760
|
if (!Number.isInteger(amount) || amount <= 0) {
|
|
539
|
-
|
|
761
|
+
throwValidation("amount must be a positive integer");
|
|
540
762
|
}
|
|
541
763
|
}
|
|
542
764
|
function validateNonEmpty(value, fieldName) {
|
|
543
765
|
if (!value || value.trim() === "") {
|
|
544
|
-
|
|
766
|
+
throwValidation(`${fieldName} is required`);
|
|
545
767
|
}
|
|
546
768
|
}
|
|
547
769
|
function createSdkInstance(config) {
|
|
@@ -564,7 +786,9 @@ function createSdkInstance(config) {
|
|
|
564
786
|
}),
|
|
565
787
|
pollIntervalMs: config.maxPollIntervalMs,
|
|
566
788
|
maxPollDuration: config.maxPollDurationMs,
|
|
567
|
-
maxPollAttempts: config.maxPollAttempts
|
|
789
|
+
maxPollAttempts: config.maxPollAttempts,
|
|
790
|
+
streaming: config.streaming,
|
|
791
|
+
openStream: config.streaming ? transport.openStream : void 0
|
|
568
792
|
};
|
|
569
793
|
async function collectPayment(input) {
|
|
570
794
|
const reference = input.reference ?? generateReference();
|
|
@@ -573,7 +797,7 @@ function createSdkInstance(config) {
|
|
|
573
797
|
validateNonEmpty(input.customer.phoneNumber, "customer.phoneNumber");
|
|
574
798
|
validateNonEmpty(input.description, "description");
|
|
575
799
|
if (input.method === "bank" && !input.bank) {
|
|
576
|
-
|
|
800
|
+
throwValidation('bank details are required when method is "bank"');
|
|
577
801
|
}
|
|
578
802
|
let payload = { ...input, reference };
|
|
579
803
|
if (config.hooks?.beforeCollect) {
|
|
@@ -594,19 +818,10 @@ function createSdkInstance(config) {
|
|
|
594
818
|
payload
|
|
595
819
|
);
|
|
596
820
|
}
|
|
597
|
-
if (result.
|
|
598
|
-
|
|
599
|
-
}
|
|
600
|
-
return createPaymentInstance(
|
|
601
|
-
{ reference, status: "pending" },
|
|
602
|
-
{
|
|
603
|
-
fetchStatus: async () => slangTs.Err(result.error),
|
|
604
|
-
fetchTransaction: async () => slangTs.Err(result.error),
|
|
605
|
-
pollIntervalMs: 0,
|
|
606
|
-
maxPollAttempts: 1,
|
|
607
|
-
maxPollDuration: Number.MAX_SAFE_INTEGER
|
|
608
|
-
}
|
|
609
|
-
);
|
|
821
|
+
if (result.isErr) {
|
|
822
|
+
throw createSdkError(parseError(result.error));
|
|
823
|
+
}
|
|
824
|
+
return createPaymentInstance(result.value, commonDeps);
|
|
610
825
|
}
|
|
611
826
|
async function collectPaymentAndResolve(input) {
|
|
612
827
|
const reference = input.reference ?? generateReference();
|
|
@@ -615,7 +830,7 @@ function createSdkInstance(config) {
|
|
|
615
830
|
validateNonEmpty(input.customer.phoneNumber, "customer.phoneNumber");
|
|
616
831
|
validateNonEmpty(input.description, "description");
|
|
617
832
|
if (input.method === "bank" && !input.bank) {
|
|
618
|
-
|
|
833
|
+
throwValidation('bank details are required when method is "bank"');
|
|
619
834
|
}
|
|
620
835
|
let payload = { ...input, reference };
|
|
621
836
|
if (config.hooks?.beforeCollect) {
|
|
@@ -674,19 +889,10 @@ function createSdkInstance(config) {
|
|
|
674
889
|
payload
|
|
675
890
|
);
|
|
676
891
|
}
|
|
677
|
-
if (result.
|
|
678
|
-
|
|
679
|
-
}
|
|
680
|
-
return createPaymentInstance(
|
|
681
|
-
{ reference, status: "pending" },
|
|
682
|
-
{
|
|
683
|
-
fetchStatus: async () => slangTs.Err(result.error),
|
|
684
|
-
fetchTransaction: async () => slangTs.Err(result.error),
|
|
685
|
-
pollIntervalMs: 0,
|
|
686
|
-
maxPollAttempts: 1,
|
|
687
|
-
maxPollDuration: Number.MAX_SAFE_INTEGER
|
|
688
|
-
}
|
|
689
|
-
);
|
|
892
|
+
if (result.isErr) {
|
|
893
|
+
throw createSdkError(parseError(result.error));
|
|
894
|
+
}
|
|
895
|
+
return createPaymentInstance(result.value, commonDeps);
|
|
690
896
|
}
|
|
691
897
|
async function makePayoutAndResolve(input) {
|
|
692
898
|
const reference = input.reference ?? generateReference();
|
|
@@ -739,7 +945,7 @@ function createSdkInstance(config) {
|
|
|
739
945
|
}
|
|
740
946
|
async function getTransaction(input) {
|
|
741
947
|
if (!input.id && !input.reference) {
|
|
742
|
-
|
|
948
|
+
throwValidation("id or reference is required");
|
|
743
949
|
}
|
|
744
950
|
const result = await transport.send({
|
|
745
951
|
action: SDK_ACTIONS.getTransaction,
|
|
@@ -767,14 +973,14 @@ function createSdkInstance(config) {
|
|
|
767
973
|
validateNonEmpty(input.description, "description");
|
|
768
974
|
if (input.items) {
|
|
769
975
|
if (input.items.length > 50) {
|
|
770
|
-
|
|
976
|
+
throwValidation("items must not exceed 50");
|
|
771
977
|
}
|
|
772
978
|
for (const item of input.items) {
|
|
773
979
|
if (!Number.isInteger(item.quantity) || item.quantity <= 0) {
|
|
774
|
-
|
|
980
|
+
throwValidation("item quantity must be a positive integer");
|
|
775
981
|
}
|
|
776
982
|
if (!Number.isInteger(item.unitPrice) || item.unitPrice <= 0) {
|
|
777
|
-
|
|
983
|
+
throwValidation("item unitPrice must be a positive integer");
|
|
778
984
|
}
|
|
779
985
|
}
|
|
780
986
|
}
|
|
@@ -834,6 +1040,7 @@ function createNylonPay(config) {
|
|
|
834
1040
|
maxPollIntervalMs: config.maxPollIntervalMs ?? DEFAULT_MAX_POLL_INTERVAL_MS,
|
|
835
1041
|
maxPollDurationMs: config.maxPollDurationMs ?? DEFAULT_MAX_POLL_DURATION_MS,
|
|
836
1042
|
maxPollAttempts: config.maxPollAttempts ?? DEFAULT_MAX_POLL_ATTEMPTS,
|
|
1043
|
+
streaming: config.streaming ?? DEFAULT_STREAMING,
|
|
837
1044
|
fetch: config.fetch ?? globalThis.fetch.bind(globalThis),
|
|
838
1045
|
hooks: config.hooks
|
|
839
1046
|
};
|
|
@@ -843,6 +1050,7 @@ function createNylonPay(config) {
|
|
|
843
1050
|
}
|
|
844
1051
|
|
|
845
1052
|
exports.createNylonPay = createNylonPay;
|
|
1053
|
+
exports.createSdkError = createSdkError;
|
|
846
1054
|
exports.parseError = parseError;
|
|
847
1055
|
exports.verifyWebhookSignature = verifyWebhookSignature;
|
|
848
1056
|
//# sourceMappingURL=index.cjs.map
|