API

Paiement de serveur à serveur

Payez un checkout entièrement depuis votre serveur : aucun client sur la page, aucun navigateur, aucun lien de paiement. Vous créez un checkout, puis vous appelez un endpoint qui débite une carte et renvoie le checkout réglé. Il existe deux façons d'indiquer la carte : une carte que Yavin a déjà enregistrée pour vous, ou les données d'une carte que vous détenez.

Activé par Yavin. Le débit d'une carte enregistrée nécessite que la fonctionnalité de cartes enregistrées soit activée sur votre compte. L'envoi des données de carte nécessite une autorisation distincte et place vos serveurs dans le périmètre PCI DSS. Les deux sont refusés tant que Yavin ne les a pas activés. Si vous devez seulement encaisser un paiement auprès d'un client, utilisez plutôt Intégration Drop-in du paiement en ligne : les données de carte n'atteignent alors jamais vos serveurs.


Choisir la forme

FormeVous envoyezPrérequis du compte
Carte enregistréecustomer_card_id, l'identifiant d'une carte que Yavin a enregistrée avec le consentement du titulaireLa fonctionnalité de cartes enregistrées. Le flux complet, y compris la façon dont la carte est enregistrée, est décrit dans Enregistrer une carte et la débiter plus tard
Données de cartecard_number, expiry_date et cvv, pour un paiement uniqueL'autorisation d'envoyer des données de carte. Rien n'est conservé

URL de base : production https://api.yavin.com/api/v5/ecommerce, sandbox https://api.sandbox.yavin.com/api/v5/ecommerce. Authentification : votre clé d'API dans l'en-tête Yavin-Secret, comme pour tous les appels e-commerce.


Fonctionnement

Le débit est effectué pendant que votre appel est ouvert. Il n'y a ni redirection, ni page 3-D Secure, ni URL de retour.


Étape 1 - Créer le checkout

Le checkout porte le montant. Créez-le avec POST /checkouts/, le même appel que pour le widget de carte.

  • amount est exprimé en centimes, minimum 100
  • Donnez à chaque checkout son propre checkout_external_id : un identifiant est réservé définitivement, même par un checkout annulé
  • Conservez la capture immédiate par défaut. Un checkout créé avec is_instant_capture: false ne peut pas être payé depuis votre serveur
  • Conservez votre webhook_url : il reçoit payment_received lorsque le débit réussit

cURL
POST https://api.yavin.com/api/v5/ecommerce/checkouts/
Yavin-Secret: <your yavin_secret_key>
Content-Type: application/json

{ "checkout_external_id": "invoice_2041",
  "amount": 4200,
  "webhook_url": "https://shop.example.com/hooks/yavin" }
JSON
// 201 Created
{ "checkout_token": "Zk9q...",
  "payment_link": "https://..." }

Étape 2 - Payer le checkout

POST https://api.yavin.com/api/v5/ecommerce/checkouts/{checkout_token}/pay/

En-têtes : Yavin-Secret, Content-Type: application/json, et éventuellement X-Request-Id, une valeur de votre choix que Yavin enregistre afin de pouvoir retracer un appel lorsque vous contactez le support.

Envoyez une seule des deux formes. Les mélanger est refusé.

Forme A - une carte enregistrée

customer_card_idString (UUID)requis
Le stored_card.id d'une carte enregistrée de votre compte

La carte doit avoir été enregistrée avec le consentement du titulaire, être activée et non expirée, et le débit doit respecter le plafond de dépenses de votre compte. Voir Enregistrer une carte et la débiter plus tard.

cURL
POST https://api.yavin.com/api/v5/ecommerce/checkouts/Zk9q.../pay/
Yavin-Secret: <your yavin_secret_key>
Content-Type: application/json

{ "customer_card_id": "9b2f4c1e-7a3d-4f55-8a61-2d9c3b7e1a10" }

Forme B - données de carte

card_numberStringrequis
Le numéro de carte, uniquement des chiffres
expiry_dateStringrequis
MMYY, par exemple 1228 pour décembre 2028
cvvStringrequis
Le code de vérification de la carte

