@reevit/react 0.4.3 → 0.4.4

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
@@ -8,8 +8,8 @@ type MobileMoneyNetwork = 'mtn' | 'vodafone' | 'airteltigo';
8
8
  /** Payment source type - indicates where the payment originated from */
9
9
  type PaymentSource = 'payment_link' | 'api' | 'subscription';
10
10
  interface ReevitCheckoutConfig {
11
- /** Your Reevit public key (pk_live_xxx or pk_test_xxx) */
12
- publicKey: string;
11
+ /** Your Reevit public key (required for API-created intents; omit for payment links) */
12
+ publicKey?: string;
13
13
  /** Amount in the smallest currency unit (e.g., pesewas for GHS) */
14
14
  amount: number;
15
15
  /** Currency code (e.g., 'GHS', 'NGN', 'USD') */
@@ -18,10 +18,16 @@ interface ReevitCheckoutConfig {
18
18
  email?: string;
19
19
  /** Customer phone number (required for mobile money) */
20
20
  phone?: string;
21
+ /** Customer name (optional, used for payment links) */
22
+ customerName?: string;
21
23
  /** Unique reference for this transaction */
22
24
  reference?: string;
23
25
  /** Additional metadata to attach to the payment */
24
26
  metadata?: Record<string, unknown>;
27
+ /** Custom fields for payment links (if applicable) */
28
+ customFields?: Record<string, unknown>;
29
+ /** Payment link code (for public checkout flows) */
30
+ paymentLinkCode?: string;
25
31
  /** Payment methods to display */
26
32
  paymentMethods?: PaymentMethod[];
27
33
  /** Optional existing payment intent to use instead of creating a new one */
@@ -182,7 +188,7 @@ interface ReevitContextValue {
182
188
  currency: string;
183
189
  }
184
190
  declare function useReevitContext(): ReevitContextValue;
185
- declare function ReevitCheckout({ publicKey, amount, currency, email, phone, reference, metadata, paymentMethods, initialPaymentIntent, onSuccess, onError, onClose, onStateChange, children, autoOpen, isOpen: controlledIsOpen, onOpenChange, theme, apiBaseUrl, }: ReevitCheckoutProps): react_jsx_runtime.JSX.Element;
191
+ declare function ReevitCheckout({ publicKey, amount, currency, email, phone, customerName, reference, metadata, customFields, paymentLinkCode, paymentMethods, initialPaymentIntent, onSuccess, onError, onClose, onStateChange, children, autoOpen, isOpen: controlledIsOpen, onOpenChange, theme, apiBaseUrl, }: ReevitCheckoutProps): react_jsx_runtime.JSX.Element;
186
192
 
187
193
  interface PaymentMethodSelectorProps {
188
194
  methods: PaymentMethod[];
@@ -291,7 +297,7 @@ declare function PaystackBridge({ publicKey, email, phone, amount, currency, ref
291
297
 
292
298
  interface HubtelBridgeProps {
293
299
  paymentId: string;
294
- publicKey: string;
300
+ publicKey?: string;
295
301
  merchantAccount: string | number;
296
302
  amount: number;
297
303
  currency?: string;
@@ -300,6 +306,8 @@ interface HubtelBridgeProps {
300
306
  phone?: string;
301
307
  description?: string;
302
308
  callbackUrl?: string;
309
+ apiBaseUrl?: string;
310
+ clientSecret?: string;
303
311
  /** Session token from server (recommended - credentials never exposed to client) */
304
312
  hubtelSessionToken?: string;
305
313
  /** Basic auth credential (legacy - credentials exposed to client, deprecated) */
@@ -310,7 +318,7 @@ interface HubtelBridgeProps {
310
318
  onClose: () => void;
311
319
  autoStart?: boolean;
312
320
  }
313
- declare function HubtelBridge({ paymentId, publicKey, merchantAccount, amount, reference, phone, description, callbackUrl, hubtelSessionToken, basicAuth, preferredMethod, onSuccess, onError, onClose, autoStart, }: HubtelBridgeProps): react_jsx_runtime.JSX.Element;
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;
314
322
  /**
315
323
  * Opens Hubtel checkout modal directly
316
324
  * Uses the @hubteljs/checkout npm package
@@ -639,7 +647,7 @@ interface PaymentDetailResponse {
639
647
  }
640
648
  interface ReevitAPIClientConfig {
641
649
  /** Your Reevit public key */
642
- publicKey: string;
650
+ publicKey?: string;
643
651
  /** Base URL for the Reevit API (defaults to production) */
644
652
  baseUrl?: string;
645
653
  /** Request timeout in milliseconds */
@@ -703,7 +711,7 @@ declare class ReevitAPIClient {
703
711
  * @param paymentId - The payment intent ID for Hubtel checkout
704
712
  * @returns Hubtel session with token, merchant account, and expiry information
705
713
  */
706
- createHubtelSession(paymentId: string): Promise<{
714
+ createHubtelSession(paymentId: string, clientSecret?: string): Promise<{
707
715
  data?: HubtelSessionResponse;
708
716
  error?: PaymentError;
709
717
  }>;
package/dist/index.d.ts CHANGED
@@ -8,8 +8,8 @@ type MobileMoneyNetwork = 'mtn' | 'vodafone' | 'airteltigo';
8
8
  /** Payment source type - indicates where the payment originated from */
9
9
  type PaymentSource = 'payment_link' | 'api' | 'subscription';
10
10
  interface ReevitCheckoutConfig {
11
- /** Your Reevit public key (pk_live_xxx or pk_test_xxx) */
12
- publicKey: string;
11
+ /** Your Reevit public key (required for API-created intents; omit for payment links) */
12
+ publicKey?: string;
13
13
  /** Amount in the smallest currency unit (e.g., pesewas for GHS) */
14
14
  amount: number;
15
15
  /** Currency code (e.g., 'GHS', 'NGN', 'USD') */
@@ -18,10 +18,16 @@ interface ReevitCheckoutConfig {
18
18
  email?: string;
19
19
  /** Customer phone number (required for mobile money) */
20
20
  phone?: string;
21
+ /** Customer name (optional, used for payment links) */
22
+ customerName?: string;
21
23
  /** Unique reference for this transaction */
22
24
  reference?: string;
23
25
  /** Additional metadata to attach to the payment */
24
26
  metadata?: Record<string, unknown>;
27
+ /** Custom fields for payment links (if applicable) */
28
+ customFields?: Record<string, unknown>;
29
+ /** Payment link code (for public checkout flows) */
30
+ paymentLinkCode?: string;
25
31
  /** Payment methods to display */
26
32
  paymentMethods?: PaymentMethod[];
27
33
  /** Optional existing payment intent to use instead of creating a new one */
@@ -182,7 +188,7 @@ interface ReevitContextValue {
182
188
  currency: string;
183
189
  }
184
190
  declare function useReevitContext(): ReevitContextValue;
185
- declare function ReevitCheckout({ publicKey, amount, currency, email, phone, reference, metadata, paymentMethods, initialPaymentIntent, onSuccess, onError, onClose, onStateChange, children, autoOpen, isOpen: controlledIsOpen, onOpenChange, theme, apiBaseUrl, }: ReevitCheckoutProps): react_jsx_runtime.JSX.Element;
191
+ declare function ReevitCheckout({ publicKey, amount, currency, email, phone, customerName, reference, metadata, customFields, paymentLinkCode, paymentMethods, initialPaymentIntent, onSuccess, onError, onClose, onStateChange, children, autoOpen, isOpen: controlledIsOpen, onOpenChange, theme, apiBaseUrl, }: ReevitCheckoutProps): react_jsx_runtime.JSX.Element;
186
192
 
187
193
  interface PaymentMethodSelectorProps {
188
194
  methods: PaymentMethod[];
@@ -291,7 +297,7 @@ declare function PaystackBridge({ publicKey, email, phone, amount, currency, ref
291
297
 
292
298
  interface HubtelBridgeProps {
293
299
  paymentId: string;
294
- publicKey: string;
300
+ publicKey?: string;
295
301
  merchantAccount: string | number;
296
302
  amount: number;
297
303
  currency?: string;
@@ -300,6 +306,8 @@ interface HubtelBridgeProps {
300
306
  phone?: string;
301
307
  description?: string;
302
308
  callbackUrl?: string;
309
+ apiBaseUrl?: string;
310
+ clientSecret?: string;
303
311
  /** Session token from server (recommended - credentials never exposed to client) */
304
312
  hubtelSessionToken?: string;
305
313
  /** Basic auth credential (legacy - credentials exposed to client, deprecated) */
@@ -310,7 +318,7 @@ interface HubtelBridgeProps {
310
318
  onClose: () => void;
311
319
  autoStart?: boolean;
312
320
  }
313
- declare function HubtelBridge({ paymentId, publicKey, merchantAccount, amount, reference, phone, description, callbackUrl, hubtelSessionToken, basicAuth, preferredMethod, onSuccess, onError, onClose, autoStart, }: HubtelBridgeProps): react_jsx_runtime.JSX.Element;
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;
314
322
  /**
315
323
  * Opens Hubtel checkout modal directly
316
324
  * Uses the @hubteljs/checkout npm package
@@ -639,7 +647,7 @@ interface PaymentDetailResponse {
639
647
  }
640
648
  interface ReevitAPIClientConfig {
641
649
  /** Your Reevit public key */
642
- publicKey: string;
650
+ publicKey?: string;
643
651
  /** Base URL for the Reevit API (defaults to production) */
644
652
  baseUrl?: string;
645
653
  /** Request timeout in milliseconds */
@@ -703,7 +711,7 @@ declare class ReevitAPIClient {
703
711
  * @param paymentId - The payment intent ID for Hubtel checkout
704
712
  * @returns Hubtel session with token, merchant account, and expiry information
705
713
  */
706
- createHubtelSession(paymentId: string): Promise<{
714
+ createHubtelSession(paymentId: string, clientSecret?: string): Promise<{
707
715
  data?: HubtelSessionResponse;
708
716
  error?: PaymentError;
709
717
  }>;
package/dist/index.js CHANGED
@@ -138,8 +138,8 @@ function createPaymentError(response, errorData) {
138
138
  }
139
139
  var ReevitAPIClient = class {
140
140
  constructor(config) {
141
- this.publicKey = config.publicKey;
142
- this.baseUrl = config.baseUrl || (isSandboxKey(config.publicKey) ? API_BASE_URL_SANDBOX : API_BASE_URL_PRODUCTION);
141
+ this.publicKey = config.publicKey || "";
142
+ this.baseUrl = config.baseUrl || (config.publicKey && isSandboxKey(config.publicKey) ? API_BASE_URL_SANDBOX : API_BASE_URL_PRODUCTION);
143
143
  this.timeout = config.timeout || DEFAULT_TIMEOUT;
144
144
  }
145
145
  /**
@@ -150,10 +150,12 @@ var ReevitAPIClient = class {
150
150
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
151
151
  const headers = {
152
152
  "Content-Type": "application/json",
153
- "X-Reevit-Key": this.publicKey,
154
153
  "X-Reevit-Client": "@reevit/react",
155
154
  "X-Reevit-Client-Version": "0.3.2"
156
155
  };
156
+ if (this.publicKey) {
157
+ headers["X-Reevit-Key"] = this.publicKey;
158
+ }
157
159
  if (method === "POST" || method === "PATCH" || method === "PUT") {
158
160
  headers["Idempotency-Key"] = `${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;
159
161
  }
@@ -260,8 +262,9 @@ var ReevitAPIClient = class {
260
262
  * @param paymentId - The payment intent ID for Hubtel checkout
261
263
  * @returns Hubtel session with token, merchant account, and expiry information
262
264
  */
263
- async createHubtelSession(paymentId) {
264
- return this.request("POST", `/v1/payments/hubtel/sessions/${paymentId}`);
265
+ async createHubtelSession(paymentId, clientSecret) {
266
+ const query = clientSecret ? `?client_secret=${encodeURIComponent(clientSecret)}` : "";
267
+ return this.request("POST", `/v1/payments/hubtel/sessions/${paymentId}${query}`);
265
268
  }
266
269
  /**
267
270
  * Maps SDK payment method to backend format
@@ -291,6 +294,18 @@ var initialState = {
291
294
  error: null,
292
295
  result: null
293
296
  };
297
+ var DEFAULT_PUBLIC_API_BASE_URL = "https://api.reevit.io";
298
+ function buildPaymentLinkError(response, data) {
299
+ return {
300
+ code: data?.code || "payment_link_error",
301
+ message: data?.message || "Payment link request failed",
302
+ recoverable: true,
303
+ details: {
304
+ httpStatus: response.status,
305
+ ...data?.details || {}
306
+ }
307
+ };
308
+ }
294
309
  function reevitReducer(state, action) {
295
310
  switch (action.type) {
296
311
  case "INIT_START":
@@ -414,15 +429,48 @@ function useReevit(options) {
414
429
  const reference = config.reference || generateReference();
415
430
  const country = detectCountryFromCurrency(config.currency);
416
431
  const paymentMethod = method || config.paymentMethods?.[0] || "card";
417
- const { data, error } = await apiClient.createPaymentIntent(
418
- { ...config, reference },
419
- paymentMethod,
420
- country,
421
- {
422
- preferredProviders: options2?.preferredProvider ? [options2.preferredProvider] : void 0,
423
- allowedProviders: options2?.allowedProviders
432
+ let data;
433
+ let error;
434
+ if (config.paymentLinkCode) {
435
+ const response = await fetch(
436
+ `${apiBaseUrl || DEFAULT_PUBLIC_API_BASE_URL}/v1/pay/${config.paymentLinkCode}/pay`,
437
+ {
438
+ method: "POST",
439
+ headers: {
440
+ "Content-Type": "application/json",
441
+ "Idempotency-Key": `${Date.now()}-${Math.random().toString(36).substring(2, 15)}`
442
+ },
443
+ body: JSON.stringify({
444
+ amount: config.amount,
445
+ email: config.email || "",
446
+ name: config.customerName || "",
447
+ phone: config.phone || "",
448
+ method: paymentMethod,
449
+ country,
450
+ provider: options2?.preferredProvider || options2?.allowedProviders?.[0],
451
+ custom_fields: config.customFields
452
+ })
453
+ }
454
+ );
455
+ const responseData = await response.json().catch(() => ({}));
456
+ if (!response.ok) {
457
+ error = buildPaymentLinkError(response, responseData);
458
+ } else {
459
+ data = responseData;
424
460
  }
425
- );
461
+ } else {
462
+ const result = await apiClient.createPaymentIntent(
463
+ { ...config, reference },
464
+ paymentMethod,
465
+ country,
466
+ {
467
+ preferredProviders: options2?.preferredProvider ? [options2.preferredProvider] : void 0,
468
+ allowedProviders: options2?.allowedProviders
469
+ }
470
+ );
471
+ data = result.data;
472
+ error = result.error;
473
+ }
426
474
  if (error) {
427
475
  dispatch({ type: "INIT_ERROR", payload: error });
428
476
  onError?.(error);
@@ -1042,6 +1090,8 @@ function HubtelBridge({
1042
1090
  phone,
1043
1091
  description = "Payment",
1044
1092
  callbackUrl,
1093
+ apiBaseUrl,
1094
+ clientSecret,
1045
1095
  hubtelSessionToken,
1046
1096
  basicAuth,
1047
1097
  preferredMethod,
@@ -1054,13 +1104,17 @@ function HubtelBridge({
1054
1104
  const checkoutRef = react.useRef(null);
1055
1105
  const [authValue, setAuthValue] = react.useState("");
1056
1106
  const [isLoading, setIsLoading] = react.useState(false);
1107
+ const [resolvedMerchantAccount, setResolvedMerchantAccount] = react.useState(merchantAccount);
1108
+ react.useEffect(() => {
1109
+ setResolvedMerchantAccount(merchantAccount);
1110
+ }, [merchantAccount]);
1057
1111
  react.useEffect(() => {
1058
1112
  const fetchAuth = async () => {
1059
1113
  if (hubtelSessionToken) {
1060
1114
  setIsLoading(true);
1061
1115
  try {
1062
- const client = createReevitClient({ publicKey });
1063
- const { data, error } = await client.createHubtelSession(paymentId);
1116
+ const client = createReevitClient({ publicKey, baseUrl: apiBaseUrl });
1117
+ const { data, error } = await client.createHubtelSession(paymentId, clientSecret);
1064
1118
  if (error) {
1065
1119
  onError({
1066
1120
  code: "SESSION_ERROR",
@@ -1071,6 +1125,9 @@ function HubtelBridge({
1071
1125
  }
1072
1126
  if (data) {
1073
1127
  setAuthValue(data.token);
1128
+ if (data.merchantAccount) {
1129
+ setResolvedMerchantAccount(data.merchantAccount);
1130
+ }
1074
1131
  }
1075
1132
  } catch (err) {
1076
1133
  onError({
@@ -1087,7 +1144,7 @@ function HubtelBridge({
1087
1144
  }
1088
1145
  };
1089
1146
  fetchAuth();
1090
- }, [paymentId, publicKey, hubtelSessionToken, basicAuth, onError]);
1147
+ }, [paymentId, publicKey, apiBaseUrl, clientSecret, hubtelSessionToken, basicAuth, onError]);
1091
1148
  const startPayment = react.useCallback(async () => {
1092
1149
  if (isLoading || !authValue) {
1093
1150
  return;
@@ -1107,7 +1164,7 @@ function HubtelBridge({
1107
1164
  const config = {
1108
1165
  branding: "enabled",
1109
1166
  callbackUrl: callbackUrl || window.location.href,
1110
- merchantAccount: typeof merchantAccount === "string" ? parseInt(merchantAccount, 10) : merchantAccount,
1167
+ merchantAccount: typeof resolvedMerchantAccount === "string" ? parseInt(resolvedMerchantAccount, 10) : resolvedMerchantAccount,
1111
1168
  // Use session token or basicAuth for authentication
1112
1169
  // Session tokens are base64-encoded credentials fetched securely from the server
1113
1170
  basicAuth: authValue || "",
@@ -1890,8 +1947,11 @@ function ReevitCheckout({
1890
1947
  currency,
1891
1948
  email = "",
1892
1949
  phone = "",
1950
+ customerName,
1893
1951
  reference,
1894
1952
  metadata,
1953
+ customFields,
1954
+ paymentLinkCode,
1895
1955
  paymentMethods = ["card", "mobile_money"],
1896
1956
  initialPaymentIntent,
1897
1957
  // Callbacks
@@ -1942,8 +2002,11 @@ function ReevitCheckout({
1942
2002
  currency,
1943
2003
  email,
1944
2004
  phone,
2005
+ customerName,
1945
2006
  reference,
1946
2007
  metadata,
2008
+ customFields,
2009
+ paymentLinkCode,
1947
2010
  paymentMethods,
1948
2011
  initialPaymentIntent
1949
2012
  },
@@ -2151,7 +2214,7 @@ function ReevitCheckout({
2151
2214
  const psp = selectedProvider || paymentIntent?.recommendedPsp || "paystack";
2152
2215
  const pspLower = psp.toLowerCase();
2153
2216
  if (showPSPBridge) {
2154
- const pspKey = paymentIntent?.pspPublicKey || publicKey;
2217
+ const pspKey = paymentIntent?.pspPublicKey || publicKey || "";
2155
2218
  const bridgeMetadata = {
2156
2219
  ...metadata,
2157
2220
  payment_id: paymentIntent?.id,
@@ -2191,6 +2254,8 @@ function ReevitCheckout({
2191
2254
  phone: momoData?.phone || phone,
2192
2255
  description: `Payment ${paymentIntent?.reference || reference || ""}`,
2193
2256
  hubtelSessionToken: paymentIntent?.id ? paymentIntent.id : void 0,
2257
+ clientSecret: paymentIntent?.clientSecret,
2258
+ apiBaseUrl,
2194
2259
  preferredMethod: selectedMethod || void 0,
2195
2260
  onSuccess: handlePSPSuccess,
2196
2261
  onError: (err) => handlePSPError(err),
@@ -2241,7 +2306,7 @@ function ReevitCheckout({
2241
2306
  currency: paymentIntent?.currency ?? currency,
2242
2307
  reference: paymentIntent?.reference || reference || `mpesa_${Date.now()}`,
2243
2308
  description: `Payment ${paymentIntent?.reference || reference || ""}`,
2244
- headers: { "x-reevit-public-key": publicKey },
2309
+ headers: { "x-reevit-public-key": publicKey || "" },
2245
2310
  onSuccess: handlePSPSuccess,
2246
2311
  onError: handlePSPError
2247
2312
  }
@@ -2334,7 +2399,7 @@ function ReevitCheckout({
2334
2399
  ] }) })
2335
2400
  ] });
2336
2401
  };
2337
- return /* @__PURE__ */ jsxRuntime.jsxs(ReevitContext.Provider, { value: { publicKey, amount, currency }, children: [
2402
+ return /* @__PURE__ */ jsxRuntime.jsxs(ReevitContext.Provider, { value: { publicKey: publicKey || "", amount, currency }, children: [
2338
2403
  trigger,
2339
2404
  isOpen && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "reevit-overlay", onClick: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs(
2340
2405
  "div",