API

Paiement en magasin : Local API

Présentation

La Local API permet à votre application de caisse de piloter un terminal Yavin via le réseau local : lancer un paiement, imprimer ou partager un ticket, annuler ou interrompre une transaction. Choisissez-la lorsque le logiciel de caisse et le terminal sont sur des appareils différents mais partagent le même réseau.

En bref

URL de basehttp://<LOCAL_IP>:16125/localapi/v4
AuthentificationAucun sur l'API elle-même : le marchand doit être connecté à Yavin Pay avec ses identifiants My Yavin (les terminaux peuvent être préconfigurés par notre équipe d'onboarding)
Convention de nommagecamelCase pour tous les champs, sauf les entrées de tax_breakdown qui sont en snake_case
Version actuellev4
Remise des résultatsSynchrone : la réponse HTTP contient le résultat de la transaction

Endpoints

EndpointMéthodeUsage
/pingGETVérifier la connectivité et la configuration
/paymentPOSTDémarrer une transaction de débit ou de remboursement
/printPOSTImprimer un contenu libre (ticket, facture)
/share-receiptPOSTPartager un ticket par SMS, e-mail ou impression
/reversalPOSTAnnuler une transaction récente (de moins de 16 heures)
/abortPOSTInterrompre le paiement en cours

Versions

Version de l'APIDernière mise à jour
v429/04/2026
v102/05/2022

Avant de commencer

Connexion

ParamètreValeur
RéseauMême réseau local que votre logiciel de caisse. Ce réseau doit avoir un accès à internet pour approuver les transactions
AdresseL'IP locale du terminal ou, de préférence, Network Service Discovery (compatible Apple Bonjour), qui résiste aux changements d'IP. Voir Add on: Protocole Bonjour
PortToujours 16125 dans l'URL (facile à retenir : P=16, A=1, Y=25)
ProtocoleHTTP par défaut, ce qui suffit pour un réseau sécurisé entre la caisse et le terminal. Pour HTTPS et la signature des réponses, voir Add on: Security, signature and HTTPS
DeviseCelle configurée sur le profil du marchand dans la base de données Yavin. Devises prises en charge actuellement : EUR, CHF, GBP

HTTPS et la signature sont tous deux conditionnels : HTTPS nécessite que le terminal ait récupéré son certificat, et les réponses ne sont signées que si la signature est activée pour votre entreprise.

Réponses

  • Chaque endpoint de cette page renvoie un corps JSON avec un champ status : ok en cas de succès, ko en cas d'échec
  • Les erreurs applicatives sont renvoyées avec HTTP 200 et {"status": "ko", "message": "..."}. Les messages d'erreur sont cités tels quels sous chaque endpoint
  • Un corps JSON mal formé est rejeté avec un HTTP 400 ou 500 sans corps JSON : vérifiez le statut HTTP avant d'analyser la réponse
  • Les clés dont la valeur est null sont omises des réponses : votre parseur doit tolérer l'absence de clés
  • Les endpoints de paiement renvoient l'objet Transaction, documenté à la fin de cette page avec les autres objets partagés

Délais d'expiration

Un paiement dispose d'une fenêtre de 120 secondes entre la réception de la requête et la lecture réussie de la carte, répartie en deux phases :

  1. Jusqu'à 60 secondes pour les écrans facultatifs (pourboires, référence, vérification). Si cette phase expire, la transaction est interrompue.
  2. Jusqu'à 60 secondes pour la lecture de la carte elle-même.

Timeout à définir côté client : 125 secondes pour une utilisation classique du terminal, 62 secondes pour une utilisation en borne (écrans optionnels désactivés) et pour les remboursements.

Idempotence

Envoyez un idempotentUuid à chaque requête de paiement, un par tentative de paiement. Voir Gestion de l'IdempotentUuid.

Le terminal garde une requête de paiement ouverte jusqu'à 15 minutes. Si votre timeout côté client expire, renvoyez la même requête avec le même idempotentUuid : si le paiement est toujours en cours, la nouvelle requête s'y rattache et renvoie son résultat.


Ping du terminal

GEThttp://<LOCAL_IP>:16125/localapi/v4/ping

