API Paiement
Wallet Partenaire

Documentation complète de l'API CHC dédiée au paiement via wallet partenaire. Intégration sécurisée avec RIA Money Transfer pour la réception et le crédit de transferts internationaux sur le wallet - Wallet Partenaire.

Base URL https://chc-platform.com/v1
Partenaire Wallet Partenaire Wallet
Format JSON / REST / HTTPS
RIA Money Transfer Connecté
Vue d'ensemble

La plateforme CHC expose une API REST sécurisée permettant au Wallet Partenaire de recevoir des paiements de transferts internationaux RIA Money Transfer. Chaque crédit wallet est conditionné à une double validation : RIA (payabilité) puis CHC (contrôle AML).

BASE URL https://chc-platform.com/v1/wallet
Architecture — Flux Wallet Partenaire
RIA Money Transfer API RIA CHC Platform AML · Validation · Audit chc-platform.com/v1 API Wallet Wallet Partenaire Wallet Partenaire agréé BCM App Client Bénéficiaire
Authentification

Toutes les requêtes nécessitent un token JWT Bearer. Le wallet Partenaire dispose en plus d'une clé partenaire dédiée à inclure dans chaque requête.

JWT Bearer Token
Authorization: Bearer <jwt_token>
Content-Type: application/json
Headers Partenaire (Wallet Partenaire)
X-Partner-Key: <clé_api_wallet-partenaire>
X-Partner-ID: WP-IDENTIFIER
X-Idempotency-Key: <uuid_v4>
Le token JWT a une durée de validité de 60 minutes. Rafraîchissement via POST /auth/refresh. Le header X-Idempotency-Key (UUID v4 unique par tentative) est obligatoire pour prévenir les doublons de transactions.
Flux de paiement wallet

Le flux suit les 10 étapes définies dans le processus officiel CHC. Chaque étape est obligatoire et séquentielle.

Processus de Paiement via Wallet Partenaire
DÉBUT Le client saisit la référence de transaction dans l'application wallet 1 Le wallet envoie une requête à POST /wallet/request 2 APPLICATION DES CONTRÔLES AML CHC 5 CHC interroge l'API RIA 3 Vérification du statut de la transaction : "Payable / Ready for payout" ? 4 OUI NON TRANSACTION BLOQUÉE SI NÉCESSAIRE → Mise en attente pour validation 6 OUI Validation Manuelle 7 NON PAIEMENT EFFECTUÉ UNIQUEMENT APRÈS VALIDATION 8 Le wallet crédite le compte du client 9 MISE À JOUR DU STATUT DE LA TRANSACTION 10 FIN
Étapes 1 – 5
1. Client saisit la référence dans l'app wallet
2. Wallet envoie la requête à l'API CHC
3. CHC interroge l'API RIA Money Transfer
4. Vérification statut : Payable / Ready for payout ?
5. Application des contrôles AML CHC
Étapes 6 – 10
6. Si nécessaire → mise en attente pour validation
7. Validation manuelle (superviseur CHC)
8. Paiement effectué uniquement après validation
9. Le wallet crédite le compte du client
10. Mise à jour du statut de la transaction
Statuts des transactions

Cycle de vie d'une transaction wallet. Les transitions sont strictement contrôlées par le moteur d'état CHC — aucune transition non autorisée n'est possible.

INITIÉE
Demande reçue, traitement démarré
EN_ATTENTE_VALIDATION_RIA
En attente de validation par les équipes RIA
VALIDÉE_PAR_RIA
Approuvée par RIA, crédit autorisé
EN_COURS_DE_VÉRIFICATION
Alerte AML — validation superviseur CHC
CRÉDITÉE_WALLET
Compte Wallet Partenaire crédité avec succès
REJETÉE_PAR_RIA
Refusée par les équipes de conformité RIA
BLOQUÉE_AML
Bloquée automatiquement par le moteur AML
ANNULÉE
Annulée avant exécution
Demande de paiement wallet

Étapes ① ② — Le wallet Partenaire soumet une demande de paiement en transmettant la référence RIA et les données KYC complètes du bénéficiaire.

