@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 +32 -1
- package/dist/index.d.ts +32 -1
- package/dist/index.js +63 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +63 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
1896
|
+
hubtelSessionToken: paymentIntent?.id ? paymentIntent.id : void 0,
|
|
1840
1897
|
onSuccess: handlePSPSuccess,
|
|
1841
1898
|
onError: (err) => handlePSPError(err),
|
|
1842
1899
|
onClose: handlePSPClose
|