@reevit/react 0.4.0 → 0.4.1

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
@@ -206,6 +206,17 @@ var ReevitAPIClient = class {
206
206
  async cancelPaymentIntent(paymentId) {
207
207
  return this.request("POST", `/v1/payments/${paymentId}/cancel`);
208
208
  }
209
+ /**
210
+ * Creates a Hubtel session token for secure checkout.
211
+ * This endpoint generates a short-lived token that maps to Hubtel credentials server-side,
212
+ * avoiding exposure of sensitive credentials to the client.
213
+ *
214
+ * @param paymentId - The payment intent ID for Hubtel checkout
215
+ * @returns Hubtel session with token, merchant account, and expiry information
216
+ */
217
+ async createHubtelSession(paymentId) {
218
+ return this.request("POST", `/v1/payments/hubtel/sessions/${paymentId}`);
219
+ }
209
220
  /**
210
221
  * Maps SDK payment method to backend format
211
222
  */
@@ -831,12 +842,15 @@ function PaystackBridge({
831
842
  ] }) });
832
843
  }
833
844
  function HubtelBridge({
845
+ paymentId,
846
+ publicKey,
834
847
  merchantAccount,
835
848
  amount,
836
849
  reference,
837
850
  phone,
838
851
  description = "Payment",
839
852
  callbackUrl,
853
+ hubtelSessionToken,
840
854
  basicAuth,
841
855
  onSuccess,
842
856
  onError,
@@ -845,7 +859,46 @@ function HubtelBridge({
845
859
  }) {
846
860
  const initialized = useRef(false);
847
861
  const checkoutRef = useRef(null);
862
+ const [authValue, setAuthValue] = useState("");
863
+ const [isLoading, setIsLoading] = useState(false);
864
+ useEffect(() => {
865
+ const fetchAuth = async () => {
866
+ if (hubtelSessionToken) {
867
+ setIsLoading(true);
868
+ try {
869
+ const client = createReevitClient({ publicKey });
870
+ const { data, error } = await client.createHubtelSession(paymentId);
871
+ if (error) {
872
+ onError({
873
+ code: "SESSION_ERROR",
874
+ message: error.message || "Failed to create Hubtel session",
875
+ recoverable: true
876
+ });
877
+ return;
878
+ }
879
+ if (data) {
880
+ setAuthValue(data.token);
881
+ }
882
+ } catch (err) {
883
+ onError({
884
+ code: "SESSION_ERROR",
885
+ message: "Failed to create Hubtel session",
886
+ recoverable: true,
887
+ originalError: err
888
+ });
889
+ } finally {
890
+ setIsLoading(false);
891
+ }
892
+ } else if (basicAuth) {
893
+ setAuthValue(basicAuth);
894
+ }
895
+ };
896
+ fetchAuth();
897
+ }, [paymentId, publicKey, hubtelSessionToken, basicAuth, onError]);
848
898
  const startPayment = useCallback(async () => {
899
+ if (isLoading || !authValue) {
900
+ return;
901
+ }
849
902
  try {
850
903
  const checkout = new CheckoutSdk();
851
904
  checkoutRef.current = checkout;
@@ -860,7 +913,9 @@ function HubtelBridge({
860
913
  branding: "enabled",
861
914
  callbackUrl: callbackUrl || window.location.href,
862
915
  merchantAccount: typeof merchantAccount === "string" ? parseInt(merchantAccount, 10) : merchantAccount,
863
- basicAuth: basicAuth || ""
916
+ // Use session token or basicAuth for authentication
917
+ // Session tokens are base64-encoded credentials fetched securely from the server
918
+ basicAuth: authValue || ""
864
919
  };
865
920
  checkout.openModal({
866
921
  purchaseInfo,
@@ -904,13 +959,13 @@ function HubtelBridge({
904
959
  };
905
960
  onError(error);
906
961
  }
907
- }, [merchantAccount, amount, reference, phone, description, callbackUrl, basicAuth, onSuccess, onError, onClose]);
962
+ }, [merchantAccount, amount, reference, phone, description, callbackUrl, authValue, isLoading, onSuccess, onError, onClose]);
908
963
  useEffect(() => {
909
- if (autoStart && !initialized.current) {
964
+ if (autoStart && !initialized.current && !isLoading && authValue) {
910
965
  initialized.current = true;
911
966
  startPayment();
912
967
  }
913
- }, [autoStart, startPayment]);
968
+ }, [autoStart, startPayment, isLoading, authValue]);
914
969
  return /* @__PURE__ */ jsx("div", { className: "reevit-psp-bridge reevit-psp-bridge--hubtel", children: /* @__PURE__ */ jsxs("div", { className: "reevit-psp-bridge__loading", children: [
915
970
  /* @__PURE__ */ jsx("div", { className: "reevit-spinner" }),
916
971
  /* @__PURE__ */ jsx("p", { children: "Connecting to Hubtel..." })
@@ -1829,14 +1884,16 @@ function ReevitCheckout({
1829
1884
  return /* @__PURE__ */ jsx(
1830
1885
  HubtelBridge,
1831
1886
  {
1832
- merchantAccount: paymentIntent?.pspCredentials?.merchantAccount || pspKey,
1887
+ paymentId: paymentIntent?.id || "",
1888
+ publicKey,
1889
+ merchantAccount: pspKey,
1833
1890
  amount: paymentIntent?.amount ?? amount,
1834
1891
  currency: paymentIntent?.currency ?? currency,
1835
1892
  reference: paymentIntent?.reference || reference,
1836
1893
  email,
1837
1894
  phone: momoData?.phone || phone,
1838
1895
  description: `Payment ${paymentIntent?.reference || reference || ""}`,
1839
- basicAuth: paymentIntent?.pspCredentials?.basicAuth,
1896
+ hubtelSessionToken: paymentIntent?.id ? paymentIntent.id : void 0,
1840
1897
  onSuccess: handlePSPSuccess,
1841
1898
  onError: (err) => handlePSPError(err),
1842
1899
  onClose: handlePSPClose