@reevit/react 0.4.3 → 0.4.5

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
@@ -132,8 +132,8 @@ function createPaymentError(response, errorData) {
132
132
  }
133
133
  var ReevitAPIClient = class {
134
134
  constructor(config) {
135
- this.publicKey = config.publicKey;
136
- this.baseUrl = config.baseUrl || (isSandboxKey(config.publicKey) ? API_BASE_URL_SANDBOX : API_BASE_URL_PRODUCTION);
135
+ this.publicKey = config.publicKey || "";
136
+ this.baseUrl = config.baseUrl || (config.publicKey && isSandboxKey(config.publicKey) ? API_BASE_URL_SANDBOX : API_BASE_URL_PRODUCTION);
137
137
  this.timeout = config.timeout || DEFAULT_TIMEOUT;
138
138
  }
139
139
  /**
@@ -144,10 +144,12 @@ var ReevitAPIClient = class {
144
144
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
145
145
  const headers = {
146
146
  "Content-Type": "application/json",
147
- "X-Reevit-Key": this.publicKey,
148
147
  "X-Reevit-Client": "@reevit/react",
149
148
  "X-Reevit-Client-Version": "0.3.2"
150
149
  };
150
+ if (this.publicKey) {
151
+ headers["X-Reevit-Key"] = this.publicKey;
152
+ }
151
153
  if (method === "POST" || method === "PATCH" || method === "PUT") {
152
154
  headers["Idempotency-Key"] = `${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;
153
155
  }
@@ -208,12 +210,14 @@ var ReevitAPIClient = class {
208
210
  const request = {
209
211
  amount: config.amount,
210
212
  currency: config.currency,
211
- method: this.mapPaymentMethod(method),
212
213
  country,
213
214
  customer_id: config.email || config.metadata?.customerId,
214
215
  phone: config.phone,
215
216
  metadata
216
217
  };
218
+ if (method) {
219
+ request.method = this.mapPaymentMethod(method);
220
+ }
217
221
  if (options?.preferredProviders?.length || options?.allowedProviders?.length) {
218
222
  request.policy = {
219
223
  prefer: options?.preferredProviders,
@@ -254,8 +258,9 @@ var ReevitAPIClient = class {
254
258
  * @param paymentId - The payment intent ID for Hubtel checkout
255
259
  * @returns Hubtel session with token, merchant account, and expiry information
256
260
  */
257
- async createHubtelSession(paymentId) {
258
- return this.request("POST", `/v1/payments/hubtel/sessions/${paymentId}`);
261
+ async createHubtelSession(paymentId, clientSecret) {
262
+ const query = clientSecret ? `?client_secret=${encodeURIComponent(clientSecret)}` : "";
263
+ return this.request("POST", `/v1/payments/hubtel/sessions/${paymentId}${query}`);
259
264
  }
260
265
  /**
261
266
  * Maps SDK payment method to backend format
@@ -285,6 +290,18 @@ var initialState = {
285
290
  error: null,
286
291
  result: null
287
292
  };
293
+ var DEFAULT_PUBLIC_API_BASE_URL = "https://api.reevit.io";
294
+ function buildPaymentLinkError(response, data) {
295
+ return {
296
+ code: data?.code || "payment_link_error",
297
+ message: data?.message || "Payment link request failed",
298
+ recoverable: true,
299
+ details: {
300
+ httpStatus: response.status,
301
+ ...data?.details || {}
302
+ }
303
+ };
304
+ }
288
305
  function reevitReducer(state, action) {
289
306
  switch (action.type) {
290
307
  case "INIT_START":
@@ -407,16 +424,50 @@ function useReevit(options) {
407
424
  }
408
425
  const reference = config.reference || generateReference();
409
426
  const country = detectCountryFromCurrency(config.currency);
410
- const paymentMethod = method || config.paymentMethods?.[0] || "card";
411
- const { data, error } = await apiClient.createPaymentIntent(
412
- { ...config, reference },
413
- paymentMethod,
414
- country,
415
- {
416
- preferredProviders: options2?.preferredProvider ? [options2.preferredProvider] : void 0,
417
- allowedProviders: options2?.allowedProviders
427
+ const defaultMethod = config.paymentMethods && config.paymentMethods.length === 1 ? config.paymentMethods[0] : void 0;
428
+ const paymentMethod = method ?? defaultMethod;
429
+ let data;
430
+ let error;
431
+ if (config.paymentLinkCode) {
432
+ const response = await fetch(
433
+ `${apiBaseUrl || DEFAULT_PUBLIC_API_BASE_URL}/v1/pay/${config.paymentLinkCode}/pay`,
434
+ {
435
+ method: "POST",
436
+ headers: {
437
+ "Content-Type": "application/json",
438
+ "Idempotency-Key": `${Date.now()}-${Math.random().toString(36).substring(2, 15)}`
439
+ },
440
+ body: JSON.stringify({
441
+ amount: config.amount,
442
+ email: config.email || "",
443
+ name: config.customerName || "",
444
+ phone: config.phone || "",
445
+ method: paymentMethod,
446
+ country,
447
+ provider: options2?.preferredProvider || options2?.allowedProviders?.[0],
448
+ custom_fields: config.customFields
449
+ })
450
+ }
451
+ );
452
+ const responseData = await response.json().catch(() => ({}));
453
+ if (!response.ok) {
454
+ error = buildPaymentLinkError(response, responseData);
455
+ } else {
456
+ data = responseData;
418
457
  }
419
- );
458
+ } else {
459
+ const result = await apiClient.createPaymentIntent(
460
+ { ...config, reference },
461
+ paymentMethod,
462
+ country,
463
+ {
464
+ preferredProviders: options2?.preferredProvider ? [options2.preferredProvider] : void 0,
465
+ allowedProviders: options2?.allowedProviders
466
+ }
467
+ );
468
+ data = result.data;
469
+ error = result.error;
470
+ }
420
471
  if (error) {
421
472
  dispatch({ type: "INIT_ERROR", payload: error });
422
473
  onError?.(error);
@@ -1036,6 +1087,8 @@ function HubtelBridge({
1036
1087
  phone,
1037
1088
  description = "Payment",
1038
1089
  callbackUrl,
1090
+ apiBaseUrl,
1091
+ clientSecret,
1039
1092
  hubtelSessionToken,
1040
1093
  basicAuth,
1041
1094
  preferredMethod,
@@ -1048,13 +1101,17 @@ function HubtelBridge({
1048
1101
  const checkoutRef = useRef(null);
1049
1102
  const [authValue, setAuthValue] = useState("");
1050
1103
  const [isLoading, setIsLoading] = useState(false);
1104
+ const [resolvedMerchantAccount, setResolvedMerchantAccount] = useState(merchantAccount);
1105
+ useEffect(() => {
1106
+ setResolvedMerchantAccount(merchantAccount);
1107
+ }, [merchantAccount]);
1051
1108
  useEffect(() => {
1052
1109
  const fetchAuth = async () => {
1053
1110
  if (hubtelSessionToken) {
1054
1111
  setIsLoading(true);
1055
1112
  try {
1056
- const client = createReevitClient({ publicKey });
1057
- const { data, error } = await client.createHubtelSession(paymentId);
1113
+ const client = createReevitClient({ publicKey, baseUrl: apiBaseUrl });
1114
+ const { data, error } = await client.createHubtelSession(paymentId, clientSecret);
1058
1115
  if (error) {
1059
1116
  onError({
1060
1117
  code: "SESSION_ERROR",
@@ -1065,6 +1122,9 @@ function HubtelBridge({
1065
1122
  }
1066
1123
  if (data) {
1067
1124
  setAuthValue(data.token);
1125
+ if (data.merchantAccount) {
1126
+ setResolvedMerchantAccount(data.merchantAccount);
1127
+ }
1068
1128
  }
1069
1129
  } catch (err) {
1070
1130
  onError({
@@ -1081,7 +1141,7 @@ function HubtelBridge({
1081
1141
  }
1082
1142
  };
1083
1143
  fetchAuth();
1084
- }, [paymentId, publicKey, hubtelSessionToken, basicAuth, onError]);
1144
+ }, [paymentId, publicKey, apiBaseUrl, clientSecret, hubtelSessionToken, basicAuth, onError]);
1085
1145
  const startPayment = useCallback(async () => {
1086
1146
  if (isLoading || !authValue) {
1087
1147
  return;
@@ -1101,7 +1161,7 @@ function HubtelBridge({
1101
1161
  const config = {
1102
1162
  branding: "enabled",
1103
1163
  callbackUrl: callbackUrl || window.location.href,
1104
- merchantAccount: typeof merchantAccount === "string" ? parseInt(merchantAccount, 10) : merchantAccount,
1164
+ merchantAccount: typeof resolvedMerchantAccount === "string" ? parseInt(resolvedMerchantAccount, 10) : resolvedMerchantAccount,
1105
1165
  // Use session token or basicAuth for authentication
1106
1166
  // Session tokens are base64-encoded credentials fetched securely from the server
1107
1167
  basicAuth: authValue || "",
@@ -1884,8 +1944,11 @@ function ReevitCheckout({
1884
1944
  currency,
1885
1945
  email = "",
1886
1946
  phone = "",
1947
+ customerName,
1887
1948
  reference,
1888
1949
  metadata,
1950
+ customFields,
1951
+ paymentLinkCode,
1889
1952
  paymentMethods = ["card", "mobile_money"],
1890
1953
  initialPaymentIntent,
1891
1954
  // Callbacks
@@ -1936,8 +1999,11 @@ function ReevitCheckout({
1936
1999
  currency,
1937
2000
  email,
1938
2001
  phone,
2002
+ customerName,
1939
2003
  reference,
1940
2004
  metadata,
2005
+ customFields,
2006
+ paymentLinkCode,
1941
2007
  paymentMethods,
1942
2008
  initialPaymentIntent
1943
2009
  },
@@ -2145,7 +2211,7 @@ function ReevitCheckout({
2145
2211
  const psp = selectedProvider || paymentIntent?.recommendedPsp || "paystack";
2146
2212
  const pspLower = psp.toLowerCase();
2147
2213
  if (showPSPBridge) {
2148
- const pspKey = paymentIntent?.pspPublicKey || publicKey;
2214
+ const pspKey = paymentIntent?.pspPublicKey || publicKey || "";
2149
2215
  const bridgeMetadata = {
2150
2216
  ...metadata,
2151
2217
  payment_id: paymentIntent?.id,
@@ -2185,6 +2251,8 @@ function ReevitCheckout({
2185
2251
  phone: momoData?.phone || phone,
2186
2252
  description: `Payment ${paymentIntent?.reference || reference || ""}`,
2187
2253
  hubtelSessionToken: paymentIntent?.id ? paymentIntent.id : void 0,
2254
+ clientSecret: paymentIntent?.clientSecret,
2255
+ apiBaseUrl,
2188
2256
  preferredMethod: selectedMethod || void 0,
2189
2257
  onSuccess: handlePSPSuccess,
2190
2258
  onError: (err) => handlePSPError(err),
@@ -2235,7 +2303,7 @@ function ReevitCheckout({
2235
2303
  currency: paymentIntent?.currency ?? currency,
2236
2304
  reference: paymentIntent?.reference || reference || `mpesa_${Date.now()}`,
2237
2305
  description: `Payment ${paymentIntent?.reference || reference || ""}`,
2238
- headers: { "x-reevit-public-key": publicKey },
2306
+ headers: { "x-reevit-public-key": publicKey || "" },
2239
2307
  onSuccess: handlePSPSuccess,
2240
2308
  onError: handlePSPError
2241
2309
  }
@@ -2328,7 +2396,7 @@ function ReevitCheckout({
2328
2396
  ] }) })
2329
2397
  ] });
2330
2398
  };
2331
- return /* @__PURE__ */ jsxs(ReevitContext.Provider, { value: { publicKey, amount, currency }, children: [
2399
+ return /* @__PURE__ */ jsxs(ReevitContext.Provider, { value: { publicKey: publicKey || "", amount, currency }, children: [
2332
2400
  trigger,
2333
2401
  isOpen && /* @__PURE__ */ jsx("div", { className: "reevit-overlay", onClick: handleClose, children: /* @__PURE__ */ jsxs(
2334
2402
  "div",