# Intégrer l’API Partenaires FastCash Ce guide accompagne le contrat [OpenAPI 3.1](./openapi.json). L’API est conçue pour des échanges B2B serveur-à-serveur. Elle ne doit jamais être appelée directement depuis un navigateur ou une application mobile. Pour tester les exemples dans Postman, importez la [collection FastCash](./fastcash-partners.postman_collection.json), renseignez la variable secrète `bearerToken`, puis gardez `baseUrl` sur l’environnement voulu. La collection ne contient aucune clé API. ## Vue d’ensemble URL de production : ```text https://gkpjwwtalnyrpktfngbc.supabase.co/functions/v1/partners-api ``` Les huit opérations publiques sont : | Méthode | Route | Rôle | | --- | --- | --- | | `GET` | `/bookmakers` | Charger les bookmakers et moyens de paiement Mobile Money | | `GET` | `/bookmakers/{id}/balance` | Consulter le solde live de la caisse bookmaker | | `POST` | `/accounts/lookup` | Vérifier un compte bookmaker avant une opération | | `POST` | `/deposits` | Initier un dépôt asynchrone | | `POST` | `/withdrawals` | Initier un retrait asynchrone | | `GET` | `/transactions/{id}` | Lire une transaction FastCash | | `GET` | `/transactions` | Rechercher les transactions du partenaire | | `GET` | `/commissions` | Générer le mois courant et lire les commissions du partenaire | ## Authentification et secrets Conservez la clé API dans un gestionnaire de secrets et injectez-la côté serveur : ```http Authorization: Bearer Content-Type: application/json ``` N’écrivez jamais la clé API ou le secret webhook dans le code, les logs, une URL, une capture d’écran ou une conversation avec un assistant IA. Les exemples de cette page utilisent uniquement des placeholders. Chaque réponse contient un `requestId` dans le JSON et un en-tête `X-Request-Id`. Conservez cet identifiant dans vos logs pour le support. ## 1. Charger le référentiel Appelez `GET /bookmakers` au démarrage puis actualisez le résultat régulièrement. La réponse contient : - `bookmakers` : plateformes de pari, capacités dépôt/retrait, minimums et frais ; - `operators` : moyens de paiement Mobile Money et codes à envoyer dans les créations d’opérations. Codes de référence : | Moyen de paiement | `deposit_code` | `withdrawal_code` | | --- | --- | --- | | Orange Money | `ORANGE_BFA_MARCHAND` | `ORANGE_BFA_CASHIN` | | Telecel Money | `TELECEL_BFA_MARCHAND` | `TELECEL_BFA_CASHIN` | | Moov Money | `MOOV_BFA_MARCHAND` | `MOOV_BFA_CASHIN` | | Wave | `WAVE_BFA_MARCHAND` | `WAVE_BFA_CASHIN` | La réponse reste la source de vérité : respectez toujours `client_deposit_enabled`, `client_withdrawal_enabled`, `supports_deposit` et `supports_withdrawal` au lieu de figer ces disponibilités dans votre application. ### Consulter le solde bookmaker Appelez `GET /bookmakers/{id}/balance` avec un `id` reçu de `GET /bookmakers`. La réponse lit le solde en direct auprès de Servcul : `balance` est le solde réel de la caisse, `withdrawable` le montant disponible pour les retraits, en XOF. `as_of` indique l'instant de la lecture. ```json { "bookmaker_platform_id": 1, "name": "1XBET", "balance": 150000, "withdrawable": 120000, "currency": "XOF", "as_of": "2026-10-01T12:00:00.000Z" } ``` Un identifiant inexistant renvoie `404`. Le contrôle n'est pas disponible pour certains bookmakers (`503`). Une erreur du service bookmaker renvoie `502` ou `504` en cas de délai dépassé. ## 2. Vérifier le compte bookmaker Appelez `POST /accounts/lookup` avant tout dépôt ou retrait : ```json { "bookmaker_platform_id": 1, "bookmaker_user_id": 12345678 } ``` Traitez explicitement les trois résultats possibles. ### Compte confirmé ```json { "exists": true, "supports_lookup": true, "account_holder_name": "Awa Ouedraogo", "reason": null } ``` Vous pouvez continuer après confirmation de l’utilisateur. ### Compte introuvable ```json { "exists": false, "supports_lookup": true, "account_holder_name": null, "reason": "Account not found." } ``` Bloquez l’opération et affichez un message compréhensible. Ne tentez pas le paiement avec le même identifiant. ### Pré-vérification non supportée ```json { "exists": true, "supports_lookup": false, "account_holder_name": null, "reason": "Bookmaker does not support account pre-validation." } ``` Ne traitez pas ce cas comme un compte confirmé. Informez l’utilisateur que la vérification préalable est indisponible, demandez-lui de confirmer les informations, puis laissez `/deposits` ou `/withdrawals` effectuer la validation finale. ## 3. Créer une opération Pour un dépôt, envoyez le `deposit_code` retourné par le référentiel : ```json { "bookmaker_platform_id": 1, "bookmaker_user_id": 12345678, "amount": 5000, "operator_code": "ORANGE_BFA_MARCHAND", "phone_number": "+22670000000", "partner_external_id": "order-demo-0001", "user_external_id": "customer-demo-42" } ``` Pour un retrait, utilisez le `withdrawal_code` Mobile Money dans `operator_code` et fournissez aussi le code de retrait bookmaker : ```json { "bookmaker_platform_id": 1, "bookmaker_user_id": 12345678, "amount": 5000, "withdrawal_code": "", "operator_code": "ORANGE_BFA_CASHIN", "phone_number": "+22670000000", "partner_external_id": "withdrawal-demo-0001", "user_external_id": "customer-demo-42" } ``` Ces payloads sont des exemples de développement. Ne les envoyez jamais en production sans validation explicite de l’utilisateur et sans remplacer toutes les valeurs fictives. Une réponse HTTP `202` signifie que FastCash a accepté la demande. Elle ne prouve pas que l’opération est terminée. Affichez `ussd_code` pour les parcours USSD ou `wave_message` pour Wave lorsque ces champs sont présents. ## 4. Suivre le résultat Utilisez `GET /transactions/{id}` pour lire une opération précise. `GET /transactions` accepte : - `user_external_id` ; - `from` et `to` au format ISO 8601 ; - `limit`, avec un maximum public de 200. Après un timeout ou une erreur réseau, recherchez d’abord la transaction par vos références. Ne recréez pas automatiquement une opération ambiguë. ## 5. Lire les commissions Appelez `GET /commissions`. L’endpoint génère ou actualise d’abord la commission du mois UTC courant, puis retourne `current_commission`, tout l’historique dans `commissions` et les agrégats dans `summary`. La génération est idempotente : plusieurs lectures simultanées ne créent pas de doublon. Une ligne dont le versement est `processing` ou `completed` est figée. ```bash curl 'https://gkpjwwtalnyrpktfngbc.supabase.co/functions/v1/partners-api/commissions' \ --header 'Authorization: Bearer ' ``` Les montants sont en XOF. `commission_rate` est une fraction (`0.60` = 60 %). La commission est `commissionable_base × commission_rate` ; `commissionable_base` correspond aux récompenses FastCash commissionnables sur les dépôts et retraits éligibles, pas au volume brut. Si le mois courant ne contient aucun volume éligible, `current_period_status` vaut `no_eligible_volume` et `current_commission` vaut `null`. Les anciennes commissions restent présentes dans `commissions`. ## Webhooks FastCash envoie les événements terminaux `transaction.completed`, `transaction.failed` et `transaction.cancelled`. Vérifiez l’en-tête `Fastbet-Signature`, au format : ```text t=,v1= ``` La valeur signée est `.`. Vérifiez la signature HMAC-SHA256 avant de parser le JSON, comparez en temps constant, refusez les timestamps vieux de plus de cinq minutes et dédupliquez durablement sur `event_id`. Répondez rapidement avec un statut `2xx`. Une livraison en échec est tentée au maximum huit fois au total avec un backoff exponentiel. Les noms d’en-têtes `Fastbet-Signature` et `X-Fastbet-*` sont historiques et restent volontairement inchangés pour assurer la compatibilité du protocole. ## Erreurs et relances Pour les lectures `GET`, les erreurs transitoires `429`, `502`, `503` et `504` peuvent être réessayées avec backoff exponentiel et jitter. Ne relancez jamais automatiquement `POST /deposits` ou `POST /withdrawals` après un timeout, une erreur `5xx` ou un résultat ambigu. Gelez l’opération et contactez le support avec `requestId` et `partner_external_id`. Les erreurs `400`, `401`, `403` et `404` exigent une correction ou une intervention. `partner_external_id` doit être unique dans votre système. La version actuelle le trace mais ne garantit pas à elle seule le rejet automatique d’un doublon. ## Prompt sûr pour un assistant IA Vous pouvez fournir ce prompt à un assistant de développement : ```text Tu aides à intégrer l’API Partenaires FastCash. Lis d’abord /docs/partners/openapi.json puis /docs/partners/integration.md. Respecte exactement les huit opérations publiques documentées. Travaille avec des variables d’environnement et des valeurs fictives. Ne demande, n’affiche, n’invente et ne journalise jamais une clé API ou un secret webhook. Prépare du code et des tests avec mocks par défaut. N’exécute aucune requête de dépôt ou retrait, aucun appel vers la production, aucun déploiement et aucune mutation réelle sans mon accord explicite donné immédiatement avant l’action. Ne relance jamais automatiquement un dépôt ou un retrait ambigu ; prépare une escalade avec requestId et partner_external_id. Signale tout écart entre mon besoin et le contrat OpenAPI. ``` ## Checklist avant production - Clé API et secret webhook stockés dans un gestionnaire de secrets. - Appels effectués uniquement depuis le backend. - Référentiel et capacités respectés dynamiquement. - Vérification `/accounts/lookup` intégrée avec ses trois branches. - Confirmation utilisateur avant toute opération monétaire. - `partner_external_id` unique et stratégie de reprise testée. - Signature, fraîcheur et déduplication des webhooks testées. - Secrets et données sensibles masqués dans les logs.