@nile-squad/nylonpay-ts 1.0.9 → 1.1.0
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 +74 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -7
- package/dist/index.d.ts +31 -7
- package/dist/index.js +74 -21
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -147,6 +147,7 @@ var KNOWN_CATEGORIES = /* @__PURE__ */ new Set([
|
|
|
147
147
|
"rate_limit",
|
|
148
148
|
"account",
|
|
149
149
|
"provider",
|
|
150
|
+
"duplicate",
|
|
150
151
|
"not_found",
|
|
151
152
|
"internal",
|
|
152
153
|
"network",
|
|
@@ -372,6 +373,7 @@ function parseError(error) {
|
|
|
372
373
|
|
|
373
374
|
// src/payment.ts
|
|
374
375
|
var STATUS_TO_EVENT = {
|
|
376
|
+
pending: "processing",
|
|
375
377
|
successful: "success",
|
|
376
378
|
failed: "failed",
|
|
377
379
|
processing: "processing",
|
|
@@ -395,6 +397,7 @@ function createPaymentInstance(initialResponse, deps) {
|
|
|
395
397
|
status: normalizeStatus(initialResponse.status),
|
|
396
398
|
transaction: null,
|
|
397
399
|
pollingTimer: null,
|
|
400
|
+
lastStatusEvent: null,
|
|
398
401
|
resolved: false,
|
|
399
402
|
pollAttempts: 0,
|
|
400
403
|
pollStartTime: Date.now(),
|
|
@@ -413,6 +416,7 @@ function createPaymentInstance(initialResponse, deps) {
|
|
|
413
416
|
function emitEvent(event, error, category, retryable) {
|
|
414
417
|
const data = {
|
|
415
418
|
event,
|
|
419
|
+
reference: state.reference,
|
|
416
420
|
transaction: state.transaction ?? void 0,
|
|
417
421
|
error,
|
|
418
422
|
category,
|
|
@@ -449,18 +453,17 @@ function createPaymentInstance(initialResponse, deps) {
|
|
|
449
453
|
return;
|
|
450
454
|
}
|
|
451
455
|
const newStatus = normalizeStatus(response.status);
|
|
452
|
-
const oldStatus = state.status;
|
|
453
456
|
state.status = newStatus;
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
}
|
|
457
|
+
const event = statusToEvent(newStatus);
|
|
458
|
+
if (!event || event === state.lastStatusEvent) {
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
state.lastStatusEvent = event;
|
|
462
|
+
if (TERMINAL_STATES.has(newStatus)) {
|
|
463
|
+
await handleTerminalState(newStatus);
|
|
464
|
+
return;
|
|
463
465
|
}
|
|
466
|
+
emitEvent(event);
|
|
464
467
|
}
|
|
465
468
|
function handlePollError(error) {
|
|
466
469
|
const parsed = parseError(error);
|
|
@@ -514,6 +517,15 @@ function createPaymentInstance(initialResponse, deps) {
|
|
|
514
517
|
}, 0);
|
|
515
518
|
return;
|
|
516
519
|
}
|
|
520
|
+
const initialEvent = statusToEvent(state.status);
|
|
521
|
+
if (initialEvent) {
|
|
522
|
+
state.lastStatusEvent = initialEvent;
|
|
523
|
+
setTimeout(() => {
|
|
524
|
+
if (!state.resolved) {
|
|
525
|
+
emitEvent(initialEvent);
|
|
526
|
+
}
|
|
527
|
+
}, 0);
|
|
528
|
+
}
|
|
517
529
|
scheduleNextPoll();
|
|
518
530
|
}
|
|
519
531
|
function stopUpdates() {
|
|
@@ -593,6 +605,15 @@ function createPaymentInstance(initialResponse, deps) {
|
|
|
593
605
|
}
|
|
594
606
|
return paymentInstance;
|
|
595
607
|
}
|
|
608
|
+
|
|
609
|
+
// src/phone.ts
|
|
610
|
+
function normalizePhone(phone) {
|
|
611
|
+
let normalized = phone.replace(/\s+/g, "").replace(/^\+/, "");
|
|
612
|
+
if (normalized.startsWith("0") && normalized.length === 10) {
|
|
613
|
+
normalized = `256${normalized.slice(1)}`;
|
|
614
|
+
}
|
|
615
|
+
return normalized;
|
|
616
|
+
}
|
|
596
617
|
var DEFAULT_TOLERANCE_SECONDS = 300;
|
|
597
618
|
function decodePayload(payload) {
|
|
598
619
|
return typeof payload === "string" ? payload : Buffer.from(payload).toString("utf8");
|
|
@@ -668,10 +689,21 @@ async function runHook(hook, ...args) {
|
|
|
668
689
|
function throwValidation(message) {
|
|
669
690
|
throw createSdkError({ category: "validation", message });
|
|
670
691
|
}
|
|
671
|
-
function
|
|
692
|
+
function validateCollectionAmount(amount) {
|
|
693
|
+
if (!Number.isInteger(amount) || amount <= 0) {
|
|
694
|
+
throwValidation("amount must be a positive integer");
|
|
695
|
+
}
|
|
696
|
+
if (amount < 500) {
|
|
697
|
+
throwValidation("Collection amount must be at least 500 UGX");
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
function validatePayoutAmount(amount) {
|
|
672
701
|
if (!Number.isInteger(amount) || amount <= 0) {
|
|
673
702
|
throwValidation("amount must be a positive integer");
|
|
674
703
|
}
|
|
704
|
+
if (amount < 5e3) {
|
|
705
|
+
throwValidation("Payout amount must be at least 5000 UGX");
|
|
706
|
+
}
|
|
675
707
|
}
|
|
676
708
|
function validateNonEmpty(value, fieldName) {
|
|
677
709
|
if (!value || value.trim() === "") {
|
|
@@ -702,14 +734,19 @@ function createSdkInstance(config) {
|
|
|
702
734
|
};
|
|
703
735
|
async function collectPayment(input) {
|
|
704
736
|
const reference = resolveReference(input.reference);
|
|
705
|
-
|
|
737
|
+
validateCollectionAmount(input.amount);
|
|
706
738
|
validateNonEmpty(input.customer.name, "customer.name");
|
|
707
739
|
validateNonEmpty(input.customer.phoneNumber, "customer.phoneNumber");
|
|
740
|
+
const normalizedPhone = normalizePhone(input.customer.phoneNumber);
|
|
708
741
|
validateNonEmpty(input.description, "description");
|
|
709
742
|
if (input.method === "bank" && !input.bank) {
|
|
710
743
|
throwValidation('bank details are required when method is "bank"');
|
|
711
744
|
}
|
|
712
|
-
let payload = {
|
|
745
|
+
let payload = {
|
|
746
|
+
...input,
|
|
747
|
+
reference,
|
|
748
|
+
customer: { ...input.customer, phoneNumber: normalizedPhone }
|
|
749
|
+
};
|
|
713
750
|
const mutated = await runHook(config.hooks?.beforeCollect, payload);
|
|
714
751
|
if (mutated != null)
|
|
715
752
|
payload = { ...mutated, reference: mutated.reference ?? reference };
|
|
@@ -733,14 +770,19 @@ function createSdkInstance(config) {
|
|
|
733
770
|
}
|
|
734
771
|
async function collectPaymentAndResolve(input) {
|
|
735
772
|
const reference = resolveReference(input.reference);
|
|
736
|
-
|
|
773
|
+
validateCollectionAmount(input.amount);
|
|
737
774
|
validateNonEmpty(input.customer.name, "customer.name");
|
|
738
775
|
validateNonEmpty(input.customer.phoneNumber, "customer.phoneNumber");
|
|
776
|
+
const normalizedPhone = normalizePhone(input.customer.phoneNumber);
|
|
739
777
|
validateNonEmpty(input.description, "description");
|
|
740
778
|
if (input.method === "bank" && !input.bank) {
|
|
741
779
|
throwValidation('bank details are required when method is "bank"');
|
|
742
780
|
}
|
|
743
|
-
let payload = {
|
|
781
|
+
let payload = {
|
|
782
|
+
...input,
|
|
783
|
+
reference,
|
|
784
|
+
customer: { ...input.customer, phoneNumber: normalizedPhone }
|
|
785
|
+
};
|
|
744
786
|
const mutated = await runHook(config.hooks?.beforeCollect, payload);
|
|
745
787
|
if (mutated != null)
|
|
746
788
|
payload = { ...mutated, reference: mutated.reference ?? reference };
|
|
@@ -760,9 +802,10 @@ function createSdkInstance(config) {
|
|
|
760
802
|
}
|
|
761
803
|
async function makePayout(input) {
|
|
762
804
|
const reference = resolveReference(input.reference);
|
|
763
|
-
|
|
805
|
+
validatePayoutAmount(input.amount);
|
|
764
806
|
validateNonEmpty(input.customer.name, "customer.name");
|
|
765
807
|
validateNonEmpty(input.customer.phoneNumber, "customer.phoneNumber");
|
|
808
|
+
const normalizedPhone = normalizePhone(input.customer.phoneNumber);
|
|
766
809
|
validateNonEmpty(input.description, "description");
|
|
767
810
|
validateNonEmpty(
|
|
768
811
|
input.destination.accountHolderName,
|
|
@@ -772,7 +815,11 @@ function createSdkInstance(config) {
|
|
|
772
815
|
input.destination.accountNumber,
|
|
773
816
|
"destination.accountNumber"
|
|
774
817
|
);
|
|
775
|
-
let payload = {
|
|
818
|
+
let payload = {
|
|
819
|
+
...input,
|
|
820
|
+
reference,
|
|
821
|
+
customer: { ...input.customer, phoneNumber: normalizedPhone }
|
|
822
|
+
};
|
|
776
823
|
const mutated = await runHook(config.hooks?.beforePayout, payload);
|
|
777
824
|
if (mutated != null)
|
|
778
825
|
payload = { ...mutated, reference: mutated.reference ?? reference };
|
|
@@ -796,9 +843,10 @@ function createSdkInstance(config) {
|
|
|
796
843
|
}
|
|
797
844
|
async function makePayoutAndResolve(input) {
|
|
798
845
|
const reference = resolveReference(input.reference);
|
|
799
|
-
|
|
846
|
+
validatePayoutAmount(input.amount);
|
|
800
847
|
validateNonEmpty(input.customer.name, "customer.name");
|
|
801
848
|
validateNonEmpty(input.customer.phoneNumber, "customer.phoneNumber");
|
|
849
|
+
const normalizedPhone = normalizePhone(input.customer.phoneNumber);
|
|
802
850
|
validateNonEmpty(input.description, "description");
|
|
803
851
|
validateNonEmpty(
|
|
804
852
|
input.destination.accountHolderName,
|
|
@@ -808,7 +856,11 @@ function createSdkInstance(config) {
|
|
|
808
856
|
input.destination.accountNumber,
|
|
809
857
|
"destination.accountNumber"
|
|
810
858
|
);
|
|
811
|
-
let payload = {
|
|
859
|
+
let payload = {
|
|
860
|
+
...input,
|
|
861
|
+
reference,
|
|
862
|
+
customer: { ...input.customer, phoneNumber: normalizedPhone }
|
|
863
|
+
};
|
|
812
864
|
const mutated = await runHook(config.hooks?.beforePayout, payload);
|
|
813
865
|
if (mutated != null)
|
|
814
866
|
payload = { ...mutated, reference: mutated.reference ?? reference };
|
|
@@ -852,9 +904,10 @@ function createSdkInstance(config) {
|
|
|
852
904
|
}
|
|
853
905
|
async function verifyPhone(input) {
|
|
854
906
|
validateNonEmpty(input.phoneNumber, "phoneNumber");
|
|
907
|
+
const normalizedPhone = normalizePhone(input.phoneNumber);
|
|
855
908
|
const result = await transport.send({
|
|
856
909
|
action: SDK_ACTIONS.verifyPhone,
|
|
857
|
-
payload: input
|
|
910
|
+
payload: { ...input, phoneNumber: normalizedPhone }
|
|
858
911
|
});
|
|
859
912
|
if (result.isOk) {
|
|
860
913
|
return Ok(result.value);
|
|
@@ -863,7 +916,7 @@ function createSdkInstance(config) {
|
|
|
863
916
|
}
|
|
864
917
|
async function createInvoice(input) {
|
|
865
918
|
const reference = resolveReference(input.reference);
|
|
866
|
-
|
|
919
|
+
validateCollectionAmount(input.amount);
|
|
867
920
|
validateNonEmpty(input.description, "description");
|
|
868
921
|
if (input.items) {
|
|
869
922
|
if (input.items.length > 50) {
|