@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.d.mts CHANGED
@@ -258,6 +258,8 @@ declare function loadPaystackScript(): Promise<void>;
258
258
  declare function PaystackBridge({ publicKey, email, phone, amount, currency, reference, accessCode, metadata, channels, onSuccess, onError, onClose, autoStart, }: PaystackBridgeProps): react_jsx_runtime.JSX.Element;
259
259
 
260
260
  interface HubtelBridgeProps {
261
+ paymentId: string;
262
+ publicKey: string;
261
263
  merchantAccount: string | number;
262
264
  amount: number;
263
265
  currency?: string;
@@ -266,13 +268,16 @@ interface HubtelBridgeProps {
266
268
  phone?: string;
267
269
  description?: string;
268
270
  callbackUrl?: string;
271
+ /** Session token from server (recommended - credentials never exposed to client) */
272
+ hubtelSessionToken?: string;
273
+ /** Basic auth credential (legacy - credentials exposed to client, deprecated) */
269
274
  basicAuth?: string;
270
275
  onSuccess: (result: PaymentResult) => void;
271
276
  onError: (error: PaymentError) => void;
272
277
  onClose: () => void;
273
278
  autoStart?: boolean;
274
279
  }
275
- declare function HubtelBridge({ merchantAccount, amount, reference, phone, description, callbackUrl, basicAuth, onSuccess, onError, onClose, autoStart, }: HubtelBridgeProps): react_jsx_runtime.JSX.Element;
280
+ declare function HubtelBridge({ paymentId, publicKey, merchantAccount, amount, reference, phone, description, callbackUrl, hubtelSessionToken, basicAuth, onSuccess, onError, onClose, autoStart, }: HubtelBridgeProps): react_jsx_runtime.JSX.Element;
276
281
  /**
277
282
  * Opens Hubtel checkout modal directly
278
283
  * Uses the @hubteljs/checkout npm package
@@ -553,6 +558,20 @@ interface PaymentIntentResponse {
553
558
  net_amount: number;
554
559
  reference?: string;
555
560
  }
561
+ /**
562
+ * Response from creating a Hubtel session token.
563
+ * The token provides secure, short-lived access to Hubtel checkout without exposing credentials.
564
+ */
565
+ interface HubtelSessionResponse {
566
+ /** Short-lived session token for Hubtel checkout */
567
+ token: string;
568
+ /** Hubtel merchant account number */
569
+ merchantAccount: string;
570
+ /** Token expiry time in seconds */
571
+ expiresInSeconds: number;
572
+ /** Unix timestamp when the token expires */
573
+ expiresAt: number;
574
+ }
556
575
  interface PaymentDetailResponse {
557
576
  id: string;
558
577
  connection_id: string;
@@ -632,6 +651,18 @@ declare class ReevitAPIClient {
632
651
  data?: PaymentDetailResponse;
633
652
  error?: PaymentError;
634
653
  }>;
654
+ /**
655
+ * Creates a Hubtel session token for secure checkout.
656
+ * This endpoint generates a short-lived token that maps to Hubtel credentials server-side,
657
+ * avoiding exposure of sensitive credentials to the client.
658
+ *
659
+ * @param paymentId - The payment intent ID for Hubtel checkout
660
+ * @returns Hubtel session with token, merchant account, and expiry information
661
+ */
662
+ createHubtelSession(paymentId: string): Promise<{
663
+ data?: HubtelSessionResponse;
664
+ error?: PaymentError;
665
+ }>;
635
666
  /**
636
667
  * Maps SDK payment method to backend format
637
668
  */
package/dist/index.d.ts CHANGED
@@ -258,6 +258,8 @@ declare function loadPaystackScript(): Promise<void>;
258
258
  declare function PaystackBridge({ publicKey, email, phone, amount, currency, reference, accessCode, metadata, channels, onSuccess, onError, onClose, autoStart, }: PaystackBridgeProps): react_jsx_runtime.JSX.Element;
259
259
 
260
260
  interface HubtelBridgeProps {
261
+ paymentId: string;
262
+ publicKey: string;
261
263
  merchantAccount: string | number;
262
264
  amount: number;
263
265
  currency?: string;
@@ -266,13 +268,16 @@ interface HubtelBridgeProps {
266
268
  phone?: string;
267
269
  description?: string;
268
270
  callbackUrl?: string;
271
+ /** Session token from server (recommended - credentials never exposed to client) */
272
+ hubtelSessionToken?: string;
273
+ /** Basic auth credential (legacy - credentials exposed to client, deprecated) */
269
274
  basicAuth?: string;
270
275
  onSuccess: (result: PaymentResult) => void;
271
276
  onError: (error: PaymentError) => void;
272
277
  onClose: () => void;
273
278
  autoStart?: boolean;
274
279
  }
275
- declare function HubtelBridge({ merchantAccount, amount, reference, phone, description, callbackUrl, basicAuth, onSuccess, onError, onClose, autoStart, }: HubtelBridgeProps): react_jsx_runtime.JSX.Element;
280
+ declare function HubtelBridge({ paymentId, publicKey, merchantAccount, amount, reference, phone, description, callbackUrl, hubtelSessionToken, basicAuth, onSuccess, onError, onClose, autoStart, }: HubtelBridgeProps): react_jsx_runtime.JSX.Element;
276
281
  /**
277
282
  * Opens Hubtel checkout modal directly
278
283
  * Uses the @hubteljs/checkout npm package
@@ -553,6 +558,20 @@ interface PaymentIntentResponse {
553
558
  net_amount: number;
554
559
  reference?: string;
555
560
  }
561
+ /**
562
+ * Response from creating a Hubtel session token.
563
+ * The token provides secure, short-lived access to Hubtel checkout without exposing credentials.
564
+ */
565
+ interface HubtelSessionResponse {
566
+ /** Short-lived session token for Hubtel checkout */
567
+ token: string;
568
+ /** Hubtel merchant account number */
569
+ merchantAccount: string;
570
+ /** Token expiry time in seconds */
571
+ expiresInSeconds: number;
572
+ /** Unix timestamp when the token expires */
573
+ expiresAt: number;
574
+ }
556
575
  interface PaymentDetailResponse {
557
576
  id: string;
558
577
  connection_id: string;
@@ -632,6 +651,18 @@ declare class ReevitAPIClient {
632
651
  data?: PaymentDetailResponse;
633
652
  error?: PaymentError;
634
653
  }>;
654
+ /**
655
+ * Creates a Hubtel session token for secure checkout.
656
+ * This endpoint generates a short-lived token that maps to Hubtel credentials server-side,
657
+ * avoiding exposure of sensitive credentials to the client.
658
+ *
659
+ * @param paymentId - The payment intent ID for Hubtel checkout
660
+ * @returns Hubtel session with token, merchant account, and expiry information
661
+ */
662
+ createHubtelSession(paymentId: string): Promise<{
663
+ data?: HubtelSessionResponse;
664
+ error?: PaymentError;
665
+ }>;
635
666
  /**
636
667
  * Maps SDK payment method to backend format
637
668
  */
package/dist/index.js CHANGED
@@ -212,6 +212,17 @@ var ReevitAPIClient = class {
212
212
  async cancelPaymentIntent(paymentId) {
213
213
  return this.request("POST", `/v1/payments/${paymentId}/cancel`);
214
214
  }
215
+ /**
216
+ * Creates a Hubtel session token for secure checkout.
217
+ * This endpoint generates a short-lived token that maps to Hubtel credentials server-side,
218
+ * avoiding exposure of sensitive credentials to the client.
219
+ *
220
+ * @param paymentId - The payment intent ID for Hubtel checkout
221
+ * @returns Hubtel session with token, merchant account, and expiry information
222
+ */
223
+ async createHubtelSession(paymentId) {
224
+ return this.request("POST", `/v1/payments/hubtel/sessions/${paymentId}`);
225
+ }
215
226
  /**
216
227
  * Maps SDK payment method to backend format
217
228
  */
@@ -837,12 +848,15 @@ function PaystackBridge({
837
848
  ] }) });
838
849
  }
839
850
  function HubtelBridge({
851
+ paymentId,
852
+ publicKey,
840
853
  merchantAccount,
841
854
  amount,
842
855
  reference,
843
856
  phone,
844
857
  description = "Payment",
845
858
  callbackUrl,
859
+ hubtelSessionToken,
846
860
  basicAuth,
847
861
  onSuccess,
848
862
  onError,
@@ -851,7 +865,46 @@ function HubtelBridge({
851
865
  }) {
852
866
  const initialized = react.useRef(false);
853
867
  const checkoutRef = react.useRef(null);
868
+ const [authValue, setAuthValue] = react.useState("");
869
+ const [isLoading, setIsLoading] = react.useState(false);
870
+ react.useEffect(() => {
871
+ const fetchAuth = async () => {
872
+ if (hubtelSessionToken) {
873
+ setIsLoading(true);
874
+ try {
875
+ const client = createReevitClient({ publicKey });
876
+ const { data, error } = await client.createHubtelSession(paymentId);
877
+ if (error) {
878
+ onError({
879
+ code: "SESSION_ERROR",
880
+ message: error.message || "Failed to create Hubtel session",
881
+ recoverable: true
882
+ });
883
+ return;
884
+ }
885
+ if (data) {
886
+ setAuthValue(data.token);
887
+ }
888
+ } catch (err) {
889
+ onError({
890
+ code: "SESSION_ERROR",
891
+ message: "Failed to create Hubtel session",
892
+ recoverable: true,
893
+ originalError: err
894
+ });
895
+ } finally {
896
+ setIsLoading(false);
897
+ }
898
+ } else if (basicAuth) {
899
+ setAuthValue(basicAuth);
900
+ }
901
+ };
902
+ fetchAuth();
903
+ }, [paymentId, publicKey, hubtelSessionToken, basicAuth, onError]);
854
904
  const startPayment = react.useCallback(async () => {
905
+ if (isLoading || !authValue) {
906
+ return;
907
+ }
855
908
  try {
856
909
  const checkout = new CheckoutSdk__default.default();
857
910
  checkoutRef.current = checkout;
@@ -866,7 +919,9 @@ function HubtelBridge({
866
919
  branding: "enabled",
867
920
  callbackUrl: callbackUrl || window.location.href,
868
921
  merchantAccount: typeof merchantAccount === "string" ? parseInt(merchantAccount, 10) : merchantAccount,
869
- basicAuth: basicAuth || ""
922
+ // Use session token or basicAuth for authentication
923
+ // Session tokens are base64-encoded credentials fetched securely from the server
924
+ basicAuth: authValue || ""
870
925
  };
871
926
  checkout.openModal({
872
927
  purchaseInfo,
@@ -910,13 +965,13 @@ function HubtelBridge({
910
965
  };
911
966
  onError(error);
912
967
  }
913
- }, [merchantAccount, amount, reference, phone, description, callbackUrl, basicAuth, onSuccess, onError, onClose]);
968
+ }, [merchantAccount, amount, reference, phone, description, callbackUrl, authValue, isLoading, onSuccess, onError, onClose]);
914
969
  react.useEffect(() => {
915
- if (autoStart && !initialized.current) {
970
+ if (autoStart && !initialized.current && !isLoading && authValue) {
916
971
  initialized.current = true;
917
972
  startPayment();
918
973
  }
919
- }, [autoStart, startPayment]);
974
+ }, [autoStart, startPayment, isLoading, authValue]);
920
975
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "reevit-psp-bridge reevit-psp-bridge--hubtel", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "reevit-psp-bridge__loading", children: [
921
976
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "reevit-spinner" }),
922
977
  /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Connecting to Hubtel..." })
@@ -1835,14 +1890,16 @@ function ReevitCheckout({
1835
1890
  return /* @__PURE__ */ jsxRuntime.jsx(
1836
1891
  HubtelBridge,
1837
1892
  {
1838
- merchantAccount: paymentIntent?.pspCredentials?.merchantAccount || pspKey,
1893
+ paymentId: paymentIntent?.id || "",
1894
+ publicKey,
1895
+ merchantAccount: pspKey,
1839
1896
  amount: paymentIntent?.amount ?? amount,
1840
1897
  currency: paymentIntent?.currency ?? currency,
1841
1898
  reference: paymentIntent?.reference || reference,
1842
1899
  email,
1843
1900
  phone: momoData?.phone || phone,
1844
1901
  description: `Payment ${paymentIntent?.reference || reference || ""}`,
1845
- basicAuth: paymentIntent?.pspCredentials?.basicAuth,
1902
+ hubtelSessionToken: paymentIntent?.id ? paymentIntent.id : void 0,
1846
1903
  onSuccess: handlePSPSuccess,
1847
1904
  onError: (err) => handlePSPError(err),
1848
1905
  onClose: handlePSPClose