POST
/v1/wallet/request
Soumettre une demande de paiement wallet depuis Wallet Partenaire avec données KYC
Endpoint réservé aux wallets partenaires agréés (rôle WALLET_PARTNER). Le header X-Partner-Key (clé API Wallet Partenaire) est obligatoire. Le header X-Idempotency-Key (UUID v4) est obligatoire pour garantir l'unicité de la demande.
Headers spécifiques
HeaderTypeRequisDescription
X-Partner-Keystring RequisClé API unique attribuée à Wallet Partenaire par CHC
X-Partner-ID: WP-IDENTIFIER
X-Idempotency-Keystring (UUID v4) RequisClé d'idempotence — même clé = même résultat, pas de doublon
Corps de la requête
JSON
{
  "ria_reference": "RIA-124xxxxxxxxx",
  "wallet_account_id": "WP-ACC-00934521",
  "beneficiary_kyc": {
    "first_name": "Mohamed Ahmed",
    "last_name": "Ould Salem",
    "date_of_birth": "1985-03-22",
    "nationality": "MR",
    "phone_number": "+22222345678",
    "document": {
      "type": "NNI",           // NNI | PASSPORT | RESIDENCE_PERMIT
      "number": "MR123456789",
      "issue_date": "2020-01-15",
      "expiry_date": "2030-01-14",
      "issuing_country": "MR",
      "photo_doc_url": "https://wallet-partenaire.mr/kyc/docs/abc123.jpg",
      
    }
  },
  "callback_url": "https://api.wallet-partenaire.mr/webhooks/chc"
}
Champs du corps
ChampTypeRequisDescription
ria_referencestring RequisRéférence unique de la transaction RIA fournie par le client
wallet_account_idstring RequisIdentifiant du compte Wallet Partenaire du bénéficiaire
beneficiary_kycobject RequisDonnées KYC complètes du bénéficiaire (voir détail)
beneficiary_kyc.documentobject RequisDocument d'identité avec photos du document et selfie
callback_urlstring (URL) RequisURL Wallet Partenaire pour recevoir les webhooks CHC (HTTPS requis)
Réponse (202 Accepted)
JSON
{
  "transaction_id": "CHC-TXN-20240615-00456",
  "status": "INITIÉE",
  "ria_reference": "RIA-125xxxxxxxxx",
  "amount": {
    "value": 25000,
    "currency": "MRU",
    "original_value": 650,
    "original_currency": "EUR"
  },
  "estimated_processing_time": "PT2M",   // ISO 8601 duration
  "poll_url": "/v1/wallet/status/CHC-TXN-20240615-00456"
}
Exemples de réponses par scénario
202 · Accepté
400 · KYC manquant
401 · Clé invalide
403 · Réf. introuvable
403 · Non payable
403 · Mauvais bénéficiaire
409 · Doublon
202
Demande acceptée
La référence RIA est valide, le traitement AML est en cours.
{
  "transaction_id": "CHC-TXN-20240615-00456",
  "status": "INITIÉE",
  "ria_reference": "RIA-124xxxxxxxxx",
  "amount": { "value": 25000, "currency": "MRU", "original_value": 650, "original_currency": "EUR" },
  "estimated_processing_time": "PT2M",
  "poll_url": "/v1/wallet/status/CHC-TXN-20240615-00456"
}
400
Données KYC incomplètes
Un ou plusieurs champs obligatoires sont absents ou malformés.
{
  "error": {
    "code": "INVALID_KYC_DATA",
    "message": "Données KYC incomplètes ou malformées.",
    "details": {
      "missing_fields": ["beneficiary_kyc.document.photo_selfie_url", "beneficiary_kyc.date_of_birth"]
    },
    "request_id": "req_1a2b3c4d..."
  }
}
401
Clé partenaire invalide
Le header X-Partner-Key est absent, révoqué ou ne correspond pas à X-Partner-ID.
{
  "error": {
    "code": "UNAUTHORIZED_PARTNER",
    "message": "Clé partenaire invalide ou absente.",
    "details": {
      "partner_id": "WALLET_PARTNER",
      "reason": "X-Partner-Key manquante ou révoquée"
    },
    "request_id": "req_2b3c4d5e..."
  }
}
403
Référence RIA introuvable
La ria_reference n'existe pas dans le système RIA. Par sécurité, le système retourne le même code que "non payable" pour ne pas confirmer l'existence de la référence.
{
  "error": {
    "code": "TRANSACTION_NOT_FOUND",
    "message": "Transaction introuvable ou non accessible.",
    "details": {
      "ria_reference": "RIA-2024-XXXXX"
    },
    "request_id": "req_3c4d5e6f..."
  }
}
403
Transaction non payable
La transaction existe chez RIA mais son statut ne permet pas le paiement (déjà payée, bloquée, expirée, en attente de vérification RIA).
{
  "error": {
    "code": "TRANSACTION_NOT_PAYABLE",
    "message": "La transaction n'est pas dans un état payable.",
    "details": {
      "ria_reference": "RIA-124xxxxxxxxx",
      "ria_status": "ALREADY_PAID",  // ALREADY_PAID | BLOCKED | EXPIRED | ON_HOLD
      "reason": "Cette transaction a déjà été payée."
    },
    "request_id": "req_4d5e6f7g..."
  }
}
403
Transaction non destinée à ce client
La référence existe et est payable, mais les données KYC du bénéficiaire ne correspondent pas aux informations enregistrées chez RIA. Par sécurité, le système retourne "transaction introuvable" pour ne pas confirmer à un tiers que la référence existe.
{
  "error": {
    "code": "TRANSACTION_NOT_FOUND",  // intentionnellement identique au cas "introuvable"
    "message": "Transaction introuvable ou non accessible.",
    "details": {
      "ria_reference": "RIA-124xxxxxxxxx"
      // Aucune indication sur la raison réelle pour des raisons de sécurité
    },
    "request_id": "req_5e6f7g8h..."
  }
}
409
Doublon — Idempotency Key déjà utilisée
Une requête avec ce X-Idempotency-Key a déjà été traitée. La transaction existante est retournée sans créer de doublon.
{
  "transaction_id": "CHC-TXN-20240615-00456",  // transaction originale
  "status": "INITIÉE",
  "ria_reference": "RIA-124xxxxxxxxx",
  "idempotency_key": "550e8400-e29b-41d4-a716-446655440000",
  "duplicate": true,
  "original_created_at": "2024-06-15T14:30:00Z"
}
Statut de la transaction