Vérifie votre configuration. Une bonne pratique consiste à ajouter un bouton TEST dans l'écran de paramètres de votre logiciel de caisse, qui appelle cette route et affiche le résultat.

Paramètres

showMessageBooleanpar défaut false
true : affiche « Hello there » sur le terminal. false : rien n'est affiché

Requête

curl -X GET 'http://<LOCAL_IP>:16125/localapi/v4/ping'

Réponse

JSON
{ "status": "ok" }

Lancer une transaction de débit

POSThttp://<LOCAL_IP>:16125/localapi/v4/payment

Lance un paiement par débit sur le terminal. Indiquez le montant et les paramètres facultatifs ; le terminal gère le déroulement du paiement et renvoie le résultat de manière synchrone.

Paramètres

amountIntegerrequis
Montant en centimes, doit être supérieur à 0
transactionTypeStringpar défaut debit
Utilisez debit. Les valeurs sont strictes (debit ou refund) : toute autre valeur, y compris credit, est traitée silencieusement comme un débit
idempotentUuidString
Identifiant unique de la tentative de paiement. Si le terminal connaît une transaction avec cet UUID (dernières 24 h), il renvoie cette transaction au lieu d'en démarrer une nouvelle. Une transaction ko est renvoyée telle quelle : générez un nouvel UUID pour réessayer. Si vous n'en fournissez pas, Yavin en génère un en interne, ce qui ne protège pas votre logiciel de caisse contre une double soumission
cartIdString
Votre numéro de commande, affiché dans le backoffice MyYavin pour relier une transaction à une commande
customerCustomer
Informations client associées à la transaction
Afficher les paramètres de Customer
customer.firstNameString
Prénom
customer.lastNameString
Nom
customer.emailString
E-mail
customer.phoneString
Format international commençant par + (par ex. +33612345678)
customer.birthDateString
Date de naissance
enableGiftScreenBoolean
null (par défaut) : la configuration des pourboires du terminal s'applique. Une valeur non nulle la remplace pour cette transaction : true affiche l'écran des pourboires, false l'ignore
acceptedPaymentAcceptedPaymentpar défaut {"acceptedMediumType":"all"}
Restreint les moyens de paiement acceptés par le terminal pour cette transaction. Voir l'objet AcceptedPayment à la fin de cette page
Afficher les paramètres de AcceptedPayment
acceptedPayment.acceptedMediumTypeStringpar défaut all
all : tous les moyens de paiement configurés sur le terminal. lunch_vouchers_only : cartes titres-restaurant uniquement. bank_cards_only : cartes bancaires uniquement
giftAmountIntegerpar défaut 0
Pourboire ou don en centimes, si le pourboire a été sélectionné côté logiciel de caisse
receiptTicketReceiptTicket
Contenu du ticket imprimé avec le ticket carte
Afficher les paramètres de ReceiptTicket
receiptTicket.dataStringrequis
Contenu à imprimer
receiptTicket.formatStringpar défaut text
Format du contenu
receiptTicket.tax_breakdownArray
Tableau d'objets Tax, un par taux de taxe
referenceString
Serveur ou personne qui traite la transaction
vendorVendor
Nom et version de votre logiciel, utiles pour le support et le débogage
Afficher les paramètres de Vendor
vendor.softwareNameString
Nom du logiciel de caisse
vendor.softwareVersionString
Version du logiciel de caisse, utile pour suivre et identifier rapidement les bugs
checkoutExternalIdString
Identifiant d'encaissement unique pour le marchand, obligatoire dès qu'un champ de commande externe ci-dessous est envoyé. Il doit être unique : la requête est rejetée si une transaction ok terminée utilise déjà cette valeur. Envoyez donc une valeur différente pour chaque transaction d'un paiement fractionné
externalTableNumberString
Numéro de table. Utilisé uniquement avec checkoutExternalId
externalOrderNumberString
Numéro de commande lisible, affiché au marchand et au client. Utilisé uniquement avec checkoutExternalId
externalOrderIdString
Identifiant technique unique de la commande dans votre logiciel de caisse, pour le rapprochement. Utilisé uniquement avec checkoutExternalId

