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