=== HayBTech for WooCommerce ===
Contributors: haybtech
Tags: payment, woocommerce, mobile money, orange money, wave, free money, africa, senegal, xof
Requires at least: 5.8
Tested up to: 6.4
Requires PHP: 7.4
Stable tag: 1.1.0
License: MIT
License URI: https://opensource.org/licenses/MIT

Acceptez les paiements via HayBTech sur votre boutique WooCommerce avec sécurité de niveau production.

== Description ==

HayBTech est l'agrégateur de paiement leader en Afrique de l'Ouest. Ce plugin intègre le guichet de paiement HayBTech directement dans votre tunnel d'achat WooCommerce — redirection vers la page hébergée HayBTech, retour automatique du client, validation cryptographique des notifications de paiement.

**Fonctionnalités clés**

* Paiements Mobile Money (Orange Money SN/CI, Wave, Free Money) via la page hébergée HayBTech
* Remboursements totaux et partiels depuis l'admin WooCommerce
* Devises supportées : XOF, XAF, GNF (0 décimales), EUR, USD (centimes)
* Compatible WooCommerce Blocks Checkout (WC 8.3+)
* Compatible HPOS (Custom Order Tables, WC 8.2+)
* PHP 7.4 → 8.5 (code unique, sans fork de compatibilité)

**Sécurité de niveau production**

* Vérification HMAC-SHA256 des webhooks en temps constant (anti timing oracle)
* Chiffrement AES-256-GCM au repos des clés API et du secret webhook (KEK dérivée des salts WordPress)
* Rate limit token-bucket 60 req/min/IP sur l'endpoint webhook
* Allowlist IP optionnelle (filtre `haybtech_webhook_ip_allowlist`, IPv4 + IPv6 + CIDR)
* Déduplication persistante des événements via table dédiée (race-safe)
* Journal d'audit complet (90 jours de rétention) sur toutes les décisions sécurité
* Idempotency-Key automatique sur paiements et remboursements
* Garde HTTPS sur l'URL de callback en mode production
* Fichiers `.htaccess` de protection déposés à l'activation

== Installation ==

1. Téléchargez le fichier zip du plugin.
2. Dans WP Admin : Extensions > Ajouter > Téléverser une extension > sélectionnez le zip > Installer maintenant > Activer.
3. Allez dans WooCommerce > Réglages > Paiements et cliquez sur HayBTech.
4. Activez le plugin, choisissez Mode Test ou Live, et collez vos clés API depuis le dashboard HayBTech.
5. Dans le dashboard HayBTech > Webhooks, créez un endpoint avec l'URL : https://votre-boutique.com/wp-json/haybtech/v1/webhook
6. Copiez le secret webhook (whsec_...) et collez-le dans le champ Secret Webhook.
7. Enregistrez.

À l'activation, le plugin crée deux tables (`wp_haybtech_webhook_events`, `wp_haybtech_audit_log`) et planifie un cron quotidien d'entretien (purge des anciennes lignes). Toutes les opérations sont idempotentes.

== Frequently Asked Questions ==

= Est-ce sécurisé ? =

Oui. Le plugin met en place huit couches indépendantes de défense sur l'endpoint webhook : rate limit IP, allowlist optionnelle, cap taille payload (1 Mo), vérification HMAC-SHA256 en temps constant, padding anti-timing-oracle 50 ms sur échec, déduplication persistante, validation structurelle stricte, et journal d'audit complet. Les clés API et le secret webhook sont chiffrés au repos en AES-256-GCM. Les données de paiement ne transitent jamais par votre serveur WordPress — votre boutique ne voit que la confirmation signée.

= Quelles devises sont supportées ? =

XOF, XAF, GNF (sans décimales), EUR et USD (avec centimes). Si la devise de votre boutique n'est pas dans cette liste, la gateway est automatiquement masquée à la caisse.

= Le plugin supporte-t-il les remboursements ? =

Oui — partiels et totaux, depuis WooCommerce > Commandes > Rembourser. Le remboursement est poussé vers `POST /v1/refunds` côté HayBTech. Les commandes créées avant la version 1.1.0 n'ont pas la meta de transaction nécessaire et doivent être remboursées depuis le dashboard HayBTech.

= Que faire si je vois "Invalid Signature" dans les logs ? =

C'est presque toujours une désynchro entre le secret côté HayBTech (dashboard) et le champ Secret Webhook du plugin. Re-copiez la valeur whsec_... depuis le dashboard, ré-enregistrez. Si l'erreur persiste, vérifiez l'heure de votre serveur (NTP) — au-delà de 5 minutes de dérive, la fenêtre anti-rejeu rejette les payloads.

= Que se passe-t-il si je tourne mes salts WordPress ? =

C'est volontaire : les secrets chiffrés deviennent illisibles (le KEK change). Re-collez vos clés API et le secret webhook dans les réglages. C'est le même modèle de sécurité que les cookies de session WordPress.