Étapes ③ ④ ⑤ ⑥ — Interroger l'état d'avancement d'une transaction en cours. Retourne le credit_token dès que la transaction est prête pour crédit.

GET
/v1/wallet/status/{transaction_id}
Consulter le statut courant d'une transaction wallet
Paramètre de chemin
ParamètreTypeRequisDescription
transaction_idstring RequisIdentifiant CHC retourné par POST /wallet/request
Réponse (200 OK) — Transaction prête pour crédit
JSON
{
  "transaction_id": "CHC-TXN-20240615-00456",
  "status": "VALIDÉE_PAR_RIA",
  "ria_reference": "RIA-124xxxxxxxxx",
  "aml_status": "CLEARED",         // CLEARED | PENDING_REVIEW | BLOCKED
  "amount": {
    "value": 25000,
    "currency": "MRU"
  },
  "beneficiary_name": "Mohamed Ahmed Ould Salem",
  "wallet_account_id": "WP-ACC-00934521",
  "ready_for_credit": true,
  "credit_token": "ctk_9f2a1b3c4d5e...",   // présent UNIQUEMENT si ready_for_credit=true
  "credit_token_expires_at": "2024-06-15T15:36:45Z",
  "updated_at": "2024-06-15T14:34:02Z"
}
Polling recommandé : interroger cet endpoint toutes les 5 secondes jusqu'à obtenir ready_for_credit: true et le credit_token. Alternativement, écouter le webhook transaction.ready_for_credit pour éviter le polling.
Si aml_status retourne PENDING_REVIEW, la transaction est en attente de validation superviseur CHC. Le credit_token ne sera émis qu'après validation manuelle.
Exemples de réponses par scénario
200 · Prête pour crédit
200 · En attente AML
200 · Bloquée AML
200 · Rejetée par RIA
403 · Accès refusé
404 · Introuvable
200
Transaction prête pour crédit
RIA a validé + AML passé. Le credit_token est disponible. Wallet Partenaire peut appeler POST /wallet/confirm.
{
  "transaction_id": "CHC-TXN-20240615-00456",
  "status": "VALIDÉE_PAR_RIA",
  "ria_reference": "RIA-124xxxxxxxxx",
  "aml_status": "CLEARED",
  "amount": { "value": 25000, "currency": "MRU" },
  "beneficiary_name": "Mohamed Ahmed Ould Salem",
  "wallet_account_id": "WP-ACC-00934521",
  "ready_for_credit": true,
  "credit_token": "ctk_9f2a1b3c4d5e...",
  "credit_token_expires_at": "2024-06-15T14:49:10Z",
  "updated_at": "2024-06-15T14:34:02Z"
}
200
En attente de validation AML
Une alerte AML a été déclenchée. La transaction est suspendue en attente de la validation manuelle d'un superviseur CHC. Aucun credit_token n'est émis.
{
  "transaction_id": "CHC-TXN-20240615-00456",
  "status": "EN_COURS_DE_VÉRIFICATION",
  "ria_reference": "RIA-124xxxxxxxxx",
  "aml_status": "PENDING_REVIEW",
  "aml_alert_reason": "HIGH_AMOUNT",  // HIGH_AMOUNT | HIGH_FREQUENCY | RISKY_COUNTRY
  "amount": { "value": 50000, "currency": "MRU" },
  "ready_for_credit": false,
  "credit_token": null,  // absent tant que non validée
  "estimated_review_time": "PT30M",
  "updated_at": "2024-06-15T14:34:02Z"
}
200
Transaction bloquée par AML
Le moteur AML a bloqué définitivement la transaction. Aucun crédit ne sera possible. Le webhook transaction.aml_blocked a été envoyé.
{
  "transaction_id": "CHC-TXN-20240615-00456",
  "status": "BLOQUÉE_AML",
  "ria_reference": "RIA-124xxxxxxxxx",
  "aml_status": "BLOCKED",
  "aml_block_reason": "SANCTION_LIST_MATCH",
  "ready_for_credit": false,
  "credit_token": null,
  "updated_at": "2024-06-15T14:35:00Z"
}
200
Transaction rejetée par RIA
Les équipes de conformité RIA ont rejeté la transaction après vérification approfondie. La transaction est définitivement close.
{
  "transaction_id": "CHC-TXN-20240615-00456",
  "status": "REJETÉE_PAR_RIA",
  "ria_reference": "RIA-124xxxxxxxxx",
  "aml_status": "CLEARED",
  "ria_rejection_reason": "COMPLIANCE_REVIEW_FAILED",
  "ready_for_credit": false,
  "credit_token": null,
  "updated_at": "2024-06-15T14:50:00Z"
}
403
Transaction appartenant à un autre partenaire
La transaction existe mais a été créée par un autre wallet partenaire. Par sécurité, le système retourne "introuvable" pour ne pas confirmer l'existence au partenaire non autorisé.
{
  "error": {
    "code": "TRANSACTION_NOT_FOUND",  // intentionnellement identique au 404
    "message": "Transaction introuvable ou non accessible.",
    "details": {
      "transaction_id": "CHC-TXN-20240615-00456"
    },
    "request_id": "req_6f7g8h9i..."
  }
}
404
Transaction introuvable
Aucune transaction ne correspond à ce transaction_id dans la base CHC.
{
  "error": {
    "code": "TRANSACTION_NOT_FOUND",
    "message": "Transaction introuvable ou non accessible.",
    "details": {
      "transaction_id": "CHC-TXN-20240615-XXXXX"
    },
    "request_id": "req_7g8h9i0j..."
  }
}
Confirmer le paiement wallet

