{"version":3,"file":"cinetpay-seamless.umd.cjs","sources":["../src/styles.ts","../src/checkout.ts","../src/logger.ts","../src/emitter.ts","../src/index.ts"],"sourcesContent":["/**\n * Styles CSS du checkout CinetPay Seamless (mode popup).\n */\nexport const STYLES = `\n.cp-seamless-overlay {\n  position: fixed;\n  inset: 0;\n  z-index: 999999;\n  background: rgba(0, 0, 0, 0.7);\n  backdrop-filter: blur(6px);\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  opacity: 0;\n  transition: opacity 0.3s ease;\n  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n}\n\n.cp-seamless-overlay.cp-visible {\n  opacity: 1;\n}\n\n.cp-seamless-wrapper {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n}\n\n/* Waiting screen (pendant que la popup est ouverte) */\n.cp-seamless-waiting {\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  gap: 20px;\n  text-align: center;\n  padding: 40px;\n}\n\n.cp-seamless-waiting-title {\n  color: #fff;\n  font-size: 22px;\n  font-weight: 600;\n  margin: 0;\n}\n\n.cp-seamless-waiting-msg {\n  color: rgba(255, 255, 255, 0.7);\n  font-size: 15px;\n  margin: 0;\n  max-width: 320px;\n  line-height: 1.5;\n}\n\n.cp-seamless-spinner {\n  width: 48px;\n  height: 48px;\n  border: 3px solid rgba(255, 255, 255, 0.2);\n  border-top-color: #e8530e;\n  border-radius: 50%;\n  animation: cp-spin 0.8s linear infinite;\n}\n\n@keyframes cp-spin {\n  to { transform: rotate(360deg); }\n}\n\n.cp-seamless-cancel-btn {\n  margin-top: 12px;\n  padding: 10px 28px;\n  background: rgba(255, 255, 255, 0.12);\n  color: rgba(255, 255, 255, 0.8);\n  border: 1px solid rgba(255, 255, 255, 0.2);\n  border-radius: 8px;\n  font-size: 14px;\n  cursor: pointer;\n  transition: all 0.2s;\n}\n\n.cp-seamless-cancel-btn:hover {\n  background: rgba(255, 255, 255, 0.2);\n  color: #fff;\n}\n\n`\n","import { STYLES } from './styles'\nimport type { PaymentResponse, PaymentError, PaymentStatus } from './types'\nimport { Logger } from './logger'\nimport { EventEmitter } from './emitter'\n\ntype StatusChecker = () => Promise<unknown>\n\n/** @internal Options du constructeur Checkout */\nexport interface CheckoutOptions {\n  onReady?: () => void\n  onPaymentSuccess?: (data: PaymentResponse) => void\n  onPaymentFailed?: (data: PaymentResponse) => void\n  onPaymentPending?: (data: PaymentResponse) => void\n  onClose?: (data: { status: string }) => void\n  onError?: (error: PaymentError) => void\n  statusChecker?: StatusChecker\n  statusPollInterval?: number\n  logger: Logger\n  emitter: EventEmitter\n}\n\n/** @internal Intervalle de polling pour vérifier si la popup est fermée */\nconst POPUP_POLL_INTERVAL = 500\n/** @internal Intervalle par défaut pour vérifier le statut via le backend marchand */\nconst STATUS_POLL_INTERVAL = 3000\n/** @internal Évite un polling trop agressif depuis le navigateur */\nconst MIN_STATUS_POLL_INTERVAL = 1000\n\n/**\n * Gère le checkout CinetPay via une popup window + overlay.\n *\n * Flow :\n * 1. Affiche un overlay sombre avec un message d'attente\n * 2. Ouvre la page de checkout dans une popup (window.open)\n * 3. Poll la popup pour détecter sa fermeture\n * 4. Écoute les messages postMessage de la popup\n * 5. Ferme l'overlay et dispatche les callbacks\n *\n * @internal Utilisé par {@link CinetPaySeamless}. Ne pas instancier directement.\n */\nexport class Checkout {\n  private overlay: HTMLDivElement | null = null\n  private popup: Window | null = null\n  private pollTimer: ReturnType<typeof setInterval> | null = null\n  private statusTimer: ReturnType<typeof setInterval> | null = null\n  private closeTimer: ReturnType<typeof setTimeout> | null = null\n  private messageHandler: ((event: MessageEvent) => void) | null = null\n  private lastStatus = 'UNKNOWN'\n  private lastDispatchKey = ''\n  private finalStatusDispatched = false\n  private statusCheckInFlight = false\n  private isClosing = false\n  private previousBodyOverflow = ''\n\n  private onReadyCallback?: () => void\n  private onPaymentSuccessCallback?: (data: PaymentResponse) => void\n  private onPaymentFailedCallback?: (data: PaymentResponse) => void\n  private onPaymentPendingCallback?: (data: PaymentResponse) => void\n  private onCloseCallback?: (data: { status: string }) => void\n  private onErrorCallback?: (error: PaymentError) => void\n  private statusChecker?: StatusChecker\n  private statusPollInterval: number\n  private logger: Logger\n  private emitter: EventEmitter\n\n  constructor(options: CheckoutOptions) {\n    this.logger = options.logger\n    this.emitter = options.emitter\n    this.onReadyCallback = options.onReady\n    this.onPaymentSuccessCallback = options.onPaymentSuccess\n    this.onPaymentFailedCallback = options.onPaymentFailed\n    this.onPaymentPendingCallback = options.onPaymentPending\n    this.onCloseCallback = options.onClose\n    this.onErrorCallback = options.onError\n    this.statusChecker = options.statusChecker\n    this.statusPollInterval = Math.max(\n      MIN_STATUS_POLL_INTERVAL,\n      options.statusPollInterval ?? STATUS_POLL_INTERVAL,\n    )\n  }\n\n  /**\n   * Ouvre la popup de checkout et affiche l'overlay d'attente.\n   *\n   * @param paymentUrl - URL complète de la page de checkout CinetPay\n   */\n  open(paymentUrl: string): void {\n    this.logger.debug('Opening checkout popup', { paymentUrl })\n    this.injectStyles()\n    this.createOverlay()\n    this.openPopup(paymentUrl)\n    if (!this.popup) return\n\n    this.listenForMessages()\n    this.startPolling()\n    this.startStatusPolling()\n\n    requestAnimationFrame(() => {\n      this.overlay?.classList.add('cp-visible')\n    })\n\n    this.previousBodyOverflow = document.body.style.overflow\n    document.body.style.overflow = 'hidden'\n  }\n\n  /**\n   * Ferme la popup et l'overlay.\n   */\n  close(): void {\n    if (this.closeTimer || this.isClosing) return\n\n    if (!this.statusChecker || this.finalStatusDispatched) {\n      this.finishClose()\n      return\n    }\n\n    this.isClosing = true\n\n    void this.checkStatus('close').finally(() => {\n      this.finishClose()\n    })\n  }\n\n  private finishClose(): void {\n    if (this.closeTimer) return\n    this.stopPolling()\n    this.stopStatusPolling()\n\n    if (this.messageHandler) {\n      window.removeEventListener('message', this.messageHandler)\n      this.messageHandler = null\n    }\n\n    if (this.popup && !this.popup.closed) {\n      this.popup.close()\n    }\n    this.popup = null\n\n    if (this.overlay) {\n      const overlay = this.overlay\n      this.overlay = null\n      overlay.classList.remove('cp-visible')\n      this.closeTimer = setTimeout(() => {\n        overlay.remove()\n        this.closeTimer = null\n        this.isClosing = false\n\n        if (!document.querySelector('.cp-seamless-overlay')) {\n          document.body.style.overflow = this.previousBodyOverflow\n        }\n\n        this.logger.debug('Checkout closed', { lastStatus: this.lastStatus })\n        this.emitter.emit('close', { status: this.lastStatus })\n        this.onCloseCallback?.({ status: this.lastStatus })\n      }, 300)\n    } else {\n      this.isClosing = false\n    }\n  }\n\n  private static isRecord(value: unknown): value is Record<string, unknown> {\n    return Boolean(value) && typeof value === 'object' && !Array.isArray(value)\n  }\n\n  private static childRecords(data: Record<string, unknown>): Record<string, unknown>[] {\n    const records: Record<string, unknown>[] = []\n    for (const key of ['details', 'transaction', 'payment', 'result', 'data']) {\n      const child = data[key]\n      if (Checkout.isRecord(child)) records.push(child)\n    }\n    records.push(data)\n    return records\n  }\n\n  private static findValue(data: Record<string, unknown>, keys: string[]): unknown {\n    for (const record of Checkout.childRecords(data)) {\n      for (const key of keys) {\n        if (record[key] !== undefined && record[key] !== null) return record[key]\n      }\n    }\n    return undefined\n  }\n\n  private static asString(value: unknown): string | undefined {\n    if (value === undefined || value === null) return undefined\n    return String(value)\n  }\n\n  private static asNumber(value: unknown): number {\n    if (typeof value === 'number') return Number.isFinite(value) ? value : 0\n    if (typeof value === 'string') {\n      const parsed = Number(value.replace(/\\s/g, ''))\n      return Number.isFinite(parsed) ? parsed : 0\n    }\n    return 0\n  }\n\n  private static asOptionalNumber(value: unknown): number | undefined {\n    if (value === undefined || value === null) return undefined\n    if (typeof value === 'number') return Number.isFinite(value) ? value : undefined\n    if (typeof value === 'string') {\n      const parsed = Number(value.trim())\n      return Number.isFinite(parsed) ? parsed : undefined\n    }\n    return undefined\n  }\n\n  private static normalizeStatus(rawStatus?: string, apiCode?: number): PaymentStatus {\n    const normalized = rawStatus?.trim().toUpperCase().replace(/[\\s-]+/g, '_')\n\n    if (normalized) {\n      if (['ACCEPTED', 'SUCCESS', 'SUCCEEDED', 'SUCCESSFUL', 'PAID', 'VALIDATED', 'APPROVED'].includes(normalized)) {\n        return 'ACCEPTED'\n      }\n      if ([\n        'REFUSED',\n        'FAILED',\n        'FAIL',\n        'FAILURE',\n        'DENIED',\n        'DECLINED',\n        'REJECTED',\n        'CANCELED',\n        'CANCELLED',\n        'CANCEL',\n        'INSUFFICIENT_BALANCE',\n      ].includes(normalized)) {\n        return 'REFUSED'\n      }\n      if (['PENDING', 'INITIATED', 'EXPIRED'].includes(normalized)) {\n        return normalized as PaymentStatus\n      }\n      if (['WAITING', 'PROCESSING', 'IN_PROGRESS'].includes(normalized)) {\n        return 'PENDING'\n      }\n    }\n\n    switch (apiCode) {\n      case 100:\n        return 'ACCEPTED'\n      case 2010:\n      case 2005:\n        return 'REFUSED'\n      case 2001:\n        return 'INITIATED'\n      case 2002:\n        return 'PENDING'\n      case 2003:\n        return 'EXPIRED'\n    }\n\n    return 'UNKNOWN'\n  }\n\n  private static isFinalStatus(status: PaymentStatus): boolean {\n    return status === 'ACCEPTED' || status === 'REFUSED'\n  }\n\n  private static buildPaymentResponse(data: Record<string, unknown>): PaymentResponse {\n    const rawStatus = Checkout.asString(Checkout.findValue(data, [\n      'status',\n      'transaction_status',\n      'trans_status',\n      'payment_status',\n    ]))\n    const apiCode = Checkout.asOptionalNumber(Checkout.findValue(data, ['code']))\n    const status = Checkout.normalizeStatus(rawStatus, apiCode)\n\n    return {\n      amount: Checkout.asNumber(Checkout.findValue(data, ['amount'])),\n      currency: Checkout.asString(Checkout.findValue(data, ['currency'])) ?? '',\n      status,\n      rawStatus,\n      apiCode,\n      paymentMethod: Checkout.asString(Checkout.findValue(data, ['payment_method', 'paymentMethod'])) ?? '',\n      description: Checkout.asString(Checkout.findValue(data, ['description', 'designation', 'message'])) ?? '',\n      metadata: Checkout.asString(Checkout.findValue(data, ['metadata', 'custom'])),\n      operatorId: Checkout.asString(Checkout.findValue(data, ['operator_id', 'operatorId'])),\n      paymentDate: Checkout.asString(Checkout.findValue(data, ['payment_date', 'paymentDate'])),\n      transactionId: Checkout.asString(Checkout.findValue(data, ['transaction_id', 'transactionId', 'merchant_transaction_id'])) ?? '',\n    }\n  }\n\n  /** Dispatche la réponse vers le bon callback selon le statut. */\n  private dispatchResponse(response: PaymentResponse): void {\n    const dispatchKey = `${response.status}:${response.rawStatus ?? ''}:${response.apiCode ?? ''}`\n    const isFinalStatus = Checkout.isFinalStatus(response.status)\n\n    if (isFinalStatus && this.finalStatusDispatched) return\n    if (dispatchKey === this.lastDispatchKey) return\n\n    this.lastDispatchKey = dispatchKey\n    this.lastStatus = response.status\n    if (isFinalStatus) {\n      this.finalStatusDispatched = true\n      this.stopStatusPolling()\n    }\n\n    this.logger.debug(`Payment response: ${response.status}`, {\n      amount: response.amount,\n      currency: response.currency,\n      transactionId: response.transactionId,\n      paymentMethod: response.paymentMethod,\n    })\n\n    switch (response.status) {\n      case 'ACCEPTED':\n        this.logger.debug('Payment accepted')\n        this.emitter.emit('payment.success', response)\n        this.onPaymentSuccessCallback?.(response)\n        break\n      case 'REFUSED':\n        this.logger.warn('Payment refused')\n        this.emitter.emit('payment.failed', response)\n        this.onPaymentFailedCallback?.(response)\n        break\n      case 'PENDING':\n      case 'INITIATED':\n      case 'EXPIRED':\n      default:\n        this.logger.debug(`Payment pending: ${response.status}`)\n        this.emitter.emit('payment.pending', response)\n        this.onPaymentPendingCallback?.(response)\n        break\n    }\n  }\n\n  private injectStyles(): void {\n    if (document.getElementById('cp-seamless-styles')) return\n    const styleEl = document.createElement('style')\n    styleEl.id = 'cp-seamless-styles'\n    styleEl.textContent = STYLES\n    document.head.appendChild(styleEl)\n  }\n\n  private createOverlay(): void {\n    this.overlay = document.createElement('div')\n    this.overlay.className = 'cp-seamless-overlay'\n\n    const wrapper = document.createElement('div')\n    wrapper.className = 'cp-seamless-wrapper'\n\n    // Spinner + message\n    const waiting = document.createElement('div')\n    waiting.className = 'cp-seamless-waiting'\n\n    const spinner = document.createElement('div')\n    spinner.className = 'cp-seamless-spinner'\n    waiting.appendChild(spinner)\n\n    const title = document.createElement('p')\n    title.className = 'cp-seamless-waiting-title'\n    title.textContent = 'Paiement en cours...'\n    waiting.appendChild(title)\n\n    const msg = document.createElement('p')\n    msg.className = 'cp-seamless-waiting-msg'\n    msg.textContent = 'Finalisez votre paiement dans la fenêtre CinetPay.'\n    waiting.appendChild(msg)\n\n    // Bouton fermer\n    const cancelBtn = document.createElement('button')\n    cancelBtn.className = 'cp-seamless-cancel-btn'\n    cancelBtn.textContent = 'Annuler'\n    cancelBtn.addEventListener('click', () => this.close())\n    waiting.appendChild(cancelBtn)\n\n    wrapper.appendChild(waiting)\n    this.overlay.appendChild(wrapper)\n    document.body.appendChild(this.overlay)\n  }\n\n  /**\n   * Ouvre la popup centrée sur l'écran.\n   */\n  private openPopup(paymentUrl: string): void {\n    const width = 500\n    const height = 700\n    const left = Math.max(0, (screen.width - width) / 2)\n    const top = Math.max(0, (screen.height - height) / 2)\n\n    this.popup = window.open(\n      paymentUrl,\n      'CinetPayCheckout',\n      `width=${width},height=${height},left=${left},top=${top},scrollbars=yes,resizable=yes`,\n    )\n\n    if (!this.popup) {\n      this.logger.error('Popup blocked by browser')\n      const err: PaymentError = {\n        code: 'POPUP_BLOCKED',\n        message: 'La fenêtre de paiement a été bloquée par le navigateur. Autorisez les popups pour ce site.',\n      }\n      this.emitter.emit('error', err)\n      this.onErrorCallback?.(err)\n      this.close()\n      return\n    }\n\n    this.logger.debug('Popup opened')\n    this.emitter.emit('ready')\n    this.onReadyCallback?.()\n  }\n\n  /**\n   * Poll toutes les 500ms pour détecter si la popup a été fermée\n   * (par l'utilisateur ou après redirection).\n   */\n  private startPolling(): void {\n    this.pollTimer = setInterval(() => {\n      if (this.popup && this.popup.closed) {\n        this.logger.debug('Popup closed by user or redirect')\n        this.stopPolling()\n\n        // Laisser un court délai pour que le postMessage arrive avant le close\n        setTimeout(() => {\n          if (this.overlay) {\n            this.close()\n          }\n        }, 500)\n      }\n    }, POPUP_POLL_INTERVAL)\n  }\n\n  private stopPolling(): void {\n    if (this.pollTimer) {\n      clearInterval(this.pollTimer)\n      this.pollTimer = null\n    }\n  }\n\n  private startStatusPolling(): void {\n    if (!this.statusChecker) return\n\n    void this.checkStatus('open')\n\n    this.statusTimer = setInterval(() => {\n      void this.checkStatus('interval')\n    }, this.statusPollInterval)\n  }\n\n  private stopStatusPolling(): void {\n    if (this.statusTimer) {\n      clearInterval(this.statusTimer)\n      this.statusTimer = null\n    }\n  }\n\n  private async checkStatus(reason: string): Promise<void> {\n    if (!this.statusChecker || this.statusCheckInFlight || this.finalStatusDispatched) return\n\n    this.statusCheckInFlight = true\n    try {\n      this.logger.debug('Checking payment status', { reason })\n      const data = await this.statusChecker()\n      if (!Checkout.isRecord(data)) return\n\n      const response = Checkout.buildPaymentResponse(data)\n      const rawStatus = response.rawStatus?.trim().toUpperCase()\n      if (response.status !== 'UNKNOWN' || (rawStatus && rawStatus !== 'OK')) {\n        this.dispatchResponse(response)\n      }\n\n      if (Checkout.isFinalStatus(response.status)) {\n        this.finishClose()\n      }\n    } catch (error) {\n      this.logger.warn('Payment status check failed', error)\n    } finally {\n      this.statusCheckInFlight = false\n    }\n  }\n\n  /** Origines autorisées pour les messages postMessage */\n  private static readonly ALLOWED_ORIGINS = [\n    'https://secure.cinetpay.net',\n    'https://secure.cinetpay.co',\n    'https://secure.cinetpay.com',\n    'https://checkout.cinetpay.net',\n    'https://checkout.cinetpay.co',\n    'https://checkout.cinetpay.com',\n    'https://api.cinetpay.net',\n    'https://api.cinetpay.co',\n  ]\n\n  /** Écoute les messages postMessage de la popup CinetPay. */\n  private listenForMessages(): void {\n    this.messageHandler = (event: MessageEvent) => {\n      if (!Checkout.ALLOWED_ORIGINS.some((o) => event.origin === o)) {\n        return\n      }\n\n      try {\n        const data = typeof event.data === 'string' ? JSON.parse(event.data) : event.data\n        if (!Checkout.isRecord(data)) return\n\n        const response = Checkout.buildPaymentResponse(data)\n        const rawStatus = response.rawStatus?.trim().toUpperCase()\n        if (response.status !== 'UNKNOWN' || (rawStatus && rawStatus !== 'OK')) {\n          this.dispatchResponse(response)\n        }\n\n        const error = Checkout.findValue(data, ['error'])\n        const code = Checkout.asString(Checkout.findValue(data, ['code']))\n        if (error || code === 'ERROR') {\n          const err: PaymentError = {\n            code: code ?? 'UNKNOWN',\n            message: Checkout.asString(Checkout.findValue(data, ['message'])) ?? Checkout.asString(error) ?? 'An error occurred',\n          }\n          this.logger.error('Payment error from popup', err)\n          this.emitter.emit('error', err)\n          this.onErrorCallback?.(err)\n        }\n\n        if (data.action === 'CLOSE' || data.type === 'close') {\n          this.close()\n        }\n      } catch {\n        // Ignorer les messages non-JSON\n      }\n    }\n\n    window.addEventListener('message', this.messageHandler)\n  }\n}\n","/** Préfixe des messages de log */\nconst PREFIX = '[CinetPay Seamless]'\n\n/**\n * Logger interne du SDK Seamless.\n * Désactivé par défaut. Activable via `debug: true` dans la config.\n *\n * Tous les logs utilisent le préfixe `[CinetPay Seamless]` pour être\n * facilement filtrables dans la console du navigateur.\n */\nexport class Logger {\n  private enabled: boolean\n\n  constructor(enabled: boolean) {\n    this.enabled = enabled\n  }\n\n  /** Log de debug — requêtes, réponses, événements */\n  debug(message: string, data?: unknown): void {\n    if (!this.enabled) return\n    if (data !== undefined) {\n      console.debug(`${PREFIX} ${message}`, data)\n    } else {\n      console.debug(`${PREFIX} ${message}`)\n    }\n  }\n\n  /** Log d'avertissement — credentials exposés, statuts inattendus */\n  warn(message: string, data?: unknown): void {\n    if (!this.enabled) return\n    if (data !== undefined) {\n      console.warn(`${PREFIX} ${message}`, data)\n    } else {\n      console.warn(`${PREFIX} ${message}`)\n    }\n  }\n\n  /** Log d'erreur — erreurs API, timeouts, postMessage invalides */\n  error(message: string, data?: unknown): void {\n    if (!this.enabled) return\n    if (data !== undefined) {\n      console.error(`${PREFIX} ${message}`, data)\n    } else {\n      console.error(`${PREFIX} ${message}`)\n    }\n  }\n}\n","import type { PaymentResponse, PaymentError } from './types'\n\n/**\n * Map des événements émis par le SDK Seamless.\n *\n * | Événement | Donnée | Quand |\n * |---|---|---|\n * | `ready` | — | Popup ouverte, passerelle prête |\n * | `payment.success` | `PaymentResponse` | Paiement accepté |\n * | `payment.failed` | `PaymentResponse` | Paiement refusé |\n * | `payment.pending` | `PaymentResponse` | En attente (PENDING, INITIATED, EXPIRED) |\n * | `close` | `{ status: string }` | Popup fermée, overlay retiré |\n * | `error` | `PaymentError` | Erreur technique |\n */\nexport interface EventMap {\n  'ready': void\n  'payment.success': PaymentResponse\n  'payment.failed': PaymentResponse\n  'payment.pending': PaymentResponse\n  'close': { status: string }\n  'error': PaymentError\n}\n\n/** Type des noms d'événements */\nexport type EventName = keyof EventMap\n\n/** Type d'un handler pour un événement donné */\ntype Handler<T> = T extends void ? () => void : (data: T) => void\n\n/**\n * Event emitter typé pour le SDK Seamless.\n *\n * Permet d'écouter les événements de paiement avec `on()` et `off()`,\n * style événementiel (`on('event', handler)`).\n *\n * @example\n * ```typescript\n * CinetPaySeamless.on('payment.success', (data) => {\n *   console.log('Payé !', data.amount, data.currency)\n * })\n *\n * CinetPaySeamless.on('payment.failed', (data) => {\n *   console.log('Refusé', data.transactionId)\n * })\n *\n * CinetPaySeamless.on('ready', () => {\n *   console.log('Passerelle chargée')\n * })\n * ```\n */\nexport class EventEmitter {\n  private listeners = new Map<string, Set<Function>>()\n\n  /**\n   * Enregistre un handler pour un événement.\n   *\n   * @param event - Nom de l'événement\n   * @param handler - Fonction appelée quand l'événement est émis\n   * @returns Fonction pour se désabonner (équivalent de `off(event, handler)`)\n   *\n   * @example\n   * ```typescript\n   * const unsubscribe = CinetPaySeamless.on('payment.success', (data) => { ... })\n   * // Plus tard :\n   * unsubscribe()\n   * ```\n   */\n  on<E extends EventName>(event: E, handler: Handler<EventMap[E]>): () => void {\n    if (!this.listeners.has(event)) {\n      this.listeners.set(event, new Set())\n    }\n    this.listeners.get(event)!.add(handler)\n\n    // Retourne une fonction de désabonnement\n    return () => this.off(event, handler)\n  }\n\n  /**\n   * Supprime un handler pour un événement.\n   *\n   * @param event - Nom de l'événement\n   * @param handler - Référence du handler à supprimer\n   */\n  off<E extends EventName>(event: E, handler: Handler<EventMap[E]>): void {\n    this.listeners.get(event)?.delete(handler)\n  }\n\n  /**\n   * Enregistre un handler qui ne sera appelé qu'une seule fois.\n   *\n   * @param event - Nom de l'événement\n   * @param handler - Fonction appelée une seule fois\n   *\n   * @example\n   * ```typescript\n   * CinetPaySeamless.once('payment.success', (data) => {\n   *   // Appelé une seule fois\n   * })\n   * ```\n   */\n  once<E extends EventName>(event: E, handler: Handler<EventMap[E]>): void {\n    const wrapper = ((...args: unknown[]) => {\n      this.off(event, wrapper as Handler<EventMap[E]>)\n      ;(handler as Function)(...args)\n    }) as Handler<EventMap[E]>\n    this.on(event, wrapper)\n  }\n\n  /**\n   * Émet un événement — appelle tous les handlers enregistrés.\n   * @internal\n   */\n  emit<E extends EventName>(event: E, ...args: EventMap[E] extends void ? [] : [EventMap[E]]): void {\n    const handlers = this.listeners.get(event)\n    if (!handlers) return\n    for (const handler of handlers) {\n      try {\n        (handler as Function)(...args)\n      } catch {\n        // Ne pas bloquer les autres handlers si un throw\n      }\n    }\n  }\n\n  /**\n   * Supprime tous les handlers pour tous les événements.\n   * @internal\n   */\n  removeAll(): void {\n    this.listeners.clear()\n  }\n}\n","import { Checkout } from './checkout'\nimport type {\n  SeamlessConfig,\n  PaymentResponse,\n  PaymentError,\n  PaymentStatus,\n  StatusCheckContext,\n  SeamlessEnvironment,\n} from './types'\nimport { Logger } from './logger'\nimport { EventEmitter, type EventName, type EventMap } from './emitter'\n\nexport type {\n  SeamlessConfig,\n  PaymentResponse,\n  PaymentError,\n  PaymentStatus,\n  StatusCheckContext,\n  SeamlessEnvironment,\n}\nexport type { EventName, EventMap } from './emitter'\n\n/** @internal URLs de base de la passerelle de paiement sécurisée */\nconst SECURE_BASE_URLS: Record<SeamlessEnvironment, string> = {\n  sandbox: 'https://secure.cinetpay.net',\n  production: 'https://secure.cinetpay.co',\n}\n\n/** Récupère un callback en tolérant la casse pour les intégrations CDN/script tag. */\nfunction getCallback<T extends Function>(config: SeamlessConfig, names: string[]): T | undefined {\n  const record = config as unknown as Record<string, unknown>\n\n  for (const name of names) {\n    const value = record[name]\n    if (typeof value === 'function') return value as T\n  }\n\n  const lowerNames = new Set(names.map((name) => name.toLowerCase()))\n  for (const [key, value] of Object.entries(record)) {\n    if (lowerNames.has(key.toLowerCase()) && typeof value === 'function') {\n      return value as T\n    }\n  }\n\n  return undefined\n}\n\n/** Récupère une option en tolérant la casse pour les intégrations CDN/script tag. */\nfunction getOption<T>(config: SeamlessConfig, names: string[]): T | undefined {\n  const record = config as unknown as Record<string, unknown>\n\n  for (const name of names) {\n    if (record[name] !== undefined) return record[name] as T\n  }\n\n  const lowerNames = new Set(names.map((name) => name.toLowerCase()))\n  for (const [key, value] of Object.entries(record)) {\n    if (lowerNames.has(key.toLowerCase())) return value as T\n  }\n\n  return undefined\n}\n\nfunction getPaymentToken(config: SeamlessConfig): string | undefined {\n  return getOption<string>(config, ['paymentToken', 'payment_token'])\n}\n\nfunction getPaymentUrl(config: SeamlessConfig): string | undefined {\n  return getOption<string>(config, ['paymentUrl', 'paymentURL', 'payment_url', 'checkoutUrl', 'checkout_url'])\n}\n\nfunction createStatusChecker(config: SeamlessConfig): (() => Promise<unknown>) | undefined {\n  const context: StatusCheckContext = { paymentToken: getPaymentToken(config) ?? '' }\n  const checkStatus = getCallback<(context: StatusCheckContext) => Promise<unknown>>(config, [\n    'checkStatus',\n    'checkPaymentStatus',\n    'checkTransactionStatus',\n  ])\n\n  if (checkStatus) {\n    return () => checkStatus(context)\n  }\n\n  const statusUrl = getOption<SeamlessConfig['statusUrl']>(config, ['statusUrl', 'statusURL'])\n  if (!statusUrl) return undefined\n\n  return async () => {\n    const url = typeof statusUrl === 'function' ? statusUrl(context) : statusUrl\n    const response = await fetch(url, {\n      method: 'GET',\n      credentials: 'same-origin',\n      headers: { Accept: 'application/json' },\n    })\n\n    if (!response.ok) {\n      throw new Error(`Status check failed with HTTP ${response.status}`)\n    }\n\n    return response.json()\n  }\n}\n\nfunction createPaymentUrl(config: SeamlessConfig): string {\n  const explicitUrl = getPaymentUrl(config)\n  if (explicitUrl) return explicitUrl\n\n  const paymentToken = getPaymentToken(config)\n  if (!paymentToken) {\n    throw new Error('Invalid paymentToken format — expected alphanumeric string (10-128 chars)')\n  }\n\n  const environment = getOption<SeamlessEnvironment>(config, ['environment', 'env']) ?? 'sandbox'\n  const checkoutBaseUrl =\n    getOption<string>(config, ['checkoutBaseUrl', 'secureBaseUrl']) ??\n    SECURE_BASE_URLS[environment] ??\n    SECURE_BASE_URLS.sandbox\n\n  return `${checkoutBaseUrl.replace(/\\/+$/, '')}/checkout/${paymentToken}`\n}\n\n/**\n * CinetPay Seamless — paiement inline via popup window.\n *\n * Affiche un overlay d'attente et ouvre la passerelle de paiement\n * CinetPay dans une popup. Le client reste sur votre page.\n *\n * Le `paymentToken` est obtenu côté serveur via l'API CinetPay :\n *\n * ```typescript\n * // Frontend\n * CinetPaySeamless.open({\n *   paymentToken: 'abc123...',\n *   onPaymentSuccess: (data) => console.log('Payé !', data.amount),\n * })\n * ```\n *\n * Ou avec des event listeners (style événementiel) :\n *\n * ```typescript\n * CinetPaySeamless.on('payment.success', (data) => { ... })\n * CinetPaySeamless.open({ paymentToken: 'abc123...' })\n * ```\n */\nexport const CinetPaySeamless = {\n  /** Instance du checkout actuellement ouvert */\n  _checkout: null as Checkout | null,\n\n  /** Event emitter partagé */\n  _emitter: new EventEmitter(),\n\n  /**\n   * Enregistre un listener d'événement (style événementiel).\n   *\n   * @param event - Nom de l'événement\n   * @param handler - Fonction appelée quand l'événement est émis\n   * @returns Fonction de désabonnement\n   *\n   * @example\n   * ```typescript\n   * const unsub = CinetPaySeamless.on('payment.success', (data) => {\n   *   console.log('Payé !', data.amount, data.currency)\n   * })\n   * unsub() // Se désabonner\n   * ```\n   */\n  on<E extends EventName>(\n    event: E,\n    handler: EventMap[E] extends void ? () => void : (data: EventMap[E]) => void,\n  ): () => void {\n    return this._emitter.on(event, handler)\n  },\n\n  /**\n   * Supprime un listener.\n   */\n  off<E extends EventName>(\n    event: E,\n    handler: EventMap[E] extends void ? () => void : (data: EventMap[E]) => void,\n  ): void {\n    this._emitter.off(event, handler)\n  },\n\n  /**\n   * Enregistre un listener appelé une seule fois.\n   */\n  once<E extends EventName>(\n    event: E,\n    handler: EventMap[E] extends void ? () => void : (data: EventMap[E]) => void,\n  ): void {\n    this._emitter.once(event, handler)\n  },\n\n  /**\n   * Ouvre le checkout CinetPay.\n   *\n   * Affiche un overlay d'attente et ouvre la page de paiement dans une popup.\n   * La popup est centrée sur l'écran (500x700px).\n   *\n   * @param config - Configuration avec `paymentToken` et callbacks optionnels\n   * @throws {Error} Si le `paymentToken` a un format invalide\n   *\n   * @example\n   * ```typescript\n   * CinetPaySeamless.open({\n   *   paymentToken: 'abc123def456...',\n   *   debug: true,\n   *   onPaymentSuccess: (data) => console.log('Payé !', data.amount),\n   *   onPaymentFailed: (data) => console.log('Refusé'),\n   *   onClose: ({ status }) => console.log('Fermé:', status),\n   * })\n   * ```\n   */\n  open(config: SeamlessConfig): void {\n    this.close()\n\n    const logger = new Logger(config.debug ?? false)\n    logger.debug('CinetPaySeamless.open() called')\n\n    // Validation du paymentToken quand le SDK doit reconstruire l'URL checkout.\n    const paymentToken = getPaymentToken(config)\n    if (paymentToken && !/^[a-zA-Z0-9_-]{10,128}$/.test(paymentToken)) {\n      throw new Error('Invalid paymentToken format — expected alphanumeric string (10-128 chars)')\n    }\n\n    const paymentUrl = createPaymentUrl(config)\n\n    this._checkout = new Checkout({\n      logger,\n      emitter: this._emitter,\n      statusChecker: createStatusChecker(config),\n      statusPollInterval: getOption<number>(config, ['statusPollInterval', 'statusCheckInterval']),\n      onReady: getCallback(config, ['onReady']),\n      onPaymentSuccess: getCallback(config, [\n        'onPaymentSuccess',\n        'onSuccess',\n        'onPaymentsuccess',\n        'onpaymentSuccess',\n        'onpaymentsuccess',\n      ]),\n      onPaymentFailed: getCallback(config, [\n        'onPaymentFailed',\n        'onPaymentFail',\n        'onPaymentFailure',\n        'onFailed',\n        'onPaymentfailed',\n        'onpaymentFailed',\n        'onpaymentfailed',\n      ]),\n      onPaymentPending: getCallback(config, ['onPaymentPending', 'onPending']),\n      onClose: getCallback(config, ['onClose']),\n      onError: getCallback(config, ['onError']),\n    })\n\n    this._checkout.open(paymentUrl)\n  },\n\n  /**\n   * Ferme le checkout (popup + overlay).\n   */\n  close(): void {\n    this._checkout?.close()\n    this._checkout = null\n  },\n}\n\n// Auto-attach to window for CDN/script tag usage\nif (typeof window !== 'undefined') {\n  (window as unknown as Record<string, unknown>).CinetPaySeamless = CinetPaySeamless\n}\n"],"names":["STYLES","_Checkout","options","paymentUrl","_a","overlay","value","data","records","key","child","keys","record","parsed","rawStatus","apiCode","normalized","status","response","dispatchKey","isFinalStatus","_b","_c","styleEl","wrapper","waiting","spinner","title","msg","cancelBtn","left","top","err","reason","error","event","o","code","Checkout","PREFIX","Logger","enabled","message","EventEmitter","handler","args","handlers","SECURE_BASE_URLS","getCallback","config","names","name","lowerNames","getOption","getPaymentToken","getPaymentUrl","createStatusChecker","context","checkStatus","statusUrl","url","createPaymentUrl","explicitUrl","paymentToken","environment","CinetPaySeamless","logger"],"mappings":"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"}