= Le plugin fonctionne-t-il en multi-site ? =

Oui, en activation par site. Chaque sous-site a ses propres clés et son propre secret webhook.

= Compatible HPOS et Blocks ? =

Oui aux deux. Compatibilité déclarée via `FeaturesUtil::declare_compatibility` au boot.

== Screenshots ==

1. Écran de configuration WooCommerce > Réglages > Paiements > HayBTech.
2. Sélection HayBTech dans la caisse classique.
3. Sélection HayBTech dans le Checkout Block (WC 8.3+).
4. Remboursement depuis la page de commande.

== Changelog ==

= 1.1.0 =

* **Comportement par défaut amélioré** : si les champs Success URL / Cancel URL sont vides, le plugin n'envoie plus la page WooCommerce par défaut au backend — il omet complètement les clés du payload, ce qui laisse le backend HayBTech utiliser son propre écran de confirmation hosted. Avantage : les boutiques sans landing page custom ne se voient plus forcer une redirection vers `/order-received/...` ; le client reste sur la page de confirmation HayBTech (avec récap + reçu) jusqu'à clic manuel sur "Retour au site du marchand".
* Si vous **voulez** une redirection automatique vers une page WC ou custom, renseignez le champ — le comportement (auto-append `?order_id=…&key=…` + redirection en 2s côté page hosted) reste identique à la 1.2.4.

= 1.2.4 =

* **Correctif critique de redirection** — le plugin envoyait `return_url` / `cancel_url` au backend HayBTech, mais le contrat API canonique attend `success_url` / `failed_url` (le validator Laravel stripait silencieusement les anciens noms). Conséquence depuis la 1.0.0 : la page hosted HayBTech ne recevait jamais d'URL de redirection custom, donc le client restait sur l'écran "Paiement approuvé" de HayBTech au lieu d'être renvoyé vers l'URL marchand configurée. Mise à jour immédiate fortement recommandée pour les boutiques qui utilisent les champs Success URL / Cancel URL.
* Aucun changement requis dans les réglages : les URLs configurées en 1.2.0-1.2.3 sont désormais effectivement envoyées au backend.

= 1.2.3 =

* **UX simplifiée des URLs de redirection** : les placeholders `{order_id}` / `{order_key}` sont supprimés. Plus de syntaxe à apprendre — collez juste votre URL, le plugin ajoute automatiquement `?order_id=<ID>&key=<order_key>` à la fin (équivalent au comportement natif WooCommerce `get_return_url`). Si votre URL contient déjà des paramètres (UTM, source de tracking…), le séparateur `&` est utilisé proprement.
* Description du champ Cancel/Failed URL nettoyée : retrait de la mention « (alignée Stripe/Wave) » qui n'apportait rien au marchand.
* Pas de migration nécessaire : les URLs existantes qui contenaient `{order_id}` continuent de fonctionner mais le placeholder n'est plus remplacé — pensez à le retirer pour ne pas avoir de `{order_id}` littéral dans l'URL finale.

= 1.2.2 =

* Cohérence d'image de marque : remplacement des références nommées aux opérateurs (« Orange Money, Wave, Free Money ») par « HayBTech » dans 3 emplacements visibles à l'admin : (1) l'entête « Description » du plugin (visible dans `Extensions > Ajouter`), (2) la `method_description` affichée en haut de `WC > Réglages > Paiements > HayBTech`, (3) le sous-titre du fichier README admin. La description **client** au tunnel d'achat avait déjà été ajustée en 1.2.1.

= 1.2.1 =

* Texte par défaut de la description gateway raccourci : « Payez de manière sécurisée avec HayBtech. » au lieu de l'ancienne formulation qui citait nommément les opérateurs (Orange Money, Wave, Free Money). Mieux aligné avec l'image de marque agrégateur de HayBTech et neutre vis-à-vis de l'ajout futur d'opérateurs.
* Note : les boutiques existantes qui ont déjà enregistré une description personnalisée ne sont pas affectées (seul le defaut sur installation propre change).

= 1.2.0 =

* **Nouveau** — URLs de redirection personnalisables depuis les réglages WooCommerce. Deux champs optionnels :
    * **URL de redirection après succès** (override de la page de confirmation WC par défaut)
    * **URL de redirection après échec ou annulation** (une seule URL pour les deux cas, alignée sur la convention HayBTech/Stripe/Wave)