Requête

{
  "amount": 1000,
  "transactionType": "debit",
  "idempotentUuid": "2f1c2e2a-6c21-4a4b-9c2b-9f6f2c8e9b51",
  "vendor": {
    "softwareName": "MyPOS",
    "softwareVersion": "1.0"
  },
  "receiptTicket": {
    "data": "This is the receipt ticket\nto print",
    "format": "text"
  },
  "customer": {
    "firstName": "John",
    "lastName": "Doe",
    "email": "john@yavin.com"
  },
  "acceptedPayment": {
    "acceptedMediumType": "all"
  },
  "checkoutExternalId": "6843z9fgved8",
  "externalTableNumber": "54",
  "externalOrderNumber": "642558",
  "externalOrderId": "14763642558"
}

Réponse

JSON
{
  "amount": 1000,
  "appVersion": "3.2.8",
  "cardToken": "1234567890",
  "clientCardTicket": "...",
  "currencyCode": "EUR",
  "giftAmount": 0,
  "scheme": "CB",
  "status": "ok",
  "transactionId": "xPUyi4fmdibD",
  "transactionType": "debit"
}

Lancer une transaction de remboursement

POSThttp://<LOCAL_IP>:16125/localapi/v4/payment

Recrédite des fonds sur la carte du client, sur le même endpoint /payment, avec transactionType défini sur refund. Il n'y a aucun écran facultatif ; le délai d'expiration recommandé côté client est donc de 62 secondes.

Paramètres

amountIntegerrequis
Montant à recréditer, en centimes ; doit être positif
transactionTypeStringrequis
Doit être défini sur refund. Si vous l'omettez ou envoyez une autre valeur, telle que credit, un débit est lancé
idempotentUuidString
Identifiant unique de la tentative de remboursement. Si le terminal connaît une transaction avec cet UUID (dans les dernières 24 h), il renvoie cette transaction au lieu d'en démarrer une nouvelle. Une transaction ko est renvoyée telle quelle : générez un nouvel UUID pour réessayer. Si vous n'en fournissez pas, Yavin en génère un en interne, ce qui ne protège pas votre logiciel de caisse contre une double soumission
cartIdString
Votre numéro de commande, affiché dans le backoffice MyYavin pour relier une transaction à une commande
customerCustomer
Informations client associées à la transaction
Afficher les paramètres de Customer
customer.firstNameString
Prénom
customer.lastNameString
Nom
customer.emailString
E-mail
customer.phoneString
Format international commençant par + (par ex. +33612345678)
customer.birthDateString
Date de naissance
enableGiftScreenBoolean
Sans effet sur les remboursements : les écrans facultatifs (pourboire, référence, récapitulatif) sont désactivés
giftAmountIntegerpar défaut 0
Pourboire ou don en centimes, si le pourboire a été sélectionné côté logiciel de caisse
receiptTicketReceiptTicket
Contenu du ticket imprimé avec le ticket carte
Afficher les paramètres de ReceiptTicket
receiptTicket.dataStringrequis
Contenu à imprimer
receiptTicket.formatStringpar défaut text
Format du contenu
receiptTicket.tax_breakdownArray
Tableau d'objets Tax, un par taux de taxe
referenceString
Serveur ou personne qui traite la transaction
vendorVendor
Nom et version de votre logiciel, utiles pour le support et le débogage
Afficher les paramètres de Vendor
vendor.softwareNameString
Nom du logiciel de caisse
vendor.softwareVersionString
Version du logiciel de caisse, utile pour suivre et identifier rapidement les bugs
checkoutExternalIdString
Identifiant d'encaissement unique pour le marchand, obligatoire dès qu'un champ de commande externe ci-dessous est envoyé. Il doit être unique : la requête est rejetée si une transaction ok terminée utilise déjà cette valeur. Envoyez donc une valeur différente pour chaque transaction d'un paiement fractionné
externalTableNumberString
Numéro de table. Utilisé uniquement avec checkoutExternalId
externalOrderNumberString
Numéro de commande lisible, affiché au marchand et au client. Utilisé uniquement avec checkoutExternalId
externalOrderIdString
Identifiant technique unique de la commande dans votre logiciel de caisse, pour le rapprochement. Utilisé uniquement avec checkoutExternalId

