@reevit/react 0.4.5 → 0.4.7
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 +7 -3
- package/dist/index.d.ts +7 -3
- package/dist/index.js +69 -17
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +69 -17
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +6 -0
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -117,6 +117,8 @@ interface ReevitTheme {
|
|
|
117
117
|
darkMode?: boolean;
|
|
118
118
|
/** Custom logo URL to display in checkout header */
|
|
119
119
|
logoUrl?: string;
|
|
120
|
+
/** Company or organization name to display in checkout header */
|
|
121
|
+
companyName?: string;
|
|
120
122
|
/** PSP selector background color */
|
|
121
123
|
pspSelectorBgColor?: string;
|
|
122
124
|
/** PSP selector text color */
|
|
@@ -308,9 +310,9 @@ interface HubtelBridgeProps {
|
|
|
308
310
|
callbackUrl?: string;
|
|
309
311
|
apiBaseUrl?: string;
|
|
310
312
|
clientSecret?: string;
|
|
311
|
-
/** Session token from server (
|
|
313
|
+
/** Session token from server (triggers session fetch) */
|
|
312
314
|
hubtelSessionToken?: string;
|
|
313
|
-
/**
|
|
315
|
+
/** Base64 basic auth credential (legacy - credentials exposed) */
|
|
314
316
|
basicAuth?: string;
|
|
315
317
|
preferredMethod?: PaymentMethod;
|
|
316
318
|
onSuccess: (result: PaymentResult) => void;
|
|
@@ -318,7 +320,7 @@ interface HubtelBridgeProps {
|
|
|
318
320
|
onClose: () => void;
|
|
319
321
|
autoStart?: boolean;
|
|
320
322
|
}
|
|
321
|
-
declare function HubtelBridge({ paymentId, publicKey, merchantAccount, amount, reference, phone, description, callbackUrl, apiBaseUrl, clientSecret, hubtelSessionToken, basicAuth, preferredMethod, onSuccess, onError, onClose, autoStart, }: HubtelBridgeProps): react_jsx_runtime.JSX.Element;
|
|
323
|
+
declare function HubtelBridge({ paymentId, publicKey, merchantAccount, amount, currency, reference, email, phone, description, callbackUrl, apiBaseUrl, clientSecret, hubtelSessionToken, basicAuth, preferredMethod, onSuccess, onError, onClose, autoStart, }: HubtelBridgeProps): react_jsx_runtime.JSX.Element;
|
|
322
324
|
/**
|
|
323
325
|
* Opens Hubtel checkout modal directly
|
|
324
326
|
* Uses the @hubteljs/checkout npm package
|
|
@@ -616,6 +618,8 @@ interface HubtelSessionResponse {
|
|
|
616
618
|
token: string;
|
|
617
619
|
/** Hubtel merchant account number */
|
|
618
620
|
merchantAccount: string;
|
|
621
|
+
/** Base64 basic auth for Hubtel checkout (exposes credentials) */
|
|
622
|
+
basicAuth?: string;
|
|
619
623
|
/** Token expiry time in seconds */
|
|
620
624
|
expiresInSeconds: number;
|
|
621
625
|
/** Unix timestamp when the token expires */
|
package/dist/index.d.ts
CHANGED
|
@@ -117,6 +117,8 @@ interface ReevitTheme {
|
|
|
117
117
|
darkMode?: boolean;
|
|
118
118
|
/** Custom logo URL to display in checkout header */
|
|
119
119
|
logoUrl?: string;
|
|
120
|
+
/** Company or organization name to display in checkout header */
|
|
121
|
+
companyName?: string;
|
|
120
122
|
/** PSP selector background color */
|
|
121
123
|
pspSelectorBgColor?: string;
|
|
122
124
|
/** PSP selector text color */
|
|
@@ -308,9 +310,9 @@ interface HubtelBridgeProps {
|
|
|
308
310
|
callbackUrl?: string;
|
|
309
311
|
apiBaseUrl?: string;
|
|
310
312
|
clientSecret?: string;
|
|
311
|
-
/** Session token from server (
|
|
313
|
+
/** Session token from server (triggers session fetch) */
|
|
312
314
|
hubtelSessionToken?: string;
|
|
313
|
-
/**
|
|
315
|
+
/** Base64 basic auth credential (legacy - credentials exposed) */
|
|
314
316
|
basicAuth?: string;
|
|
315
317
|
preferredMethod?: PaymentMethod;
|
|
316
318
|
onSuccess: (result: PaymentResult) => void;
|
|
@@ -318,7 +320,7 @@ interface HubtelBridgeProps {
|
|
|
318
320
|
onClose: () => void;
|
|
319
321
|
autoStart?: boolean;
|
|
320
322
|
}
|
|
321
|
-
declare function HubtelBridge({ paymentId, publicKey, merchantAccount, amount, reference, phone, description, callbackUrl, apiBaseUrl, clientSecret, hubtelSessionToken, basicAuth, preferredMethod, onSuccess, onError, onClose, autoStart, }: HubtelBridgeProps): react_jsx_runtime.JSX.Element;
|
|
323
|
+
declare function HubtelBridge({ paymentId, publicKey, merchantAccount, amount, currency, reference, email, phone, description, callbackUrl, apiBaseUrl, clientSecret, hubtelSessionToken, basicAuth, preferredMethod, onSuccess, onError, onClose, autoStart, }: HubtelBridgeProps): react_jsx_runtime.JSX.Element;
|
|
322
324
|
/**
|
|
323
325
|
* Opens Hubtel checkout modal directly
|
|
324
326
|
* Uses the @hubteljs/checkout npm package
|
|
@@ -616,6 +618,8 @@ interface HubtelSessionResponse {
|
|
|
616
618
|
token: string;
|
|
617
619
|
/** Hubtel merchant account number */
|
|
618
620
|
merchantAccount: string;
|
|
621
|
+
/** Base64 basic auth for Hubtel checkout (exposes credentials) */
|
|
622
|
+
basicAuth?: string;
|
|
619
623
|
/** Token expiry time in seconds */
|
|
620
624
|
expiresInSeconds: number;
|
|
621
625
|
/** Unix timestamp when the token expires */
|
package/dist/index.js
CHANGED
|
@@ -366,6 +366,36 @@ function mapAvailableProviders(providers) {
|
|
|
366
366
|
};
|
|
367
367
|
}).filter((provider) => provider.methods.length > 0);
|
|
368
368
|
}
|
|
369
|
+
function normalizeBranding(branding) {
|
|
370
|
+
if (!branding) {
|
|
371
|
+
return {};
|
|
372
|
+
}
|
|
373
|
+
const raw = branding;
|
|
374
|
+
const theme = { ...raw };
|
|
375
|
+
const getString = (value) => typeof value === "string" ? value : void 0;
|
|
376
|
+
const getBoolean = (value) => typeof value === "boolean" ? value : void 0;
|
|
377
|
+
const setIf = (key, value) => {
|
|
378
|
+
if (value !== void 0) {
|
|
379
|
+
theme[key] = value;
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
setIf("logoUrl", getString(raw.logoUrl ?? raw.logo_url));
|
|
383
|
+
setIf("companyName", getString(raw.companyName ?? raw.company_name));
|
|
384
|
+
setIf("primaryColor", getString(raw.primaryColor ?? raw.primary_color));
|
|
385
|
+
setIf("primaryForegroundColor", getString(raw.primaryForegroundColor ?? raw.primary_foreground_color));
|
|
386
|
+
setIf("backgroundColor", getString(raw.backgroundColor ?? raw.background_color));
|
|
387
|
+
setIf("surfaceColor", getString(raw.surfaceColor ?? raw.surface_color));
|
|
388
|
+
setIf("textColor", getString(raw.textColor ?? raw.text_color));
|
|
389
|
+
setIf("mutedTextColor", getString(raw.mutedTextColor ?? raw.muted_text_color));
|
|
390
|
+
setIf("borderRadius", getString(raw.borderRadius ?? raw.border_radius));
|
|
391
|
+
setIf("fontFamily", getString(raw.fontFamily ?? raw.font_family));
|
|
392
|
+
setIf("darkMode", getBoolean(raw.darkMode ?? raw.dark_mode));
|
|
393
|
+
setIf("pspSelectorBgColor", getString(raw.pspSelectorBgColor ?? raw.psp_selector_bg_color));
|
|
394
|
+
setIf("pspSelectorTextColor", getString(raw.pspSelectorTextColor ?? raw.psp_selector_text_color));
|
|
395
|
+
setIf("pspSelectorBorderColor", getString(raw.pspSelectorBorderColor ?? raw.psp_selector_border_color));
|
|
396
|
+
setIf("pspSelectorUseBorder", getBoolean(raw.pspSelectorUseBorder ?? raw.psp_selector_use_border));
|
|
397
|
+
return theme;
|
|
398
|
+
}
|
|
369
399
|
function mapToPaymentIntent(response, config) {
|
|
370
400
|
return {
|
|
371
401
|
id: response.id,
|
|
@@ -385,7 +415,7 @@ function mapToPaymentIntent(response, config) {
|
|
|
385
415
|
netAmount: response.net_amount,
|
|
386
416
|
metadata: config.metadata,
|
|
387
417
|
availableProviders: mapAvailableProviders(response.available_psps),
|
|
388
|
-
branding: response.branding
|
|
418
|
+
branding: normalizeBranding(response.branding)
|
|
389
419
|
};
|
|
390
420
|
}
|
|
391
421
|
function useReevit(options) {
|
|
@@ -1089,7 +1119,9 @@ function HubtelBridge({
|
|
|
1089
1119
|
publicKey,
|
|
1090
1120
|
merchantAccount,
|
|
1091
1121
|
amount,
|
|
1122
|
+
currency,
|
|
1092
1123
|
reference,
|
|
1124
|
+
email,
|
|
1093
1125
|
phone,
|
|
1094
1126
|
description = "Payment",
|
|
1095
1127
|
callbackUrl,
|
|
@@ -1104,7 +1136,6 @@ function HubtelBridge({
|
|
|
1104
1136
|
autoStart = true
|
|
1105
1137
|
}) {
|
|
1106
1138
|
const initialized = react.useRef(false);
|
|
1107
|
-
const checkoutRef = react.useRef(null);
|
|
1108
1139
|
const [authValue, setAuthValue] = react.useState("");
|
|
1109
1140
|
const [isLoading, setIsLoading] = react.useState(false);
|
|
1110
1141
|
const [resolvedMerchantAccount, setResolvedMerchantAccount] = react.useState(merchantAccount);
|
|
@@ -1118,19 +1149,17 @@ function HubtelBridge({
|
|
|
1118
1149
|
try {
|
|
1119
1150
|
const client = createReevitClient({ publicKey, baseUrl: apiBaseUrl });
|
|
1120
1151
|
const { data, error } = await client.createHubtelSession(paymentId, clientSecret);
|
|
1121
|
-
if (error) {
|
|
1152
|
+
if (error || !data?.basicAuth) {
|
|
1122
1153
|
onError({
|
|
1123
1154
|
code: "SESSION_ERROR",
|
|
1124
|
-
message: error
|
|
1155
|
+
message: error?.message || "Failed to create Hubtel session",
|
|
1125
1156
|
recoverable: true
|
|
1126
1157
|
});
|
|
1127
1158
|
return;
|
|
1128
1159
|
}
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
setResolvedMerchantAccount(data.merchantAccount);
|
|
1133
|
-
}
|
|
1160
|
+
setAuthValue(data.basicAuth);
|
|
1161
|
+
if (data.merchantAccount) {
|
|
1162
|
+
setResolvedMerchantAccount(data.merchantAccount);
|
|
1134
1163
|
}
|
|
1135
1164
|
} catch (err) {
|
|
1136
1165
|
onError({
|
|
@@ -1154,13 +1183,13 @@ function HubtelBridge({
|
|
|
1154
1183
|
}
|
|
1155
1184
|
try {
|
|
1156
1185
|
const checkout = new CheckoutSdk__default.default();
|
|
1157
|
-
checkoutRef.current = checkout;
|
|
1158
1186
|
const methodPreference = preferredMethod === "mobile_money" ? "momo" : preferredMethod === "card" ? "card" : void 0;
|
|
1159
1187
|
const purchaseInfo = {
|
|
1160
1188
|
amount: amount / 100,
|
|
1161
1189
|
// Convert from minor to major units
|
|
1162
1190
|
purchaseDescription: description,
|
|
1163
1191
|
customerPhoneNumber: phone || "",
|
|
1192
|
+
...email ? { customerEmail: email } : {},
|
|
1164
1193
|
clientReference: reference || `hubtel_${Date.now()}`,
|
|
1165
1194
|
...methodPreference ? { paymentMethod: methodPreference } : {}
|
|
1166
1195
|
};
|
|
@@ -1168,8 +1197,6 @@ function HubtelBridge({
|
|
|
1168
1197
|
branding: "enabled",
|
|
1169
1198
|
callbackUrl: callbackUrl || window.location.href,
|
|
1170
1199
|
merchantAccount: typeof resolvedMerchantAccount === "string" ? parseInt(resolvedMerchantAccount, 10) : resolvedMerchantAccount,
|
|
1171
|
-
// Use session token or basicAuth for authentication
|
|
1172
|
-
// Session tokens are base64-encoded credentials fetched securely from the server
|
|
1173
1200
|
basicAuth: authValue || "",
|
|
1174
1201
|
...methodPreference ? { paymentMethod: methodPreference } : {}
|
|
1175
1202
|
};
|
|
@@ -1183,8 +1210,8 @@ function HubtelBridge({
|
|
|
1183
1210
|
paymentId: data.transactionId || reference || "",
|
|
1184
1211
|
reference: data.clientReference || reference || "",
|
|
1185
1212
|
amount,
|
|
1186
|
-
currency: "GHS",
|
|
1187
|
-
paymentMethod: "mobile_money",
|
|
1213
|
+
currency: currency || "GHS",
|
|
1214
|
+
paymentMethod: preferredMethod || "mobile_money",
|
|
1188
1215
|
psp: "hubtel",
|
|
1189
1216
|
pspReference: data.transactionId || "",
|
|
1190
1217
|
status: "success"
|
|
@@ -1215,7 +1242,21 @@ function HubtelBridge({
|
|
|
1215
1242
|
};
|
|
1216
1243
|
onError(error);
|
|
1217
1244
|
}
|
|
1218
|
-
}, [
|
|
1245
|
+
}, [
|
|
1246
|
+
amount,
|
|
1247
|
+
reference,
|
|
1248
|
+
phone,
|
|
1249
|
+
description,
|
|
1250
|
+
callbackUrl,
|
|
1251
|
+
authValue,
|
|
1252
|
+
isLoading,
|
|
1253
|
+
preferredMethod,
|
|
1254
|
+
onSuccess,
|
|
1255
|
+
onError,
|
|
1256
|
+
onClose,
|
|
1257
|
+
resolvedMerchantAccount,
|
|
1258
|
+
currency
|
|
1259
|
+
]);
|
|
1219
1260
|
react.useEffect(() => {
|
|
1220
1261
|
if (autoStart && !initialized.current && !isLoading && authValue) {
|
|
1221
1262
|
initialized.current = true;
|
|
@@ -2173,6 +2214,7 @@ function ReevitCheckout({
|
|
|
2173
2214
|
};
|
|
2174
2215
|
}, [paymentIntent?.branding, theme]);
|
|
2175
2216
|
const themeStyles = resolvedTheme ? createThemeVariables(resolvedTheme) : {};
|
|
2217
|
+
const brandName = resolvedTheme?.companyName;
|
|
2176
2218
|
const themeMode = resolvedTheme?.darkMode;
|
|
2177
2219
|
const dataTheme = react.useMemo(() => {
|
|
2178
2220
|
if (typeof themeMode === "boolean") {
|
|
@@ -2249,7 +2291,7 @@ function ReevitCheckout({
|
|
|
2249
2291
|
{
|
|
2250
2292
|
paymentId: paymentIntent?.id || "",
|
|
2251
2293
|
publicKey,
|
|
2252
|
-
merchantAccount:
|
|
2294
|
+
merchantAccount: paymentIntent?.pspCredentials?.merchantAccount || "",
|
|
2253
2295
|
amount: paymentIntent?.amount ?? amount,
|
|
2254
2296
|
currency: paymentIntent?.currency ?? currency,
|
|
2255
2297
|
reference: paymentIntent?.reference || reference,
|
|
@@ -2415,7 +2457,17 @@ function ReevitCheckout({
|
|
|
2415
2457
|
"aria-modal": "true",
|
|
2416
2458
|
children: [
|
|
2417
2459
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "reevit-modal__header", children: [
|
|
2418
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2460
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "reevit-modal__branding", children: [
|
|
2461
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2462
|
+
"img",
|
|
2463
|
+
{
|
|
2464
|
+
src: resolvedTheme?.logoUrl || "https://i.imgur.com/bzUR5Lm.png",
|
|
2465
|
+
alt: brandName || "Reevit",
|
|
2466
|
+
className: "reevit-modal__logo"
|
|
2467
|
+
}
|
|
2468
|
+
),
|
|
2469
|
+
brandName && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "reevit-modal__brand-name", children: brandName })
|
|
2470
|
+
] }),
|
|
2419
2471
|
/* @__PURE__ */ jsxRuntime.jsx("button", { className: "reevit-modal__close", onClick: handleClose, "aria-label": "Close", children: "\u2715" })
|
|
2420
2472
|
] }),
|
|
2421
2473
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "reevit-modal__amount", children: [
|