Les trois champs sont obligatoires ensemble. Ce qu'il faut savoir sur cette forme :

  • Un paiement, rien n'est conservé. La carte n'est pas enregistrée et la transaction n'a pas de stored_card. Pour conserver une carte pour plus tard, utilisez le flux de carte enregistrée
  • Pas de titulaire, donc pas de 3-D Secure. Le paiement demande à l'émetteur de ne pas le soumettre à authentification. Si l'émetteur exige d'authentifier le titulaire, le paiement ne peut pas aboutir et est refusé avec challenge_not_completable. Pour une telle carte, utilisez le widget de carte, où le client peut s'authentifier
  • Ne journalisez et ne conservez jamais les données de carte. Leur protection au titre de PCI DSS vous incombe dès qu'elles atteignent votre serveur

Dans les deux formes, la carte est débitée de la totalité du montant restant à payer sur le checkout.

cURL
POST https://api.yavin.com/api/v5/ecommerce/checkouts/Zk9q.../pay/
Yavin-Secret: <your yavin_secret_key>
Content-Type: application/json

{ "card_number": "4242424242420042",
  "expiry_date": "1228",
  "cvv": "123" }

Réponse

La réponse est le Paiement en ligne : E-commerce API, renvoyé directement et non encapsulé dans data. C'est le même objet que celui que reçoit votre webhook_url sous la forme payment_received. stored_card vaut null pour une carte à usage unique, et contient la carte enregistrée pour la forme A.

Définissez un timeout côté client d'au moins 30 secondes et ne relancez jamais un paiement à l'aveugle. Si vous n'avez reçu aucune réponse, lisez d'abord le checkout avec /get_cart_information/ : le paiement a peut-être abouti.


JSON
// 200 OK, the Checkout object
{ "checkout_external_id": "invoice_2041",
  "payment_link": "https://...",
  "requested_amount": 4200,
  "asked_amount": 4200,
  "paid_amount": 4200,
  "service_fee": 0,
  "gift_amount": 0,
  "status": "ok",
  "transactions": [
    { "transaction_id": "trs_91c4d0aa",
      "total_amount": 4200,
      "gift_amount": 0,
      "currency_code": "EUR",
      "date_of_payment": "2026-11-20 09:12:44",
      "gateway": "NEPTING_ECOMMERCE",
      "issuer": "VISA",
      "pan": "4242********0042",
      "status": "ok",
      "stored_card": null } ] }

Étape 3 - Confirmer

La réponse 200 et le webhook payment_received constituent votre confirmation, comme pour tout autre paiement. Pour réconcilier un checkout plus tard, ou après une réponse peu claire :

Remettez les biens en vous basant sur le status du checkout (ok) et paid_amount, jamais sur l'absence d'erreur.


cURL
POST https://api.yavin.com/api/v5/ecommerce/get_cart_information/
{ "checkout_external_id": "invoice_2041" }

Erreurs

Chaque refus renvoie un corps de même forme. code est la valeur stable sur laquelle effectuer vos branchements, detail est un texte en anglais destiné à vos logs, et errors indique les champs concernés en cas d'échec de validation. transaction_id est présent lorsque la tentative a atteint la passerelle de paiement.

La requête ou le checkout

codeHTTPSignification et action à mener
invalid_payload422Le corps ne correspond pas exactement à un seul formulaire : ni customer_card_id ni les trois champs de carte, les deux ensemble, ou un champ de carte manquant. errors indique les champs concernés.
card_data_not_allowed422Formulaire B sur un compte sans l'autorisation d'envoyer des données de carte (errors indique card_number). Contactez Yavin, ou utilisez le formulaire de carte enregistrée ou le widget.
checkout_not_found404Aucun checkout avec ce token sur votre compte.
checkout_cancelled409Le checkout a été annulé. Créez-en un nouveau.
checkout_already_paid409Le checkout est déjà payé. Ne débitez pas à nouveau.
checkout_not_payable409Le checkout n'attend pas de paiement.
attempt_in_progress409Une autre tentative de paiement est en cours sur ce checkout. Patientez, puis consultez le checkout avant de réessayer.
checkout_amount_changed409Le montant à payer a changé pendant l'appel. Consultez le checkout et décidez de la suite.
checkout_requires_capture422Le checkout utilise la capture différée. Créez-en un avec la capture immédiate par défaut.
checkout_version_incompatible422Ce checkout ne peut pas être payé depuis votre serveur. Créez-le avec POST /checkouts/.