Requête

{
  "amount": 1000,
  "transactionType": "refund",
  "idempotentUuid": "8a4d1f0b-2e57-4c1a-b3d9-1c7e5f2a6d40",
  "vendor": {
    "softwareName": "MyPOS",
    "softwareVersion": "1.0"
  },
  "receiptTicket": {
    "data": "This is the receipt ticket\nto print",
    "format": "text"
  }
}

Réponse

JSON
{
  "amount": 1000,
  "appVersion": "3.2.8",
  "clientCardTicket": "...",
  "currencyCode": "EUR",
  "giftAmount": 0,
  "scheme": "CB",
  "status": "ok",
  "transactionId": "kQm2Vw9pLxTc",
  "transactionType": "refund"
}

Partager un ticket

POSThttp://<LOCAL_IP>:16125/localapi/v4/share-receipt

Partage un ticket par SMS, e-mail ou impression. Le terminal demande les informations du destinataire (numéro de téléphone ou e-mail).

Paramètres

receiptTicketReceiptTicketrequis
Ticket à partager
Afficher les paramètres de ReceiptTicket
receiptTicket.dataStringrequis
Contenu à imprimer
receiptTicket.formatStringpar défaut text
Format du contenu
receiptTicket.tax_breakdownArray
Tableau d'objets Tax, un par taux de taxe
transactionIdStringrequis
Transaction liée au ticket
mediumStringrequis
L'une des valeurs yavin, sms, email, print, en minuscules (SMS est rejeté). Avec yavin, le ticket est enregistré et partagé selon les préférences de notification de l'utilisateur

Requête

{
  "receiptTicket": {
    "data": "This is the receipt ticket\nto print",
    "format": "text"
  },
  "transactionId": "fsOv53g7wxZ",
  "medium": "email"
}

Réponse

status = ok (avec un message facultatif) lorsque le ticket a été partagé. En cas d'échec, status = ko avec l'une des valeurs suivantes :

  • Parameter 'transactionId' is missing or invalid : transactionId null ou introuvable
  • Parameter 'receiptTicket' is missing or invalid : receiptTicket null, data null, ou format différent de text
  • Parameter 'medium' is missing or invalid : medium est manquant, ou n'est pas print, email, sms ou yavin en minuscules
  • Error: bad request : requête mal formatée

Annuler une transaction

POSThttp://<LOCAL_IP>:16125/localapi/v4/reversal

Annule une transaction récente.

Conditions d'annulation. La transaction d'origine est un débit ok traité sur le même terminal que celui qui émet l'annulation, il y a moins de 16 heures (heure du terminal), et le montant de l'annulation est égal au montant total d'origine, pourboire inclus (amount + giftAmount).

Paramètres

amountIntegerrequis
Montant en centimes, doit être égal au montant total d'origine (amount • giftAmount)
initialTransactionIdStringrequis
Transaction à annuler

Requête

{
  "amount": 1000,
  "initialTransactionId": "xPUyi4fmdibD"
}

Réponse