Étapes ⑦ ⑧ ⑨ ⑩ — Après réception du credit_token, Wallet Partenaire soumet la confirmation de crédit. CHC notifie RIA de la finalisation.

POST
/v1/wallet/confirm
Confirmer le crédit wallet après validation RIA + AML
Le credit_token (obtenu via GET /wallet/status) est obligatoire et à usage unique. Il expire 15 minutes après émission. Le crédit du compte client ne doit être effectué par Wallet Partenaire qu'après réception du status: CRÉDITÉE_WALLET en réponse. Toute tentative sans token valide sera rejetée (403) et journalisée.
Corps de la requête
JSON
{
  "transaction_id": "CHC-TXN-20240615-00456",
  "credit_token": "ctk_9f2a1b3c4d5e...",
  "wallet_account_id": "WP-ACC-00934521",
  "amount_to_credit": 25000,
  "currency": "MRU"
}
Champs du corps
ChampTypeRequisDescription
transaction_idstring RequisIdentifiant CHC de la transaction
credit_tokenstring RequisToken de crédit à usage unique, obtenu via GET /wallet/status
wallet_account_idstring RequisDoit correspondre au wallet_account_id de la demande initiale
amount_to_creditinteger RequisMontant en unités entières (MRU) — doit correspondre au montant validé
currencystring (ISO 4217) RequisDevise — toujours MRU pour les paiements locaux
Réponse (200 OK)
JSON
{
  "transaction_id": "CHC-TXN-20240615-00456",
  "payment_status": "CRÉDITÉE_WALLET",
  "credited_at": "2024-06-15T14:36:45Z",
  "wallet_account_id": "WP-ACC-00934521",
  "amount_credited": 25000,
  "currency": "MRU",
  "ria_reference": "RIA-124xxxxxxxxx",
  "ria_confirmation_code": "RIA-CONF-9876543",
  "chc_receipt_id": "RCP-W-20240615-00456"
}
Exemples de réponses par scénario
200 · Crédité
403 · Token expiré
403 · Token déjà utilisé
403 · Mauvais wallet
422 · Montant incorrect
503 · RIA indisponible
200
Wallet crédité avec succès
Le crédit est confirmé côté CHC et RIA. La transaction est finalisée. Wallet Partenaire peut maintenant créditer le compte du client.
{
  "transaction_id": "CHC-TXN-20240615-00456",
  "payment_status": "CRÉDITÉE_WALLET",
  "credited_at": "2024-06-15T14:36:45Z",
  "wallet_account_id": "WP-ACC-00934521",
  "amount_credited": 25000,
  "currency": "MRU",
  "ria_reference": "RIA-124xxxxxxxxx",
  "ria_confirmation_code": "RIA-CONF-9876543",
  "chc_receipt_id": "RCP-W-20240615-00456"
}
403
Credit token expiré
Le credit_token a une durée de validité de 15 minutes. Passé ce délai, il faut rappeler GET /wallet/status pour en obtenir un nouveau.
{
  "error": {
    "code": "INVALID_CREDIT_TOKEN",
    "message": "Le credit_token a expiré.",
    "details": {
      "transaction_id": "CHC-TXN-20240615-00456",
      "reason": "TOKEN_EXPIRED",
      "expired_at": "2024-06-15T14:49:10Z",
      "action": "Appeler GET /v1/wallet/status/{id} pour un nouveau token"
    },
    "request_id": "req_8h9i0j1k..."
  }
}
403
Credit token déjà utilisé
Le credit_token est à usage unique. Une tentative de réutilisation est journalisée comme tentative de double crédit.
{
  "error": {
    "code": "INVALID_CREDIT_TOKEN",
    "message": "Le credit_token a déjà été utilisé.",
    "details": {
      "transaction_id": "CHC-TXN-20240615-00456",
      "reason": "TOKEN_ALREADY_USED",
      "used_at": "2024-06-15T14:36:45Z",
      "current_status": "CRÉDITÉE_WALLET"
    },
    "request_id": "req_9i0j1k2l..."
  }
}
403
Wallet account non autorisé
Le wallet_account_id soumis ne correspond pas à celui enregistré lors de la demande initiale (POST /wallet/request).
{
  "error": {
    "code": "WALLET_ACCOUNT_MISMATCH",
    "message": "Le wallet_account_id ne correspond pas à la transaction.",
    "details": {
      "transaction_id": "CHC-TXN-20240615-00456",
      "reason": "ACCOUNT_ID_MISMATCH"
      // Le wallet_account_id attendu n'est pas divulgué pour des raisons de sécurité
    },
    "request_id": "req_0j1k2l3m..."
  }
}
422
Montant incorrect
Le montant soumis dans amount_to_credit ne correspond pas au montant validé par RIA. Le montant attendu est retourné pour correction.
{
  "error": {
    "code": "AMOUNT_MISMATCH",
    "message": "Le montant soumis ne correspond pas au montant validé.",
    "details": {
      "transaction_id": "CHC-TXN-20240615-00456",
      "amount_submitted": 200000,
      "amount_expected": 25000,
      "currency": "MRU"
    },
    "request_id": "req_1k2l3m4n..."
  }
}
503
API RIA temporairement indisponible
CHC n'a pas pu confirmer la transaction auprès de RIA. La transaction reste en statut VALIDÉE_PAR_RIA. Réessayer après le délai retry_after.
{
  "error": {
    "code": "RIA_UNAVAILABLE",
    "message": "L'API RIA est temporairement indisponible. Réessayez.",
    "details": {
      "transaction_id": "CHC-TXN-20240615-00456",
      "current_status": "VALIDÉE_PAR_RIA",  // statut inchangé
      "retry_after": 30,  // secondes avant de réessayer
      "credit_token_still_valid": true
    },
    "request_id": "req_2l3m4n5o..."
  }
}
Annuler une transaction

