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
| Forme | Vous envoyez | Prérequis du compte |
|---|---|---|
| Carte enregistrée | customer_card_id, l'identifiant d'une carte que Yavin a enregistrée avec le consentement du titulaire | La 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 carte | card_number, expiry_date et cvv, pour un paiement unique | L'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.
amountest exprimé en centimes, minimum100- 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: falsene peut pas être payé depuis votre serveur - Conservez votre
webhook_url: il reçoitpayment_receivedlorsque le débit réussit
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" }// 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.
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.
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.
// 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.
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
| code | HTTP | Signification et action à mener |
|---|---|---|
invalid_payload | 422 | Le 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_allowed | 422 | Formulaire 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_found | 404 | Aucun checkout avec ce token sur votre compte. |
checkout_cancelled | 409 | Le checkout a été annulé. Créez-en un nouveau. |
checkout_already_paid | 409 | Le checkout est déjà payé. Ne débitez pas à nouveau. |
checkout_not_payable | 409 | Le checkout n'attend pas de paiement. |
attempt_in_progress | 409 | Une autre tentative de paiement est en cours sur ce checkout. Patientez, puis consultez le checkout avant de réessayer. |
checkout_amount_changed | 409 | Le montant à payer a changé pendant l'appel. Consultez le checkout et décidez de la suite. |
checkout_requires_capture | 422 | Le checkout utilise la capture différée. Créez-en un avec la capture immédiate par défaut. |
checkout_version_incompatible | 422 | Ce checkout ne peut pas être payé depuis votre serveur. Créez-le avec POST /checkouts/. |
La carte enregistrée (formulaire A)
| code | HTTP | Signification et action à mener |
|---|---|---|
card_not_found | 404 | Aucune carte enregistrée avec cet identifiant sur votre compte. |
card_not_consented | 422 | La carte n'a jamais été enregistrée avec le consentement du titulaire. |
card_disabled | 422 | La carte a été désactivée. |
card_expired | 422 | Le mois d'expiration de la carte est dépassé. Demandez une nouvelle carte au client. |
amount_over_limit | 422 | Ce débit ferait dépasser au client le plafond de dépenses sur cartes enregistrées de votre compte. |
amount_invalid | 422 | Le montant à débiter n'est pas supérieur à zéro. |
company_not_configured | 422 | Le compte n'est pas configuré pour débiter des cartes enregistrées. Contactez Yavin. |
Le paiement a été tenté
| code | HTTP | Signification et action à mener |
|---|---|---|
invalid_auth | 422 | Les 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_declined | 402 | L'émetteur a refusé le paiement. Rien n'a été débité. Proposez un autre moyen de paiement. |
insufficient_funds | 402 | Le solde de la carte est insuffisant. Rien n'a été prélevé. |
challenge_not_completable | 402 | L'é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_error | 503 | La passerelle de paiement est injoignable, donc rien n'a été débité. Vous pouvez réessayer sans risque. |
acquirer_timeout | 504 | L'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_error | 502 | La 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.
{ "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.