* Placeholders supportés dans les deux champs : `{order_id}` et `{order_key}`, remplacés à chaud par l'ID et la clé de la commande.
* Garde HTTPS sur les URLs custom en mode production (les URLs HTTP sont rejetées avec fallback automatique sur les défauts WC + entrée d'audit `redirect_url_rejected_insecure`).
* Si les champs sont vides → comportement identique à 1.1.x (page de confirmation WC pour succès, page d'annulation WC pour échec/cancel). Pas de migration nécessaire.

= 1.1.1 =

* **Correctif critique** — l'extraction du `merchant_reference` dans le payload webhook lisait l'ancienne clé `merchant_ref` (utilisée par l'API d'envoi `POST /v1/payments`), au lieu de la clé `merchant_reference` réellement émise par les webhooks HayBTech (formats `legacy` et `2026-06-01`). Conséquence : les commandes restaient bloquées en statut `pending` après paiement avec la mention `webhook_order_not_found` dans les logs. Fallback ajouté sur `merchant_ref` puis `metadata.order_id` pour résilience.

= 1.1.0 =

**Fonctionnel**

* Compatibilité PHP 7.4 → 8.5 (code unique, polyfills `str_starts_with`/`str_contains`)
* Remboursements totaux et partiels via `POST /v1/refunds`
* Intégration native WooCommerce Blocks Checkout
* Compatibilité HPOS (Custom Order Tables) déclarée
* Endpoint webhook REST API `/wp-json/haybtech/v1/webhook` (l'ancienne URL `?wc-api=wc_haybtech_gateway` reste fonctionnelle)
* Acceptation des formats de payload legacy ET v2026-06-01 (Stripe-compatible)
* Gestion des événements `payment.refunded` et `payment.partially_refunded`
* Idempotency-Key automatique sur paiements et remboursements
* Masquage automatique pour devises non supportées
* Multi-devises (XOF/XAF/GNF sans décimales, EUR/USD avec centimes)
* Intégration WC Logger (WooCommerce > État > Journaux, source : `haybtech-gateway`)

**Sécurité (hardening sprint)**

* Chiffrement AES-256-GCM au repos des clés API et du secret webhook (KEK dérivée des salts WordPress, migration automatique des valeurs existantes en clair)
* Rate limit token-bucket 60 req/min/IP sur l'endpoint webhook (transients WP)
* Table de déduplication persistante `wp_haybtech_webhook_events` (rétention 30 jours, race-safe via `INSERT IGNORE`)
* Table d'audit `wp_haybtech_audit_log` traçant toutes les décisions sécurité (rétention 90 jours, redaction automatique des clés sensibles)
* Padding de réponse en temps constant (≥ 50 ms) sur échec de signature
* Filtre `haybtech_webhook_ip_allowlist` pour restreindre les IP source autorisées (IPv4/IPv6/CIDR)
* Garde HTTPS sur l'URL de callback en mode production
* Fichiers `.htaccess` de blocage d'exécution PHP directe déposés dans `includes/` et `includes/sdk/` à l'activation
* Whitelist du format des transaction_id (regex stricte) sur les remboursements
* Mapping des codes d'erreur API vers des messages clients neutres (jamais de fuite de détail interne)
* Cron quotidien `haybtech_daily_maintenance` (purge des tables d'audit + event store)

= 1.0.0 =

* Version initiale.

== Upgrade Notice ==

= 1.1.0 =

Comportement par défaut amélioré : champ Success/Cancel URL vide = le client reste sur la page de confirmation HayBTech (au lieu d'être forcé sur la page WC par défaut). Aucun impact si vos champs étaient déjà renseignés.

= 1.2.4 =

Correctif critique : la redirection vers l'URL Success/Cancel configurée n'était jamais effective car le plugin envoyait les anciens noms (`return_url`/`cancel_url`) au lieu des noms canoniques HayBTech (`success_url`/`failed_url`). Mise à jour fortement recommandée si vous utilisez les URLs de redirection custom.

= 1.2.3 =

UX des URLs de redirection simplifiée : plus de placeholder `{order_id}` à écrire — le plugin ajoute automatiquement `?order_id=...&key=...` à votre URL. Si vous aviez mis `{order_id}` dans vos réglages, retirez-le pour éviter un paramètre littéral dans l'URL finale.

= 1.2.2 =

Cohérence d'image de marque : textes admin alignés sur « HayBTech » (entête plugin + description admin). Aucun changement fonctionnel.

= 1.2.1 =

Ajustement mineur du texte par défaut affiché au client à la caisse. Les boutiques avec description personnalisée ne sont pas affectées.

= 1.2.0 =

Nouveau : possibilité de personnaliser les URLs de retour après succès et après échec/annulation depuis les réglages WooCommerce, avec placeholders `{order_id}` / `{order_key}`. Aucune action requise si vous utilisez les pages WC par défaut.

= 1.1.1 =

Correctif critique : les commandes WooCommerce restaient en statut "pending" après paiement en raison d'une lecture incorrecte du payload webhook. Mise à jour fortement recommandée pour toutes les boutiques en production.

= 1.1.0 =

Mise à jour majeure : sécurité de niveau production (chiffrement au repos, rate limit, audit log, déduplication persistante), support des remboursements WooCommerce, compatibilité Blocks Checkout, HPOS et PHP 8.5. Aucune action manuelle requise — les anciens webhooks et clés en clair sont automatiquement migrés au premier enregistrement.