Annulation possible uniquement si la transaction est au statut INITIÉE ou EN_COURS_DE_VÉRIFICATION. Toute transaction déjà confirmée ou créditée ne peut être annulée.

PUT
/v1/wallet/cancel/{transaction_id}
Annuler une transaction wallet avant exécution du crédit
Corps de la requête
JSON
{
  "reason": "CLIENT_REQUEST",    // CLIENT_REQUEST | TIMEOUT | TECHNICAL_ERROR
  "notes": "Le client a demandé l'annulation"
}
Réponse (200 OK)
JSON
{
  "transaction_id": "CHC-TXN-20240615-00456",
  "status": "ANNULÉE",
  "cancelled_at": "2024-06-15T14:40:00Z",
  "reason": "CLIENT_REQUEST"
}
Exemples de réponses par scénario
200 · Annulée
403 · Déjà créditée
403 · Validée par RIA
404 · Introuvable
200
Transaction annulée avec succès
La transaction était au statut INITIÉE ou EN_COURS_DE_VÉRIFICATION et a pu être annulée.
{
  "transaction_id": "CHC-TXN-20240615-00456",
  "status": "ANNULÉE",
  "cancelled_at": "2024-06-15T14:40:00Z",
  "reason": "CLIENT_REQUEST"
}
403
Transaction déjà créditée
Le wallet a déjà été crédité — la transaction est close et ne peut pas être annulée.
{
  "error": {
    "code": "CANNOT_CANCEL",
    "message": "La transaction ne peut pas être annulée dans son état actuel.",
    "details": {
      "transaction_id": "CHC-TXN-20240615-00456",
      "current_status": "CRÉDITÉE_WALLET",
      "reason": "La transaction a déjà été créditée sur le wallet client."
    },
    "request_id": "req_3m4n5o6p..."
  }
}
403
Transaction validée par RIA — non annulable
RIA a déjà validé la transaction. Elle ne peut plus être annulée côté CHC ; il faut contacter RIA directement pour un éventuel remboursement.
{
  "error": {
    "code": "CANNOT_CANCEL",
    "message": "La transaction ne peut pas être annulée dans son état actuel.",
    "details": {
      "transaction_id": "CHC-TXN-20240615-00456",
      "current_status": "VALIDÉE_PAR_RIA",
      "reason": "Transaction validée par RIA — contacter RIA pour toute demande de remboursement."
    },
    "request_id": "req_4n5o6p7q..."
  }
}
404
Transaction introuvable
Aucune transaction ne correspond à ce transaction_id, ou elle appartient à un autre partenaire.
{
  "error": {
    "code": "TRANSACTION_NOT_FOUND",
    "message": "Transaction introuvable ou non accessible.",
    "details": {
      "transaction_id": "CHC-TXN-20240615-XXXXX"
    },
    "request_id": "req_5o6p7q8r..."
  }
}
Webhooks

