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 base | http://<LOCAL_IP>:16125/localapi/v4 |
| Authentification | Aucun 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 nommage | camelCase pour tous les champs, sauf les entrées de tax_breakdown qui sont en snake_case |
| Version actuelle | v4 |
| Remise des résultats | Synchrone : la réponse HTTP contient le résultat de la transaction |
Endpoints
| Endpoint | Méthode | Usage |
|---|---|---|
/ping | GET | Vérifier la connectivité et la configuration |
/payment | POST | Démarrer une transaction de débit ou de remboursement |
/print | POST | Imprimer un contenu libre (ticket, facture) |
/share-receipt | POST | Partager un ticket par SMS, e-mail ou impression |
/reversal | POST | Annuler une transaction récente (de moins de 16 heures) |
/abort | POST | Interrompre le paiement en cours |
Versions
| Version de l'API | Dernière mise à jour |
|---|---|
v4 | 29/04/2026 |
v1 | 02/05/2022 |
Avant de commencer
Connexion
| Paramètre | Valeur |
|---|---|
| Réseau | Même réseau local que votre logiciel de caisse. Ce réseau doit avoir un accès à internet pour approuver les transactions |
| Adresse | L'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 |
| Port | Toujours 16125 dans l'URL (facile à retenir : P=16, A=1, Y=25) |
| Protocole | HTTP 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 |
| Devise | Celle 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:oken cas de succès,koen 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 :
- Jusqu'à 60 secondes pour les écrans facultatifs (pourboires, référence, vérification). Si cette phase expire, la transaction est interrompue.
- 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
http://<LOCAL_IP>:16125/localapi/v4/pingVé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'(async () => {
const response = await fetch("http://<LOCAL_IP>:16125/localapi/v4/ping", {
method: "GET",
});
if (!response.ok) throw new Error(`Yavin API error ${response.status}`);
const data = await response.json();
console.log(data);
})();import requests
response = requests.get(
"http://<LOCAL_IP>:16125/localapi/v4/ping",
timeout=125,
)
response.raise_for_status()
data = response.json()Réponse
{ "status": "ok" }Lancer une transaction de débit
http://<LOCAL_IP>:16125/localapi/v4/paymentLance 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 CustomerMasquer les paramètres de Customer
customer.firstNameString- Prénom
customer.lastNameString- Nom
customer.emailStringcustomer.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 AcceptedPaymentMasquer 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 ReceiptTicketMasquer 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 VendorMasquer 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"
}curl -X POST 'http://<LOCAL_IP>:16125/localapi/v4/payment' \
-H 'Content-Type: application/json' \
-d '{
"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"
}'(async () => {
const response = await fetch("http://<LOCAL_IP>:16125/localapi/v4/payment", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
"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"
}),
});
if (!response.ok) throw new Error(`Yavin API error ${response.status}`);
const data = await response.json();
console.log(data);
})();import requests
headers = {
"Content-Type": "application/json",
}
payload = {
"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"
}
response = requests.post(
"http://<LOCAL_IP>:16125/localapi/v4/payment",
headers=headers,
json=payload,
timeout=125,
)
response.raise_for_status()
data = response.json()Réponse
{
"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
http://<LOCAL_IP>:16125/localapi/v4/paymentRecré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 CustomerMasquer les paramètres de Customer
customer.firstNameString- Prénom
customer.lastNameString- Nom
customer.emailStringcustomer.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 ReceiptTicketMasquer 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 VendorMasquer 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"
}
}curl -X POST 'http://<LOCAL_IP>:16125/localapi/v4/payment' \
-H 'Content-Type: application/json' \
-d '{
"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"
}
}'(async () => {
const response = await fetch("http://<LOCAL_IP>:16125/localapi/v4/payment", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
"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"
}
}),
});
if (!response.ok) throw new Error(`Yavin API error ${response.status}`);
const data = await response.json();
console.log(data);
})();import requests
headers = {
"Content-Type": "application/json",
}
payload = {
"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"
}
}
response = requests.post(
"http://<LOCAL_IP>:16125/localapi/v4/payment",
headers=headers,
json=payload,
timeout=125,
)
response.raise_for_status()
data = response.json()Réponse
{
"amount": 1000,
"appVersion": "3.2.8",
"clientCardTicket": "...",
"currencyCode": "EUR",
"giftAmount": 0,
"scheme": "CB",
"status": "ok",
"transactionId": "kQm2Vw9pLxTc",
"transactionType": "refund"
}Imprimer un ticket
http://<LOCAL_IP>:16125/localapi/v4/printImprime un contenu libre sur le terminal (facture, ticket, bon de cuisine), en texte brut (text) ou sous forme de commandes ESC/POS (escpos).
Paramètres
dataStringrequis- Contenu à imprimer
formatStringpar défaut text- text ou escpos
Requête
{
"data": "This is the text\nto print",
"format": "text"
}curl -X POST 'http://<LOCAL_IP>:16125/localapi/v4/print' \
-H 'Content-Type: application/json' \
-d '{
"data": "This is the text\nto print",
"format": "text"
}'(async () => {
const response = await fetch("http://<LOCAL_IP>:16125/localapi/v4/print", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
"data": "This is the text\nto print",
"format": "text"
}),
});
if (!response.ok) throw new Error(`Yavin API error ${response.status}`);
const data = await response.json();
console.log(data);
})();import requests
headers = {
"Content-Type": "application/json",
}
payload = {
"data": "This is the text\nto print",
"format": "text"
}
response = requests.post(
"http://<LOCAL_IP>:16125/localapi/v4/print",
headers=headers,
json=payload,
timeout=125,
)
response.raise_for_status()
data = response.json()Réponse
status = ok signifie que la requête d'impression a été acceptée, et non que le ticket a été imprimé : un terminal qui ne peut pas imprimer répond aussi ok. En cas d'échec, status = ko avec l'une des valeurs suivantes :
Parameter 'data' is missing or empty: champ data vide ou manquantWrong parameter 'format': le format n'est nitextniescpos
Annuler une transaction
http://<LOCAL_IP>:16125/localapi/v4/reversalAnnule 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"
}curl -X POST 'http://<LOCAL_IP>:16125/localapi/v4/reversal' \
-H 'Content-Type: application/json' \
-d '{
"amount": 1000,
"initialTransactionId": "xPUyi4fmdibD"
}'(async () => {
const response = await fetch("http://<LOCAL_IP>:16125/localapi/v4/reversal", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
"amount": 1000,
"initialTransactionId": "xPUyi4fmdibD"
}),
});
if (!response.ok) throw new Error(`Yavin API error ${response.status}`);
const data = await response.json();
console.log(data);
})();import requests
headers = {
"Content-Type": "application/json",
}
payload = {
"amount": 1000,
"initialTransactionId": "xPUyi4fmdibD"
}
response = requests.post(
"http://<LOCAL_IP>:16125/localapi/v4/reversal",
headers=headers,
json=payload,
timeout=125,
)
response.raise_for_status()
data = response.json()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 manquantError : Transaction not found for ID: <transactionId>: transaction inconnue sur ce terminalError : Amount mismatch: le montant diffère du montant total d'origine (amount+giftAmount)Error : Transaction has already been reversedError : 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 heuresError : No suitable gateway found to handle reversalError : An unexpected error occurred. Please try again later.: erreur générique
Interrompre une transaction
http://<LOCAL_IP>:16125/localapi/v4/abortInterrompt 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"
}curl -X POST 'http://<LOCAL_IP>:16125/localapi/v4/abort' \
-H 'Content-Type: application/json' \
-d '{
"idempotentUuid": "2f1c2e2a-6c21-4a4b-9c2b-9f6f2c8e9b51"
}'(async () => {
const response = await fetch("http://<LOCAL_IP>:16125/localapi/v4/abort", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
"idempotentUuid": "2f1c2e2a-6c21-4a4b-9c2b-9f6f2c8e9b51"
}),
});
if (!response.ok) throw new Error(`Yavin API error ${response.status}`);
const data = await response.json();
console.log(data);
})();import requests
headers = {
"Content-Type": "application/json",
}
payload = {
"idempotentUuid": "2f1c2e2a-6c21-4a4b-9c2b-9f6f2c8e9b51"
}
response = requests.post(
"http://<LOCAL_IP>:16125/localapi/v4/abort",
headers=headers,
json=payload,
timeout=125,
)
response.raise_for_status()
data = response.json()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/paymentinitiale fait alors foi : unstatus=oksignifie que le client a été débitéNothing to abort: aucun paiement n'est en coursAbort is not allowed: le paiement en cours n'a pas été lancé via la Local APIA 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 transactionError 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/paymentinitiale et traitez-la : surok, 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
{
"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
emailStringphoneString- Format international commençant par + (par ex. +33612345678)
birthDateString- Date de naissance
{
"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
{
"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 %)
{
"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
{
"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 transactionokest 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
{
"acceptedPayment": {
"acceptedMediumType": "lunch_vouchers_only"
}
}