status = ok avec reversalTransactionId (la nouvelle transaction d'annulation) et initialTransactionId (la transaction annulée). En cas d'échec, status = ko avec l'un des messages suivants, toujours préfixés par Error : :

  • Error : Transaction ID is mandatory : initialTransactionId manquant
  • Error : Transaction not found for ID: <transactionId> : transaction inconnue sur ce terminal
  • Error : Amount mismatch : le montant diffère du montant total d'origine (amount + giftAmount)
  • Error : Transaction has already been reversed
  • Error : Cannot reverse this Transaction or time window expired : la transaction n'est pas une transaction de débit ok ou VAD, ou date de plus de 16 heures
  • Error : No suitable gateway found to handle reversal
  • Error : An unexpected error occurred. Please try again later. : erreur générique

Interrompre une transaction

POSThttp://<LOCAL_IP>:16125/localapi/v4/abort

Interrompt le paiement en cours : tous les écrans de paiement sont fermés et le terminal revient à son écran principal.

Évitez d'interrompre pendant la phase de lecture de la carte. L'écran de la passerelle de paiement peut se fermer de manière inattendue et les informations de paiement risquent de ne pas être transmises correctement, ce qui peut entraîner des incohérences de données.

Quand l'interruption peut agir. L'interruption agit à partir de la réception de la requête de paiement et jusqu'à ce que le terminal passe la main à l'écran bancaire.

  • Pour un paiement sans écrans facultatifs (pourboire, référence, récapitulatif), ce passage de relais a lieu environ 1 à 2 secondes après l'appel à /payment
  • Passé ce stade, l'interruption ne peut plus arrêter le paiement, même si aucune carte n'a encore été présentée : le client peut toujours présenter une carte et finaliser le paiement au montant demandé

Paramètres

idempotentUuidString
UUID de la tentative de paiement à interrompre

Requête

{
  "idempotentUuid": "2f1c2e2a-6c21-4a4b-9c2b-9f6f2c8e9b51"
}

Réponse

status = ok lorsque la transaction est interrompue.

La réponse est envoyée une fois le résultat connu : si le paiement ne peut plus être interrompu, elle n'arrive qu'après la fin du paiement, ce qui peut prendre plusieurs dizaines de secondes, le temps que le terminal attende la carte et affiche l'écran de résultat.

En cas d'échec (transaction toujours en cours ou rien à interrompre), status = ko avec l'une des valeurs suivantes :

  • Abort not possible : le paiement n'a pas pu être interrompu et est allé à son terme. La réponse à la /payment initiale fait alors foi : un status = ok signifie que le client a été débité
  • Nothing to abort : aucun paiement n'est en cours
  • Abort is not allowed : le paiement en cours n'a pas été lancé via la Local API
  • A transaction with the given idempotentUuid is already in progress (dans le message réel, idempotentUuid est entouré de backticks) : la requête tente d'interrompre une autre transaction
  • Error while responding to local API: <cause> : erreur interne Yavin Pay

Après une demande d'interruption. Attendez toujours la réponse à la demande d'interruption avant de considérer le paiement comme annulé.

  • Sur ko, attendez la réponse à la /payment initiale et traitez-la : sur ok, le client a été débité, et la commande doit en tenir compte ou un remboursement doit être déclenché
  • Ne lancez pas de nouveau paiement pour la même commande avant l'arrivée de cette réponse : il serait rejeté avec A transaction with the given idempotentUuid is already in progress.

L'objet Transaction

Renvoyé par les endpoints de paiement. Les champs provenant de votre requête sont renvoyés tels quels. Les clés dont la valeur est null sont omises : tolérez les clés manquantes. Un paiement refusé a status = ko et n'a pas de champ message.

Attributs

statusString
ok ou ko
transactionIdString
Identifiant côté serveur
amountInteger
Montant en centimes, hors giftAmount. Le client est débité de la somme de amount et giftAmount (égale à total_amount dans le payload du webhook)
giftAmountInteger
Pourboire ou don en centimes
currencyCodeString
Code ISO 4217
transactionTypeString
En minuscules : debit ou refund. Tolérez les autres valeurs (par ex. na)
appVersionString
Version de l'application Yavin Pay
cardTokenString
Token unique de la carte du client
clientCardTicket / merchantCardTicketString
Tickets de carte du client et du marchand
paymentApplicationString
AMEX, ANCV, CONECS_CONTACT, CONECS_CONTACTLESS, EMV_CONTACT, EMV_CONTACTLESS, EMV_MOTO, EMV_PAYMENT_LINK, RESTOFLASH, DISCOVER, CUP
schemeString
Réseau d'acceptation (par ex. VISA)
issuerString
Émetteur de la carte (par ex. CB, VISA, MASTERCARD)
idempotentUuidString
UUID issu de la requête
cartId, reference, customer
Renvoyé tel quel depuis la requête
checkoutExternalId, externalTableNumber, externalOrderNumber, externalOrderIdString
Renvoyé tel quel depuis la requête

JSON
{
  "status": "ok",
  "transactionId": "xPUyi4fmdibD",
  "amount": 1000,
  "giftAmount": 0,
  "currencyCode": "EUR",
  "transactionType": "debit",
  "appVersion": "3.2.8",
  "cardToken": "1234567890",
  "clientCardTicket": "...",
  "merchantCardTicket": "...",
  "paymentApplication": "EMV_CONTACTLESS",
  "scheme": "CB",
  "issuer": "VISA",
  "idempotentUuid": "2f1c2e2a-6c21-4a4b-9c2b-9f6f2c8e9b51",
  "cartId": "ORDER-2026-000123",
  "reference": "Luke",
  "customer": {
    "firstName": "John",
    "lastName": "Doe",
    "email": "john@yavin.com"
  },
  "checkoutExternalId": "6843z9fgved8",
  "externalTableNumber": "54",
  "externalOrderNumber": "642558",
  "externalOrderId": "14763642558"
}

L'objet Customer

Facultatif sur /payment. Informations client associées à la transaction et renvoyées dans la réponse. Elles ne sont pas utilisées par /share-receipt, où le terminal demande toujours le destinataire.

Attributs

firstNameString
Prénom
lastNameString
Nom
emailString
E-mail
phoneString
Format international commençant par + (par ex. +33612345678)
birthDateString
Date de naissance

JSON
{
  "customer": {
    "firstName": "John",
    "lastName": "Doe",
    "phone": "+33612345678",
    "email": "john@yavin.com"
  }
}

L'objet ReceiptTicket

Contenu imprimé avec le ticket carte sur /payment, ou partagé sur /share-receipt.

Attributs

dataStringrequis
Contenu à imprimer
formatStringpar défaut text
Format du contenu
tax_breakdownArray
Tableau d'objets Tax, un par taux de taxe

JSON
{
  "receiptTicket": {
    "data": "Receipt ticket here to print if needed",
    "format": "text"
  }
}

L'objet Tax

Ventilation facultative associée à un ReceiptTicket, sous la clé tax_breakdown, avec une entrée par taux de taxe.

La clé est tax_breakdown (et non tax), et ses entrées sont en snake_case.

Attributs

tax_amountInteger
Montant de taxe calculé en centimes, à partir de tax_percentage appliqué au montant de la transaction
tax_percentageInteger
Pourcentage appliqué au montant (par ex. 20 pour 20 %)

JSON
{
  "tax_breakdown": [
    { "tax_amount": 167, "tax_percentage": 20 },
    { "tax_amount": 50, "tax_percentage": 10 }
  ]
}

L'objet Vendor

Identifie votre logiciel de caisse. Facultatif partout, mais fortement recommandé : il permet à notre équipe support de remonter d'un problème à une intégration et une version précises.

Attributs

softwareNameString
Nom du logiciel de caisse
softwareVersionString
Version du logiciel de caisse, utile pour suivre et identifier rapidement les bugs

JSON
{
  "vendor": {
    "softwareName": "MyPOS",
    "softwareVersion": "1.0"
  }
}

L'objet AcceptedPayment

Facultatif sur /payment pour les transactions debit. Restreint les moyens de paiement acceptés par le terminal : le client ne peut pas payer avec un moyen exclu.

  • Usage typique : paiements fractionnés où une première transaction est réglée uniquement en titres-restaurant et une seconde transaction couvre le reste uniquement par carte bancaire
  • Si vous envoyez un checkoutExternalId, utilisez une valeur différente pour chaque transaction : une valeur déjà utilisée par une transaction ok est rejetée
  • Le terminal ne fractionne jamais un paiement de lui-même : si le montant demandé dépasse le plafond de la carte (par ex. le plafond des titres-restaurant), la transaction est entièrement refusée (statut ko), sans approbation partielle

Attributs

acceptedMediumTypeStringpar défaut all
all : tous les moyens de paiement configurés sur le terminal. lunch_vouchers_only : cartes titres-restaurant uniquement. bank_cards_only : cartes bancaires uniquement

JSON
{
  "acceptedPayment": {
    "acceptedMediumType": "lunch_vouchers_only"
  }
}