CHC envoie des notifications en temps réel vers l'URL de callback Wallet Partenaire définie dans POST /wallet/request. Chaque payload est signé HMAC-SHA256.

Chaque webhook inclut le header X-CHC-Signature: sha256=<hmac>. Wallet Partenaire doit vérifier cette signature avant tout traitement. La clé secrète HMAC est fournie lors de l'onboarding partenaire.
transaction.ready_for_credit
RIA validé + AML OK — le credit_token est disponible pour confirmer le crédit
transaction.credited
Confirmation finale : wallet crédité et transaction clôturée côté CHC et RIA
transaction.rejected
Transaction rejetée par RIA ou bloquée définitivement par le moteur AML
transaction.pending_review
Alerte AML déclenchée — en attente de validation superviseur CHC
transaction.cancelled
Transaction annulée (demande client, timeout ou erreur technique)
transaction.aml_blocked
Transaction bloquée automatiquement par le moteur AML — non récupérable
Exemple de payload webhook
JSON
// POST https://api.wallet-partenaire.mr/webhooks/chc
// Headers: X-CHC-Signature: sha256=abc123..., Content-Type: application/json

{
  "event": "transaction.ready_for_credit",
  "event_id": "evt_7f3a2b1c9d8e...",
  "occurred_at": "2024-06-15T14:34:10Z",
  "data": {
    "transaction_id": "CHC-TXN-20240615-00456",
    "status": "VALIDÉE_PAR_RIA",
    "credit_token": "ctk_9f2a1b3c4d5e...",
    "credit_token_expires_at": "2024-06-15T14:49:10Z",
    "amount": { "value": 25000, "currency": "MRU" },
    "ria_reference": "RIA-124xxxxxxxxx"
  }
}
Wallet Partenaire doit répondre aux webhooks avec un HTTP 200 dans les 5 secondes. En l'absence de réponse, CHC retentera jusqu'à 3 fois avec un délai exponentiel (30s, 2min, 10min).
AML / KYC