La carte enregistrée (formulaire A)

codeHTTPSignification et action à mener
card_not_found404Aucune carte enregistrée avec cet identifiant sur votre compte.
card_not_consented422La carte n'a jamais été enregistrée avec le consentement du titulaire.
card_disabled422La carte a été désactivée.
card_expired422Le mois d'expiration de la carte est dépassé. Demandez une nouvelle carte au client.
amount_over_limit422Ce débit ferait dépasser au client le plafond de dépenses sur cartes enregistrées de votre compte.
amount_invalid422Le montant à débiter n'est pas supérieur à zéro.
company_not_configured422Le compte n'est pas configuré pour débiter des cartes enregistrées. Contactez Yavin.

Le paiement a été tenté

codeHTTPSignification et action à mener
invalid_auth422Les données de carte n'ont pas été acceptées comme valides (formulaire B). Rien n'a été débité : corrigez-les et renvoyez la requête.
payment_declined402L'émetteur a refusé le paiement. Rien n'a été débité. Proposez un autre moyen de paiement.
insufficient_funds402Le solde de la carte est insuffisant. Rien n'a été prélevé.
challenge_not_completable402L'émetteur exige une authentification du titulaire de la carte, ce qui est impossible ici. Rien n'a été débité. Utilisez le widget de carte pour cette carte.
gateway_connection_error503La passerelle de paiement est injoignable, donc rien n'a été débité. Vous pouvez réessayer sans risque.
acquirer_timeout504L'acquéreur n'a pas répondu dans le délai imparti. Le résultat est inconnu. Consultez le checkout avant de réessayer.
gateway_error502La passerelle a renvoyé une réponse dont Yavin n'a pas pu tirer de conclusion. Le résultat n'est pas certain. Consultez le checkout avant de réessayer.

Le code challenge_in_progress est rare : considérez le paiement comme non effectué et contactez le support si le problème persiste.

Un résultat inconnu n'est pas un échec. Après acquirer_timeout, gateway_error ou tout appel qui ne vous a donné aucune réponse, lisez le checkout avec /get_cart_information/ et consultez ses champs status et paid_amount avant de débiter à nouveau. Un checkout payé ne peut pas être payé deux fois, mais un débit rejoué sur un nouveau checkout peut débiter le client deux fois.


JSON
{ "detail": "The payment was declined.",
  "code": "payment_declined",
  "errors": {},
  "transaction_id": "trs_91c4d0aa" }

Nouvelles tentatives et idempotence

  • Un checkout ne peut être payé qu'une fois. Un second appel sur un checkout payé est refusé avec checkout_already_paid, c'est pourquoi le checkout est l'unité sur laquelle effectuer les nouvelles tentatives
  • Une seule tentative s'exécute à la fois sur un checkout : un appel effectué pendant qu'un autre est en cours reçoit attempt_in_progress
  • Après un refus où rien n'a été débité (payment_declined, insufficient_funds, invalid_auth, challenge_not_completable), le checkout reste payable et vous pouvez rappeler /pay/ dessus, avec la même carte ou une autre
  • Après un résultat peu clair, lisez d'abord le checkout. Ne créez un nouveau checkout que si le premier n'indique aucun paiement

Sandbox

Appelez api.sandbox.yavin.com avec votre clé sandbox : mêmes endpoints et mêmes codes, sans carte débitée ni mouvement d'argent. Les données de carte du formulaire B se comportent comme les cartes de test sandbox du widget de carte : consultez le tableau des cartes de test dans Intégration Drop-in du paiement en ligne. Utilisez n'importe quelle date d'expiration future et n'importe quel cvv à 3 chiffres. Une carte qui déclenche une authentification renforcée 3-D Secure dans le widget est refusée ici avec challenge_not_completable.