@reevit/react 0.2.8 → 0.3.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.d.mts +10 -2
- package/dist/index.d.ts +10 -2
- package/dist/index.js +85 -17
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +85 -17
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -176,6 +176,7 @@ var ReevitAPIClient = class {
|
|
|
176
176
|
method: this.mapPaymentMethod(method),
|
|
177
177
|
country,
|
|
178
178
|
customer_id: config.email || config.metadata?.customerId,
|
|
179
|
+
phone: config.phone,
|
|
179
180
|
metadata
|
|
180
181
|
};
|
|
181
182
|
return this.request("POST", "/v1/payments/intents", request);
|
|
@@ -231,7 +232,12 @@ function reevitReducer(state, action) {
|
|
|
231
232
|
case "INIT_START":
|
|
232
233
|
return { ...state, status: "loading", error: null };
|
|
233
234
|
case "INIT_SUCCESS":
|
|
234
|
-
return {
|
|
235
|
+
return {
|
|
236
|
+
...state,
|
|
237
|
+
status: "ready",
|
|
238
|
+
paymentIntent: action.payload,
|
|
239
|
+
selectedMethod: action.payload.availableMethods?.length === 1 ? action.payload.availableMethods[0] : state.selectedMethod
|
|
240
|
+
};
|
|
235
241
|
case "INIT_ERROR":
|
|
236
242
|
return { ...state, status: "failed", error: action.payload };
|
|
237
243
|
case "SELECT_METHOD":
|
|
@@ -277,9 +283,22 @@ function mapToPaymentIntent(response, config) {
|
|
|
277
283
|
}
|
|
278
284
|
function useReevit(options) {
|
|
279
285
|
const { config, onSuccess, onError, onClose, onStateChange, apiBaseUrl } = options;
|
|
280
|
-
const [state, dispatch] = useReducer(reevitReducer,
|
|
286
|
+
const [state, dispatch] = useReducer(reevitReducer, {
|
|
287
|
+
...initialState,
|
|
288
|
+
status: config.initialPaymentIntent ? "ready" : "idle",
|
|
289
|
+
paymentIntent: config.initialPaymentIntent || null,
|
|
290
|
+
selectedMethod: config.initialPaymentIntent?.availableMethods?.length === 1 ? config.initialPaymentIntent.availableMethods[0] : null
|
|
291
|
+
});
|
|
281
292
|
const apiClientRef = useRef(null);
|
|
282
|
-
const initializingRef = useRef(
|
|
293
|
+
const initializingRef = useRef(!!config.initialPaymentIntent);
|
|
294
|
+
useEffect(() => {
|
|
295
|
+
if (config.initialPaymentIntent) {
|
|
296
|
+
if (!state.paymentIntent || state.paymentIntent.id !== config.initialPaymentIntent.id) {
|
|
297
|
+
dispatch({ type: "INIT_SUCCESS", payload: config.initialPaymentIntent });
|
|
298
|
+
initializingRef.current = true;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}, [config.initialPaymentIntent, state.paymentIntent?.id]);
|
|
283
302
|
if (!apiClientRef.current) {
|
|
284
303
|
apiClientRef.current = new ReevitAPIClient({
|
|
285
304
|
publicKey: config.publicKey,
|
|
@@ -370,11 +389,16 @@ function useReevit(options) {
|
|
|
370
389
|
paymentMethod: state.selectedMethod,
|
|
371
390
|
psp: state.paymentIntent.recommendedPsp,
|
|
372
391
|
pspReference: paymentData.pspReference || data?.provider_ref_id || "",
|
|
373
|
-
status: "success",
|
|
392
|
+
status: data?.status === "succeeded" ? "success" : "pending",
|
|
374
393
|
metadata: paymentData
|
|
375
394
|
};
|
|
376
|
-
|
|
377
|
-
|
|
395
|
+
if (result.status === "success") {
|
|
396
|
+
dispatch({ type: "PROCESS_SUCCESS", payload: result });
|
|
397
|
+
onSuccess?.(result);
|
|
398
|
+
} else {
|
|
399
|
+
dispatch({ type: "PROCESS_SUCCESS", payload: result });
|
|
400
|
+
onSuccess?.(result);
|
|
401
|
+
}
|
|
378
402
|
} catch (err) {
|
|
379
403
|
const error = {
|
|
380
404
|
code: "PAYMENT_FAILED",
|
|
@@ -664,6 +688,7 @@ function loadPaystackScript() {
|
|
|
664
688
|
function PaystackBridge({
|
|
665
689
|
publicKey,
|
|
666
690
|
email,
|
|
691
|
+
phone,
|
|
667
692
|
amount,
|
|
668
693
|
currency = "GHS",
|
|
669
694
|
reference,
|
|
@@ -693,6 +718,7 @@ function PaystackBridge({
|
|
|
693
718
|
const handler = window.PaystackPop.setup({
|
|
694
719
|
key: publicKey,
|
|
695
720
|
email,
|
|
721
|
+
phone,
|
|
696
722
|
amount,
|
|
697
723
|
// Paystack expects amount in kobo/pesewas (smallest unit)
|
|
698
724
|
currency,
|
|
@@ -700,13 +726,18 @@ function PaystackBridge({
|
|
|
700
726
|
metadata,
|
|
701
727
|
channels,
|
|
702
728
|
callback: (response) => {
|
|
729
|
+
let usedMethod = "card";
|
|
730
|
+
if (channels && channels.length === 1) {
|
|
731
|
+
usedMethod = channels[0];
|
|
732
|
+
} else if (response.message?.toLowerCase().includes("mobile money")) {
|
|
733
|
+
usedMethod = "mobile_money";
|
|
734
|
+
}
|
|
703
735
|
const result = {
|
|
704
736
|
paymentId: response.transaction,
|
|
705
737
|
reference: response.reference,
|
|
706
738
|
amount,
|
|
707
739
|
currency,
|
|
708
|
-
paymentMethod:
|
|
709
|
-
// Paystack handles this internally
|
|
740
|
+
paymentMethod: usedMethod,
|
|
710
741
|
psp: "paystack",
|
|
711
742
|
pspReference: response.trans,
|
|
712
743
|
status: response.status === "success" ? "success" : "pending",
|
|
@@ -759,6 +790,7 @@ function ReevitCheckout({
|
|
|
759
790
|
reference,
|
|
760
791
|
metadata,
|
|
761
792
|
paymentMethods = ["card", "mobile_money"],
|
|
793
|
+
initialPaymentIntent,
|
|
762
794
|
// Callbacks
|
|
763
795
|
onSuccess,
|
|
764
796
|
onError,
|
|
@@ -767,10 +799,23 @@ function ReevitCheckout({
|
|
|
767
799
|
// UI
|
|
768
800
|
children,
|
|
769
801
|
autoOpen = false,
|
|
802
|
+
isOpen: controlledIsOpen,
|
|
803
|
+
onOpenChange,
|
|
770
804
|
theme,
|
|
771
805
|
apiBaseUrl
|
|
772
806
|
}) {
|
|
773
|
-
const [
|
|
807
|
+
const [internalIsOpen, setInternalIsOpen] = useState(autoOpen);
|
|
808
|
+
const isOpen = controlledIsOpen !== void 0 ? controlledIsOpen : internalIsOpen;
|
|
809
|
+
const setIsOpen = useCallback(
|
|
810
|
+
(value) => {
|
|
811
|
+
if (onOpenChange) {
|
|
812
|
+
onOpenChange(value);
|
|
813
|
+
} else {
|
|
814
|
+
setInternalIsOpen(value);
|
|
815
|
+
}
|
|
816
|
+
},
|
|
817
|
+
[onOpenChange]
|
|
818
|
+
);
|
|
774
819
|
const [showPSPBridge, setShowPSPBridge] = useState(false);
|
|
775
820
|
const [momoData, setMomoData] = useState(null);
|
|
776
821
|
const {
|
|
@@ -787,7 +832,17 @@ function ReevitCheckout({
|
|
|
787
832
|
isLoading,
|
|
788
833
|
isComplete
|
|
789
834
|
} = useReevit({
|
|
790
|
-
config: {
|
|
835
|
+
config: {
|
|
836
|
+
publicKey,
|
|
837
|
+
amount,
|
|
838
|
+
currency,
|
|
839
|
+
email,
|
|
840
|
+
phone,
|
|
841
|
+
reference,
|
|
842
|
+
metadata,
|
|
843
|
+
paymentMethods,
|
|
844
|
+
initialPaymentIntent
|
|
845
|
+
},
|
|
791
846
|
apiBaseUrl,
|
|
792
847
|
onSuccess: (result2) => {
|
|
793
848
|
onSuccess?.(result2);
|
|
@@ -803,21 +858,31 @@ function ReevitCheckout({
|
|
|
803
858
|
onStateChange
|
|
804
859
|
});
|
|
805
860
|
useEffect(() => {
|
|
806
|
-
if (isOpen && status === "idle") {
|
|
861
|
+
if (isOpen && status === "idle" && !initialPaymentIntent) {
|
|
807
862
|
initialize();
|
|
808
863
|
}
|
|
809
|
-
}, [isOpen, status, initialize]);
|
|
864
|
+
}, [isOpen, status, initialize, initialPaymentIntent]);
|
|
865
|
+
useEffect(() => {
|
|
866
|
+
if (isOpen && (selectedMethod === "card" || selectedMethod === "mobile_money") && !showPSPBridge) {
|
|
867
|
+
if (selectedMethod === "card" && paymentIntent) {
|
|
868
|
+
setShowPSPBridge(true);
|
|
869
|
+
} else if (selectedMethod === "mobile_money" && paymentIntent && (momoData?.phone || phone)) {
|
|
870
|
+
setShowPSPBridge(true);
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
}, [isOpen, selectedMethod, showPSPBridge, paymentIntent, momoData, phone]);
|
|
810
874
|
const handleOpen = useCallback(() => {
|
|
875
|
+
if (controlledIsOpen !== void 0) return;
|
|
811
876
|
setIsOpen(true);
|
|
812
877
|
setShowPSPBridge(false);
|
|
813
878
|
setMomoData(null);
|
|
814
|
-
}, []);
|
|
879
|
+
}, [controlledIsOpen, setIsOpen]);
|
|
815
880
|
const handleClose = useCallback(() => {
|
|
816
881
|
closeCheckout();
|
|
817
882
|
setIsOpen(false);
|
|
818
883
|
setShowPSPBridge(false);
|
|
819
884
|
setMomoData(null);
|
|
820
|
-
}, [closeCheckout]);
|
|
885
|
+
}, [closeCheckout, setIsOpen]);
|
|
821
886
|
const handleMethodSelect = useCallback(
|
|
822
887
|
(method) => {
|
|
823
888
|
selectMethod(method);
|
|
@@ -859,10 +924,11 @@ function ReevitCheckout({
|
|
|
859
924
|
setShowPSPBridge(false);
|
|
860
925
|
}, [reset]);
|
|
861
926
|
const themeStyles = theme ? createThemeVariables(theme) : {};
|
|
862
|
-
const
|
|
927
|
+
const isControlled = controlledIsOpen !== void 0;
|
|
928
|
+
const trigger = children ? /* @__PURE__ */ jsx("span", { onClick: isControlled ? void 0 : handleOpen, role: isControlled ? void 0 : "button", tabIndex: isControlled ? void 0 : 0, children }) : !isControlled ? /* @__PURE__ */ jsxs("button", { className: "reevit-trigger-btn", onClick: handleOpen, children: [
|
|
863
929
|
"Pay ",
|
|
864
930
|
formatAmount(amount, currency)
|
|
865
|
-
] });
|
|
931
|
+
] }) : null;
|
|
866
932
|
const renderContent = () => {
|
|
867
933
|
if (status === "loading") {
|
|
868
934
|
return /* @__PURE__ */ jsxs("div", { className: "reevit-loading", children: [
|
|
@@ -895,6 +961,7 @@ function ReevitCheckout({
|
|
|
895
961
|
{
|
|
896
962
|
publicKey: pspKey,
|
|
897
963
|
email,
|
|
964
|
+
phone: momoData?.phone || phone,
|
|
898
965
|
amount: paymentIntent?.amount ?? amount,
|
|
899
966
|
currency: paymentIntent?.currency ?? currency,
|
|
900
967
|
reference,
|
|
@@ -903,7 +970,8 @@ function ReevitCheckout({
|
|
|
903
970
|
// Override with correct payment intent ID for webhook routing
|
|
904
971
|
// This ensures Paystack webhook includes the correct ID to find the payment
|
|
905
972
|
payment_id: paymentIntent?.id,
|
|
906
|
-
connection_id: paymentIntent?.connectionId ?? metadata?.connection_id
|
|
973
|
+
connection_id: paymentIntent?.connectionId ?? metadata?.connection_id,
|
|
974
|
+
customer_phone: momoData?.phone || phone
|
|
907
975
|
},
|
|
908
976
|
channels: selectedMethod === "mobile_money" ? ["mobile_money"] : ["card"],
|
|
909
977
|
onSuccess: handlePSPSuccess,
|