Le double niveau de contrôle (Wallet Partenaire + CHC) garantit une conformité renforcée. Wallet Partenaire applique le KYC à l'entrée ; CHC applique les règles AML à chaque transaction.

Déclencheurs AML automatiques
Montant élevé> 50 000 MRU → mise en attente superviseur
Fréquence> 3 transactions / 24h / bénéficiaire
Pays à risqueOrigine sur liste FATF → vérification renforcée
Document expiréBlocage automatique immédiat
Incohérence KYCDonnées ≠ registre RIA → rejet
Données KYC obligatoires (Wallet Partenaire → CHC)
Nom complet Requis
Date de naissance Requis
Nationalité Requis
Numéro de téléphone Requis
Document ID + photo Requis
Selfie bénéficiaire Requis
Conservation des données : Toutes les données KYC, journaux d'audit et confirmations de transaction sont conservés 10 ans minimum, conformément aux exigences de la Banque Centrale de Mauritanie (BCM).
Codes d'erreur

Toutes les erreurs suivent la même structure JSON. Le champ request_id permet de tracer la requête dans les journaux CHC.

JSON — Structure standard erreur
{
  "error": {
    "code": "AML_BLOCKED",
    "message": "La transaction a été bloquée par le moteur AML.",
    "details": {
      "transaction_id": "CHC-TXN-20240615-00456",
      "triggered_rule": "HIGH_FREQUENCY"
    },
    "request_id": "req_9a8b7c6d5e4f..."
  }
}
Code erreurHTTPDescription
TRANSACTION_NOT_FOUND404Référence RIA introuvable
TRANSACTION_NOT_PAYABLE403Statut RIA non payable au moment de la requête
AML_BLOCKED403Transaction bloquée définitivement par le moteur AML CHC
IDENTITY_MISMATCH422Données KYC incohérentes avec les données RIA
INVALID_CREDIT_TOKEN403credit_token absent, expiré ou déjà utilisé
AMOUNT_MISMATCH422Montant soumis différent du montant validé
DUPLICATE_TRANSACTION409X-Idempotency-Key déjà utilisée — la transaction existante est retournée
INVALID_KYC_DATA400Données KYC manquantes ou malformées dans le corps
UNAUTHORIZED_PARTNER401X-Partner-Key invalide ou wallet non autorisé
CANNOT_CANCEL403Transaction dans un statut non annulable
RIA_UNAVAILABLE503API RIA temporairement indisponible — réessayer après 30 secondes