{"version":3,"sources":["../src/context/BeninPaymentContext.tsx","../src/utils/scriptLoader.ts","../src/utils/logger.ts","../src/utils/analytics.ts","../src/utils/errors.ts","../src/utils/verifyTransaction.ts","../src/core/createPaymentEngine.ts","../src/core/usePaymentEngine.ts","../src/utils/keyValidator.ts","../src/utils/currency.ts","../src/core/validateCommonConfig.ts","../src/providers/fedapay.ts","../src/utils/environment.ts","../src/hooks/mergeI18nOptions.ts","../src/hooks/useFedaPay.ts","../src/providers/kkiapay.ts","../src/hooks/useKkiaPay.ts","../src/hooks/useBeninPay.ts","../src/hooks/usePaymentStatus.ts","../src/hooks/usePaymentHistory.ts","../src/hooks/useRetryPayment.ts","../src/utils/pdfHelpers.ts","../src/utils/generateReceipt.ts","../src/utils/sendReceiptEmail.ts","../src/hooks/usePaymentReceipt.ts","../src/components/FedaPayButton.tsx","../src/components/KkiaPayButton.tsx","../src/components/FedaPayConsumer.tsx","../src/components/KkiaPayConsumer.tsx","../src/components/icons/FedaPayLogo.tsx","../src/components/icons/KkiaPayLogo.tsx","../src/components/PaymentStatusBadge.tsx"],"names":["validationError","useMemo","useRef","useCallback","useState","useEffect","y","jsx","forwardRef","jsxs","DEFAULT_LABELS"],"mappings":"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","file":"index.mjs","sourcesContent":["\"use client\";\r\n\r\nimport {\r\n  createContext,\r\n  useContext,\r\n  useMemo,\r\n  type ReactNode,\r\n} from \"react\";\r\nimport type { Currency } from \"../types\";\r\nimport type { BeninPaymentAnalyticsHandler } from \"../utils/analytics\";\r\nimport type { ErrorMessageResolver, PaymentMessageOverrides } from \"../types/validation\";\r\nimport type { EnvironmentWarningMessages } from \"../utils/keyValidator\";\r\n\r\n/**\r\n * Global configuration for Benin Payment providers.\r\n */\r\nexport interface BeninPaymentConfig {\r\n  /** \r\n   * Default FedaPay public key.\r\n   * Will be used if no key is provided at the component level.\r\n   * @example \"pk_live_xxxxxxxxxxxx\"\r\n   */\r\n  fedaPayPublicKey?: string;\r\n  /** \r\n   * Default KKiaPay public key.\r\n   * Will be used if no key is provided at the component level.\r\n   * @example \"pk_xxxxxxxxxxxx\"\r\n   */\r\n  kkiaPayPublicKey?: string;\r\n  /** \r\n   * Default currency for all transactions.\r\n   * @default \"XOF\"\r\n   */\r\n  defaultCurrency?: Currency;\r\n  /** \r\n   * Force sandbox/test mode globally.\r\n   * When true, all transactions will be in test mode.\r\n   * @default false\r\n   */\r\n  isTestMode?: boolean;\r\n  /** \r\n   * Enable debug mode globally.\r\n   * Shows console logs for all payment operations.\r\n   * @default false\r\n   */\r\n  debug?: boolean;\r\n  /**\r\n   * Global analytics callback for standardized payment events.\r\n   */\r\n  onAnalyticsEvent?: BeninPaymentAnalyticsHandler;\r\n  /**\r\n   * Overrides the wording of built-in validation error messages\r\n   * (missing key, invalid amount, SDK not loaded...) for every hook.\r\n   * Can be refined per-hook via `useFedaPay`/`useKkiaPay` options.\r\n   */\r\n  messages?: PaymentMessageOverrides;\r\n  /**\r\n   * Resolves the message for arbitrary caught errors (SDK load failures,\r\n   * network errors...) surfaced via a hook's `error` state. Falls back to\r\n   * the built-in French translations when it returns `undefined`.\r\n   */\r\n  resolveErrorMessage?: ErrorMessageResolver;\r\n  /**\r\n   * Overrides the wording of dev-time console warnings (live key used in\r\n   * sandbox mode, etc.) for every hook. Can be refined per-hook via\r\n   * `useFedaPay`/`useKkiaPay` options.\r\n   */\r\n  environmentWarnings?: EnvironmentWarningMessages;\r\n}\r\n\r\n/**\r\n * Internal context value with resolved defaults.\r\n */\r\ninterface BeninPaymentContextValue {\r\n  fedaPayPublicKey: string | undefined;\r\n  kkiaPayPublicKey: string | undefined;\r\n  defaultCurrency: Currency;\r\n  isTestMode: boolean;\r\n  debug: boolean;\r\n  onAnalyticsEvent?: BeninPaymentAnalyticsHandler;\r\n  messages?: PaymentMessageOverrides;\r\n  resolveErrorMessage?: ErrorMessageResolver;\r\n  environmentWarnings?: EnvironmentWarningMessages;\r\n  isProviderMounted: boolean;\r\n}\r\n\r\nconst BeninPaymentContext = createContext<BeninPaymentContextValue | null>(null);\r\n\r\n/**\r\n * Props for the BeninPaymentProvider component.\r\n */\r\nexport interface BeninPaymentProviderProps extends BeninPaymentConfig {\r\n  /** Child components that will have access to the payment context */\r\n  children: ReactNode;\r\n}\r\n\r\n/**\r\n * Global provider for Benin Payment configuration.\r\n * \r\n * Wrap your application (or a section of it) with this provider to set\r\n * default values for all FedaPay and KKiaPay hooks and components.\r\n * \r\n * @example\r\n * ```tsx\r\n * import { BeninPaymentProvider } from \"react-benin-payments\";\r\n * \r\n * function App() {\r\n *   return (\r\n *     <BeninPaymentProvider\r\n *       fedaPayPublicKey=\"pk_live_xxxxxxxxxxxx\"\r\n *       kkiaPayPublicKey=\"pk_xxxxxxxxxxxx\"\r\n *       defaultCurrency=\"XOF\"\r\n *       isTestMode={process.env.NODE_ENV === \"development\"}\r\n *       debug={true}\r\n *     >\r\n *       <YourApp />\r\n *     </BeninPaymentProvider>\r\n *   );\r\n * }\r\n * ```\r\n * \r\n * @example\r\n * ```tsx\r\n * // Components inside the provider can now use hooks without passing keys\r\n * function PaymentButton() {\r\n *   const { openDialog, loading } = useFedaPay({\r\n *     transaction: { amount: 5000 }\r\n *     // No need for public_key - it's taken from the provider!\r\n *   });\r\n * \r\n *   return <button onClick={openDialog}>Pay</button>;\r\n * }\r\n * ```\r\n */\r\nexport function BeninPaymentProvider({\r\n  fedaPayPublicKey,\r\n  kkiaPayPublicKey,\r\n  defaultCurrency = \"XOF\",\r\n  isTestMode = false,\r\n  debug = false,\r\n  onAnalyticsEvent,\r\n  messages,\r\n  resolveErrorMessage,\r\n  environmentWarnings,\r\n  children,\r\n}: BeninPaymentProviderProps) {\r\n  const value = useMemo<BeninPaymentContextValue>(\r\n    () => ({\r\n      fedaPayPublicKey,\r\n      kkiaPayPublicKey,\r\n      defaultCurrency,\r\n      isTestMode,\r\n      debug,\r\n      onAnalyticsEvent,\r\n      messages,\r\n      resolveErrorMessage,\r\n      environmentWarnings,\r\n      isProviderMounted: true,\r\n    }),\r\n    [\r\n      fedaPayPublicKey,\r\n      kkiaPayPublicKey,\r\n      defaultCurrency,\r\n      isTestMode,\r\n      debug,\r\n      onAnalyticsEvent,\r\n      messages,\r\n      resolveErrorMessage,\r\n      environmentWarnings,\r\n    ]\r\n  );\r\n\r\n  return (\r\n    <BeninPaymentContext.Provider value={value}>\r\n      {children}\r\n    </BeninPaymentContext.Provider>\r\n  );\r\n}\r\n\r\n/**\r\n * Hook to access the global Benin Payment configuration.\r\n * \r\n * Returns the configuration from the nearest BeninPaymentProvider,\r\n * or default values if no provider is found.\r\n * \r\n * @returns The current payment configuration\r\n * \r\n * @example\r\n * ```tsx\r\n * function PaymentStatus() {\r\n *   const { isTestMode, defaultCurrency, debug } = useBeninConfig();\r\n *   \r\n *   return (\r\n *     <div>\r\n *       Mode: {isTestMode ? \"Test\" : \"Production\"}\r\n *       Currency: {defaultCurrency}\r\n *     </div>\r\n *   );\r\n * }\r\n * ```\r\n */\r\nexport function useBeninConfig(): BeninPaymentContextValue {\r\n  const context = useContext(BeninPaymentContext);\r\n  \r\n  if (!context) {\r\n    return {\r\n      fedaPayPublicKey: undefined,\r\n      kkiaPayPublicKey: undefined,\r\n      defaultCurrency: \"XOF\",\r\n      isTestMode: false,\r\n      debug: false,\r\n      onAnalyticsEvent: undefined,\r\n      isProviderMounted: false,\r\n    };\r\n  }\r\n  \r\n  return context;\r\n}\r\n\r\n/**\r\n * Hook to check if the app is wrapped with BeninPaymentProvider.\r\n * \r\n * @returns true if provider is mounted, false otherwise\r\n */\r\nexport function useIsBeninProviderMounted(): boolean {\r\n  const context = useContext(BeninPaymentContext);\r\n  return context?.isProviderMounted ?? false;\r\n}\r\n","/**\r\n * Loads an external JavaScript script dynamically.\r\n * \r\n * Checks if a script with the given ID already exists to prevent duplicates.\r\n * Scripts are loaded asynchronously to avoid blocking page rendering.\r\n * \r\n * @param src - The URL of the script to load\r\n * @param id - Unique ID for the script element (used for deduplication)\r\n * @returns Promise that resolves to `true` when loaded, or rejects on error\r\n * \r\n * @example\r\n * ```ts\r\n * await loadScript(\"https://cdn.example.com/sdk.js\", \"example-sdk\");\r\n * // SDK is now available on window\r\n * ```\r\n */\r\nexport function loadScript(src: string, id: string): Promise<boolean> {\r\n  // Guard for SSR environments (Next.js server components, Node.js)\r\n  if (typeof document === \"undefined\") {\r\n    return Promise.resolve(false);\r\n  }\r\n\r\n  return new Promise((resolve, reject) => {\r\n    const existingScript = document.getElementById(id) as HTMLScriptElement | null;\r\n\r\n    if (existingScript) {\r\n      // Script already in the DOM — resolve immediately to avoid duplicates.\r\n      // We trust the existing element is either loaded or being loaded elsewhere.\r\n      resolve(true);\r\n      return;\r\n    }\r\n\r\n    const script = document.createElement(\"script\");\r\n    script.id = id;\r\n    script.src = src;\r\n    script.async = true;\r\n\r\n    script.onload = () => {\r\n      script.dataset.loaded = \"true\";\r\n      resolve(true);\r\n    };\r\n\r\n    script.onerror = () => {\r\n      reject(new Error(`Failed to load script: ${src}`));\r\n    };\r\n\r\n    document.body.appendChild(script);\r\n  });\r\n}\r\n","const PREFIX = \"[react-benin-payments]\";\r\n\r\nconst STYLES = {\r\n  info: \"color: #4E6BFF; font-weight: bold;\",\r\n  success: \"color: #0AB67A; font-weight: bold;\",\r\n  error: \"color: #EF4444; font-weight: bold;\",\r\n  warn: \"color: #F59E0B; font-weight: bold;\",\r\n};\r\n\r\n/**\r\n * Creates a styled logger for debug mode.\r\n * \r\n * When enabled, logs are color-coded by level:\r\n * - Info: Blue (#4E6BFF)\r\n * - Success: Green (#0AB67A)\r\n * - Error: Red (#EF4444)\r\n * - Warn: Orange (#F59E0B)\r\n * \r\n * @param enabled - Whether logging is enabled\r\n * @returns Logger object with info, success, error, and warn methods\r\n * \r\n * @example\r\n * ```ts\r\n * const log = createLogger(true);\r\n * log.info(\"Loading SDK...\");\r\n * log.success(\"SDK loaded!\");\r\n * log.error(\"Failed to load\", error);\r\n * ```\r\n */\r\nexport function createLogger(enabled: boolean): Logger {\r\n  return {\r\n    info: (message: string, ...args: unknown[]) => {\r\n      if (enabled) {\r\n        console.log(`%c${PREFIX} ${message}`, STYLES.info, ...args);\r\n      }\r\n    },\r\n    success: (message: string, ...args: unknown[]) => {\r\n      if (enabled) {\r\n        console.log(`%c${PREFIX} ${message}`, STYLES.success, ...args);\r\n      }\r\n    },\r\n    error: (message: string, ...args: unknown[]) => {\r\n      if (enabled) {\r\n        console.error(`%c${PREFIX} ${message}`, STYLES.error, ...args);\r\n      }\r\n    },\r\n    warn: (message: string, ...args: unknown[]) => {\r\n      if (enabled) {\r\n        console.warn(`%c${PREFIX} ${message}`, STYLES.warn, ...args);\r\n      }\r\n    },\r\n  };\r\n}\r\n\r\n/**\r\n * Logger interface with color-coded methods.\r\n */\r\nexport interface Logger {\r\n  /** Log informational message (blue) */\r\n  info: (message: string, ...args: unknown[]) => void;\r\n  /** Log success message (green) */\r\n  success: (message: string, ...args: unknown[]) => void;\r\n  /** Log error message (red) */\r\n  error: (message: string, ...args: unknown[]) => void;\r\n  /** Log warning message (orange) */\r\n  warn: (message: string, ...args: unknown[]) => void;\r\n}\r\n","import type { PaymentProviderId } from \"../core/types\";\r\n\r\nexport type BeninPaymentAnalyticsEventName =\r\n  | \"sdk_load_started\"\r\n  | \"sdk_load_succeeded\"\r\n  | \"sdk_load_failed\"\r\n  | \"payment_validation_failed\"\r\n  | \"payment_pre_validation_started\"\r\n  | \"payment_pre_validation_succeeded\"\r\n  | \"payment_pre_validation_cancelled\"\r\n  | \"payment_pre_validation_failed\"\r\n  | \"payment_open_attempted\"\r\n  | \"payment_opened\"\r\n  | \"payment_completed\"\r\n  | \"payment_failed\"\r\n  | \"payment_closed\"\r\n  | \"payment_verification_started\"\r\n  | \"payment_verification_succeeded\"\r\n  | \"payment_verification_failed\";\r\n\r\nexport interface BeninPaymentAnalyticsEvent {\r\n  name: BeninPaymentAnalyticsEventName;\r\n  /** `\"fedapay\"` / `\"kkiapay\"`, or a custom provider identifier for a driver you wrote yourself. */\r\n  provider: PaymentProviderId;\r\n  amount?: number;\r\n  currency?: string;\r\n  mode: \"mock\" | \"live\";\r\n  transactionId?: string;\r\n  status?: string;\r\n  errorCode?: string;\r\n  errorMessage?: string;\r\n  timestamp: string;\r\n  metadata?: Record<string, unknown>;\r\n}\r\n\r\nexport type BeninPaymentAnalyticsHandler = (\r\n  event: BeninPaymentAnalyticsEvent\r\n) => void | Promise<void>;\r\n\r\nexport function createAnalyticsEmitter(\r\n  handlers: Array<BeninPaymentAnalyticsHandler | undefined>,\r\n  debugLog?: (message: string, ...args: unknown[]) => void\r\n): (event: Omit<BeninPaymentAnalyticsEvent, \"timestamp\">) => void {\r\n  return (event) => {\r\n    const fullEvent: BeninPaymentAnalyticsEvent = {\r\n      ...event,\r\n      timestamp: new Date().toISOString(),\r\n    };\r\n\r\n    handlers.forEach((handler) => {\r\n      if (!handler) return;\r\n\r\n      try {\r\n        void Promise.resolve(handler(fullEvent)).catch((error) => {\r\n          debugLog?.(\"Analytics handler failed\", error);\r\n        });\r\n      } catch (error) {\r\n        debugLog?.(\"Analytics handler failed\", error);\r\n      }\r\n    });\r\n  };\r\n}\r\n","/**\n * A pattern matched against a raw error message, with the user-facing\n * message to show when it matches.\n */\nexport interface ErrorPattern {\n  pattern: RegExp;\n  message: string;\n}\n\n/**\n * Options to fully control `parseError`'s output — pass your own patterns\n * and/or fallback message to translate or reword the built-in French\n * defaults, instead of being stuck with them.\n */\nexport interface ParseErrorOptions {\n  /**\n   * Patterns checked in order; the first match wins. Defaults to\n   * `DEFAULT_ERROR_PATTERNS`. Spread the defaults in if you only want to\n   * add or reorder a few: `{ patterns: [...myPatterns, ...DEFAULT_ERROR_PATTERNS] }`.\n   */\n  patterns?: ErrorPattern[];\n  /** Returned when nothing matches and the error has no usable message. */\n  fallbackMessage?: string;\n}\n\n/**\n * Default error patterns and their French, user-friendly translations.\n * Exported so you can extend rather than fully replace them — see\n * `ParseErrorOptions.patterns`.\n */\nexport const DEFAULT_ERROR_PATTERNS: ErrorPattern[] = [\n  { pattern: /closed|dismissed|cancel/i, message: \"Paiement annulé.\" },\n  { pattern: /insufficient.*(fund|balance)/i, message: \"Solde insuffisant sur votre compte.\" },\n  { pattern: /network|connection|offline/i, message: \"Problème de connexion internet.\" },\n  { pattern: /timeout/i, message: \"La requête a expiré. Veuillez réessayer.\" },\n  { pattern: /invalid.*key/i, message: \"Clé API invalide.\" },\n  { pattern: /invalid.*amount/i, message: \"Montant invalide.\" },\n  { pattern: /unauthorized|401/i, message: \"Accès non autorisé.\" },\n  { pattern: /not.*found|404/i, message: \"Ressource introuvable.\" },\n  { pattern: /server.*error|500/i, message: \"Erreur serveur. Veuillez réessayer.\" },\n];\n\nconst DEFAULT_FALLBACK_MESSAGE = \"Une erreur inconnue est survenue.\";\n\n/**\n * Parses an error and returns a user-friendly message.\n *\n * Defaults to French translations (`DEFAULT_ERROR_PATTERNS`), but you're\n * never stuck with them — pass your own `patterns` and/or `fallbackMessage`\n * to translate or reword every message this library can produce.\n *\n * @param error - The error to parse (can be any type)\n * @param options - Optional custom patterns / fallback message\n * @returns A clean, user-friendly error message\n *\n * @example\n * ```ts\n * parseError(new Error(\"Network connection failed\"));\n * // Returns: \"Problème de connexion internet.\"\n *\n * // Full control — e.g. an English-speaking product:\n * parseError(err, {\n *   patterns: [\n *     { pattern: /closed|dismissed|cancel/i, message: \"Payment cancelled.\" },\n *     { pattern: /network|connection|offline/i, message: \"No internet connection.\" },\n *   ],\n *   fallbackMessage: \"Something went wrong.\",\n * });\n * ```\n */\nexport function parseError(error: unknown, options: ParseErrorOptions = {}): string {\n  const patterns = options.patterns ?? DEFAULT_ERROR_PATTERNS;\n  const fallbackMessage = options.fallbackMessage ?? DEFAULT_FALLBACK_MESSAGE;\n\n  if (!error) {\n    return fallbackMessage;\n  }\n\n  let errorMessage: string;\n\n  if (typeof error === \"string\") {\n    errorMessage = error;\n  } else if (error instanceof Error) {\n    errorMessage = error.message;\n  } else if (typeof error === \"object\" && error !== null) {\n    const errorObj = error as Record<string, unknown>;\n    errorMessage =\n      (errorObj.message as string) ||\n      (errorObj.error as string) ||\n      (errorObj.msg as string) ||\n      JSON.stringify(error);\n  } else {\n    return fallbackMessage;\n  }\n\n  for (const { pattern, message } of patterns) {\n    if (pattern.test(errorMessage)) {\n      return message;\n    }\n  }\n\n  return errorMessage || fallbackMessage;\n}\n\n/**\n * Creates a standardized error object with parsed message.\n *\n * @param error - The raw error\n * @param options - Optional custom patterns / fallback message, forwarded to `parseError`\n * @returns An Error object with a user-friendly message\n */\nexport function createParsedError(error: unknown, options?: ParseErrorOptions): Error {\n  return new Error(parseError(error, options));\n}\n","import type { VerificationConfig, VerificationResponse, VerifyMethod } from \"../types\";\r\nimport type { PaymentProviderId } from \"../core/types\";\r\n\r\n/**\r\n * Payload sent to the verification endpoint.\r\n */\r\nexport interface VerifyPayload {\r\n  /** Transaction ID from the payment provider */\r\n  transactionId: string;\r\n  /** Amount that was charged */\r\n  amount: number;\r\n  /** Payment provider used — `\"fedapay\"` / `\"kkiapay\"`, or a custom driver's identifier */\r\n  provider: PaymentProviderId;\r\n  /** Additional metadata */\r\n  metadata?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Thrown when backend verification fails. `isBackendMessage` tells callers\r\n * whether `message` is text your own `verifyUrl` endpoint returned (and\r\n * should therefore be shown to the user exactly as written) or a generic\r\n * fallback/network message that's safe to run through further translation.\r\n */\r\nexport class VerificationError extends Error {\r\n  constructor(message: string, public readonly isBackendMessage: boolean) {\r\n    super(message);\r\n    this.name = \"VerificationError\";\r\n  }\r\n}\r\n\r\n/**\r\n * Verifies a transaction with the backend.\r\n *\r\n * @param config - Verification configuration\r\n * @param payload - Transaction data to verify\r\n * @returns Verification response from the backend\r\n * @throws {VerificationError} if verification fails or network error occurs\r\n *\r\n * @example\r\n * ```ts\r\n * const result = await verifyTransaction(\r\n *   { verifyUrl: \"/api/verify\", verifyMethod: \"POST\" },\r\n *   { transactionId: \"tx_123\", amount: 5000, provider: \"fedapay\" }\r\n * );\r\n * ```\r\n */\r\nexport async function verifyTransaction(\r\n  config: VerificationConfig,\r\n  payload: VerifyPayload\r\n): Promise<VerificationResponse> {\r\n  if (!config.verifyUrl) {\r\n    throw new Error(\"verifyUrl is required for transaction verification\");\r\n  }\r\n\r\n  const method: VerifyMethod = config.verifyMethod ?? \"POST\";\r\n  const headers: Record<string, string> = {\r\n    \"Content-Type\": \"application/json\",\r\n    ...config.customVerifyHeaders,\r\n  };\r\n\r\n  let url = config.verifyUrl;\r\n  const fetchOptions: RequestInit = {\r\n    method,\r\n    headers,\r\n  };\r\n\r\n  if (method === \"POST\") {\r\n    fetchOptions.body = JSON.stringify(payload);\r\n  } else {\r\n    const params = new URLSearchParams({\r\n      transactionId: payload.transactionId,\r\n      amount: payload.amount.toString(),\r\n      provider: payload.provider,\r\n    });\r\n    url = `${config.verifyUrl}?${params.toString()}`;\r\n  }\r\n\r\n  const response = await fetch(url, fetchOptions);\r\n\r\n  if (!response.ok) {\r\n    let errorMessage = `Verification failed with status ${response.status}`;\r\n    let isBackendMessage = false;\r\n\r\n    try {\r\n      const errorData = await response.json();\r\n      if (errorData.message) {\r\n        errorMessage = errorData.message;\r\n        isBackendMessage = true;\r\n      }\r\n    } catch {\r\n      // Response is not JSON, use default message\r\n    }\r\n\r\n    throw new VerificationError(errorMessage, isBackendMessage);\r\n  }\r\n\r\n  const data = await response.json();\r\n  \r\n  return {\r\n    success: data.success ?? true,\r\n    message: data.message,\r\n    data: data.data ?? data,\r\n  };\r\n}\r\n","import { loadScript } from \"../utils/scriptLoader\";\nimport { createLogger } from \"../utils/logger\";\nimport { createAnalyticsEmitter, type BeninPaymentAnalyticsEvent } from \"../utils/analytics\";\nimport { parseError } from \"../utils/errors\";\nimport { verifyTransaction, VerificationError } from \"../utils/verifyTransaction\";\nimport type { PaymentValidationError } from \"../types/validation\";\nimport type {\n  PaymentDriver,\n  PaymentEngine,\n  PaymentEngineOptions,\n  PaymentEngineState,\n} from \"./types\";\n\ntype AnalyticsEventInput = Omit<BeninPaymentAnalyticsEvent, \"timestamp\" | \"provider\">;\n\n/**\n * Creates a framework-agnostic payment flow controller for a given provider\n * driver. Handles script loading, validation, mock simulation, the optional\n * `onBeforePayment` hook, backend verification and standardized analytics —\n * identically for every provider that implements `PaymentDriver`.\n *\n * This has no dependency on React: `subscribe`/`getState` can be wired into\n * any UI layer. `usePaymentEngine` is the thin React binding used internally\n * by `useFedaPay` / `useKkiaPay`.\n */\nexport function createPaymentEngine<TConfig, TRaw>(\n  driver: PaymentDriver<TConfig, TRaw>,\n  getOptions: () => PaymentEngineOptions<TConfig, TRaw>\n): PaymentEngine<TConfig> {\n  const initialMock = getOptions().isMockMode;\n\n  let state: PaymentEngineState = {\n    loading: !initialMock,\n    scriptLoaded: initialMock,\n    error: null,\n    isVerifying: false,\n    isPreparing: false,\n  };\n  let lastConfig: TConfig | null = null;\n  let destroyed = false;\n  const listeners = new Set<() => void>();\n\n  function getState() {\n    return state;\n  }\n\n  function subscribe(listener: () => void) {\n    listeners.add(listener);\n    return () => listeners.delete(listener);\n  }\n\n  function setState(patch: Partial<PaymentEngineState>) {\n    state = { ...state, ...patch };\n    // The `destroyed` guard is what makes it safe for usePaymentEngine to\n    // swap in a new engine (e.g. when `isMockMode` changes) without\n    // explicitly cancelling this one first: React runs this engine's\n    // `start()` cleanup (which sets `destroyed = true`) before the new\n    // engine's effect runs, so any in-flight promise/timer that resolves\n    // late just updates dead internal state instead of notifying React.\n    if (!destroyed) listeners.forEach((listener) => listener());\n  }\n\n  function getLog() {\n    return createLogger(getOptions().debug ?? false);\n  }\n\n  function emit(event: AnalyticsEventInput, configForExtras: TConfig | undefined) {\n    const options = getOptions();\n    const emitter = createAnalyticsEmitter(\n      [options.globalAnalyticsHandler, options.onAnalyticsEvent],\n      getLog().warn\n    );\n    const extras = driver.getAnalyticsExtras?.(configForExtras) ?? {};\n    emitter({ ...extras, ...event, provider: driver.name });\n  }\n\n  /** Applies a per-code message override (`options.messages`), if configured. */\n  function applyMessageOverride(error: PaymentValidationError): PaymentValidationError {\n    const override = getOptions().messages?.[error.code];\n    return override ? { ...error, message: override } : error;\n  }\n\n  /**\n   * Resolves a user-facing message for a caught technical error (SDK load\n   * failure, network error, thrown SDK exception...). Tries the caller's\n   * `resolveErrorMessage` first, then falls back to `parseError`'s built-in\n   * translations.\n   */\n  function resolveGenericErrorMessage(error: unknown): string {\n    const custom = getOptions().resolveErrorMessage?.(error);\n    return custom !== undefined ? custom : parseError(error);\n  }\n\n  function handleSuccess(raw: TRaw, config?: TConfig) {\n    const options = getOptions();\n    const log = getLog();\n    const resolvedConfig = config ?? (lastConfig as TConfig);\n    const mode: \"mock\" | \"live\" = options.isMockMode ? \"mock\" : \"live\";\n\n    log.success(\"Payment completed by provider\", raw);\n\n    const payload = driver.toVerifyPayload(raw, resolvedConfig);\n    const status = driver.getStatus?.(raw);\n    const verifyUrl = options.verification?.verifyUrl;\n\n    if (!verifyUrl) {\n      emit(\n        { name: \"payment_completed\", amount: payload.amount, mode, transactionId: payload.transactionId, status },\n        resolvedConfig\n      );\n      options.onRawSuccess?.(raw);\n      return;\n    }\n\n    setState({ isVerifying: true });\n    log.info(\"🔐 Verifying transaction with backend...\", { url: verifyUrl });\n    emit(\n      { name: \"payment_verification_started\", amount: payload.amount, mode, transactionId: payload.transactionId },\n      resolvedConfig\n    );\n\n    verifyTransaction(\n      {\n        verifyUrl,\n        verifyMethod: options.verification?.verifyMethod,\n        customVerifyHeaders: options.verification?.customVerifyHeaders,\n      },\n      {\n        transactionId: payload.transactionId,\n        amount: payload.amount,\n        provider: driver.name,\n        metadata: payload.metadata,\n      }\n    )\n      .then((verifyResult) => {\n        setState({ isVerifying: false });\n        log.success(\"🔐 Backend verification successful\", verifyResult);\n        emit(\n          { name: \"payment_verification_succeeded\", amount: payload.amount, mode, transactionId: payload.transactionId },\n          resolvedConfig\n        );\n        emit(\n          { name: \"payment_completed\", amount: payload.amount, mode, transactionId: payload.transactionId, status },\n          resolvedConfig\n        );\n        options.onRawSuccess?.(raw);\n      })\n      .catch((err) => {\n        setState({ isVerifying: false });\n        const verifyError = err instanceof Error ? err : new Error(\"Verification failed\");\n        log.error(\"🔐 Backend verification failed\", verifyError);\n        emit(\n          {\n            name: \"payment_verification_failed\",\n            amount: payload.amount,\n            mode,\n            transactionId: payload.transactionId,\n            errorMessage: verifyError.message,\n          },\n          resolvedConfig\n        );\n        // A message your own verifyUrl endpoint wrote is shown exactly as you\n        // wrote it — only messages WE generated (network failures, a bare\n        // HTTP status with no body) go through translation/resolution.\n        const userMessage =\n          verifyError instanceof VerificationError && verifyError.isBackendMessage\n            ? verifyError.message\n            : resolveGenericErrorMessage(verifyError);\n        options.onValidationError?.(applyMessageOverride({ code: \"SDK_ERROR\", message: userMessage }));\n      });\n  }\n\n  function start(): () => void {\n    const options = getOptions();\n    const log = getLog();\n\n    if (options.isMockMode) {\n      log.info(\"🧪 Running in Mock Mode - No real SDK loaded\");\n      setState({ scriptLoaded: true, loading: false });\n      return () => {\n        destroyed = true;\n      };\n    }\n\n    let cancelled = false;\n    const analyticsConfig = options.getAnalyticsConfig?.();\n\n    log.info(`Loading ${driver.name} SDK...`);\n    emit({ name: \"sdk_load_started\", mode: \"live\", amount: driver.getAmount(analyticsConfig) }, analyticsConfig);\n\n    loadScript(driver.scriptUrl, driver.scriptId)\n      .then(() => {\n        if (cancelled) return;\n        setState({ scriptLoaded: true, loading: false });\n        log.success(`${driver.name} SDK loaded successfully`);\n        emit(\n          { name: \"sdk_load_succeeded\", mode: \"live\", amount: driver.getAmount(analyticsConfig) },\n          analyticsConfig\n        );\n      })\n      .catch((err) => {\n        if (cancelled) return;\n        const friendlyMessage = resolveGenericErrorMessage(err);\n        setState({ error: new Error(friendlyMessage), loading: false });\n        log.error(`Failed to load ${driver.name} SDK`, err);\n        emit(\n          {\n            name: \"sdk_load_failed\",\n            mode: \"live\",\n            amount: driver.getAmount(analyticsConfig),\n            errorMessage: friendlyMessage,\n          },\n          analyticsConfig\n        );\n      });\n\n    return () => {\n      cancelled = true;\n      destroyed = true;\n    };\n  }\n\n  async function runOpen(config: TConfig) {\n    const options = getOptions();\n    const log = getLog();\n    const isMockMode = options.isMockMode;\n    const mode: \"mock\" | \"live\" = isMockMode ? \"mock\" : \"live\";\n\n    if (state.isPreparing) {\n      log.warn(\"Payment pre-validation already in progress\");\n      return;\n    }\n\n    log.info(`Opening ${driver.name} dialog...`, { config, isMockMode });\n\n    driver.logEnvironmentWarnings?.(config, { isMockMode, environmentWarnings: options.environmentWarnings });\n\n    const validationError = driver.validate(config, { isMockMode });\n    if (validationError) {\n      log.error(`Validation failed: ${validationError.message}`);\n      emit(\n        {\n          name: \"payment_validation_failed\",\n          amount: driver.getAmount(config),\n          mode,\n          errorCode: validationError.code,\n          errorMessage: validationError.message,\n        },\n        config\n      );\n      options.onValidationError?.(applyMessageOverride(validationError));\n      return;\n    }\n\n    emit({ name: \"payment_open_attempted\", amount: driver.getAmount(config), mode }, config);\n\n    if (options.onBeforePayment) {\n      try {\n        setState({ isPreparing: true });\n        emit({ name: \"payment_pre_validation_started\", amount: driver.getAmount(config), mode }, config);\n        const shouldContinue = await options.onBeforePayment();\n        if (shouldContinue === false) {\n          log.info(\"Payment opening cancelled by onBeforePayment\");\n          emit({ name: \"payment_pre_validation_cancelled\", amount: driver.getAmount(config), mode }, config);\n          return;\n        }\n        emit({ name: \"payment_pre_validation_succeeded\", amount: driver.getAmount(config), mode }, config);\n      } catch (err) {\n        const preValidationError = err instanceof Error ? err : new Error(\"Payment pre-validation failed\");\n        setState({ error: preValidationError });\n        log.error(\"onBeforePayment failed\", preValidationError);\n        emit(\n          {\n            name: \"payment_pre_validation_failed\",\n            amount: driver.getAmount(config),\n            mode,\n            errorMessage: preValidationError.message,\n          },\n          config\n        );\n        options.onValidationError?.(\n          applyMessageOverride({ code: \"PRE_VALIDATION_FAILED\", message: preValidationError.message })\n        );\n        return;\n      } finally {\n        setState({ isPreparing: false });\n      }\n    }\n\n    if (isMockMode) {\n      log.info(\"🧪 Simulating payment...\");\n      emit({ name: \"payment_opened\", amount: driver.getAmount(config), mode: \"mock\" }, config);\n      setTimeout(() => {\n        const mockResponse = driver.buildMockSuccess(config);\n        log.success(\"🧪 Mock Payment Successful\", mockResponse);\n        handleSuccess(mockResponse, config);\n      }, 1000);\n      return;\n    }\n\n    if (!state.scriptLoaded || !driver.isSdkReady()) {\n      const validationError = {\n        code: \"SDK_NOT_LOADED\" as const,\n        message: `${driver.name} SDK not loaded. Please wait for the script to load.`,\n      };\n      log.error(\"SDK not loaded. Cannot open dialog.\");\n      emit(\n        {\n          name: \"payment_validation_failed\",\n          amount: driver.getAmount(config),\n          mode: \"live\",\n          errorCode: validationError.code,\n          errorMessage: validationError.message,\n        },\n        config\n      );\n      options.onValidationError?.(applyMessageOverride(validationError));\n      return;\n    }\n\n    try {\n      driver.open(\n        config,\n        {\n          onSuccess: (raw) => handleSuccess(raw, config),\n          onFailure: (raw) => getOptions().onRawFailure?.(raw),\n          onClose: () => getOptions().onClose?.(),\n        },\n        {\n          log,\n          isMockMode,\n          emit: (partial) => emit({ amount: driver.getAmount(config), mode: \"live\", ...partial }, config),\n        }\n      );\n\n      log.success(`${driver.name} dialog opened successfully`);\n      emit({ name: \"payment_opened\", amount: driver.getAmount(config), mode: \"live\" }, config);\n    } catch (err) {\n      log.error(`Failed to open ${driver.name} dialog`, err);\n      const sdkError = err instanceof Error ? err : new Error(`Failed to open ${driver.name} dialog`);\n      setState({ error: sdkError });\n      emit(\n        {\n          name: \"payment_failed\",\n          amount: driver.getAmount(config),\n          mode: \"live\",\n          errorCode: \"SDK_ERROR\",\n          errorMessage: sdkError.message,\n        },\n        config\n      );\n      options.onValidationError?.(\n        applyMessageOverride({ code: \"SDK_ERROR\", message: resolveGenericErrorMessage(sdkError) })\n      );\n    }\n  }\n\n  function open(config: TConfig) {\n    lastConfig = config;\n    void runOpen(config);\n  }\n\n  return { getState, subscribe, start, open };\n}\n","\"use client\";\n\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { createPaymentEngine } from \"./createPaymentEngine\";\nimport type { PaymentDriver, PaymentEngineOptions, PaymentEngineState } from \"./types\";\n\n/**\n * React binding for `createPaymentEngine`. Owns one engine instance per\n * hook call (recreated only if the driver or mock-mode flag changes),\n * subscribes to its state, and starts its background lifecycle\n * (script loading, persistent SDK listeners) for the component's lifetime.\n *\n * `getOptions` is called fresh on every render, so callbacks and config\n * values it returns are always up to date without needing to be listed in\n * any dependency array.\n */\nexport function usePaymentEngine<TConfig, TRaw>(\n  driver: PaymentDriver<TConfig, TRaw>,\n  getOptions: () => PaymentEngineOptions<TConfig, TRaw>\n): [PaymentEngineState, (config: TConfig) => void] {\n  const getOptionsRef = useRef(getOptions);\n  getOptionsRef.current = getOptions;\n\n  const isMockMode = getOptions().isMockMode;\n\n  const engine = useMemo(\n    () => createPaymentEngine(driver, () => getOptionsRef.current()),\n    // Recreated only when the driver identity or the mock flag changes —\n    // mirrors the original hooks re-running their script-loading effect then.\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n    [driver, isMockMode]\n  );\n\n  const [state, setState] = useState<PaymentEngineState>(() => engine.getState());\n\n  useEffect(() => {\n    setState(engine.getState());\n    const unsubscribe = engine.subscribe(() => setState(engine.getState()));\n    const stop = engine.start();\n    return () => {\n      unsubscribe();\n      stop();\n    };\n  }, [engine]);\n\n  return [state, engine.open];\n}\n","/**\n * Overrides the wording of the dev-time console warnings emitted by\n * `validateKeyEnvironment`/`logSandboxMode`. Every field is optional — any\n * warning you don't override keeps its default English text.\n */\nexport interface EnvironmentWarningMessages {\n  /** Shown when a live key is used while sandbox mode is on. Receives the provider name (e.g. \"FedaPay\"). */\n  liveKeyInSandbox?: (provider: string) => string;\n  /** Shown when a test/sandbox key is used while sandbox mode is off. Receives the provider name. */\n  testKeyInProduction?: (provider: string) => string;\n  /** Shown once whenever sandbox mode is active. Receives the provider name. */\n  sandboxModeActive?: (provider: string) => string;\n}\n\n/**\n * Validates API key consistency with sandbox mode.\n * Warns developers about potential misconfigurations.\n *\n * @param key - The API public key\n * @param sandbox - Whether sandbox mode is enabled\n * @param provider - The payment provider name (for logging)\n * @param messages - Optional overrides for the warning text\n */\nexport function validateKeyEnvironment(\n  key: string,\n  sandbox: boolean,\n  provider: \"FedaPay\" | \"KKiaPay\",\n  messages?: EnvironmentWarningMessages\n): void {\n  if (!key) return;\n\n  const isLiveKey = key.startsWith(\"pk_live_\") || key.startsWith(\"pk_live\");\n  const isTestKey =\n    key.startsWith(\"pk_test_\") ||\n    key.startsWith(\"pk_sandbox_\") ||\n    key.startsWith(\"pk_sandbox\");\n\n  if (sandbox && isLiveKey) {\n    console.warn(\n      messages?.liveKeyInSandbox?.(provider) ??\n        `⚠️ [react-benin-payments] ${provider}: You are in Sandbox mode but using a LIVE key! This may cause unexpected charges.`\n    );\n  }\n\n  if (!sandbox && isTestKey) {\n    console.warn(\n      messages?.testKeyInProduction?.(provider) ??\n        `⚠️ [react-benin-payments] ${provider}: You are in Production mode but using a TEST key! Payments will not be processed.`\n    );\n  }\n}\n\n/**\n * Logs sandbox mode warning if enabled.\n *\n * @param sandbox - Whether sandbox mode is enabled\n * @param provider - The payment provider name\n * @param messages - Optional overrides for the warning text\n */\nexport function logSandboxMode(\n  sandbox: boolean,\n  provider: \"FedaPay\" | \"KKiaPay\",\n  messages?: EnvironmentWarningMessages\n): void {\n  if (sandbox) {\n    console.log(\n      messages?.sandboxModeActive?.(provider) ??\n        `⚠️ [react-benin-payments] ${provider}: Running in Sandbox Mode - No real transactions will be processed.`\n    );\n  }\n}\n","import type { Currency } from \"../types\";\r\n\r\n/**\r\n * Formats an amount in XOF (West African CFA Franc).\r\n * \r\n * @param amount - The amount to format\r\n * @returns Formatted string with FCFA suffix (e.g., \"5 000 FCFA\")\r\n * \r\n * @example\r\n * ```ts\r\n * formatXOF(5000);    // \"5 000 FCFA\"\r\n * formatXOF(1500000); // \"1 500 000 FCFA\"\r\n * formatXOF(0);       // \"0 FCFA\"\r\n * ```\r\n */\r\nexport function formatXOF(amount: number): string {\r\n  const formatted = new Intl.NumberFormat(\"fr-FR\", {\r\n    style: \"decimal\",\r\n    minimumFractionDigits: 0,\r\n    maximumFractionDigits: 0,\r\n  }).format(amount);\r\n\r\n  return `${formatted} FCFA`;\r\n}\r\n\r\n/**\r\n * Formats an amount in the specified currency.\r\n * \r\n * @param amount - The amount to format\r\n * @param currency - The currency code (XOF, USD, EUR)\r\n * @returns Formatted string with currency symbol\r\n * \r\n * @example\r\n * ```ts\r\n * formatCurrency(5000, \"XOF\");  // \"5 000 FCFA\"\r\n * formatCurrency(100, \"USD\");   // \"$100.00\"\r\n * formatCurrency(100, \"EUR\");   // \"100,00 €\"\r\n * ```\r\n */\r\nexport function formatCurrency(amount: number, currency: Currency): string {\r\n  switch (currency) {\r\n    case \"XOF\":\r\n      return formatXOF(amount);\r\n    case \"USD\":\r\n      return new Intl.NumberFormat(\"en-US\", {\r\n        style: \"currency\",\r\n        currency: \"USD\",\r\n      }).format(amount);\r\n    case \"EUR\":\r\n      return new Intl.NumberFormat(\"fr-FR\", {\r\n        style: \"currency\",\r\n        currency: \"EUR\",\r\n      }).format(amount);\r\n    default:\r\n      return `${amount} ${currency}`;\r\n  }\r\n}\r\n\r\n/**\r\n * Generates a mock transaction ID for testing.\r\n * \r\n * @returns A unique mock transaction ID\r\n */\r\nexport function generateMockTransactionId(): string {\r\n  const timestamp = Date.now().toString(36);\r\n  const random = Math.random().toString(36).substring(2, 8);\r\n  return `mock_tx_${timestamp}_${random}`;\r\n}\r\n","import type { PaymentValidationError } from \"../types/validation\";\n\n/**\n * The most common `PaymentDriver.validate` shape: a required public key\n * (unless in mock mode) and a positive amount. Both built-in drivers\n * (FedaPay, KKiaPay) use this — reach for it in a custom driver too instead\n * of re-implementing the same two checks.\n *\n * @example\n * ```ts\n * validate: (config, { isMockMode }) =>\n *   validatePublicKeyAndAmount(config.apiKey, config.amount, isMockMode),\n * ```\n */\nexport function validatePublicKeyAndAmount(\n  publicKey: string | undefined,\n  amount: number | undefined,\n  isMockMode: boolean\n): PaymentValidationError | null {\n  if (!isMockMode && (!publicKey || publicKey.trim() === \"\")) {\n    return {\n      code: \"MISSING_PUBLIC_KEY\",\n      message: \"Missing Public Key. Provide it via config or BeninPaymentProvider.\",\n    };\n  }\n  if (!amount || amount <= 0) {\n    return { code: \"INVALID_AMOUNT\", message: \"Invalid amount. Amount must be greater than 0.\" };\n  }\n  return null;\n}\n","import { validateKeyEnvironment, logSandboxMode } from \"../utils/keyValidator\";\nimport { generateMockTransactionId } from \"../utils/currency\";\nimport { validatePublicKeyAndAmount } from \"../core/validateCommonConfig\";\nimport type { PaymentDriver } from \"../core/types\";\nimport type { FedaPayConfig, FedaPayCallbackResponse } from \"../types\";\n\nconst FEDAPAY_SCRIPT_URL = \"https://cdn.fedapay.com/checkout.js?v=1.1.7\";\nconst FEDAPAY_SCRIPT_ID = \"fedapay-checkout-script\";\n\n/**\n * FedaPay adapter for `createPaymentEngine`. FedaPay's SDK takes inline\n * `onComplete`/`onClose` callbacks per call (`window.FedaPay.init(...).open()`),\n * so `open()` wires the engine's handlers directly into that call.\n */\nexport function createFedaPayDriver(): PaymentDriver<FedaPayConfig, FedaPayCallbackResponse> {\n  return {\n    name: \"fedapay\",\n    scriptUrl: FEDAPAY_SCRIPT_URL,\n    scriptId: FEDAPAY_SCRIPT_ID,\n\n    isSdkReady: () => typeof window !== \"undefined\" && !!window.FedaPay,\n\n    logEnvironmentWarnings(config, { isMockMode, environmentWarnings }) {\n      if (isMockMode) return;\n      if (config.public_key) {\n        validateKeyEnvironment(config.public_key, !!config.sandbox, \"FedaPay\", environmentWarnings);\n      }\n      logSandboxMode(!!config.sandbox, \"FedaPay\", environmentWarnings);\n    },\n\n    validate: (config, { isMockMode }) =>\n      validatePublicKeyAndAmount(config.public_key, config.transaction?.amount, isMockMode),\n\n    getAmount: (config) => config?.transaction?.amount,\n\n    getAnalyticsExtras: (config) => ({ currency: config?.currency?.iso }),\n\n    buildMockSuccess: (config) => ({\n      reason: \"mock_transaction_completed\",\n      transaction: {\n        id: Math.floor(Math.random() * 1000000),\n        reference: generateMockTransactionId(),\n        amount: config.transaction.amount,\n        status: \"approved\",\n      },\n    }),\n\n    toVerifyPayload: (raw, config) => ({\n      transactionId: raw.transaction.reference,\n      amount: raw.transaction.amount,\n      metadata: config.metadata,\n    }),\n\n    getStatus: (raw) => raw.transaction.status,\n\n    open(config, handlers, ctx) {\n      const transactionWithMetadata = {\n        ...config.transaction,\n        custom_metadata: {\n          ...config.transaction.custom_metadata,\n          ...config.metadata,\n        },\n      };\n\n      const widget = window.FedaPay!.init({\n        public_key: config.public_key,\n        transaction: transactionWithMetadata,\n        customer: config.customer,\n        currency: config.currency,\n        onComplete: (response: FedaPayCallbackResponse) => handlers.onSuccess(response),\n        onClose: () => {\n          ctx.log.info(\"Payment dialog closed by user\");\n          ctx.emit({ name: \"payment_closed\" });\n          handlers.onClose();\n        },\n      });\n\n      widget.open();\n    },\n  };\n}\n","/**\r\n * Checks if the current environment is a test environment.\r\n * Safe to use in browser and Node.js contexts.\r\n * \r\n * @returns true if running in test mode\r\n */\r\nexport function isTestEnvironment(): boolean {\r\n  // Safe check for Node.js environment\r\n  if (typeof process === \"undefined\") {\r\n    return false;\r\n  }\r\n  \r\n  if (!process.env) {\r\n    return false;\r\n  }\r\n  \r\n  return process.env.NODE_ENV === \"test\";\r\n}\r\n","import type { ErrorMessageResolver, PaymentMessageOverrides } from \"../types/validation\";\nimport type { EnvironmentWarningMessages } from \"../utils/keyValidator\";\n\ninterface I18nConfig {\n  messages?: PaymentMessageOverrides;\n  resolveErrorMessage?: ErrorMessageResolver;\n  environmentWarnings?: EnvironmentWarningMessages;\n}\n\n/**\n * Merges a hook's local `messages`/`resolveErrorMessage`/`environmentWarnings`\n * with `BeninPaymentProvider`'s global config — local wins per validation\n * code, and `resolveErrorMessage` tries local first, then global. Shared by\n * `useFedaPay`/`useKkiaPay`/`useBeninPay` so the precedence rule lives in one place.\n */\nexport function mergeI18nOptions(\n  global: I18nConfig,\n  local: I18nConfig\n): Required<Pick<I18nConfig, \"messages\" | \"environmentWarnings\">> &\n  Pick<I18nConfig, \"resolveErrorMessage\"> {\n  return {\n    messages: { ...global.messages, ...local.messages },\n    resolveErrorMessage: (error) => local.resolveErrorMessage?.(error) ?? global.resolveErrorMessage?.(error),\n    environmentWarnings: { ...global.environmentWarnings, ...local.environmentWarnings },\n  };\n}\n","\"use client\";\n\nimport { useCallback, useMemo, useRef } from \"react\";\nimport { usePaymentEngine } from \"../core/usePaymentEngine\";\nimport { createFedaPayDriver } from \"../providers/fedapay\";\nimport { isTestEnvironment } from \"../utils/environment\";\nimport { useBeninConfig } from \"../context\";\nimport { mergeI18nOptions } from \"./mergeI18nOptions\";\nimport type { FedaPayConfig, FedaPayCallbackResponse, Currency } from \"../types\";\nimport type {\n  ErrorMessageResolver,\n  PaymentMessageOverrides,\n  PaymentValidationError,\n} from \"../types/validation\";\nimport type { EnvironmentWarningMessages } from \"../utils/keyValidator\";\nimport type { BeninPaymentAnalyticsHandler } from \"../utils/analytics\";\n\nconst fedaPayDriver = createFedaPayDriver();\n\n/**\n * Options for the useFedaPay hook.\n */\nexport interface UseFedaPayOptions {\n  /**\n   * Enable debug mode with styled console logs.\n   * If not provided, uses the value from BeninPaymentProvider.\n   * @default false\n   */\n  debug?: boolean;\n  /**\n   * Enable mock mode for testing.\n   * When true, no real SDK is loaded and payments are simulated.\n   * Automatically enabled when process.env.NODE_ENV === 'test'.\n   * @default false\n   */\n  mock?: boolean;\n  /**\n   * Runs before opening the payment modal.\n   * Return `false` to cancel opening without throwing an error.\n   */\n  onBeforePayment?: () => void | boolean | Promise<void | boolean>;\n  /**\n   * Receives standardized analytics events for the payment lifecycle.\n   */\n  onAnalyticsEvent?: BeninPaymentAnalyticsHandler;\n  /**\n   * Callback fired when validation fails or SDK errors occur.\n   * @param error - The validation error with code and message\n   */\n  onError?: (error: PaymentValidationError) => void;\n  /**\n   * Overrides the wording of validation error messages for this hook only\n   * (takes precedence over `BeninPaymentProvider`'s `messages`).\n   */\n  messages?: PaymentMessageOverrides;\n  /**\n   * Resolves the message for arbitrary caught errors (SDK load failures...)\n   * for this hook only. Falls back to the provider's `resolveErrorMessage`,\n   * then to the built-in translations.\n   */\n  resolveErrorMessage?: ErrorMessageResolver;\n  /**\n   * Overrides the wording of dev-time console warnings for this hook only\n   * (takes precedence over `BeninPaymentProvider`'s `environmentWarnings`).\n   */\n  environmentWarnings?: EnvironmentWarningMessages;\n}\n\n/**\n * Return type for the useFedaPay hook.\n */\nexport interface UseFedaPayReturn {\n  /** Function to open the FedaPay payment dialog */\n  openDialog: () => void;\n  /** Whether the SDK is currently loading */\n  loading: boolean;\n  /** Error object if SDK loading failed */\n  error: Error | null;\n  /** Whether the SDK script has been successfully loaded */\n  scriptLoaded: boolean;\n  /** Whether running in mock mode */\n  isMockMode: boolean;\n  /** Whether backend verification is in progress */\n  isVerifying: boolean;\n  /** Whether async pre-validation is in progress */\n  isPreparing: boolean;\n}\n\n/**\n * Configuration for useFedaPay that supports optional public_key.\n * When used inside BeninPaymentProvider, public_key can be omitted.\n */\nexport type UseFedaPayConfig = Omit<FedaPayConfig, \"public_key\"> & {\n  /**\n   * Your FedaPay public key.\n   * Optional if using BeninPaymentProvider with fedaPayPublicKey set.\n   */\n  public_key?: string;\n};\n\n/**\n * React hook for integrating FedaPay payments.\n *\n * Handles script loading, validation, payment dialog, and backend verification.\n * Supports mock mode for testing without loading the actual SDK.\n *\n * Internally this is a thin binding over the framework-agnostic payment\n * engine (see `src/core`) configured with the FedaPay driver — the same\n * engine that powers `useKkiaPay`.\n *\n * @param config - FedaPay configuration (public_key optional if using Provider)\n * @param options - Optional settings for debug mode, mock mode, and error handling\n * @returns Object with `openDialog` function, loading states, and `isVerifying`\n *\n * @example\n * ```tsx\n * // With automatic backend verification\n * const { openDialog, loading, isVerifying } = useFedaPay({\n *   transaction: { amount: 5000 },\n *   verifyUrl: \"/api/payments/verify\",\n *   customVerifyHeaders: { \"Authorization\": \"Bearer xxx\" },\n *   onComplete: (response) => {\n *     // Called AFTER backend verification succeeds\n *     console.log(\"Payment verified!\", response.transaction.id);\n *   }\n * });\n * ```\n */\nexport function useFedaPay(\n  config: UseFedaPayConfig,\n  options: UseFedaPayOptions = {}\n): UseFedaPayReturn {\n  const globalConfig = useBeninConfig();\n\n  const resolvedPublicKey = config.public_key || globalConfig.fedaPayPublicKey || \"\";\n  const resolvedSandbox = config.sandbox ?? globalConfig.isTestMode;\n  const resolvedCurrency: Currency = config.currency?.iso || globalConfig.defaultCurrency;\n  const isMockMode = options.mock ?? isTestEnvironment();\n\n  // Fully-resolved config handed to the driver/engine — it never needs to\n  // know about BeninPaymentProvider defaults.\n  const resolvedConfig: FedaPayConfig = useMemo(\n    () => ({\n      ...config,\n      public_key: resolvedPublicKey,\n      sandbox: resolvedSandbox,\n      currency: { iso: resolvedCurrency },\n    }),\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n    [config, resolvedPublicKey, resolvedSandbox, resolvedCurrency]\n  );\n\n  const configRef = useRef(resolvedConfig);\n  configRef.current = resolvedConfig;\n\n  const { onError, onBeforePayment, onAnalyticsEvent, messages, resolveErrorMessage, environmentWarnings } =\n    options;\n\n  const [state, open] = usePaymentEngine(fedaPayDriver, () => ({\n    debug: options.debug ?? globalConfig.debug,\n    isMockMode,\n    verification: {\n      verifyUrl: config.verifyUrl,\n      verifyMethod: config.verifyMethod,\n      customVerifyHeaders: config.customVerifyHeaders,\n    },\n    onBeforePayment,\n    onAnalyticsEvent,\n    globalAnalyticsHandler: globalConfig.onAnalyticsEvent,\n    onRawSuccess: (response: FedaPayCallbackResponse) => config.onComplete?.(response),\n    onClose: config.onClose,\n    onValidationError: onError,\n    getAnalyticsConfig: () => configRef.current,\n    ...mergeI18nOptions(globalConfig, { messages, resolveErrorMessage, environmentWarnings }),\n  }));\n\n  const openDialog = useCallback(() => {\n    open(configRef.current);\n  }, [open]);\n\n  return {\n    openDialog,\n    loading: state.loading,\n    error: state.error,\n    scriptLoaded: state.scriptLoaded,\n    isMockMode,\n    isVerifying: state.isVerifying,\n    isPreparing: state.isPreparing,\n  };\n}\n","import { validateKeyEnvironment, logSandboxMode } from \"../utils/keyValidator\";\nimport { generateMockTransactionId } from \"../utils/currency\";\nimport { validatePublicKeyAndAmount } from \"../core/validateCommonConfig\";\nimport type { PaymentDriver, PaymentDriverHandlers } from \"../core/types\";\nimport type { KkiaPayConfig, KkiaPaySuccessResponse, KkiaPayFailedResponse } from \"../types\";\n\nconst KKIAPAY_SCRIPT_URL = \"https://cdn.kkiapay.me/k.js\";\nconst KKIAPAY_SCRIPT_ID = \"kkiapay-widget-script\";\n\n// The KKiaPay SDK exposes ONE global event bus (`addKkiapayListener`) and\n// only ever supports one open widget at a time. So rather than a persistent\n// per-engine subscription (which would relay one real event to every\n// mounted useKkiaPay() instance, not just the one that opened the widget),\n// we track a single \"active call\" reference: whichever `open()` call is\n// currently in flight owns the next success/failed/close event.\nlet activeHandlers: PaymentDriverHandlers<KkiaPaySuccessResponse> | null = null;\nlet globalListenersAttached = false;\n\nfunction ensureGlobalListeners(): void {\n  if (globalListenersAttached || typeof window === \"undefined\" || !window.addKkiapayListener) {\n    return;\n  }\n\n  window.addKkiapayListener<KkiaPaySuccessResponse>(\"success\", (data) => {\n    const handlers = activeHandlers;\n    activeHandlers = null;\n    handlers?.onSuccess(data);\n  });\n  window.addKkiapayListener<KkiaPayFailedResponse>(\"failed\", (data) => {\n    const handlers = activeHandlers;\n    activeHandlers = null;\n    handlers?.onFailure(data);\n  });\n  window.addKkiapayListener(\"close\", () => {\n    const handlers = activeHandlers;\n    activeHandlers = null;\n    handlers?.onClose();\n  });\n\n  globalListenersAttached = true;\n}\n\n/**\n * KKiaPay adapter for `createPaymentEngine`. Unlike FedaPay, the SDK relays\n * success/failure/close through a global event bus rather than a per-call\n * callback, so `open()` registers itself as the \"active call\" just before\n * triggering the widget instead of receiving an inline callback.\n */\nexport function createKkiaPayDriver(): PaymentDriver<KkiaPayConfig, KkiaPaySuccessResponse> {\n  return {\n    name: \"kkiapay\",\n    scriptUrl: KKIAPAY_SCRIPT_URL,\n    scriptId: KKIAPAY_SCRIPT_ID,\n\n    isSdkReady: () => typeof window !== \"undefined\" && !!window.openKkiapayWidget,\n\n    logEnvironmentWarnings(config, { isMockMode, environmentWarnings }) {\n      if (isMockMode) return;\n      if (config.key) {\n        validateKeyEnvironment(config.key, !!config.sandbox, \"KKiaPay\", environmentWarnings);\n      }\n      logSandboxMode(!!config.sandbox, \"KKiaPay\", environmentWarnings);\n    },\n\n    validate: (config, { isMockMode }) =>\n      validatePublicKeyAndAmount(config.key, config.amount, isMockMode),\n\n    getAmount: (config) => config?.amount,\n\n    buildMockSuccess: (config) => ({\n      transactionId: generateMockTransactionId(),\n      amount: config.amount,\n      phone: config.phone || \"+22900000000\",\n    }),\n\n    toVerifyPayload: (raw) => ({\n      transactionId: raw.transactionId,\n      amount: raw.amount,\n    }),\n\n    open(config, handlers) {\n      ensureGlobalListeners();\n      activeHandlers = handlers;\n\n      const configWithDefaults: KkiaPayConfig = {\n        ...config,\n        theme: config.theme ?? \"#4E6BFF\",\n        paymentMethods: config.paymentMethods ?? [\"momo\", \"card\"],\n      };\n      window.openKkiapayWidget!(configWithDefaults);\n    },\n  };\n}\n","\"use client\";\n\nimport { useCallback } from \"react\";\nimport { usePaymentEngine } from \"../core/usePaymentEngine\";\nimport { createKkiaPayDriver } from \"../providers/kkiapay\";\nimport { isTestEnvironment } from \"../utils/environment\";\nimport { useBeninConfig } from \"../context\";\nimport { mergeI18nOptions } from \"./mergeI18nOptions\";\nimport type {\n  KkiaPayConfig,\n  KkiaPaySuccessResponse,\n  KkiaPayFailedResponse,\n  VerificationConfig,\n} from \"../types\";\nimport type {\n  ErrorMessageResolver,\n  PaymentMessageOverrides,\n  PaymentValidationError,\n} from \"../types/validation\";\nimport type { EnvironmentWarningMessages } from \"../utils/keyValidator\";\nimport type { BeninPaymentAnalyticsHandler } from \"../utils/analytics\";\n\nconst kkiaPayDriver = createKkiaPayDriver();\n\n/**\n * Options for the useKkiaPay hook.\n */\nexport interface UseKkiaPayOptions extends VerificationConfig {\n  /**\n   * Enable debug mode with styled console logs.\n   * If not provided, uses the value from BeninPaymentProvider.\n   * @default false\n   */\n  debug?: boolean;\n  /**\n   * Enable mock mode for testing.\n   * When true, no real SDK is loaded and payments are simulated.\n   * Automatically enabled when process.env.NODE_ENV === 'test'.\n   * @default false\n   */\n  mock?: boolean;\n  /**\n   * Runs before opening the payment widget.\n   * Return `false` to cancel opening without throwing an error.\n   */\n  onBeforePayment?: () => void | boolean | Promise<void | boolean>;\n  /**\n   * Receives standardized analytics events for the payment lifecycle.\n   */\n  onAnalyticsEvent?: BeninPaymentAnalyticsHandler;\n  /**\n   * Callback fired when payment is successful (after backend verification if configured).\n   * @param data - Contains transactionId, amount, and phone\n   */\n  onSuccess?: (data: KkiaPaySuccessResponse) => void;\n  /**\n   * Callback fired when payment fails.\n   * @param data - Contains error code and message\n   */\n  onFailed?: (data: KkiaPayFailedResponse) => void;\n  /**\n   * Callback fired when the widget is closed without completing payment.\n   */\n  onClose?: () => void;\n  /**\n   * Callback fired when validation fails or SDK errors occur.\n   * @param error - The validation error with code and message\n   */\n  onValidationError?: (error: PaymentValidationError) => void;\n  /**\n   * Overrides the wording of validation error messages for this hook only\n   * (takes precedence over `BeninPaymentProvider`'s `messages`).\n   */\n  messages?: PaymentMessageOverrides;\n  /**\n   * Resolves the message for arbitrary caught errors (SDK load failures...)\n   * for this hook only. Falls back to the provider's `resolveErrorMessage`,\n   * then to the built-in translations.\n   */\n  resolveErrorMessage?: ErrorMessageResolver;\n  /**\n   * Overrides the wording of dev-time console warnings for this hook only\n   * (takes precedence over `BeninPaymentProvider`'s `environmentWarnings`).\n   */\n  environmentWarnings?: EnvironmentWarningMessages;\n}\n\n/**\n * Return type for the useKkiaPay hook.\n */\nexport interface UseKkiaPayReturn {\n  /** Function to open the KKiaPay payment widget */\n  openKkiapay: (config: UseKkiaPayConfig) => void;\n  /** Whether the SDK is currently loading */\n  loading: boolean;\n  /** Error object if SDK loading failed */\n  error: Error | null;\n  /** Whether the SDK script has been successfully loaded */\n  scriptLoaded: boolean;\n  /** Whether running in mock mode */\n  isMockMode: boolean;\n  /** Whether backend verification is in progress */\n  isVerifying: boolean;\n  /** Whether async pre-validation is in progress */\n  isPreparing: boolean;\n}\n\n/**\n * Configuration for useKkiaPay that supports optional key.\n * When used inside BeninPaymentProvider, key can be omitted.\n */\nexport type UseKkiaPayConfig = Omit<KkiaPayConfig, \"key\"> & {\n  /**\n   * Your KKiaPay public key.\n   * Optional if using BeninPaymentProvider with kkiaPayPublicKey set.\n   */\n  key?: string;\n};\n\n/**\n * React hook for integrating KKiaPay payments.\n *\n * Handles script loading, event listeners, validation, widget management, and backend verification.\n * Supports mock mode for testing without loading the actual SDK.\n *\n * Internally this is a thin binding over the framework-agnostic payment\n * engine (see `src/core`) configured with the KKiaPay driver — the same\n * engine that powers `useFedaPay`.\n *\n * @param options - Configuration for callbacks, debug mode, mock mode, and verification\n * @returns Object with `openKkiapay` function, loading states, and `isVerifying`\n *\n * @example\n * ```tsx\n * // With automatic backend verification\n * const { openKkiapay, loading, isVerifying } = useKkiaPay({\n *   verifyUrl: \"/api/payments/verify\",\n *   customVerifyHeaders: { \"Authorization\": \"Bearer xxx\" },\n *   onSuccess: (data) => {\n *     // Called AFTER backend verification succeeds\n *     console.log(\"Payment verified!\", data.transactionId);\n *   }\n * });\n * ```\n */\nexport function useKkiaPay(options: UseKkiaPayOptions = {}): UseKkiaPayReturn {\n  const globalConfig = useBeninConfig();\n  const isMockMode = options.mock ?? isTestEnvironment();\n\n  const {\n    onSuccess,\n    onFailed,\n    onClose,\n    onValidationError,\n    onBeforePayment,\n    onAnalyticsEvent,\n    verifyUrl,\n    verifyMethod,\n    customVerifyHeaders,\n    messages,\n    resolveErrorMessage,\n    environmentWarnings,\n  } = options;\n\n  const [state, open] = usePaymentEngine(kkiaPayDriver, () => ({\n    debug: options.debug ?? globalConfig.debug,\n    isMockMode,\n    verification: { verifyUrl, verifyMethod, customVerifyHeaders },\n    onBeforePayment,\n    onAnalyticsEvent,\n    globalAnalyticsHandler: globalConfig.onAnalyticsEvent,\n    onRawSuccess: (data: KkiaPaySuccessResponse) => onSuccess?.(data),\n    onRawFailure: (data) => onFailed?.(data as KkiaPayFailedResponse),\n    onClose,\n    onValidationError,\n    ...mergeI18nOptions(globalConfig, { messages, resolveErrorMessage, environmentWarnings }),\n  }));\n\n  const openKkiapay = useCallback(\n    (config: UseKkiaPayConfig) => {\n      const resolvedKey = config.key || globalConfig.kkiaPayPublicKey || \"\";\n      const resolvedSandbox = config.sandbox ?? globalConfig.isTestMode;\n\n      open({\n        ...config,\n        key: resolvedKey,\n        sandbox: resolvedSandbox,\n      });\n    },\n    [open, globalConfig.kkiaPayPublicKey, globalConfig.isTestMode]\n  );\n\n  return {\n    openKkiapay,\n    loading: state.loading,\n    error: state.error,\n    scriptLoaded: state.scriptLoaded,\n    isMockMode,\n    isVerifying: state.isVerifying,\n    isPreparing: state.isPreparing,\n  };\n}\n","\"use client\";\r\n\r\nimport { useState } from \"react\";\r\nimport { useFedaPay, type UseFedaPayConfig, type UseFedaPayOptions } from \"./useFedaPay\";\r\nimport { useKkiaPay, type UseKkiaPayConfig } from \"./useKkiaPay\";\r\nimport type { FedaPayCallbackResponse, KkiaPaySuccessResponse, KkiaPayFailedResponse } from \"../types\";\r\nimport type {\r\n  ErrorMessageResolver,\r\n  PaymentMessageOverrides,\r\n  PaymentValidationError,\r\n} from \"../types/validation\";\r\nimport type { BeninPaymentAnalyticsHandler } from \"../utils/analytics\";\r\nimport type { EnvironmentWarningMessages } from \"../utils/keyValidator\";\r\nimport type { PaymentProvider } from \"../core/types\";\r\n\r\nexport type { PaymentProvider };\r\n\r\n/**\r\n * Unified payment result from any provider.\r\n */\r\nexport interface UnifiedPaymentResult {\r\n  /** Transaction ID from the provider */\r\n  transactionId: string;\r\n  /** Amount that was charged */\r\n  amount: number;\r\n  /** Payment status */\r\n  status: \"success\" | \"failed\" | \"pending\";\r\n  /** Original provider-specific response */\r\n  rawResponse: FedaPayCallbackResponse | KkiaPaySuccessResponse;\r\n}\r\n\r\n/**\r\n * Config for useBeninPay hook.\r\n */\r\nexport interface UseBeninPayConfig {\r\n  /** The payment provider to use */\r\n  provider: PaymentProvider;\r\n  /** \r\n   * FedaPay specific configuration.\r\n   * Required when provider is \"fedapay\".\r\n   */\r\n  fedapay?: UseFedaPayConfig;\r\n  /** \r\n   * KKiaPay specific configuration.\r\n   * Required when provider is \"kkiapay\".\r\n   */\r\n  kkiapay?: UseKkiaPayConfig;\r\n}\r\n\r\n/**\r\n * Options for useBeninPay hook.\r\n */\r\nexport interface UseBeninPayOptions {\r\n  /** Enable debug mode */\r\n  debug?: boolean;\r\n  /** Enable mock mode for testing */\r\n  mock?: boolean;\r\n  /** Runs before opening the selected payment provider modal/widget */\r\n  onBeforePayment?: () => void | boolean | Promise<void | boolean>;\r\n  /** Receives standardized analytics events for the payment lifecycle */\r\n  onAnalyticsEvent?: BeninPaymentAnalyticsHandler;\r\n  /** Callback on successful payment */\r\n  onSuccess?: (result: UnifiedPaymentResult) => void;\r\n  /** Callback on failed payment */\r\n  onFailed?: (error: KkiaPayFailedResponse) => void;\r\n  /** Callback when payment dialog is closed */\r\n  onClose?: () => void;\r\n  /** Callback on validation errors */\r\n  onError?: (error: PaymentValidationError) => void;\r\n  /** Overrides the wording of validation error messages for this hook only. */\r\n  messages?: PaymentMessageOverrides;\r\n  /** Resolves the message for arbitrary caught errors (SDK load failures...) for this hook only. */\r\n  resolveErrorMessage?: ErrorMessageResolver;\r\n  /** Overrides the wording of dev-time console warnings for this hook only. */\r\n  environmentWarnings?: EnvironmentWarningMessages;\r\n}\r\n\r\n/**\r\n * Return type for useBeninPay hook.\r\n */\r\nexport interface UseBeninPayReturn {\r\n  /** Function to initiate payment */\r\n  pay: () => void;\r\n  /** Whether the SDK is loading */\r\n  loading: boolean;\r\n  /** Error if SDK loading failed */\r\n  error: Error | null;\r\n  /** Whether SDK is ready */\r\n  isReady: boolean;\r\n  /** Current provider being used */\r\n  provider: PaymentProvider;\r\n  /** Whether running in mock mode */\r\n  isMockMode: boolean;\r\n  /** Whether backend verification is in progress */\r\n  isVerifying: boolean;\r\n  /** The most recent successful transaction, if any */\r\n  lastTransaction: UnifiedPaymentResult | null;\r\n  /** Whether async pre-validation is in progress */\r\n  isPreparing: boolean;\r\n}\r\n\r\n/**\r\n * Universal payment hook that abstracts FedaPay and KKiaPay.\r\n * \r\n * Allows switching between payment providers without changing your code structure.\r\n * Provides a unified interface for both providers.\r\n * \r\n * @param config - Configuration including provider selection\r\n * @param options - Options for callbacks and modes\r\n * @returns Unified payment interface\r\n * \r\n * @example\r\n * ```tsx\r\n * import { useBeninPay } from \"react-benin-payments\";\r\n * \r\n * function PaymentButton() {\r\n *   // Easy provider switching - just change this value!\r\n *   const provider = useFeatureFlag(\"payment_provider\") || \"fedapay\";\r\n * \r\n *   const { pay, loading, isReady } = useBeninPay(\r\n *     {\r\n *       provider,\r\n *       fedapay: { transaction: { amount: 5000 } },\r\n *       kkiapay: { amount: 5000 }\r\n *     },\r\n *     {\r\n *       onSuccess: (result) => {\r\n *         console.log(`Paid via ${provider}!`, result.transactionId);\r\n *       }\r\n *     }\r\n *   );\r\n * \r\n *   return (\r\n *     <button onClick={pay} disabled={loading || !isReady}>\r\n *       {loading ? \"Loading...\" : `Pay with ${provider}`}\r\n *     </button>\r\n *   );\r\n * }\r\n * ```\r\n * \r\n * @example\r\n * ```tsx\r\n * // Mock mode for testing\r\n * const { pay, isMockMode } = useBeninPay(\r\n *   { provider: \"fedapay\", fedapay: { transaction: { amount: 1000 } } },\r\n *   { mock: true }\r\n * );\r\n * ```\r\n */\r\nexport function useBeninPay(\r\n  config: UseBeninPayConfig,\r\n  options: UseBeninPayOptions = {}\r\n): UseBeninPayReturn {\r\n  const { provider, fedapay, kkiapay } = config;\r\n  const {\r\n    debug,\r\n    mock,\r\n    onBeforePayment,\r\n    onAnalyticsEvent,\r\n    onSuccess,\r\n    onFailed,\r\n    onClose,\r\n    onError,\r\n    messages,\r\n    resolveErrorMessage,\r\n    environmentWarnings,\r\n  } = options;\r\n  const [lastTransaction, setLastTransaction] =\r\n    useState<UnifiedPaymentResult | null>(null);\r\n\r\n  // BUG FIX 1: Pass mock:true to the non-selected provider so its SDK script\r\n  // is never loaded. Both hooks must always be called (React rules of hooks),\r\n  // but only the active provider's real SDK is fetched.\r\n  const fedaPayOptions: UseFedaPayOptions = {\r\n    debug,\r\n    mock: provider !== \"fedapay\" ? true : mock,\r\n    onBeforePayment,\r\n    onAnalyticsEvent,\r\n    onError,\r\n    messages,\r\n    resolveErrorMessage,\r\n    environmentWarnings,\r\n  };\r\n\r\n  // BUG FIX 2: Build a new config object with spread instead of mutating the\r\n  // fedapay prop reference directly (which caused subtle re-render bugs).\r\n  const fedaPayConfig: UseFedaPayConfig = {\r\n    ...(fedapay ?? { transaction: { amount: 0 } }),\r\n    ...(fedapay && onSuccess\r\n      ? {\r\n          onComplete: (response) => {\r\n            const unified: UnifiedPaymentResult = {\r\n              transactionId: response.transaction.reference,\r\n              amount: response.transaction.amount,\r\n              status:\r\n                response.transaction.status === \"approved\" ? \"success\" : \"pending\",\r\n              rawResponse: response,\r\n            };\r\n            setLastTransaction(unified);\r\n            fedapay.onComplete?.(response);\r\n            onSuccess(unified);\r\n          },\r\n        }\r\n      : {}),\r\n    ...(fedapay && onClose\r\n      ? {\r\n          onClose: () => {\r\n            fedapay.onClose?.();\r\n            onClose();\r\n          },\r\n        }\r\n      : {}),\r\n  };\r\n\r\n  const {\r\n    openDialog,\r\n    loading: fedaLoading,\r\n    error: fedaError,\r\n    scriptLoaded: fedaReady,\r\n    isMockMode: fedaMock,\r\n    isVerifying: fedaVerifying,\r\n    isPreparing: fedaPreparing,\r\n  } = useFedaPay(fedaPayConfig, fedaPayOptions);\r\n\r\n  // BUG FIX 1 (continued): mirror the same mock-bypass for KKiaPay.\r\n  const {\r\n    openKkiapay,\r\n    loading: kkiaLoading,\r\n    error: kkiaError,\r\n    scriptLoaded: kkiaReady,\r\n    isMockMode: kkiaMock,\r\n    isVerifying: kkiaVerifying,\r\n    isPreparing: kkiaPreparing,\r\n  } = useKkiaPay({\r\n    debug,\r\n    mock: provider !== \"kkiapay\" ? true : mock,\r\n    verifyUrl: kkiapay?.verifyUrl,\r\n    verifyMethod: kkiapay?.verifyMethod,\r\n    customVerifyHeaders: kkiapay?.customVerifyHeaders,\r\n    onBeforePayment,\r\n    onAnalyticsEvent,\r\n    onSuccess: onSuccess\r\n      ? (data) => {\r\n          const unified: UnifiedPaymentResult = {\r\n            transactionId: data.transactionId,\r\n            amount: data.amount,\r\n            status: \"success\",\r\n            rawResponse: data,\r\n          };\r\n          setLastTransaction(unified);\r\n          onSuccess(unified);\r\n        }\r\n      : undefined,\r\n    onFailed,\r\n    onClose: onClose\r\n      ? () => {\r\n          onClose();\r\n        }\r\n      : undefined,\r\n    onValidationError: onError,\r\n    messages,\r\n    resolveErrorMessage,\r\n    environmentWarnings,\r\n  });\r\n\r\n  if (provider === \"fedapay\") {\r\n    return {\r\n      pay: openDialog,\r\n      loading: fedaLoading,\r\n      error: fedaError,\r\n      isReady: fedaReady,\r\n      provider: \"fedapay\",\r\n      isMockMode: fedaMock,\r\n      isVerifying: fedaVerifying,\r\n      lastTransaction,\r\n      isPreparing: fedaPreparing,\r\n    };\r\n  }\r\n\r\n  const kkiaPayConfig: UseKkiaPayConfig = kkiapay ?? { amount: 0 };\r\n\r\n  return {\r\n    pay: () => openKkiapay(kkiaPayConfig),\r\n    loading: kkiaLoading,\r\n    error: kkiaError,\r\n    isReady: kkiaReady,\r\n    provider: \"kkiapay\",\r\n    isMockMode: kkiaMock,\r\n    isVerifying: kkiaVerifying,\r\n    lastTransaction,\r\n    isPreparing: kkiaPreparing,\r\n  };\r\n}\r\n","\"use client\";\r\n\r\nimport { useCallback, useEffect, useMemo, useRef, useState, type MutableRefObject } from \"react\";\r\nimport { createLogger } from \"../utils/logger\";\r\nimport { useBeninConfig } from \"../context\";\r\n\r\n/**\r\n * Possible statuses for a transaction returned by your backend.\r\n */\r\nexport type TransactionStatus =\r\n  | \"pending\"\r\n  | \"approved\"\r\n  | \"declined\"\r\n  | \"cancelled\"\r\n  | \"unknown\";\r\n\r\nconst TERMINAL_STATUSES: TransactionStatus[] = [\r\n  \"approved\",\r\n  \"declined\",\r\n  \"cancelled\",\r\n];\r\n\r\nexport type PaymentStatusTransport = \"polling\" | \"websocket\";\r\n\r\nexport interface PaymentStatusWebSocketLike {\r\n  close: () => void;\r\n  onopen: ((event: Event) => void) | null;\r\n  onmessage: ((event: MessageEvent) => void) | null;\r\n  onerror: ((event: Event) => void) | null;\r\n  onclose: ((event: CloseEvent) => void) | null;\r\n}\r\n\r\nexport interface UsePaymentStatusWebSocketMessage {\r\n  status?: TransactionStatus;\r\n}\r\n\r\n/**\r\n * Options for the usePaymentStatus hook.\r\n */\r\nexport interface UsePaymentStatusOptions {\r\n  /**\r\n   * URL of your backend endpoint that returns the transaction status.\r\n   * The hook sends: GET `checkUrl?transactionId=xxx&provider=yyy`\r\n   * Expected response: `{ status: TransactionStatus }`\r\n   * @example \"/api/payments/status\"\r\n   */\r\n  checkUrl?: string;\r\n  /**\r\n   * Transaction ID returned by FedaPay or KKiaPay after payment.\r\n   */\r\n  transactionId: string;\r\n  /**\r\n   * The payment provider used for this transaction.\r\n   */\r\n  provider: \"fedapay\" | \"kkiapay\";\r\n  /**\r\n   * How often to poll in milliseconds.\r\n   * @default 3000\r\n   */\r\n  pollInterval?: number;\r\n  /**\r\n   * Transport used to follow status updates.\r\n   * @default \"polling\"\r\n   */\r\n  transport?: PaymentStatusTransport;\r\n  /**\r\n   * WebSocket endpoint used when `transport` is `\"websocket\"`.\r\n   * @example \"wss://api.example.com/payments/status\"\r\n   */\r\n  websocketUrl?: string;\r\n  /**\r\n   * Optional WebSocket protocols.\r\n   */\r\n  websocketProtocols?: string | string[];\r\n  /**\r\n   * Optional factory used to create the WebSocket instance.\r\n   * Useful for tests or custom runtimes.\r\n   */\r\n  websocketFactory?: (\r\n    url: string,\r\n    protocols?: string | string[]\r\n  ) => PaymentStatusWebSocketLike;\r\n  /**\r\n   * Parses incoming WebSocket messages into a transaction status.\r\n   * By default expects either a raw status string or `{ status: ... }`.\r\n   */\r\n  parseWebSocketMessage?: (\r\n    event: MessageEvent\r\n  ) => TransactionStatus | UsePaymentStatusWebSocketMessage | null | undefined;\r\n  /**\r\n   * Maximum number of polling attempts before stopping.\r\n   * Prevents infinite loops if the backend never returns a terminal status.\r\n   * @default 10\r\n   */\r\n  maxAttempts?: number;\r\n  /**\r\n   * Custom headers to include in every status check request.\r\n   * @example { \"Authorization\": \"Bearer xxx\" }\r\n   */\r\n  customHeaders?: Record<string, string>;\r\n  /**\r\n   * Called every time the status changes.\r\n   * @param status - The new transaction status\r\n   */\r\n  onStatusChange?: (status: TransactionStatus) => void;\r\n  /**\r\n   * Whether to start polling immediately when the hook mounts.\r\n   * Set to false to delay polling until you call startPolling().\r\n   * @default true\r\n   */\r\n  enabled?: boolean;\r\n  /**\r\n   * Enable debug logs.\r\n   * If not provided, uses the value from BeninPaymentProvider.\r\n   * @default false\r\n   */\r\n  debug?: boolean;\r\n}\r\n\r\n/**\r\n * Return type for the usePaymentStatus hook.\r\n */\r\nexport interface UsePaymentStatusReturn {\r\n  /** Current transaction status returned by your backend */\r\n  status: TransactionStatus;\r\n  /** Whether a status check is currently in progress */\r\n  loading: boolean;\r\n  /** Error from the last failed check */\r\n  error: Error | null;\r\n  /** Total number of polling attempts made */\r\n  attempts: number;\r\n  /** Whether the polling loop is currently active */\r\n  isPolling: boolean;\r\n  /** Stop the polling loop */\r\n  stopPolling: () => void;\r\n  /** Resume polling (resets attempt counter and status to pending) */\r\n  startPolling: () => void;\r\n  /** Trigger a single immediate check without affecting the polling loop */\r\n  refetch: () => void;\r\n}\r\n\r\n/**\r\n * Hook to poll your backend for a transaction status after payment.\r\n *\r\n * Automatically stops polling when a terminal status is reached\r\n * (approved, declined, cancelled) or when maxAttempts is exceeded.\r\n *\r\n * @example\r\n * ```tsx\r\n * // After a FedaPay payment completes:\r\n * const { status, isPolling, attempts } = usePaymentStatus({\r\n *   checkUrl: \"/api/payments/status\",\r\n *   transactionId: response.transaction.reference,\r\n *   provider: \"fedapay\",\r\n *   pollInterval: 3000,\r\n *   maxAttempts: 10,\r\n *   onStatusChange: (status) => {\r\n *     if (status === \"approved\") router.push(\"/success\");\r\n *     if (status === \"declined\") router.push(\"/failed\");\r\n *   },\r\n * });\r\n *\r\n * return (\r\n *   <div>\r\n *     {isPolling && <p>Vérification en cours... (tentative {attempts}/10)</p>}\r\n *     {status === \"approved\" && <p>Paiement confirmé !</p>}\r\n *     {status === \"declined\" && <p>Paiement refusé.</p>}\r\n *   </div>\r\n * );\r\n * ```\r\n */\r\nexport function usePaymentStatus(\r\n  options: UsePaymentStatusOptions\r\n): UsePaymentStatusReturn {\r\n  const {\r\n    checkUrl,\r\n    transactionId,\r\n    provider,\r\n    pollInterval = 3000,\r\n    transport = \"polling\",\r\n    websocketUrl,\r\n    websocketProtocols,\r\n    websocketFactory,\r\n    parseWebSocketMessage,\r\n    maxAttempts = 10,\r\n    customHeaders,\r\n    onStatusChange,\r\n    enabled = true,\r\n    debug,\r\n  } = options;\r\n\r\n  const globalConfig = useBeninConfig();\r\n  const resolvedDebug = debug ?? globalConfig.debug;\r\n  const log = useMemo(() => createLogger(resolvedDebug), [resolvedDebug]);\r\n\r\n  const [status, setStatus] = useState<TransactionStatus>(\"pending\");\r\n  const [loading, setLoading] = useState(false);\r\n  const [error, setError] = useState<Error | null>(null);\r\n  const [attempts, setAttempts] = useState(0);\r\n  const [isPolling, setIsPolling] = useState(enabled);\r\n\r\n  // Refs to avoid stale closures inside the async checkStatus callback\r\n  const statusRef = useRef<TransactionStatus>(\"pending\");\r\n  const attemptsRef = useRef(0);\r\n  const isPollingRef = useRef(enabled);\r\n  const webSocketRef = useRef<PaymentStatusWebSocketLike | null>(null);\r\n\r\n  // Stabilise les callbacks passés en props pour éviter des re-runs d'effet inutiles\r\n  // lorsque l'appelant crée des fonctions inline (nouvelle référence à chaque render).\r\n  const websocketFactoryRef = useRef(websocketFactory) as MutableRefObject<typeof websocketFactory>;\r\n  websocketFactoryRef.current = websocketFactory;\r\n  const parseWebSocketMessageRef = useRef(parseWebSocketMessage) as MutableRefObject<typeof parseWebSocketMessage>;\r\n  parseWebSocketMessageRef.current = parseWebSocketMessage;\r\n\r\n  useEffect(() => {\r\n    isPollingRef.current = isPolling;\r\n  }, [isPolling]);\r\n\r\n  const applyStatus = useCallback(\r\n    (newStatus: TransactionStatus) => {\r\n      if (newStatus !== statusRef.current) {\r\n        statusRef.current = newStatus;\r\n        setStatus(newStatus);\r\n        log.info(`Transaction status: ${newStatus}`);\r\n        onStatusChange?.(newStatus);\r\n      }\r\n\r\n      if (TERMINAL_STATUSES.includes(newStatus)) {\r\n        log.success(`Terminal status reached: ${newStatus}`);\r\n        setIsPolling(false);\r\n        webSocketRef.current?.close();\r\n        webSocketRef.current = null;\r\n      }\r\n    },\r\n    [log, onStatusChange]\r\n  );\r\n\r\n  const checkStatus = useCallback(async () => {\r\n    if (!transactionId || !checkUrl) return;\r\n\r\n    setLoading(true);\r\n    setError(null);\r\n    attemptsRef.current += 1;\r\n    setAttempts(attemptsRef.current);\r\n\r\n    try {\r\n      const params = new URLSearchParams({ transactionId, provider });\r\n      const fullUrl = `${checkUrl}?${params.toString()}`;\r\n\r\n      const response = await fetch(fullUrl, {\r\n        method: \"GET\",\r\n        headers: {\r\n          \"Content-Type\": \"application/json\",\r\n          ...customHeaders,\r\n        },\r\n      });\r\n\r\n      if (!response.ok) {\r\n        let errorMessage = `Status check failed with HTTP ${response.status}`;\r\n        try {\r\n          const errorData = await response.json();\r\n          if (errorData.message) errorMessage = errorData.message;\r\n        } catch {\r\n          // Response is not JSON — use default message\r\n        }\r\n        throw new Error(errorMessage);\r\n      }\r\n\r\n      const data = await response.json();\r\n      const newStatus: TransactionStatus = data.status ?? \"unknown\";\r\n\r\n      applyStatus(newStatus);\r\n\r\n      if (TERMINAL_STATUSES.includes(newStatus)) {\r\n        return;\r\n      }\r\n\r\n      // Stop polling after maxAttempts\r\n      if (attemptsRef.current >= maxAttempts) {\r\n        log.warn(`Max polling attempts (${maxAttempts}) reached`);\r\n        setIsPolling(false);\r\n      }\r\n    } catch (err) {\r\n      const checkError =\r\n        err instanceof Error ? err : new Error(\"Status check failed\");\r\n      setError(checkError);\r\n      log.error(\"Status check failed\", checkError);\r\n\r\n      if (attemptsRef.current >= maxAttempts) {\r\n        log.warn(`Max polling attempts (${maxAttempts}) reached after errors`);\r\n        setIsPolling(false);\r\n      }\r\n    } finally {\r\n      setLoading(false);\r\n    }\r\n  }, [checkUrl, transactionId, provider, customHeaders, maxAttempts, log, applyStatus]);\r\n\r\n  const resolveWebSocketStatus = useCallback(\r\n    (event: MessageEvent): TransactionStatus | null => {\r\n      // Lit depuis le ref pour éviter de recréer ce callback quand parseWebSocketMessage change.\r\n      const parsed = parseWebSocketMessageRef.current?.(event);\r\n\r\n      if (typeof parsed === \"string\") {\r\n        return parsed;\r\n      }\r\n\r\n      if (parsed && typeof parsed === \"object\" && \"status\" in parsed) {\r\n        return parsed.status ?? null;\r\n      }\r\n\r\n      if (typeof event.data === \"string\") {\r\n        try {\r\n          const data = JSON.parse(event.data) as\r\n            | UsePaymentStatusWebSocketMessage\r\n            | TransactionStatus;\r\n\r\n          if (typeof data === \"string\") {\r\n            return data;\r\n          }\r\n\r\n          return data.status ?? null;\r\n        } catch {\r\n          return null;\r\n        }\r\n      }\r\n\r\n      return null;\r\n    },\r\n    // parseWebSocketMessageRef est stable — pas besoin de l'ajouter ici.\r\n    // eslint-disable-next-line react-hooks/exhaustive-deps\r\n    []\r\n  );\r\n\r\n  useEffect(() => {\r\n    if (!isPolling || !transactionId) return;\r\n\r\n    if (transport === \"websocket\") {\r\n      if (!websocketUrl) return;\r\n\r\n      // Lit depuis le ref pour éviter de recréer la socket quand le callback change de référence.\r\n      const createSocket =\r\n        websocketFactoryRef.current ??\r\n        ((url: string, protocols?: string | string[]) =>\r\n          new WebSocket(url, protocols) as unknown as PaymentStatusWebSocketLike);\r\n\r\n      setLoading(true);\r\n      setError(null);\r\n\r\n      const socket = createSocket(websocketUrl, websocketProtocols);\r\n      webSocketRef.current = socket;\r\n\r\n      socket.onopen = () => {\r\n        setLoading(false);\r\n        log.info(\"WebSocket status tracking connected\");\r\n      };\r\n\r\n      socket.onmessage = (event) => {\r\n        attemptsRef.current += 1;\r\n        setAttempts(attemptsRef.current);\r\n\r\n        const nextStatus = resolveWebSocketStatus(event);\r\n        if (!nextStatus) return;\r\n        applyStatus(nextStatus);\r\n      };\r\n\r\n      socket.onerror = () => {\r\n        setLoading(false);\r\n        setError(new Error(\"WebSocket status tracking failed\"));\r\n        log.error(\"WebSocket status tracking failed\");\r\n      };\r\n\r\n      socket.onclose = () => {\r\n        webSocketRef.current = null;\r\n        setLoading(false);\r\n      };\r\n\r\n      return () => {\r\n        socket.close();\r\n        if (webSocketRef.current === socket) {\r\n          webSocketRef.current = null;\r\n        }\r\n      };\r\n    }\r\n\r\n    if (!checkUrl) return;\r\n\r\n    // Différer la première vérification via setTimeout pour que les appels\r\n    // synchrones (ex: startPolling dans act()) voient attempts=0 avant le premier check.\r\n    const immediateId = setTimeout(() => {\r\n      if (isPollingRef.current) void checkStatus();\r\n    }, 0);\r\n\r\n    const intervalId = setInterval(() => {\r\n      if (!isPollingRef.current) {\r\n        clearInterval(intervalId);\r\n        return;\r\n      }\r\n      void checkStatus();\r\n    }, pollInterval);\r\n\r\n    return () => {\r\n      clearTimeout(immediateId);\r\n      clearInterval(intervalId);\r\n    };\r\n  }, [\r\n    isPolling,\r\n    transactionId,\r\n    checkUrl,\r\n    pollInterval,\r\n    checkStatus,\r\n    transport,\r\n    websocketUrl,\r\n    // websocketFactory et parseWebSocketMessage sont lus via refs — pas dans les deps.\r\n    websocketProtocols,\r\n    resolveWebSocketStatus,\r\n    applyStatus,\r\n    log,\r\n  ]);\r\n\r\n  const stopPolling = useCallback(() => {\r\n    log.info(\"Polling stopped manually\");\r\n    webSocketRef.current?.close();\r\n    webSocketRef.current = null;\r\n    setIsPolling(false);\r\n  }, [log]);\r\n\r\n  const startPolling = useCallback(() => {\r\n    log.info(\"Polling restarted\");\r\n    attemptsRef.current = 0;\r\n    statusRef.current = \"pending\";\r\n    setAttempts(0);\r\n    setStatus(\"pending\");\r\n    setError(null);\r\n    setIsPolling(true);\r\n  }, [log]);\r\n\r\n  const refetch = useCallback(() => {\r\n    checkStatus();\r\n  }, [checkStatus]);\r\n\r\n  return {\r\n    status,\r\n    loading,\r\n    error,\r\n    attempts,\r\n    isPolling,\r\n    stopPolling,\r\n    startPolling,\r\n    refetch,\r\n  };\r\n}\r\n","\"use client\";\r\n\r\nimport { useCallback, useEffect, useRef, useState } from \"react\";\r\nimport type { UnifiedPaymentResult } from \"./useBeninPay\";\r\nimport type { PaymentProvider } from \"./useBeninPay\";\r\n\r\n/**\r\n * Storage strategy for payment history.\r\n *\r\n * - `\"memory\"` — In-memory only. Cleared when the component unmounts or the\r\n *   page is refreshed. Best for ephemeral UX flows (default).\r\n * - `\"session\"` — Persisted in `sessionStorage`. Survives page reloads within\r\n *   the same browser tab, cleared when the tab/browser closes.\r\n * - `\"local\"` — Persisted in `localStorage`. Survives full browser restarts.\r\n *   Use when you want cross-session history (e.g. a receipts page).\r\n */\r\nexport type PaymentHistoryStorage = \"memory\" | \"session\" | \"local\";\r\n\r\n/**\r\n * A single entry in the payment history.\r\n * Extends UnifiedPaymentResult with audit fields.\r\n */\r\nexport interface PaymentHistoryEntry extends UnifiedPaymentResult {\r\n  /** ISO 8601 timestamp of when the payment was recorded */\r\n  recordedAt: string;\r\n  /** The payment provider used for this transaction */\r\n  provider?: PaymentProvider;\r\n}\r\n\r\n/**\r\n * Options for the usePaymentHistory hook.\r\n */\r\nexport interface UsePaymentHistoryOptions {\r\n  /**\r\n   * Storage strategy for persisting history.\r\n   * @default \"memory\"\r\n   */\r\n  storage?: PaymentHistoryStorage;\r\n  /**\r\n   * Key to use in sessionStorage or localStorage.\r\n   * Change this if you have multiple independent payment flows.\r\n   * @default \"rbp_payment_history\"\r\n   */\r\n  storageKey?: string;\r\n  /**\r\n   * Maximum number of entries to keep.\r\n   * When exceeded, the oldest entries are dropped.\r\n   * @default 50\r\n   */\r\n  maxEntries?: number;\r\n}\r\n\r\n/**\r\n * Return type for the usePaymentHistory hook.\r\n */\r\nexport interface UsePaymentHistoryReturn {\r\n  /** Full list of recorded payments, ordered from most recent to oldest */\r\n  history: PaymentHistoryEntry[];\r\n  /** The most recently recorded payment, or `null` if history is empty */\r\n  lastTransaction: PaymentHistoryEntry | null;\r\n  /** Sum of all `amount` values across the recorded transactions */\r\n  totalPaid: number;\r\n  /** Number of entries in history */\r\n  count: number;\r\n  /**\r\n   * Add a payment result to history.\r\n   *\r\n   * Automatically called by `useBeninPay` when integrated, but can be called\r\n   * manually for advanced use-cases (e.g. recording a server-confirmed payment).\r\n   *\r\n   * Duplicate `transactionId` values are silently ignored.\r\n   *\r\n   * @param result - The UnifiedPaymentResult returned by useBeninPay's onSuccess\r\n   * @param provider - The provider that processed the payment\r\n   */\r\n  addToHistory: (result: UnifiedPaymentResult, provider?: PaymentProvider) => void;\r\n  /**\r\n   * Remove a specific entry from history by its `transactionId`.\r\n   * No-op if the ID is not found.\r\n   */\r\n  removeFromHistory: (transactionId: string) => void;\r\n  /** Clear all entries from history (and from storage if applicable) */\r\n  clearHistory: () => void;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Internal helpers\r\n// ---------------------------------------------------------------------------\r\n\r\nconst DEFAULT_STORAGE_KEY = \"rbp_payment_history\";\r\nconst DEFAULT_MAX_ENTRIES = 50;\r\n\r\n/** Returns the relevant Web Storage instance, or null for memory/SSR. */\r\nfunction getWebStorage(type: PaymentHistoryStorage): Storage | null {\r\n  if (typeof window === \"undefined\") return null; // SSR guard\r\n  if (type === \"session\") return window.sessionStorage;\r\n  if (type === \"local\") return window.localStorage;\r\n  return null; // \"memory\"\r\n}\r\n\r\n/** Safely reads and parses entries from Web Storage. */\r\nfunction readFromStorage(\r\n  storage: Storage | null,\r\n  key: string\r\n): PaymentHistoryEntry[] {\r\n  if (!storage) return [];\r\n  try {\r\n    const raw = storage.getItem(key);\r\n    if (!raw) return [];\r\n    const parsed = JSON.parse(raw);\r\n    return Array.isArray(parsed) ? parsed : [];\r\n  } catch {\r\n    return [];\r\n  }\r\n}\r\n\r\n/** Safely serialises entries to Web Storage. Fails silently on quota errors. */\r\nfunction writeToStorage(\r\n  storage: Storage | null,\r\n  key: string,\r\n  entries: PaymentHistoryEntry[]\r\n): void {\r\n  if (!storage) return;\r\n  try {\r\n    storage.setItem(key, JSON.stringify(entries));\r\n  } catch {\r\n    // Storage quota exceeded or access denied — degrade gracefully.\r\n  }\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Hook\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Hook for tracking payment history within a session or across sessions.\r\n *\r\n * Supports three storage strategies: in-memory (default), sessionStorage, and\r\n * localStorage. Automatically deduplicates entries by `transactionId` and\r\n * enforces a configurable `maxEntries` limit.\r\n *\r\n * @example\r\n * ```tsx\r\n * // Basic in-memory usage\r\n * const { history, lastTransaction, totalPaid, clearHistory } = usePaymentHistory();\r\n *\r\n * // Persist across page reloads within the tab\r\n * const { history } = usePaymentHistory({ storage: \"session\" });\r\n *\r\n * // Integrated with useBeninPay\r\n * const { addToHistory } = usePaymentHistory({ storage: \"session\" });\r\n *\r\n * const { pay } = useBeninPay(config, {\r\n *   onSuccess: (result) => addToHistory(result, \"fedapay\"),\r\n * });\r\n * ```\r\n *\r\n * @example\r\n * ```tsx\r\n * // Display a receipt list\r\n * const { history, totalPaid, count } = usePaymentHistory({ storage: \"session\" });\r\n *\r\n * return (\r\n *   <div>\r\n *     <p>{count} paiement(s) — Total : {formatXOF(totalPaid)}</p>\r\n *     <ul>\r\n *       {history.map((entry) => (\r\n *         <li key={entry.transactionId}>\r\n *           {entry.transactionId} — {formatXOF(entry.amount)} ({entry.status})\r\n *         </li>\r\n *       ))}\r\n *     </ul>\r\n *   </div>\r\n * );\r\n * ```\r\n */\r\nexport function usePaymentHistory(\r\n  options: UsePaymentHistoryOptions = {}\r\n): UsePaymentHistoryReturn {\r\n  const {\r\n    storage = \"memory\",\r\n    storageKey = DEFAULT_STORAGE_KEY,\r\n    maxEntries = DEFAULT_MAX_ENTRIES,\r\n  } = options;\r\n\r\n  // Lazy initializer: read from web storage on first render (SSR-safe — the\r\n  // function only runs client-side, after hydration).\r\n  const [history, setHistory] = useState<PaymentHistoryEntry[]>(() => {\r\n    const webStorage = getWebStorage(storage);\r\n    return readFromStorage(webStorage, storageKey);\r\n  });\r\n\r\n  // Keep a stable ref to the current web storage so effects don't stale-close.\r\n  const webStorageRef = useRef<Storage | null>(null);\r\n  useEffect(() => {\r\n    webStorageRef.current = getWebStorage(storage);\r\n  }, [storage]);\r\n\r\n  useEffect(() => {\r\n    const nextStorage = getWebStorage(storage);\r\n    webStorageRef.current = nextStorage;\r\n    setHistory(readFromStorage(nextStorage, storageKey));\r\n  }, [storage, storageKey]);\r\n\r\n  // Sync history to web storage whenever it changes.\r\n  useEffect(() => {\r\n    if (history.length === 0) {\r\n      try {\r\n        webStorageRef.current?.removeItem(storageKey);\r\n      } catch {\r\n        // fail silently if storage access is denied\r\n      }\r\n    } else {\r\n      writeToStorage(webStorageRef.current, storageKey, history);\r\n    }\r\n  }, [history, storageKey]);\r\n\r\n  const addToHistory = useCallback(\r\n    (result: UnifiedPaymentResult, provider?: PaymentProvider) => {\r\n      setHistory((prev) => {\r\n        // Deduplicate: silently ignore already-recorded transaction IDs.\r\n        const alreadyExists = prev.some(\r\n          (e) => e.transactionId === result.transactionId\r\n        );\r\n        if (alreadyExists) return prev;\r\n\r\n        const entry: PaymentHistoryEntry = {\r\n          ...result,\r\n          provider,\r\n          recordedAt: new Date().toISOString(),\r\n        };\r\n\r\n        const updated = [entry, ...prev];\r\n\r\n        // Enforce the maxEntries cap by trimming the oldest entries.\r\n        return updated.length > maxEntries\r\n          ? updated.slice(0, maxEntries)\r\n          : updated;\r\n      });\r\n    },\r\n    [maxEntries]\r\n  );\r\n\r\n  const removeFromHistory = useCallback((transactionId: string) => {\r\n    setHistory((prev) =>\r\n      prev.filter((e) => e.transactionId !== transactionId)\r\n    );\r\n  }, []);\r\n\r\n  const clearHistory = useCallback(() => {\r\n    setHistory([]);\r\n  }, []);\r\n\r\n  const lastTransaction = history.length > 0 ? history[0] : null;\r\n  const totalPaid = history.reduce((sum, e) => sum + e.amount, 0);\r\n\r\n  return {\r\n    history,\r\n    lastTransaction,\r\n    totalPaid,\r\n    count: history.length,\r\n    addToHistory,\r\n    removeFromHistory,\r\n    clearHistory,\r\n  };\r\n}\r\n","\"use client\";\r\n\r\nimport { useState, useCallback, useRef, useEffect } from \"react\";\r\n\r\nexport interface UseRetryPaymentOptions<TResult = unknown> {\r\n  /**\r\n   * Nombre maximum de tentatives après le premier échec.\r\n   * @default 3\r\n   */\r\n  maxRetries?: number;\r\n  /**\r\n   * Délai de base en millisecondes avant la première tentative de retry.\r\n   * @default 1000\r\n   */\r\n  baseDelay?: number;\r\n  /**\r\n   * Facteur multiplicateur exponentiel pour le délai après chaque échec.\r\n   * Exemple pour factor = 2, delay = 1000: 1000ms, 2000ms, 4000ms...\r\n   * @default 2\r\n   */\r\n  backoffFactor?: number;\r\n  /** Callback appelé avant chaque nouvelle tentative */\r\n  onRetry?: (attempt: number, delayMs: number, error: unknown) => void;\r\n  /** Callback appelé en cas de succès final */\r\n  onSuccess?: (data: TResult) => void;\r\n  /** Callback appelé quand toutes les tentatives sont épuisées */\r\n  onFail?: (error: unknown) => void;\r\n}\r\n\r\nexport interface UseRetryPaymentReturn<TArgs extends unknown[], TResult> {\r\n  /** Déclenche l'action asynchrone avec backoff en cas d'échec */\r\n  execute: (...args: TArgs) => Promise<TResult | undefined>;\r\n  /** Annule la tentative en cours et stoppe le retry */\r\n  cancel: () => void;\r\n  /** Indique si l'action (ou ses retrys) est en cours d'exécution */\r\n  isPending: boolean;\r\n  /** L'erreur du dernier échec rencontré */\r\n  error: unknown | null;\r\n  /** Le nombre de retrys effectués jusqu'à présent (0 si premier essai) */\r\n  attemptCount: number;\r\n}\r\n\r\n/**\r\n * Hook utilitaire pour retenter automatiquement une action de paiement\r\n * (ex: vérification de statut API, initialisation asynchrone) avec\r\n * un système de délai exponentiel (exponential backoff).\r\n *\r\n * @example\r\n * ```tsx\r\n * const { execute, isPending, error, attemptCount } = useRetryPayment(\r\n *   async (transactionId) => {\r\n *     return await verifyOnMyBackend(transactionId);\r\n *   },\r\n *   {\r\n *     maxRetries: 3,\r\n *     baseDelay: 2000,\r\n *     onSuccess: (data) => console.log(\"Paiement validé !\", data),\r\n *     onFail: (err) => console.error(\"Échec définitif\", err),\r\n *     onRetry: (attempt, delay) => console.log(`Essai ${attempt} dans ${delay}ms`)\r\n *   }\r\n * );\r\n * ```\r\n */\r\nexport function useRetryPayment<TArgs extends unknown[], TResult>(\r\n  action: (...args: TArgs) => Promise<TResult>,\r\n  options: UseRetryPaymentOptions<TResult> = {}\r\n): UseRetryPaymentReturn<TArgs, TResult> {\r\n  const {\r\n    maxRetries = 3,\r\n    baseDelay = 1000,\r\n    backoffFactor = 2,\r\n  } = options;\r\n\r\n  const [isPending, setIsPending] = useState(false);\r\n  const [error, setError] = useState<unknown | null>(null);\r\n  const [attemptCount, setAttemptCount] = useState(0);\r\n\r\n  const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n  const isCancelledRef = useRef(false);\r\n\r\n  // Utilisation de refs pour l'action et les options afin d'éviter\r\n  // de redéclencher les useEffect/useCallback à chaque rendu.\r\n  const actionRef = useRef(action);\r\n  const optionsRef = useRef(options);\r\n\r\n  useEffect(() => {\r\n    actionRef.current = action;\r\n    optionsRef.current = options;\r\n  });\r\n\r\n  const cancel = useCallback(() => {\r\n    isCancelledRef.current = true;\r\n    if (timeoutRef.current) {\r\n      clearTimeout(timeoutRef.current);\r\n      timeoutRef.current = null;\r\n    }\r\n    setIsPending(false);\r\n  }, []);\r\n\r\n  const execute = useCallback(\r\n    async (...args: TArgs): Promise<TResult | undefined> => {\r\n      cancel(); // Annule toute exécution précédente en cours\r\n      isCancelledRef.current = false;\r\n      setIsPending(true);\r\n      setError(null);\r\n      setAttemptCount(0);\r\n\r\n      let currentAttempt = 0;\r\n\r\n      const attempt = async (): Promise<TResult | undefined> => {\r\n        if (isCancelledRef.current) return undefined;\r\n\r\n        try {\r\n          const result = await actionRef.current(...args);\r\n          if (isCancelledRef.current) return undefined;\r\n\r\n          setIsPending(false);\r\n          optionsRef.current.onSuccess?.(result);\r\n          return result;\r\n        } catch (err) {\r\n          if (isCancelledRef.current) return undefined;\r\n\r\n          setError(err);\r\n\r\n          if (currentAttempt < maxRetries) {\r\n            currentAttempt++;\r\n            setAttemptCount(currentAttempt);\r\n\r\n            const delayMs = baseDelay * Math.pow(backoffFactor, currentAttempt - 1);\r\n            optionsRef.current.onRetry?.(currentAttempt, delayMs, err);\r\n\r\n            return new Promise<TResult | undefined>((resolve) => {\r\n              timeoutRef.current = setTimeout(() => {\r\n                resolve(attempt());\r\n              }, delayMs);\r\n            });\r\n          } else {\r\n            setIsPending(false);\r\n            optionsRef.current.onFail?.(err);\r\n            throw err;\r\n          }\r\n        }\r\n      };\r\n\r\n      return attempt();\r\n    },\r\n    [baseDelay, backoffFactor, maxRetries, cancel]\r\n  );\r\n\r\n  // Nettoyage lors du démontage du composant\r\n  useEffect(() => {\r\n    return () => cancel();\r\n  }, [cancel]);\r\n\r\n  return {\r\n    execute,\r\n    cancel,\r\n    isPending,\r\n    error,\r\n    attemptCount,\r\n  };\r\n}\r\n","/**\n * Converts a Blob to a base64 data URL (e.g. `\"data:application/pdf;base64,...\"`).\n * Relies on `FileReader`, so this only runs in a browser (or jsdom) environment.\n */\nexport function blobToDataUrl(blob: Blob): Promise<string> {\n  return new Promise((resolve, reject) => {\n    const reader = new FileReader();\n    reader.onload = () => resolve(reader.result as string);\n    reader.onerror = reject;\n    reader.readAsDataURL(blob);\n  });\n}\n\n/**\n * Triggers a browser download for a Blob via a temporary `<a download>` link.\n * No-op outside the browser (SSR).\n */\nexport function triggerBlobDownload(blob: Blob, filename: string): void {\n  if (typeof document === \"undefined\") return;\n\n  const url = URL.createObjectURL(blob);\n  const link = document.createElement(\"a\");\n  link.href = url;\n  link.download = filename.endsWith(\".pdf\") ? filename : `${filename}.pdf`;\n  document.body.appendChild(link);\n  link.click();\n  document.body.removeChild(link);\n  URL.revokeObjectURL(url);\n}\n","import type {\n  ReceiptConfig,\n  ReceiptTransactionData,\n  ReceiptLabels,\n} from \"../types/receipt\";\nimport type { Currency } from \"../types\";\nimport type { PaymentProviderId } from \"../core/types\";\nimport { blobToDataUrl, triggerBlobDownload } from \"./pdfHelpers\";\n\n/** Nice display name for the two built-in providers; any other driver's identifier is shown as-is. */\nexport function formatProviderName(provider: PaymentProviderId): string {\n  if (provider === \"fedapay\") return \"FedaPay\";\n  if (provider === \"kkiapay\") return \"KKiaPay\";\n  return provider;\n}\n\nconst DEFAULT_LABELS: ReceiptLabels = {\n  receiptTitle: \"REÇU DE PAIEMENT\",\n  invoiceNumberLabel: \"N° Facture\",\n  transactionIdLabel: \"ID Transaction\",\n  amountLabel: \"Montant\",\n  dateLabel: \"Date\",\n  statusLabel: \"Statut\",\n  fromLabel: \"DE\",\n  toLabel: \"À\",\n  serviceLabel: \"Service\",\n  descriptionLabel: \"Description\",\n  totalLabel: \"TOTAL\",\n  thankYouNote: \"Merci pour votre paiement.\",\n};\n\nconst DEFAULT_PRIMARY = \"#4E6BFF\";\n// Neutral hairline/rule color — kept configurable via `secondaryColor` for\n// brand consistency, but no longer used as a loud background fill.\nconst DEFAULT_SECONDARY = \"#E4E4E7\";\nconst DEFAULT_TEXT = \"#18181B\";\nconst MUTED_TEXT: [number, number, number] = [113, 113, 122];\n\nfunction hexToRgb(hex: string): [number, number, number] {\n  const clean = hex.replace(\"#\", \"\");\n  const r = parseInt(clean.substring(0, 2), 16);\n  const g = parseInt(clean.substring(2, 4), 16);\n  const b = parseInt(clean.substring(4, 6), 16);\n  if (isNaN(r) || isNaN(g) || isNaN(b)) return [78, 107, 255];\n  return [r, g, b];\n}\n\n/**\n * jsPDF's built-in fonts (Helvetica) only cover the WinAnsi range. `Intl`\n * formatters commonly insert narrow/no-break spaces (e.g. as a thousands\n * separator) that fall outside it and render as garbled glyphs — normalize\n * them to a plain space before handing text to jsPDF.\n */\nfunction toPdfSafeText(text: string): string {\n  // U+00A0 no-break space, U+2007 figure space, U+2009 thin space,\n  // U+200A hair space, U+202F narrow no-break space.\n  return text.replace(/[\\u00A0\\u2007\\u2009\\u200A\\u202F]/g, \" \");\n}\n\nfunction formatAmount(amount: number, currency: Currency, locale: string): string {\n  try {\n    return toPdfSafeText(\n      new Intl.NumberFormat(locale, {\n        style: \"currency\",\n        currency,\n        minimumFractionDigits: 0,\n      }).format(amount)\n    );\n  } catch {\n    return `${amount.toLocaleString(locale)} ${currency}`;\n  }\n}\n\nfunction formatDate(date: string | Date | undefined, locale: string): string {\n  const d = date ? new Date(date) : new Date();\n  try {\n    return toPdfSafeText(\n      new Intl.DateTimeFormat(locale, {\n        year: \"numeric\",\n        month: \"long\",\n        day: \"numeric\",\n        hour: \"2-digit\",\n        minute: \"2-digit\",\n      }).format(d)\n    );\n  } catch {\n    return d.toLocaleDateString();\n  }\n}\n\nfunction resolveInvoiceNumber(\n  config: ReceiptConfig,\n  data: ReceiptTransactionData\n): string {\n  const prefix = config.invoicePrefix ?? \"FAC-\";\n  if (!config.invoiceNumber) {\n    return `${prefix}${data.transactionId.slice(-8).toUpperCase()}`;\n  }\n  if (typeof config.invoiceNumber === \"function\") {\n    return String(config.invoiceNumber(data));\n  }\n  return `${prefix}${config.invoiceNumber}`;\n}\n\nfunction resolveFilename(\n  config: ReceiptConfig,\n  data: ReceiptTransactionData\n): string {\n  if (!config.filename) return `recu-${data.transactionId}`;\n  if (typeof config.filename === \"function\") return config.filename(data);\n  return config.filename;\n}\n\nasync function fetchImageAsBase64(url: string): Promise<string> {\n  const response = await fetch(url);\n  const blob = await response.blob();\n  return blobToDataUrl(blob);\n}\n\nexport interface GenerateReceiptResult {\n  blob: Blob;\n  dataUrl: string;\n  /** Nom du fichier sans extension */\n  filename: string;\n}\n\n/** Résultat interne d'un rendu (par défaut ou personnalisé), avant résolution du nom de fichier / data URL. */\ninterface RenderedPdf {\n  blob: Blob;\n  dataUrl?: string;\n  filename?: string;\n}\n\n/**\n * Génère le reçu PDF par défaut avec jsPDF.\n *\n * jsPDF est chargé dynamiquement — il n'est requis (et donc installé) que si\n * `config.renderPdf` n'est pas fourni. C'est un peer dependency optionnel :\n * `npm install jspdf`.\n */\nasync function renderDefaultPdf(\n  data: ReceiptTransactionData,\n  config: ReceiptConfig\n): Promise<RenderedPdf> {\n  let jsPDF: (typeof import(\"jspdf\"))[\"jsPDF\"];\n  try {\n    ({ jsPDF } = await import(\"jspdf\"));\n  } catch {\n    throw new Error(\n      \"Le générateur de reçu par défaut nécessite jsPDF. Exécutez `npm install jspdf`, \" +\n        \"ou fournissez `config.renderPdf` pour utiliser votre propre générateur de PDF.\"\n    );\n  }\n\n  const locale = config.locale ?? \"fr-BJ\";\n  const currency: Currency = data.currency ?? config.currency ?? \"XOF\";\n  const labels: ReceiptLabels = { ...DEFAULT_LABELS, ...config.labels };\n\n  const [pr, pg, pb] = hexToRgb(config.primaryColor ?? DEFAULT_PRIMARY);\n  const [lr, lg, lb] = hexToRgb(config.secondaryColor ?? DEFAULT_SECONDARY);\n  const [tr, tg, tb] = hexToRgb(config.textColor ?? DEFAULT_TEXT);\n  const [mr, mg, mb] = MUTED_TEXT;\n\n  const doc = new jsPDF({ orientation: \"portrait\", unit: \"mm\", format: \"a4\" });\n  const PAGE_W = 210;\n  const MARGIN = 20;\n  const CONTENT_W = PAGE_W - MARGIN * 2;\n\n  const hairline = (y: number, weight = 0.25) => {\n    doc.setDrawColor(lr, lg, lb);\n    doc.setLineWidth(weight);\n    doc.line(MARGIN, y, PAGE_W - MARGIN, y);\n  };\n\n  // Thin brand-colored bar at the very top edge — the only block of color on\n  // the page. Everything else relies on whitespace, hairlines and typography.\n  doc.setFillColor(pr, pg, pb);\n  doc.rect(0, 0, PAGE_W, 2.5, \"F\");\n\n  const headerTop = 14;\n\n  // Logo + company identity (left)\n  let leftX = MARGIN;\n  if (config.logo) {\n    try {\n      let logoData = config.logo;\n      if (config.logo.startsWith(\"http\")) {\n        logoData = await fetchImageAsBase64(config.logo);\n      }\n      const imgType = logoData.includes(\"data:image/jpeg\") ? \"JPEG\" : \"PNG\";\n      doc.addImage(logoData, imgType, MARGIN, headerTop, 16, 16);\n      leftX = MARGIN + 16 + 6;\n    } catch {\n      // Logo unavailable — continue without it.\n    }\n  }\n\n  let leftY = headerTop + 4;\n  if (config.appName) {\n    doc.setFont(\"helvetica\", \"bold\");\n    doc.setFontSize(13);\n    doc.setTextColor(tr, tg, tb);\n    doc.text(config.appName, leftX, leftY);\n    leftY += 6;\n  }\n  doc.setFont(\"helvetica\", \"normal\");\n  doc.setFontSize(8.5);\n  doc.setTextColor(mr, mg, mb);\n  for (const line of [\n    config.appDescription,\n    config.appAddress,\n    config.appEmail,\n    config.appPhone,\n    config.appWebsite,\n  ]) {\n    if (line) {\n      doc.text(line, leftX, leftY);\n      leftY += 4.5;\n    }\n  }\n\n  // Title + invoice number + date (right)\n  const invoiceNum = resolveInvoiceNumber(config, data);\n  doc.setFont(\"helvetica\", \"bold\");\n  doc.setFontSize(9);\n  doc.setTextColor(mr, mg, mb);\n  doc.text(labels.receiptTitle.toUpperCase(), PAGE_W - MARGIN, headerTop + 4, { align: \"right\" });\n  doc.setFont(\"helvetica\", \"normal\");\n  doc.setFontSize(9.5);\n  doc.setTextColor(tr, tg, tb);\n  doc.text(`${labels.invoiceNumberLabel} ${invoiceNum}`, PAGE_W - MARGIN, headerTop + 11, {\n    align: \"right\",\n  });\n  doc.setFontSize(8.5);\n  doc.setTextColor(mr, mg, mb);\n  doc.text(formatDate(data.date, locale), PAGE_W - MARGIN, headerTop + 16.5, { align: \"right\" });\n\n  let y = Math.max(leftY, headerTop + 22) + 5;\n  hairline(y);\n  y += 9;\n\n  // From / To\n  const midX = MARGIN + CONTENT_W / 2 + 4;\n  doc.setFont(\"helvetica\", \"bold\");\n  doc.setFontSize(7.5);\n  doc.setTextColor(mr, mg, mb);\n  doc.text(labels.fromLabel.toUpperCase(), MARGIN, y);\n  doc.text(labels.toLabel.toUpperCase(), midX, y);\n  y += 5.5;\n\n  doc.setFontSize(9.5);\n  let fromY = y;\n  let toY = y;\n\n  if (config.appName) {\n    doc.setFont(\"helvetica\", \"bold\");\n    doc.setTextColor(tr, tg, tb);\n    doc.text(config.appName, MARGIN, fromY);\n    fromY += 5;\n  }\n  doc.setFont(\"helvetica\", \"normal\");\n  doc.setTextColor(mr, mg, mb);\n  for (const line of [config.appAddress, config.appEmail, config.appPhone].filter(Boolean) as string[]) {\n    doc.text(line, MARGIN, fromY);\n    fromY += 5;\n  }\n\n  if (data.customerName) {\n    doc.setFont(\"helvetica\", \"bold\");\n    doc.setTextColor(tr, tg, tb);\n    doc.text(data.customerName, midX, toY);\n    toY += 5;\n  }\n  doc.setFont(\"helvetica\", \"normal\");\n  doc.setTextColor(mr, mg, mb);\n  for (const line of [data.customerEmail, data.customerPhone].filter(Boolean) as string[]) {\n    doc.text(line, midX, toY);\n    toY += 5;\n  }\n\n  y = Math.max(fromY, toY) + 7;\n  hairline(y);\n  y += 8;\n\n  // Transaction details\n  doc.setFont(\"helvetica\", \"bold\");\n  doc.setFontSize(8);\n  doc.setTextColor(pr, pg, pb);\n  doc.text(\"DÉTAILS DE LA TRANSACTION\", MARGIN, y);\n  y += 7;\n\n  const rows: Array<{ label: string; value: string }> = [];\n  rows.push({ label: labels.transactionIdLabel, value: data.transactionId });\n  rows.push({ label: labels.dateLabel, value: formatDate(data.date, locale) });\n  if (data.serviceName) rows.push({ label: labels.serviceLabel, value: data.serviceName });\n  if (data.description) rows.push({ label: labels.descriptionLabel, value: data.description });\n  if (data.provider) {\n    rows.push({ label: \"Fournisseur\", value: formatProviderName(data.provider) });\n  }\n  if (data.status) rows.push({ label: labels.statusLabel, value: data.status });\n  if (config.extraFields) {\n    for (const field of config.extraFields) {\n      const val = typeof field.value === \"function\" ? field.value(data) : field.value;\n      rows.push({ label: field.label, value: String(val) });\n    }\n  }\n\n  const ROW_H = 8;\n  const LABEL_COL_W = 62;\n\n  rows.forEach((row, i) => {\n    const rowTop = y + i * ROW_H;\n    doc.setFont(\"helvetica\", \"normal\");\n    doc.setFontSize(8.5);\n    doc.setTextColor(mr, mg, mb);\n    doc.text(row.label, MARGIN, rowTop + 5);\n\n    doc.setFontSize(9.5);\n    doc.setTextColor(tr, tg, tb);\n    doc.text(row.value, MARGIN + LABEL_COL_W, rowTop + 5);\n\n    hairline(rowTop + ROW_H, 0.2);\n  });\n\n  y += rows.length * ROW_H + 10;\n\n  // Total — emphasized with size and the brand color, not a filled block.\n  hairline(y, 0.5);\n  y += 9;\n  doc.setFont(\"helvetica\", \"bold\");\n  doc.setFontSize(9);\n  doc.setTextColor(mr, mg, mb);\n  doc.text(labels.totalLabel, MARGIN, y);\n  doc.setFontSize(17);\n  doc.setTextColor(pr, pg, pb);\n  doc.text(formatAmount(data.amount, currency, locale), PAGE_W - MARGIN, y, { align: \"right\" });\n  y += 14;\n\n  const footerNote = config.footerNote ?? labels.thankYouNote;\n  doc.setFont(\"helvetica\", \"italic\");\n  doc.setFontSize(8.5);\n  doc.setTextColor(mr, mg, mb);\n  doc.text(footerNote, PAGE_W / 2, y, { align: \"center\" });\n\n  // Footer\n  hairline(280);\n  if (config.appWebsite) {\n    doc.setFont(\"helvetica\", \"normal\");\n    doc.setFontSize(8);\n    doc.setTextColor(mr, mg, mb);\n    doc.text(config.appWebsite, PAGE_W / 2, 286, { align: \"center\" });\n  }\n\n  return {\n    blob: doc.output(\"blob\"),\n    dataUrl: doc.output(\"datauristring\"),\n  };\n}\n\n/**\n * Génère un reçu PDF à partir des données de transaction et d'une configuration\n * optionnelle de mise en page.\n *\n * Par défaut, utilise un template jsPDF minimaliste (chargé à la demande —\n * `npm install jspdf` requis). Fournissez `config.renderPdf` pour remplacer\n * entièrement ce rendu par le vôtre ; le téléchargement, le data URL et\n * l'envoi par email continuent de fonctionner à l'identique.\n *\n * @param data   Données de la transaction (ID, montant, client…)\n * @param config Configuration du design et du contenu du reçu\n * @returns      Blob, data URL base64 et nom du fichier\n */\nexport async function generateReceiptPdf(\n  data: ReceiptTransactionData,\n  config: ReceiptConfig = {}\n): Promise<GenerateReceiptResult> {\n  const rendered: RenderedPdf = config.renderPdf\n    ? await config.renderPdf(data, config)\n    : await renderDefaultPdf(data, config);\n\n  const filename = rendered.filename ?? resolveFilename(config, data);\n  const dataUrl = rendered.dataUrl ?? (await blobToDataUrl(rendered.blob));\n\n  if (config.autoDownload !== false) {\n    triggerBlobDownload(rendered.blob, filename);\n  }\n\n  config.onGenerated?.(rendered.blob, dataUrl);\n\n  return { blob: rendered.blob, dataUrl, filename };\n}\n","import type {\r\n  ReceiptEmailConfig,\r\n  ReceiptEmailParams,\r\n  ReceiptTransactionData,\r\n} from \"../types/receipt\";\r\n\r\ninterface SendReceiptEmailInput {\r\n  pdfBlob: Blob;\r\n  dataUrl: string;\r\n  filename: string;\r\n  transactionData: ReceiptTransactionData;\r\n}\r\n\r\n/**\r\n * Envoie un reçu PDF par email via la configuration fournie.\r\n *\r\n * Deux stratégies sont supportées :\r\n * - `sendFn` — délègue à une fonction async personnalisée (Resend, SendGrid, etc.)\r\n * - `sendUrl` — POST JSON vers un endpoint HTTP de votre backend\r\n *\r\n * @throws si ni `sendFn` ni `sendUrl` ne sont configurés\r\n * @throws si la requête HTTP retourne un statut d'erreur (mode `sendUrl`)\r\n */\r\nexport async function sendReceiptEmail(\r\n  to: string,\r\n  input: SendReceiptEmailInput,\r\n  emailConfig: ReceiptEmailConfig\r\n): Promise<void> {\r\n  // Extraire le base64 pur depuis le data URL (\"data:application/pdf;base64,XXX\")\r\n  const pdfBase64 = input.dataUrl.includes(\",\")\r\n    ? (input.dataUrl.split(\",\")[1] ?? input.dataUrl)\r\n    : input.dataUrl;\r\n\r\n  const subject =\r\n    typeof emailConfig.subject === \"function\"\r\n      ? emailConfig.subject(input.transactionData)\r\n      : (emailConfig.subject ?? \"Votre reçu de paiement\");\r\n\r\n  const params: ReceiptEmailParams = {\r\n    to,\r\n    subject,\r\n    pdfBase64,\r\n    pdfBlob: input.pdfBlob,\r\n    filename: `${input.filename}.pdf`,\r\n    transactionData: input.transactionData,\r\n  };\r\n\r\n  if (emailConfig.sendFn) {\r\n    await emailConfig.sendFn(params);\r\n    return;\r\n  }\r\n\r\n  if (emailConfig.sendUrl) {\r\n    const bodyHtml =\r\n      typeof emailConfig.bodyHtml === \"function\"\r\n        ? emailConfig.bodyHtml(input.transactionData)\r\n        : emailConfig.bodyHtml;\r\n\r\n    const bodyText =\r\n      typeof emailConfig.bodyText === \"function\"\r\n        ? emailConfig.bodyText(input.transactionData)\r\n        : emailConfig.bodyText;\r\n\r\n    const response = await fetch(emailConfig.sendUrl, {\r\n      method: \"POST\",\r\n      headers: {\r\n        \"Content-Type\": \"application/json\",\r\n        ...emailConfig.sendHeaders,\r\n      },\r\n      body: JSON.stringify({\r\n        to,\r\n        subject,\r\n        pdfBase64,\r\n        filename: params.filename,\r\n        bodyHtml,\r\n        bodyText,\r\n        transactionData: input.transactionData,\r\n      }),\r\n    });\r\n\r\n    if (!response.ok) {\r\n      const errorText = await response.text().catch(() => \"Erreur inconnue\");\r\n      throw new Error(\r\n        `Échec de l'envoi du reçu par email : ${response.status} ${errorText}`\r\n      );\r\n    }\r\n    return;\r\n  }\r\n\r\n  throw new Error(\r\n    \"Configuration email invalide : fournissez sendFn ou sendUrl dans config.email.\"\r\n  );\r\n}\r\n","\"use client\";\r\n\r\nimport { useCallback, useState } from \"react\";\r\nimport { generateReceiptPdf, type GenerateReceiptResult } from \"../utils/generateReceipt\";\r\nimport { sendReceiptEmail } from \"../utils/sendReceiptEmail\";\r\nimport type { ReceiptConfig, ReceiptTransactionData } from \"../types/receipt\";\r\n\r\nexport type { ReceiptConfig, ReceiptTransactionData } from \"../types/receipt\";\r\nexport type {\r\n  ReceiptField,\r\n  ReceiptLabels,\r\n  ReceiptEmailConfig,\r\n  ReceiptEmailParams,\r\n} from \"../types/receipt\";\r\nexport type { GenerateReceiptResult } from \"../utils/generateReceipt\";\r\n\r\n/**\r\n * Valeur retournée par `usePaymentReceipt`.\r\n */\r\nexport interface UsePaymentReceiptReturn {\r\n  /**\r\n   * Génère le PDF et déclenche le téléchargement dans le navigateur.\r\n   * Respecte `config.autoDownload` (défaut : `true`).\r\n   *\r\n   * @returns Blob, data URL et nom de fichier — ou `null` en cas d'erreur\r\n   */\r\n  generateAndDownload: (\r\n    data: ReceiptTransactionData\r\n  ) => Promise<GenerateReceiptResult | null>;\r\n\r\n  /**\r\n   * Génère le PDF sans téléchargement et retourne le Blob.\r\n   * Utile pour l'afficher dans un `<iframe>` ou l'uploader.\r\n   *\r\n   * @returns Blob — ou `null` en cas d'erreur\r\n   */\r\n  generateBlob: (data: ReceiptTransactionData) => Promise<Blob | null>;\r\n\r\n  /**\r\n   * Génère le PDF et retourne le data URL base64.\r\n   * Utile pour prévisualiser le PDF dans le navigateur.\r\n   *\r\n   * @returns Data URL `\"data:application/pdf;base64,...\"` — ou `null` en cas d'erreur\r\n   */\r\n  generateDataUrl: (data: ReceiptTransactionData) => Promise<string | null>;\r\n\r\n  /**\r\n   * Génère le reçu et l'envoie par email à l'adresse indiquée.\r\n   * Nécessite que `config.email` soit configuré.\r\n   *\r\n   * @param to   Adresse email du destinataire\r\n   * @param data Données de la transaction\r\n   * @throws si `config.email` est absent ou si l'envoi échoue\r\n   */\r\n  sendByEmail: (to: string, data: ReceiptTransactionData) => Promise<void>;\r\n\r\n  /** `true` pendant la génération du PDF */\r\n  isGenerating: boolean;\r\n\r\n  /** `true` pendant l'envoi de l'email */\r\n  isSending: boolean;\r\n\r\n  /** Dernière erreur survenue, ou `null` */\r\n  error: Error | null;\r\n\r\n  /** Efface l'erreur courante */\r\n  clearError: () => void;\r\n}\r\n\r\n/**\r\n * Hook React pour générer des reçus PDF et les envoyer par email.\r\n *\r\n * Toute la mise en page est contrôlée via le paramètre `config` :\r\n * logo, couleurs, numérotation des factures, champs personnalisés, pied de page.\r\n *\r\n * @example\r\n * ```tsx\r\n * // Génération + téléchargement automatique\r\n * const { generateAndDownload, isGenerating } = usePaymentReceipt({\r\n *   appName: \"MonShop\",\r\n *   logo: \"/logo.png\",\r\n *   primaryColor: \"#22C55E\",\r\n *   invoicePrefix: \"CMD-\",\r\n *   footerNote: \"Merci pour votre achat !\",\r\n * });\r\n *\r\n * // Dans le callback onComplete de useFedaPay :\r\n * onComplete: (response) => {\r\n *   generateAndDownload({\r\n *     transactionId: response.transaction.reference,\r\n *     amount: response.transaction.amount,\r\n *     status: \"Approuvé\",\r\n *     customerName: \"Jean Dupont\",\r\n *     customerEmail: \"jean@example.com\",\r\n *   });\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```tsx\r\n * // Envoi automatique par email\r\n * const { sendByEmail } = usePaymentReceipt({\r\n *   appName: \"MonShop\",\r\n *   email: {\r\n *     sendFn: async ({ to, pdfBase64, filename }) => {\r\n *       await fetch(\"/api/send-receipt\", {\r\n *         method: \"POST\",\r\n *         body: JSON.stringify({ to, pdfBase64, filename }),\r\n *       });\r\n *     },\r\n *   },\r\n * });\r\n *\r\n * sendByEmail(\"client@example.com\", transactionData);\r\n * ```\r\n */\r\nexport function usePaymentReceipt(\r\n  config: ReceiptConfig = {}\r\n): UsePaymentReceiptReturn {\r\n  const [isGenerating, setIsGenerating] = useState(false);\r\n  const [isSending, setIsSending] = useState(false);\r\n  const [error, setError] = useState<Error | null>(null);\r\n\r\n  const clearError = useCallback(() => setError(null), []);\r\n\r\n  // Génère + télécharge\r\n  const generateAndDownload = useCallback(\r\n    async (data: ReceiptTransactionData): Promise<GenerateReceiptResult | null> => {\r\n      setIsGenerating(true);\r\n      setError(null);\r\n      try {\r\n        return await generateReceiptPdf(data, { ...config, autoDownload: true });\r\n      } catch (err) {\r\n        const e =\r\n          err instanceof Error ? err : new Error(\"Échec de la génération du reçu\");\r\n        setError(e);\r\n        return null;\r\n      } finally {\r\n        setIsGenerating(false);\r\n      }\r\n    },\r\n    // eslint-disable-next-line react-hooks/exhaustive-deps\r\n    [JSON.stringify(config)]\r\n  );\r\n\r\n  // Génère → Blob uniquement (pas de téléchargement)\r\n  const generateBlob = useCallback(\r\n    async (data: ReceiptTransactionData): Promise<Blob | null> => {\r\n      setIsGenerating(true);\r\n      setError(null);\r\n      try {\r\n        const result = await generateReceiptPdf(data, {\r\n          ...config,\r\n          autoDownload: false,\r\n        });\r\n        return result.blob;\r\n      } catch (err) {\r\n        const e =\r\n          err instanceof Error ? err : new Error(\"Échec de la génération du reçu\");\r\n        setError(e);\r\n        return null;\r\n      } finally {\r\n        setIsGenerating(false);\r\n      }\r\n    },\r\n    // eslint-disable-next-line react-hooks/exhaustive-deps\r\n    [JSON.stringify(config)]\r\n  );\r\n\r\n  // Génère → data URL uniquement\r\n  const generateDataUrl = useCallback(\r\n    async (data: ReceiptTransactionData): Promise<string | null> => {\r\n      setIsGenerating(true);\r\n      setError(null);\r\n      try {\r\n        const result = await generateReceiptPdf(data, {\r\n          ...config,\r\n          autoDownload: false,\r\n        });\r\n        return result.dataUrl;\r\n      } catch (err) {\r\n        const e =\r\n          err instanceof Error ? err : new Error(\"Échec de la génération du reçu\");\r\n        setError(e);\r\n        return null;\r\n      } finally {\r\n        setIsGenerating(false);\r\n      }\r\n    },\r\n    // eslint-disable-next-line react-hooks/exhaustive-deps\r\n    [JSON.stringify(config)]\r\n  );\r\n\r\n  // Génère + envoie par email\r\n  const sendByEmail = useCallback(\r\n    async (to: string, data: ReceiptTransactionData): Promise<void> => {\r\n      if (!config.email) {\r\n        throw new Error(\r\n          \"Configuration email manquante. Fournissez config.email dans usePaymentReceipt.\"\r\n        );\r\n      }\r\n\r\n      setIsSending(true);\r\n      setError(null);\r\n      try {\r\n        const result = await generateReceiptPdf(data, {\r\n          ...config,\r\n          autoDownload: false,\r\n        });\r\n        await sendReceiptEmail(\r\n          to,\r\n          {\r\n            pdfBlob: result.blob,\r\n            dataUrl: result.dataUrl,\r\n            filename: result.filename,\r\n            transactionData: data,\r\n          },\r\n          config.email\r\n        );\r\n      } catch (err) {\r\n        const e =\r\n          err instanceof Error\r\n            ? err\r\n            : new Error(\"Échec de l'envoi du reçu par email\");\r\n        setError(e);\r\n        throw e;\r\n      } finally {\r\n        setIsSending(false);\r\n      }\r\n    },\r\n    // eslint-disable-next-line react-hooks/exhaustive-deps\r\n    [JSON.stringify(config)]\r\n  );\r\n\r\n  return {\r\n    generateAndDownload,\r\n    generateBlob,\r\n    generateDataUrl,\r\n    sendByEmail,\r\n    isGenerating,\r\n    isSending,\r\n    error,\r\n    clearError,\r\n  };\r\n}\r\n","\"use client\";\r\n\r\nimport React, { forwardRef } from \"react\";\r\nimport { useFedaPay } from \"../hooks/useFedaPay\";\r\nimport type { UseFedaPayConfig } from \"../hooks/useFedaPay\";\r\nimport type { PaymentValidationError } from \"../types/validation\";\r\nimport type { BeninPaymentAnalyticsHandler } from \"../utils/analytics\";\r\n\r\nexport interface FedaPayButtonProps\r\n  extends React.ButtonHTMLAttributes<HTMLButtonElement> {\r\n  config: UseFedaPayConfig;\r\n  /** @default \"Payer\" */\r\n  text?: string;\r\n  /** @default \"Chargement...\" */\r\n  loadingText?: string;\r\n  /** @default \"Vérification...\" */\r\n  verifyingText?: string;\r\n  /** @default false */\r\n  debug?: boolean;\r\n  onBeforePayment?: () => void | boolean | Promise<void | boolean>;\r\n  onAnalyticsEvent?: BeninPaymentAnalyticsHandler;\r\n  onPaymentError?: (error: PaymentValidationError) => void;\r\n}\r\n\r\nexport const FedaPayButton = forwardRef<HTMLButtonElement, FedaPayButtonProps>(\r\n  (\r\n    {\r\n      config,\r\n      text = \"Payer\",\r\n      loadingText = \"Chargement...\",\r\n      verifyingText = \"Vérification...\",\r\n      debug = false,\r\n      onBeforePayment,\r\n      onAnalyticsEvent,\r\n      onPaymentError,\r\n      children,\r\n      disabled,\r\n      style,\r\n      ...props\r\n    },\r\n    ref\r\n  ) => {\r\n    const { openDialog, loading, scriptLoaded, isVerifying, isPreparing } = useFedaPay(config, {\r\n      debug,\r\n      onBeforePayment,\r\n      onAnalyticsEvent,\r\n      onError: onPaymentError,\r\n    });\r\n\r\n    const isDisabled = disabled || loading || !scriptLoaded || isVerifying || isPreparing;\r\n\r\n    const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\r\n      if (isDisabled) {\r\n        e.preventDefault();\r\n        return;\r\n      }\r\n      openDialog();\r\n      props.onClick?.(e);\r\n    };\r\n\r\n    const getButtonText = () => {\r\n      if (loading || isPreparing) return loadingText;\r\n      if (isVerifying) return verifyingText;\r\n      return children ?? text;\r\n    };\r\n\r\n    return (\r\n      <button\r\n        ref={ref}\r\n        type=\"button\"\r\n        disabled={isDisabled}\r\n        aria-busy={loading || isVerifying || isPreparing}\r\n        onClick={handleClick}\r\n        style={{ cursor: isDisabled ? \"not-allowed\" : \"pointer\", ...style }}\r\n        {...props}\r\n      >\r\n        {getButtonText()}\r\n      </button>\r\n    );\r\n  }\r\n);\r\n\r\nFedaPayButton.displayName = \"FedaPayButton\";\r\n","\"use client\";\r\n\r\nimport React, { forwardRef } from \"react\";\r\nimport { useKkiaPay } from \"../hooks/useKkiaPay\";\r\nimport type { UseKkiaPayConfig } from \"../hooks/useKkiaPay\";\r\nimport type { KkiaPaySuccessResponse, KkiaPayFailedResponse } from \"../types\";\r\nimport type { PaymentValidationError } from \"../types/validation\";\r\nimport type { BeninPaymentAnalyticsHandler } from \"../utils/analytics\";\r\n\r\nexport interface KkiaPayButtonProps\r\n  extends React.ButtonHTMLAttributes<HTMLButtonElement> {\r\n  config: UseKkiaPayConfig;\r\n  onSuccess?: (data: KkiaPaySuccessResponse) => void;\r\n  onFailed?: (data: KkiaPayFailedResponse) => void;\r\n  onPaymentClose?: () => void;\r\n  onValidationError?: (error: PaymentValidationError) => void;\r\n  /** @default \"Payer\" */\r\n  text?: string;\r\n  /** @default \"Chargement...\" */\r\n  loadingText?: string;\r\n  /** @default \"Vérification...\" */\r\n  verifyingText?: string;\r\n  /** @default false */\r\n  debug?: boolean;\r\n  onBeforePayment?: () => void | boolean | Promise<void | boolean>;\r\n  onAnalyticsEvent?: BeninPaymentAnalyticsHandler;\r\n  verifyUrl?: string;\r\n  customVerifyHeaders?: Record<string, string>;\r\n}\r\n\r\nexport const KkiaPayButton = forwardRef<HTMLButtonElement, KkiaPayButtonProps>(\r\n  (\r\n    {\r\n      config,\r\n      onSuccess,\r\n      onFailed,\r\n      onPaymentClose,\r\n      onValidationError,\r\n      text = \"Payer\",\r\n      loadingText = \"Chargement...\",\r\n      verifyingText = \"Vérification...\",\r\n      debug = false,\r\n      onBeforePayment,\r\n      onAnalyticsEvent,\r\n      verifyUrl,\r\n      customVerifyHeaders,\r\n      children,\r\n      disabled,\r\n      style,\r\n      ...props\r\n    },\r\n    ref\r\n  ) => {\r\n    const { openKkiapay, loading, scriptLoaded, isVerifying, isPreparing } = useKkiaPay({\r\n      debug,\r\n      onBeforePayment,\r\n      onAnalyticsEvent,\r\n      onSuccess,\r\n      onFailed,\r\n      onClose: onPaymentClose,\r\n      onValidationError,\r\n      verifyUrl,\r\n      customVerifyHeaders,\r\n    });\r\n\r\n    const isDisabled = disabled || loading || !scriptLoaded || isVerifying || isPreparing;\r\n\r\n    const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\r\n      if (isDisabled) {\r\n        e.preventDefault();\r\n        return;\r\n      }\r\n      openKkiapay(config);\r\n      props.onClick?.(e);\r\n    };\r\n\r\n    const getButtonText = () => {\r\n      if (loading || isPreparing) return loadingText;\r\n      if (isVerifying) return verifyingText;\r\n      return children ?? text;\r\n    };\r\n\r\n    return (\r\n      <button\r\n        ref={ref}\r\n        type=\"button\"\r\n        disabled={isDisabled}\r\n        aria-busy={loading || isVerifying || isPreparing}\r\n        onClick={handleClick}\r\n        style={{ cursor: isDisabled ? \"not-allowed\" : \"pointer\", ...style }}\r\n        {...props}\r\n      >\r\n        {getButtonText()}\r\n      </button>\r\n    );\r\n  }\r\n);\r\n\r\nKkiaPayButton.displayName = \"KkiaPayButton\";\r\n","\"use client\";\r\n\r\nimport { useFedaPay } from \"../hooks/useFedaPay\";\r\nimport type { UseFedaPayConfig } from \"../hooks/useFedaPay\";\r\nimport type { PaymentValidationError } from \"../types/validation\";\r\nimport type { ReactNode } from \"react\";\r\nimport type { BeninPaymentAnalyticsHandler } from \"../utils/analytics\";\r\n\r\nexport interface FedaPayRenderProps {\r\n  open: () => void;\r\n  loading: boolean;\r\n  error: Error | null;\r\n  scriptLoaded: boolean;\r\n  isVerifying: boolean;\r\n  isPreparing: boolean;\r\n}\r\n\r\nexport interface FedaPayConsumerProps {\r\n  config: UseFedaPayConfig;\r\n  debug?: boolean;\r\n  onBeforePayment?: () => void | boolean | Promise<void | boolean>;\r\n  onAnalyticsEvent?: BeninPaymentAnalyticsHandler;\r\n  onPaymentError?: (error: PaymentValidationError) => void;\r\n  children: (props: FedaPayRenderProps) => ReactNode;\r\n}\r\n\r\nexport function FedaPayConsumer({\r\n  config,\r\n  debug = false,\r\n  onBeforePayment,\r\n  onAnalyticsEvent,\r\n  onPaymentError,\r\n  children,\r\n}: FedaPayConsumerProps): ReactNode {\r\n  const { openDialog, loading, error, scriptLoaded, isVerifying, isPreparing } = useFedaPay(config, {\r\n    debug,\r\n    onBeforePayment,\r\n    onAnalyticsEvent,\r\n    onError: onPaymentError,\r\n  });\r\n\r\n  return children({\r\n    open: openDialog,\r\n    loading,\r\n    error,\r\n    scriptLoaded,\r\n    isVerifying,\r\n    isPreparing,\r\n  });\r\n}\r\n","\"use client\";\r\n\r\nimport { useKkiaPay } from \"../hooks/useKkiaPay\";\r\nimport type { UseKkiaPayConfig } from \"../hooks/useKkiaPay\";\r\nimport type { KkiaPaySuccessResponse, KkiaPayFailedResponse } from \"../types\";\r\nimport type { PaymentValidationError } from \"../types/validation\";\r\nimport type { ReactNode } from \"react\";\r\nimport type { BeninPaymentAnalyticsHandler } from \"../utils/analytics\";\r\n\r\nexport interface KkiaPayRenderProps {\r\n  open: (config: UseKkiaPayConfig) => void;\r\n  loading: boolean;\r\n  error: Error | null;\r\n  scriptLoaded: boolean;\r\n  isVerifying: boolean;\r\n  isPreparing: boolean;\r\n}\r\n\r\nexport interface KkiaPayConsumerProps {\r\n  debug?: boolean;\r\n  onSuccess?: (data: KkiaPaySuccessResponse) => void;\r\n  onFailed?: (data: KkiaPayFailedResponse) => void;\r\n  onClose?: () => void;\r\n  onBeforePayment?: () => void | boolean | Promise<void | boolean>;\r\n  onAnalyticsEvent?: BeninPaymentAnalyticsHandler;\r\n  onValidationError?: (error: PaymentValidationError) => void;\r\n  verifyUrl?: string;\r\n  customVerifyHeaders?: Record<string, string>;\r\n  children: (props: KkiaPayRenderProps) => ReactNode;\r\n}\r\n\r\nexport function KkiaPayConsumer({\r\n  debug = false,\r\n  onSuccess,\r\n  onFailed,\r\n  onClose,\r\n  onBeforePayment,\r\n  onAnalyticsEvent,\r\n  onValidationError,\r\n  verifyUrl,\r\n  customVerifyHeaders,\r\n  children,\r\n}: KkiaPayConsumerProps): ReactNode {\r\n  const { openKkiapay, loading, error, scriptLoaded, isVerifying, isPreparing } = useKkiaPay({\r\n    debug,\r\n    onSuccess,\r\n    onFailed,\r\n    onClose,\r\n    onBeforePayment,\r\n    onAnalyticsEvent,\r\n    onValidationError,\r\n    verifyUrl,\r\n    customVerifyHeaders,\r\n  });\r\n\r\n  return children({\r\n    open: openKkiapay,\r\n    loading,\r\n    error,\r\n    scriptLoaded,\r\n    isVerifying,\r\n    isPreparing,\r\n  });\r\n}\r\n","\r\n\r\n\"use client\";\r\n\r\nimport React from \"react\";\r\n\r\n/**\r\n * FedaPay logo SVG component.\r\n * \r\n * Customizable via standard SVG props (width, height, fill, className, etc.)\r\n * Uses `currentColor` for text, allowing color inheritance from parent.\r\n * \r\n * @example\r\n * ```tsx\r\n * import { FedaPayLogo } from \"react-benin-payments\";\r\n * \r\n * // Default size\r\n * <FedaPayLogo />\r\n * \r\n * // Custom size and color\r\n * <FedaPayLogo width={80} height={28} className=\"text-green-600\" />\r\n * ```\r\n */\r\nexport function FedaPayLogo(props: React.SVGProps<SVGSVGElement>) {\r\n  return (\r\n    <svg\r\n      xmlns=\"http://www.w3.org/2000/svg\"\r\n      viewBox=\"0 0 120 40\"\r\n      width=\"120\"\r\n      height=\"40\"\r\n      fill=\"currentColor\"\r\n      aria-label=\"FedaPay\"\r\n      role=\"img\"\r\n      {...props}\r\n    >\r\n      <rect x=\"2\" y=\"8\" width=\"24\" height=\"24\" rx=\"4\" fill=\"#0AB67A\" />\r\n      <path\r\n        d=\"M8 16h12M8 20h8M8 24h10\"\r\n        stroke=\"white\"\r\n        strokeWidth=\"2\"\r\n        strokeLinecap=\"round\"\r\n      />\r\n      <text\r\n        x=\"32\"\r\n        y=\"26\"\r\n        fontFamily=\"Arial, sans-serif\"\r\n        fontSize=\"16\"\r\n        fontWeight=\"bold\"\r\n        fill=\"currentColor\"\r\n      >\r\n        FedaPay\r\n      </text>\r\n    </svg>\r\n  );\r\n}\r\n","\r\n\r\n\"use client\";\r\n\r\nimport React from \"react\";\r\n\r\n/**\r\n * KKiaPay logo SVG component.\r\n * \r\n * Customizable via standard SVG props (width, height, fill, className, etc.)\r\n * Uses `currentColor` for text, allowing color inheritance from parent.\r\n * \r\n * @example\r\n * ```tsx\r\n * import { KkiaPayLogo } from \"react-benin-payments\";\r\n * \r\n * // Default size\r\n * <KkiaPayLogo />\r\n * \r\n * // Custom size and color\r\n * <KkiaPayLogo width={80} height={28} className=\"text-blue-600\" />\r\n * ```\r\n */\r\nexport function KkiaPayLogo(props: React.SVGProps<SVGSVGElement>) {\r\n  return (\r\n    <svg\r\n      xmlns=\"http://www.w3.org/2000/svg\"\r\n      viewBox=\"0 0 120 40\"\r\n      width=\"120\"\r\n      height=\"40\"\r\n      fill=\"currentColor\"\r\n      aria-label=\"KkiaPay\"\r\n      role=\"img\"\r\n      {...props}\r\n    >\r\n      <circle cx=\"14\" cy=\"20\" r=\"12\" fill=\"#4E6BFF\" />\r\n      <path\r\n        d=\"M10 15l4 5-4 5M14 20h6\"\r\n        stroke=\"white\"\r\n        strokeWidth=\"2\"\r\n        strokeLinecap=\"round\"\r\n        strokeLinejoin=\"round\"\r\n        fill=\"none\"\r\n      />\r\n      <text\r\n        x=\"32\"\r\n        y=\"26\"\r\n        fontFamily=\"Arial, sans-serif\"\r\n        fontSize=\"16\"\r\n        fontWeight=\"bold\"\r\n        fill=\"currentColor\"\r\n      >\r\n        KkiaPay\r\n      </text>\r\n    </svg>\r\n  );\r\n}\r\n","\"use client\";\r\n\r\nimport React from \"react\";\r\nimport type { TransactionStatus } from \"../hooks/usePaymentStatus\";\r\n\r\nexport interface PaymentStatusBadgeProps\r\n  extends React.HTMLAttributes<HTMLSpanElement> {\r\n  /** Le statut de la transaction à afficher */\r\n  status: TransactionStatus;\r\n  /** Surcharge des libellés par défaut pour chaque statut */\r\n  labels?: Partial<Record<TransactionStatus, React.ReactNode>>;\r\n  /** Surcharge des classes CSS spécifiques par statut (ex: Tailwind) */\r\n  statusClasses?: Partial<Record<TransactionStatus, string>>;\r\n  /** Si true, aucun style en ligne par défaut ne sera appliqué (Headless) */\r\n  unstyled?: boolean;\r\n}\r\n\r\nconst DEFAULT_LABELS: Record<TransactionStatus, string> = {\r\n  pending: \"En attente\",\r\n  approved: \"Approuvé\",\r\n  declined: \"Refusé\",\r\n  cancelled: \"Annulé\",\r\n  unknown: \"Inconnu\",\r\n};\r\n\r\nconst DEFAULT_STYLES: Record<TransactionStatus, React.CSSProperties> = {\r\n  pending: { backgroundColor: \"#fef3c7\", color: \"#d97706\" }, // Amber\r\n  approved: { backgroundColor: \"#d1fae5\", color: \"#059669\" }, // Emerald\r\n  declined: { backgroundColor: \"#fee2e2\", color: \"#dc2626\" }, // Red\r\n  cancelled: { backgroundColor: \"#f3f4f6\", color: \"#4b5563\" }, // Gray\r\n  unknown: { backgroundColor: \"#e5e7eb\", color: \"#374151\" }, // Gray\r\n};\r\n\r\nconst BASE_STYLE: React.CSSProperties = {\r\n  display: \"inline-flex\",\r\n  alignItems: \"center\",\r\n  padding: \"0.25rem 0.75rem\",\r\n  borderRadius: \"9999px\",\r\n  fontSize: \"0.875rem\",\r\n  fontWeight: 500,\r\n  lineHeight: 1,\r\n};\r\n\r\n/**\r\n * Composant visuel permettant d'afficher le statut d'un paiement.\r\n * \r\n * Il intègre des couleurs et libellés par défaut (en français) pour chaque statut.\r\n * Peut être utilisé en mode \"Headless\" (`unstyled={true}`) pour laisser \r\n * votre propre framework CSS (comme Tailwind) gérer le visuel via `statusClasses`.\r\n * \r\n * @example\r\n * // Mode par défaut (styles en ligne injectés)\r\n * <PaymentStatusBadge status=\"approved\" />\r\n * \r\n * @example\r\n * // Mode Headless avec Tailwind CSS\r\n * <PaymentStatusBadge \r\n *   status=\"pending\" \r\n *   unstyled \r\n *   className=\"px-3 py-1 rounded-full text-sm font-medium\"\r\n *   statusClasses={{\r\n *     pending: \"bg-yellow-100 text-yellow-800\",\r\n *     approved: \"bg-green-100 text-green-800\"\r\n *   }}\r\n * />\r\n */\r\nexport const PaymentStatusBadge: React.FC<PaymentStatusBadgeProps> = ({\r\n  status,\r\n  labels,\r\n  statusClasses,\r\n  unstyled = false,\r\n  className,\r\n  style,\r\n  ...rest\r\n}) => {\r\n  const label = labels?.[status] ?? DEFAULT_LABELS[status];\r\n\r\n  const computedStyle: React.CSSProperties = unstyled\r\n    ? { ...style }\r\n    : { ...BASE_STYLE, ...DEFAULT_STYLES[status], ...style };\r\n\r\n  const combinedClassName =\r\n    [className, statusClasses?.[status]].filter(Boolean).join(\" \") || undefined;\r\n\r\n  return (\r\n    <span\r\n      className={combinedClassName}\r\n      style={Object.keys(computedStyle).length > 0 ? computedStyle : undefined}\r\n      data-status={status}\r\n      data-testid=\"payment-status-badge\"\r\n      {...rest}\r\n    >\r\n      {label}\r\n    </span>\r\n  );\r\n};\r\n"]}