Une API REST pour intégrer Virevo à un site sur mesure ou un plugin CMS : créez un paiement, redirigez le client, recevez un webhook signé à l'encaissement.
Base URL : https://app.virevo.fr · Référence détaillée par
endpoint : Référence API.
Créez une clé d'API depuis votre dashboard → Développeurs.
Deux modes : vrv_test_… (bac à sable, paiements fictifs) et
vrv_live_… (réel). Passez-la en en-tête sur chaque appel
/v1 :
Authorization: Bearer vrv_live_xxxxxxxx
curl -X POST https://app.virevo.fr/v1/payments \
-H "Authorization: Bearer vrv_live_xxxxxxxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: commande-1042" \
-d '{
"amount_cents": 250000,
"currency": "EUR",
"reference": "CMD-1042",
"return_url": "https://votre-site.fr/merci",
"cancel_url": "https://votre-site.fr/panier"
}'
Réponse :
{
"id": "b3f1…",
"status": "pending",
"amount_cents": 250000,
"currency": "EUR",
"reference": "CMD-1042",
"payment_url": "https://app.virevo.fr/pay/…",
"test": false,
"created_at": "2026-06-24T09:00:00.000Z"
}
Redirigez ensuite le client vers payment_url pour qu'il valide
le virement. L'Idempotency-Key (recommandée) garantit qu'un
même envoi ne crée pas deux paiements.
| Champ | Description |
|---|---|
amount_cents | Montant en centimes (entier, max 10 000 000). |
currency | EUR. |
reference | Votre référence de commande (sert au rapprochement). |
return_url | Optionnel. Redirection du client après paiement réussi (avec ?virevo_payment_id&status=succeeded&reference). |
cancel_url | Optionnel. Redirection si le client annule. |
curl https://app.virevo.fr/v1/payments/b3f1… \
-H "Authorization: Bearer vrv_live_xxxxxxxx"
Statuts possibles :
| Statut | Signification |
|---|---|
pending | En attente de règlement. |
succeeded | Virement reçu, vous pouvez valider la commande. |
failed | Refusé. |
canceled | Annulé / expiré. |
Pagination par curseur. La liste est limitée au mode de
votre clé (une clé test ne voit que les paiements de test). Paramètres :
limit (1–100, défaut 20), starting_after (id du
dernier élément reçu), status, from,
to (dates ISO sur created_at).
curl "https://app.virevo.fr/v1/payments?limit=20&status=succeeded" \
-H "Authorization: Bearer vrv_live_xxxxxxxx"
{
"object": "list",
"data": [ { "id": "b3f1…", "status": "succeeded", … } ],
"has_more": true
}
# page suivante : reprendre à partir du dernier id reçu
curl "https://app.virevo.fr/v1/payments?limit=20&starting_after=b3f1…" \
-H "Authorization: Bearer vrv_live_xxxxxxxx"
has_more vaut true, redemandez avec starting_after = id du dernier élément.
Créez un remboursement (total ou partiel) sur un paiement réglé, puis
relisez-les. Idempotency-Key recommandé sur la création (un
rejeu ne crée pas de doublon). Émet l'événement payment.refunded.
# créer (montant en centimes ; sans amount_cents = solde restant)
curl -X POST https://app.virevo.fr/v1/payments/{id}/refund \
-H "Authorization: Bearer vrv_live_xxxxxxxx" \
-H "Idempotency-Key: refund-cmd-1042" \
-H "Content-Type: application/json" \
-d '{"amount_cents": 2000, "reason": "geste commercial"}'
# lister les remboursements d'un paiement
curl https://app.virevo.fr/v1/payments/{id}/refunds \
-H "Authorization: Bearer vrv_live_xxxxxxxx"
# → { "object": "list", "data": [ { "id": "ref_…", "amount_cents": 2000, … } ] }
# relire un remboursement par id
curl https://app.virevo.fr/v1/refunds/{refund_id} \
-H "Authorization: Bearer vrv_live_xxxxxxxx"
Avec une clé vrv_test_…, les paiements sont fictifs
(aucun KYC, aucun mouvement réel). Pour simuler un encaissement et
déclencher le webhook :
curl -X POST https://app.virevo.fr/v1/payments/{id}/simulate \
-H "Authorization: Bearer vrv_test_xxxxxxxx"
# → status: "succeeded" + envoi du webhook payment.succeeded
Vous pouvez ainsi développer toute votre intégration de bout en bout avant la mise en production.
Enregistrez l'URL de votre serveur dans le dashboard → Développeurs.
Vous recevez un secret (whsec_…). Événements émis :
payment.succeeded, payment.refunded,
payment.canceled. À chaque encaissement, Virevo envoie :
webhook.test signé vers votre URL, pour valider votre
intégration sans créer de paiement. Votre handler doit ignorer les types
d'événements inconnus (dont webhook.test).
POST https://votre-site.fr/virevo/webhook
Virevo-Signature: t=1750000000,v1=<hmac-sha256>
Virevo-Event-Type: payment.succeeded
{
"id": "evt_…",
"type": "payment.succeeded",
"created_at": "2026-06-24T09:01:00.000Z",
"data": { "payment": {
"id": "b3f1…", "status": "succeeded",
"amount_cents": 250000, "currency": "EUR", "reference": "CMD-1042"
} }
}
La signature est un HMAC-SHA256 de "{t}.{corps_brut}" avec
votre secret. Recalculez-la et comparez à v1 ; rejetez si
l'écart de temps dépasse 5 minutes (anti-rejeu). L'en-tête peut contenir
plusieurs v1 (pendant une rotation de
secret, cf. §5.1) : acceptez si l'un d'eux correspond.
PHP (WordPress / WooCommerce) :
$payload = file_get_contents('php://input');
$sig = $_SERVER['HTTP_VIREVO_SIGNATURE'] ?? '';
$t = null; $sigs = [];
foreach (explode(',', $sig) as $part) { // t=…,v1=…,v1=…
[$k, $v] = array_pad(explode('=', $part, 2), 2, '');
if (trim($k) === 't') $t = (int) trim($v);
elseif (trim($k) === 'v1') $sigs[] = trim($v);
}
$expected = hash_hmac('sha256', $t . '.' . $payload, $secret);
$ok = false;
foreach ($sigs as $v1) { if (hash_equals($expected, $v1)) { $ok = true; break; } }
if (!$ok || $t === null || abs(time() - $t) > 300) {
http_response_code(400); exit;
}
$event = json_decode($payload, true);
// $event['data']['payment']['reference'] → valider la commande
Node.js :
import { createHmac, timingSafeEqual } from "node:crypto";
function verify(secret, header, rawBody) {
let t = NaN; const sigs = [];
for (const kv of header.split(",")) { // t=…,v1=…,v1=…
const i = kv.indexOf("="); if (i < 0) continue;
const k = kv.slice(0, i).trim(), v = kv.slice(i + 1).trim();
if (k === "t") t = Number(v); else if (k === "v1") sigs.push(v);
}
const expected = createHmac("sha256", secret)
.update(`${t}.${rawBody}`).digest("hex");
const eb = Buffer.from(expected);
const ok = sigs.some((v1) => v1.length === expected.length &&
timingSafeEqual(eb, Buffer.from(v1)));
return ok && Number.isFinite(t) && Math.abs(Date.now() / 1000 - t) <= 300;
}
2xx rapidement. En cas d'erreur ou de timeout, Virevo réessaie (jusqu'à 6 fois, délai croissant).
Depuis le dashboard → Développeurs, le bouton
« Renouveler le secret » génère un nouveau whsec_….
L'ancien reste valide 24 h : pendant cette fenêtre, Virevo
signe chaque livraison avec les deux secrets (deux
v1 dans l'en-tête). Vous pouvez donc déployer le nouveau
secret sans aucune livraison perdue, du moment que votre vérification
accepte l'un des v1 (code ci-dessus). Passé 24 h, seul le
nouveau secret signe.
Détail de chaque endpoint (paramètres, corps, réponses, authentification) : Référence API.