API publique de collecte de paiement
Documentation d'integration SOLIMI pour marchands, fintechs et banques
Ce guide explique comment connecter votre application a l'API publique SOLIMI pour initier des paiements, consulter leur statut, lire votre solde, recuperer les moyens de paiement disponibles et recevoir les notifications webhook.
Environnements et pre-requis
Avant l'integration, l'equipe SOLIMI vous fournit un compte partenaire, une cle API, un secret API et configure les adresses IP autorisees. Le secret API est affiche une seule fois: conservez-le dans un coffre de secrets.
| Environnement | Base URL | Usage |
|---|---|---|
| Local developpement | http://localhost:8000 |
Tests internes SOLIMI ou recette locale. |
| Sandbox | https://sandbox-api.solimi.co |
Integration partenaire avant mise en production. |
| Production | https://api.solimi.co |
Transactions reelles apres validation SOLIMI. |
Authentification HMAC
Toutes les routes publiques securisees utilisent une signature HMAC SHA-256. SOLIMI verifie votre cle API, l'adresse IP source, l'horodatage et la signature calculee a partir du corps exact de la requete.
Headers obligatoires
| Header | Description |
|---|---|
x-api-key |
Votre cle API publique, par exemple sk_test_... ou sk_live_.... |
x-timestamp |
Timestamp Unix en secondes. La tolerance est de 300 secondes. |
x-signature |
HMAC SHA-256 hexadecimal du message raw_body + timestamp. |
Idempotency-Key |
Obligatoire pour POST /v1/payments/request. Doit etre unique par tentative logique. |
Algorithme
message = raw_request_body + x_timestamp
x_signature = HMAC_SHA256_HEX(api_secret, message)
Pour une requete GET, le corps est vide. Le message signe est donc uniquement le timestamp.
Paiements
Une demande de paiement cree une intention de collecte. Selon le type de paiement, le client approuve le paiement sur mobile money, via son compte SOLIMI ou via une carte SOLIMI.
Mobile money
payment_type = mobile_money
Requiert provider: mixx, coris_money ou moov_money.
Compte SOLIMI
payment_type = solimi_account
Requiert account_id sur 12 chiffres.
Carte SOLIMI
payment_type = solimi_card
Requiert card_id sur 8 chiffres.
Cycle de vie
| Statut | Signification |
|---|---|
INITIATED | La demande de paiement est creee. |
PENDING_APPROVAL | Le paiement attend l'approbation du client. |
APPROVED | Le client a approuve le paiement. |
PROCESSING | Le traitement est en cours. |
SUCCESS | Le paiement est reussi. |
FAILED | Le paiement a echoue. |
DECLINED | Le client ou le systeme a refuse le paiement. |
EXPIRED | La demande a expire. |
CANCELLED | La demande a ete annulee. |
Reference des payloads et validations
Cette section precise le role de chaque champ, son type, son caractere obligatoire, sa taille et le format attendu. Les regex ci-dessous sont les validations recommandees cote integrateur, afin de detecter les erreurs avant l'appel API.
account_id pour un paiement mobile_money.
Headers de securite
| Champ | Role | Type | Obligatoire | Taille | Regex / Format | Exemple |
|---|---|---|---|---|---|---|
x-api-key |
Identifie la cle API du partenaire. | string | Oui | Variable | ^sk_(test|live)_[A-Za-z0-9]+$ |
sk_test_abcd... |
x-timestamp |
Protege contre le rejeu de requetes. | string numeric | Oui | 10 chiffres en secondes | ^\d{10}$, Unix timestamp, tolerance 300s |
1781899200 |
x-signature |
Prouve que la requete vient du serveur partenaire. | string | Oui | 64 caracteres | ^[a-f0-9]{64}$ |
7d9f...a31c |
Idempotency-Key |
Evite la creation de doublons lors des retries. | string | Oui pour creation paiement | Recommande: 1 a 100 | ^[A-Za-z0-9._:-]{1,100}$ |
ORDER-2026-0001 |
PaymentRequestCreate - Creation d'un paiement
| Champ | Role metier | Type | Obligatoire | Taille | Regex / Valeurs | Notes |
|---|---|---|---|---|---|---|
merchant_reference |
Reference unique de la transaction dans le systeme du marchand. | string | Oui | 1 a 100 caracteres | ^[A-Za-z0-9._:-]{1,100}$ recommande |
Utilisez la meme valeur comme base de Idempotency-Key. |
payment_type |
Canal de paiement a utiliser. | enum string | Oui | Variable | mobile_money, solimi_account, solimi_card |
Determine les champs conditionnels requis. |
amount |
Montant a collecter. | integer | Oui | Nombre entier positif | ^[1-9]\d*$ |
Montant en XOF, sans decimales. |
currency |
Devise de la transaction. | literal string | Non | 3 caracteres | ^XOF$ |
Facultatif. Si absent, le backend applique XOF. |
description |
Libelle visible pour reconciliation ou support. | string | Oui | Minimum 1 caractere | ^.{1,}$ |
Recommande: inclure le numero de commande. |
customer_phone |
Numero du client payeur. | string | Oui | 8 a 20 caracteres | ^\+?[0-9]{8,20}$ recommande |
Envoyez le numero au format international quand possible. |
provider |
Operateur mobile money a utiliser. | enum string | Oui si mobile_money |
Variable | mixx, coris_money, moov_money |
Ne pas envoyer pour solimi_account ou solimi_card. |
account_id |
Identifiant du compte SOLIMI client. | string | Oui si solimi_account |
Exactement 12 chiffres | ^\d{12}$ |
Refuse si la longueur est differente de 12. |
card_id |
Identifiant de la carte SOLIMI client. | string | Oui si solimi_card |
Exactement 8 chiffres | ^\d{8}$ |
Refuse si la longueur est differente de 8. |
Regles conditionnelles par type de paiement
payment_type |
Champ requis | Champs a ne pas envoyer | Exemple minimal |
|---|---|---|---|
mobile_money |
provider |
account_id, card_id |
{"payment_type":"mobile_money","provider":"mixx"} |
solimi_account |
account_id |
provider, card_id |
{"payment_type":"solimi_account","account_id":"1234567890"} |
solimi_card |
card_id |
provider, account_id |
{"payment_type":"solimi_card","card_id":"12345678"} |
PaymentRequestResponse - Reponse de creation
| Champ | Role | Type | Format / Valeurs |
|---|---|---|---|
reference | Reference SOLIMI du paiement. | string | PAY-..., a conserver pour le suivi. |
merchant_reference | Reference marchand transmise dans la requete. | string | 1 a 100 caracteres. |
payment_type | Type de paiement retenu. | enum | mobile_money, solimi_account, solimi_card. |
provider | Operateur mobile money. | enum ou null | mixx, coris_money, moov_money, ou null. |
amount | Montant demande. | integer | Entier positif. |
currency | Devise. | string | XOF. |
description | Libelle de la demande. | string | Texte non vide. |
customer_phone | Numero client. | string | 8 a 20 caracteres. |
status | Etat initial ou courant. | enum | Voir la table des statuts. |
expires_at | Date d'expiration de la demande. | datetime | ISO 8601, UTC recommande. |
created_at | Date de creation. | datetime | ISO 8601. |
PaymentStatusResponse - Suivi de paiement
| Champ | Role | Type | Format / Valeurs |
|---|---|---|---|
reference | Reference SOLIMI a interroger. | string | PAY-.... |
merchant_reference | Reference du marchand. | string | 1 a 100 caracteres. |
partner_id | Identifiant technique du partenaire. | UUID | ^[0-9a-fA-F-]{36}$. |
payment_type | Canal utilise. | enum | Types de paiement supportes. |
provider | Provider mobile money. | enum ou null | Null hors mobile money. |
amount | Montant. | integer | Entier positif. |
currency | Devise. | string | XOF. |
status | Etat courant. | enum | INITIATED, PENDING_APPROVAL, APPROVED, PROCESSING, SUCCESS, FAILED, DECLINED, EXPIRED, CANCELLED. |
failure_reason | Cause d'echec si disponible. | string ou null | Renseigne principalement les statuts non reussis. |
expires_at | Expiration. | datetime | ISO 8601. |
approved_at | Date d'approbation client. | datetime ou null | ISO 8601. |
completed_at | Date de succes final. | datetime ou null | ISO 8601. |
failed_at | Date d'echec. | datetime ou null | ISO 8601. |
declined_at | Date de refus. | datetime ou null | ISO 8601. |
Payloads webhook
| Champ | Role | Type | Obligatoire | Format / Regex |
|---|---|---|---|---|
url | Endpoint HTTPS du partenaire. | URL | Oui a la creation | ^https://.+ recommande en production. |
secret | Secret partage avec SOLIMI pour authentifier les webhooks recus. | string | Non | Minimum 16 caracteres. Recommande: 32+ caracteres aleatoires. |
is_active | Active ou desactive la reception. | boolean | Non, uniquement update | true ou false. |
Endpoints publics
Les endpoints ci-dessous sont accessibles sous le prefixe /v1.
GET/v1/health
PublicVerifie la disponibilite de l'API.
Headers
| Header | Obligatoire | Valeur |
|---|---|---|
content-type | Non | application/json |
Payload
Aucun body requis.
Reponses possibles
| HTTP | Cas | Corps |
|---|---|---|
200 | API disponible | {"status":"ok","service":"solimi-payment-api"} |
5xx | Service indisponible | Erreur serveur ou timeout infrastructure. |
Exemples d'appel
cURL
curl -X GET "{{base_url}}/v1/health"PHP
<?php
echo file_get_contents("{{base_url}}/v1/health");Node.js
const response = await fetch("{{base_url}}/v1/health");
console.log(await response.json());Python
import requests
response = requests.get("{{base_url}}/v1/health")
print(response.json())Exemple de reponse 200
{
"status": "ok",
"service": "solimi-payment-api"
}
POST/v1/payments/request
HMAC + Idempotency-KeyCree une demande de paiement.
Headers obligatoires
| Header | Role | Format / valeur |
|---|---|---|
content-type | Format du body. | application/json |
x-api-key | Identifie le partenaire. | Cle API fournie par SOLIMI. |
x-timestamp | Protection anti-rejeu. | Timestamp Unix en secondes, tolerance 300s. |
x-signature | Authentifie la requete. | HMAC SHA-256 hex de raw_body + timestamp. |
Idempotency-Key | Evite les doublons lors des retries. | Unique par tentative logique, ex: ORDER-2026-0001. |
Payload et validations
| Champ | Type | Obligatoire | Valeurs / regex | Role |
|---|---|---|---|---|
merchant_reference | string | Oui | 1-100, ^[A-Za-z0-9._:-]{1,100}$ | Reference unique cote marchand. |
payment_type | enum | Oui | mobile_money, solimi_account, solimi_card | Canal de collecte. |
provider | enum/null | Oui si mobile money | mixx, moov_money, coris_money | Operateur mobile money. |
amount | integer | Oui | ^[1-9]\d*$ | Montant XOF sans decimales. |
currency | string | Non | XOF | Facultatif. Devise par defaut appliquee par le backend. |
description | string | Oui | Non vide | Libelle/reconciliation. |
customer_phone | string | Oui | ^\+?[0-9]{8,20}$ | Numero du client payeur. |
account_id | string/null | Oui si compte SOLIMI | ^\d{12}$ | Compte SOLIMI du client. |
card_id | string/null | Oui si carte SOLIMI | ^\d{8}$ | Carte SOLIMI du client. |
Exemple de payload
{
"merchant_reference": "ORDER-2026-0001",
"payment_type": "mobile_money",
"provider": "mixx",
"amount": 25000,
"description": "Commande ORDER-2026-0001",
"customer_phone": "22890112233"
}
Reponses possibles
| HTTP | Code applicatif | Cas |
|---|---|---|
201 | - | Demande de paiement creee. |
400 | domain_error | Regle metier invalide. |
401 | authentication_failed | Headers HMAC manquants ou invalides. |
403 | authorization_failed | IP non autorisee, partenaire inactif ou credentials invalides. |
409 | idempotency_conflict / duplicate_merchant_reference | Cle idempotente reutilisee avec un payload different ou reference marchand deja utilisee. |
422 | validation_error | Champ manquant ou format invalide. |
500 | payment_core_sync_failed | Erreur de synchronisation interne avec le noyau SOLIMI. |
Exemples d'appel
cURL
BODY='{"merchant_reference":"ORDER-2026-0001","payment_type":"mobile_money","provider":"mixx","amount":25000,"description":"Commande ORDER-2026-0001","customer_phone":"22890112233"}'
TIMESTAMP=$(date +%s)
SIGNATURE=$(printf "%s%s" "$BODY" "$TIMESTAMP" | openssl dgst -sha256 -hmac "$SOLIMI_API_SECRET" -hex | sed 's/^.* //')
curl -X POST "{{base_url}}/v1/payments/request" \
-H "content-type: application/json" \
-H "x-api-key: $SOLIMI_API_KEY" \
-H "x-timestamp: $TIMESTAMP" \
-H "x-signature: $SIGNATURE" \
-H "Idempotency-Key: ORDER-2026-0001" \
-d "$BODY"PHP
<?php
$apiKey = getenv("SOLIMI_API_KEY");
$apiSecret = getenv("SOLIMI_API_SECRET");
$timestamp = (string) time();
$body = json_encode([
"merchant_reference" => "ORDER-2026-0001",
"payment_type" => "mobile_money",
"provider" => "mixx",
"amount" => 25000,
"description" => "Commande ORDER-2026-0001",
"customer_phone" => "22890112233"
], JSON_UNESCAPED_SLASHES);
$signature = hash_hmac("sha256", $body . $timestamp, $apiSecret);
$ch = curl_init("{{base_url}}/v1/payments/request");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => $body,
CURLOPT_HTTPHEADER => [
"content-type: application/json",
"x-api-key: $apiKey",
"x-timestamp: $timestamp",
"x-signature: $signature",
"Idempotency-Key: ORDER-2026-0001"
]
]);
echo curl_exec($ch);Node.js
import crypto from "node:crypto";
const body = JSON.stringify({
merchant_reference: "ORDER-2026-0001",
payment_type: "mobile_money",
provider: "mixx",
amount: 25000,
description: "Commande ORDER-2026-0001",
customer_phone: "22890112233"
});
const timestamp = Math.floor(Date.now() / 1000).toString();
const signature = crypto.createHmac("sha256", process.env.SOLIMI_API_SECRET).update(body + timestamp).digest("hex");
const response = await fetch("{{base_url}}/v1/payments/request", {
method: "POST",
headers: {
"content-type": "application/json",
"x-api-key": process.env.SOLIMI_API_KEY,
"x-timestamp": timestamp,
"x-signature": signature,
"Idempotency-Key": "ORDER-2026-0001"
},
body
});
console.log(await response.json());Python
import hashlib
import hmac
import json
import os
import time
import requests
payload = {
"merchant_reference": "ORDER-2026-0001",
"payment_type": "mobile_money",
"provider": "mixx",
"amount": 25000,
"description": "Commande ORDER-2026-0001",
"customer_phone": "22890112233",
}
body = json.dumps(payload, separators=(",", ":"), ensure_ascii=False)
timestamp = str(int(time.time()))
signature = hmac.new(os.environ["SOLIMI_API_SECRET"].encode(), (body + timestamp).encode(), hashlib.sha256).hexdigest()
response = requests.post(
"{{base_url}}/v1/payments/request",
data=body.encode(),
headers={
"content-type": "application/json",
"x-api-key": os.environ["SOLIMI_API_KEY"],
"x-timestamp": timestamp,
"x-signature": signature,
"Idempotency-Key": "ORDER-2026-0001",
},
)
print(response.json())Exemple de reponse 201
{
"reference": "PAY-8C7F36A1B2",
"merchant_reference": "ORDER-2026-0001",
"payment_type": "mobile_money",
"provider": "mixx",
"amount": 25000,
"currency": "XOF",
"description": "Commande ORDER-2026-0001",
"customer_phone": "22890112233",
"status": "PENDING_APPROVAL",
"expires_at": "2026-06-19T21:00:00Z",
"created_at": "2026-06-19T20:45:00Z"
}
GET/v1/payments/status/{reference}
HMACRetourne l'etat courant d'un paiement.
Headers obligatoires
| Header | Role | Format / valeur |
|---|---|---|
x-api-key | Identifie le partenaire. | Cle API fournie par SOLIMI. |
x-timestamp | Protection anti-rejeu. | Timestamp Unix en secondes. |
x-signature | Authentifie la requete GET. | HMAC SHA-256 hex du timestamp. |
Parametres
| Parametre | Type | Obligatoire | Format | Role |
|---|---|---|---|---|
reference | path string | Oui | PAY-... ou SOLPAY... | Reference SOLIMI retournee a la creation. |
Reponses possibles
| HTTP | Code applicatif | Cas |
|---|---|---|
200 | - | Statut retourne. |
401 | authentication_failed | Signature invalide. |
403 | authorization_failed | Partenaire non autorise. |
404 | not_found | Reference inconnue pour ce partenaire. |
Exemples d'appel
cURL
TIMESTAMP=$(date +%s)
SIGNATURE=$(printf "%s" "$TIMESTAMP" | openssl dgst -sha256 -hmac "$SOLIMI_API_SECRET" -hex | sed 's/^.* //')
curl -X GET "{{base_url}}/v1/payments/status/PAY-8C7F36A1B2" \
-H "x-api-key: $SOLIMI_API_KEY" \
-H "x-timestamp: $TIMESTAMP" \
-H "x-signature: $SIGNATURE"PHP
<?php
$timestamp = (string) time();
$signature = hash_hmac("sha256", $timestamp, getenv("SOLIMI_API_SECRET"));
$opts = ["http" => ["header" => "x-api-key: ".getenv("SOLIMI_API_KEY")."\r\nx-timestamp: $timestamp\r\nx-signature: $signature\r\n"]];
echo file_get_contents("{{base_url}}/v1/payments/status/PAY-8C7F36A1B2", false, stream_context_create($opts));Node.js
import crypto from "node:crypto";
const timestamp = Math.floor(Date.now() / 1000).toString();
const signature = crypto.createHmac("sha256", process.env.SOLIMI_API_SECRET).update(timestamp).digest("hex");
const response = await fetch("{{base_url}}/v1/payments/status/PAY-8C7F36A1B2", {
headers: {"x-api-key": process.env.SOLIMI_API_KEY, "x-timestamp": timestamp, "x-signature": signature}
});
console.log(await response.json());Python
import hashlib, hmac, os, time, requests
timestamp = str(int(time.time()))
signature = hmac.new(os.environ["SOLIMI_API_SECRET"].encode(), timestamp.encode(), hashlib.sha256).hexdigest()
response = requests.get(
"{{base_url}}/v1/payments/status/PAY-8C7F36A1B2",
headers={"x-api-key": os.environ["SOLIMI_API_KEY"], "x-timestamp": timestamp, "x-signature": signature},
)
print(response.json())Exemple de reponse 200
{
"reference": "PAY-8C7F36A1B2",
"merchant_reference": "ORDER-2026-0001",
"partner_id": "945adbc3-1e63-46da-8128-8ef790b50714",
"payment_type": "mobile_money",
"provider": "mixx",
"amount": 25000,
"currency": "XOF",
"status": "SUCCESS",
"failure_reason": null,
"expires_at": "2026-06-19T21:00:00Z",
"approved_at": "2026-06-19T20:46:11Z",
"completed_at": "2026-06-19T20:46:18Z",
"failed_at": null,
"declined_at": null
}
GET/v1/account/balance
HMACRetourne le solde disponible et le solde reserve du partenaire.
Headers obligatoires
| Header | Role | Format / valeur |
|---|---|---|
x-api-key | Identifie le partenaire. | Cle API fournie par SOLIMI. |
x-timestamp | Protection anti-rejeu. | Timestamp Unix en secondes. |
x-signature | Authentifie la requete GET. | HMAC SHA-256 hex du timestamp. |
Payload
Aucun body requis.
Reponses possibles
| HTTP | Code applicatif | Cas |
|---|---|---|
200 | - | Solde retourne. |
401 | authentication_failed | Signature invalide. |
403 | authorization_failed | Partenaire non autorise. |
Exemples d'appel
cURL
TIMESTAMP=$(date +%s)
SIGNATURE=$(printf "%s" "$TIMESTAMP" | openssl dgst -sha256 -hmac "$SOLIMI_API_SECRET" -hex | sed 's/^.* //')
curl -X GET "{{base_url}}/v1/account/balance" \
-H "x-api-key: $SOLIMI_API_KEY" \
-H "x-timestamp: $TIMESTAMP" \
-H "x-signature: $SIGNATURE"PHP
<?php
$timestamp = (string) time();
$signature = hash_hmac("sha256", $timestamp, getenv("SOLIMI_API_SECRET"));
$opts = ["http" => ["header" => "x-api-key: ".getenv("SOLIMI_API_KEY")."\r\nx-timestamp: $timestamp\r\nx-signature: $signature\r\n"]];
echo file_get_contents("{{base_url}}/v1/account/balance", false, stream_context_create($opts));Node.js
import crypto from "node:crypto";
const timestamp = Math.floor(Date.now() / 1000).toString();
const signature = crypto.createHmac("sha256", process.env.SOLIMI_API_SECRET).update(timestamp).digest("hex");
const response = await fetch("{{base_url}}/v1/account/balance", {
headers: {"x-api-key": process.env.SOLIMI_API_KEY, "x-timestamp": timestamp, "x-signature": signature}
});
console.log(await response.json());Python
import hashlib, hmac, os, time, requests
timestamp = str(int(time.time()))
signature = hmac.new(os.environ["SOLIMI_API_SECRET"].encode(), timestamp.encode(), hashlib.sha256).hexdigest()
response = requests.get(
"{{base_url}}/v1/account/balance",
headers={"x-api-key": os.environ["SOLIMI_API_KEY"], "x-timestamp": timestamp, "x-signature": signature},
)
print(response.json())Exemple de reponse 200
{
"partner_reference": "PART-637C64AC5B75",
"currency": "XOF",
"available_balance": 1250000,
"reserved_balance": 50000,
"environment": "sandbox"
}
GET/v1/payment-methods
HMACListe les moyens de paiement actifs.
Headers obligatoires
| Header | Role | Format / valeur |
|---|---|---|
x-api-key | Identifie le partenaire. | Cle API fournie par SOLIMI. |
x-timestamp | Protection anti-rejeu. | Timestamp Unix en secondes. |
x-signature | Authentifie la requete GET. | HMAC SHA-256 hex du timestamp. |
Payload
Aucun body requis.
Champs de reponse
| Champ | Type | Valeurs possibles | Role |
|---|---|---|---|
code | string | mixx, moov_money, solimi_account | Code technique a envoyer dans provider si applicable. |
name | string | Libelle humain | Nom affichable. |
provider | string/null | Provider mobile money ou null | Operateur associe. |
is_active | boolean | true/false | Disponibilite du moyen. |
Reponses possibles
| HTTP | Code applicatif | Cas |
|---|---|---|
200 | - | Liste retournee. |
401 | authentication_failed | Signature invalide. |
403 | authorization_failed | Partenaire non autorise. |
Exemples d'appel
cURL
TIMESTAMP=$(date +%s)
SIGNATURE=$(printf "%s" "$TIMESTAMP" | openssl dgst -sha256 -hmac "$SOLIMI_API_SECRET" -hex | sed 's/^.* //')
curl -X GET "{{base_url}}/v1/payment-methods" \
-H "x-api-key: $SOLIMI_API_KEY" \
-H "x-timestamp: $TIMESTAMP" \
-H "x-signature: $SIGNATURE"PHP
<?php
$timestamp = (string) time();
$signature = hash_hmac("sha256", $timestamp, getenv("SOLIMI_API_SECRET"));
$opts = ["http" => ["header" => "x-api-key: ".getenv("SOLIMI_API_KEY")."\r\nx-timestamp: $timestamp\r\nx-signature: $signature\r\n"]];
echo file_get_contents("{{base_url}}/v1/payment-methods", false, stream_context_create($opts));Node.js
import crypto from "node:crypto";
const timestamp = Math.floor(Date.now() / 1000).toString();
const signature = crypto.createHmac("sha256", process.env.SOLIMI_API_SECRET).update(timestamp).digest("hex");
const response = await fetch("{{base_url}}/v1/payment-methods", {
headers: {"x-api-key": process.env.SOLIMI_API_KEY, "x-timestamp": timestamp, "x-signature": signature}
});
console.log(await response.json());Python
import hashlib, hmac, os, time, requests
timestamp = str(int(time.time()))
signature = hmac.new(os.environ["SOLIMI_API_SECRET"].encode(), timestamp.encode(), hashlib.sha256).hexdigest()
response = requests.get(
"{{base_url}}/v1/payment-methods",
headers={"x-api-key": os.environ["SOLIMI_API_KEY"], "x-timestamp": timestamp, "x-signature": signature},
)
print(response.json())Exemple de reponse 200
[
{
"code": "mixx",
"name": "Mixx by Yas",
"provider": "mixx",
"is_active": true
},
{
"code": "moov_money",
"name": "Moov Money",
"provider": "moov_money",
"is_active": true
}
]
Collection Postman
La collection Postman SOLIMI regroupe les requetes pretes a tester pour les endpoints publics: creation de paiement, consultation de statut, solde du partenaire et moyens de paiement disponibles. Elle aide les equipes techniques a demarrer rapidement sans reconstruire les headers et payloads depuis zero.
Comment l'utiliser
- Telechargez le fichier JSON de collection.
- Dans Postman, cliquez sur
Import, puis selectionnez le fichier telecharge. - Renseignez les variables
base_url,api_key,api_secretet les valeurs de test. - Lancez les requetes de la section
03 - Paymentspour valider l'integration.
Fichier disponible
Format JSON compatible avec Postman. Le fichier contient les scripts necessaires pour calculer les headers HMAC et ajouter automatiquement l'idempotency key sur les paiements.
Telecharger la collection PostmanWebhooks
SOLIMI appelle votre endpoint webhook lorsqu'un paiement change d'etat. Votre serveur doit repondre avec
un statut HTTP 2xx. En cas d'echec, SOLIMI relance selon les delais: 30s, 60s, 300s, 900s.
| Header SOLIMI | Description |
|---|---|
x-solimi-signature | Secret webhook partage avec SOLIMI. Comparez cette valeur au secret configure. |
x-solimi-timestamp | Timestamp Unix en secondes, utile pour refuser les notifications trop anciennes. |
x-solimi-event | Nom de l'evenement, par exemple payment.success. |
Evenements
payment.initiated, payment.pending_approval, payment.success,
payment.failed, payment.declined, payment.expired.
Verification webhook FastAPI
import time
from fastapi import APIRouter, Header, HTTPException, Request
router = APIRouter()
SOLIMI_WEBHOOK_SECRET = "secret_fourni_par_solimi"
SIGNATURE_TOLERANCE_SECONDS = 300
@router.post("/webhooks/solimi/payments")
async def solimi_payment_webhook(
request: Request,
x_solimi_signature: str = Header(...),
x_solimi_timestamp: str = Header(...),
x_solimi_event: str = Header(...),
):
if x_solimi_signature != SOLIMI_WEBHOOK_SECRET:
raise HTTPException(status_code=401, detail="Invalid webhook signature")
try:
timestamp = int(x_solimi_timestamp)
except ValueError:
raise HTTPException(status_code=400, detail="Invalid timestamp")
if abs(int(time.time()) - timestamp) > SIGNATURE_TOLERANCE_SECONDS:
raise HTTPException(status_code=400, detail="Expired webhook timestamp")
payload = await request.json()
payment = payload.get("payment", {})
# Mettre a jour la commande/facture du partenaire ici.
# Exemple: payment.success => commande payee.
return {
"received": True,
"event": x_solimi_event,
"merchant_reference": payment.get("merchant_reference"),
"solimi_reference": payment.get("reference"),
"status": payment.get("status"),
}
x-solimi-signature contient directement
le secret webhook. Gardez ce secret cote serveur uniquement.
Erreurs
Les erreurs sont retournees au format JSON suivant.
{
"code": "authentication_failed",
"message": "Missing authentication headers",
"details": null
}
| HTTP | Code | Action recommandee |
|---|---|---|
| 401 | authentication_failed | Verifier les headers HMAC, le timestamp et la signature. |
| 403 | authorization_failed | Verifier l'IP autorisee, l'etat de la cle API et du partenaire. |
| 404 | not_found | Verifier la reference de paiement ou la route appelee. |
| 409 | idempotency_conflict | Reutiliser une meme cle uniquement pour la meme requete logique. |
| 422 | validation_error | Corriger les champs invalides dans le payload. |
Checklist de mise en production
- Stocker la cle API et le secret API dans un coffre de secrets cote serveur.
- Signer toutes les requetes avec le corps exact envoye a SOLIMI.
- Utiliser une cle d'idempotence unique pour chaque paiement marchand.
- Verifier les webhooks en comparant
x-solimi-signatureau secret webhook configure. - Prevoir le polling de statut en secours si un webhook est indisponible.
- Fournir a SOLIMI les adresses IP publiques de vos serveurs.
- Tester les cas succes, echec, refus, expiration et retry webhook en sandbox.