@reevit/react 0.2.9 → 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.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 { ...state, status: "ready", paymentIntent: action.payload };
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":
@@ -280,14 +286,17 @@ function useReevit(options) {
280
286
  const [state, dispatch] = useReducer(reevitReducer, {
281
287
  ...initialState,
282
288
  status: config.initialPaymentIntent ? "ready" : "idle",
283
- paymentIntent: config.initialPaymentIntent || null
289
+ paymentIntent: config.initialPaymentIntent || null,
290
+ selectedMethod: config.initialPaymentIntent?.availableMethods?.length === 1 ? config.initialPaymentIntent.availableMethods[0] : null
284
291
  });
285
292
  const apiClientRef = useRef(null);
286
293
  const initializingRef = useRef(!!config.initialPaymentIntent);
287
294
  useEffect(() => {
288
- if (config.initialPaymentIntent && (!state.paymentIntent || state.paymentIntent.id !== config.initialPaymentIntent.id)) {
289
- dispatch({ type: "INIT_SUCCESS", payload: config.initialPaymentIntent });
290
- initializingRef.current = true;
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
+ }
291
300
  }
292
301
  }, [config.initialPaymentIntent, state.paymentIntent?.id]);
293
302
  if (!apiClientRef.current) {
@@ -380,11 +389,16 @@ function useReevit(options) {
380
389
  paymentMethod: state.selectedMethod,
381
390
  psp: state.paymentIntent.recommendedPsp,
382
391
  pspReference: paymentData.pspReference || data?.provider_ref_id || "",
383
- status: "success",
392
+ status: data?.status === "succeeded" ? "success" : "pending",
384
393
  metadata: paymentData
385
394
  };
386
- dispatch({ type: "PROCESS_SUCCESS", payload: result });
387
- onSuccess?.(result);
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
+ }
388
402
  } catch (err) {
389
403
  const error = {
390
404
  code: "PAYMENT_FAILED",
@@ -674,6 +688,7 @@ function loadPaystackScript() {
674
688
  function PaystackBridge({
675
689
  publicKey,
676
690
  email,
691
+ phone,
677
692
  amount,
678
693
  currency = "GHS",
679
694
  reference,
@@ -703,6 +718,7 @@ function PaystackBridge({
703
718
  const handler = window.PaystackPop.setup({
704
719
  key: publicKey,
705
720
  email,
721
+ phone,
706
722
  amount,
707
723
  // Paystack expects amount in kobo/pesewas (smallest unit)
708
724
  currency,
@@ -710,13 +726,18 @@ function PaystackBridge({
710
726
  metadata,
711
727
  channels,
712
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
+ }
713
735
  const result = {
714
736
  paymentId: response.transaction,
715
737
  reference: response.reference,
716
738
  amount,
717
739
  currency,
718
- paymentMethod: "card",
719
- // Paystack handles this internally
740
+ paymentMethod: usedMethod,
720
741
  psp: "paystack",
721
742
  pspReference: response.trans,
722
743
  status: response.status === "success" ? "success" : "pending",
@@ -769,6 +790,7 @@ function ReevitCheckout({
769
790
  reference,
770
791
  metadata,
771
792
  paymentMethods = ["card", "mobile_money"],
793
+ initialPaymentIntent,
772
794
  // Callbacks
773
795
  onSuccess,
774
796
  onError,
@@ -810,7 +832,17 @@ function ReevitCheckout({
810
832
  isLoading,
811
833
  isComplete
812
834
  } = useReevit({
813
- config: { publicKey, amount, currency, email, phone, reference, metadata, paymentMethods },
835
+ config: {
836
+ publicKey,
837
+ amount,
838
+ currency,
839
+ email,
840
+ phone,
841
+ reference,
842
+ metadata,
843
+ paymentMethods,
844
+ initialPaymentIntent
845
+ },
814
846
  apiBaseUrl,
815
847
  onSuccess: (result2) => {
816
848
  onSuccess?.(result2);
@@ -826,10 +858,19 @@ function ReevitCheckout({
826
858
  onStateChange
827
859
  });
828
860
  useEffect(() => {
829
- if (isOpen && status === "idle") {
861
+ if (isOpen && status === "idle" && !initialPaymentIntent) {
830
862
  initialize();
831
863
  }
832
- }, [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]);
833
874
  const handleOpen = useCallback(() => {
834
875
  if (controlledIsOpen !== void 0) return;
835
876
  setIsOpen(true);
@@ -883,10 +924,11 @@ function ReevitCheckout({
883
924
  setShowPSPBridge(false);
884
925
  }, [reset]);
885
926
  const themeStyles = theme ? createThemeVariables(theme) : {};
886
- const trigger = children ? /* @__PURE__ */ jsx("span", { onClick: handleOpen, role: "button", tabIndex: 0, children }) : /* @__PURE__ */ jsxs("button", { className: "reevit-trigger-btn", onClick: handleOpen, children: [
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: [
887
929
  "Pay ",
888
930
  formatAmount(amount, currency)
889
- ] });
931
+ ] }) : null;
890
932
  const renderContent = () => {
891
933
  if (status === "loading") {
892
934
  return /* @__PURE__ */ jsxs("div", { className: "reevit-loading", children: [
@@ -919,6 +961,7 @@ function ReevitCheckout({
919
961
  {
920
962
  publicKey: pspKey,
921
963
  email,
964
+ phone: momoData?.phone || phone,
922
965
  amount: paymentIntent?.amount ?? amount,
923
966
  currency: paymentIntent?.currency ?? currency,
924
967
  reference,
@@ -927,7 +970,8 @@ function ReevitCheckout({
927
970
  // Override with correct payment intent ID for webhook routing
928
971
  // This ensures Paystack webhook includes the correct ID to find the payment
929
972
  payment_id: paymentIntent?.id,
930
- connection_id: paymentIntent?.connectionId ?? metadata?.connection_id
973
+ connection_id: paymentIntent?.connectionId ?? metadata?.connection_id,
974
+ customer_phone: momoData?.phone || phone
931
975
  },
932
976
  channels: selectedMethod === "mobile_money" ? ["mobile_money"] : ["card"],
933
977
  onSuccess: handlePSPSuccess,