Introduction
Welcome to the Yavin API documentation !
The API allows to easily integrate the functionalities of your Yavin X Android Terminal with an API REST or Android Intent, for instance, to initiate a payment or to print directly from your POS.
There are three levels of API integration to initiate a payment:
- API Cloud (doc)
Perk: The terminal can use a 3G/4G SIM card to connect to the bank.
Drawback: The response is asynchronous towards a public IP.
Typical use case: Web SaaS POS.
You can also use this API to extract information for your My Yavin backoffice, for instance, to connect your accounting software.
- API Local (doc)
Perk: The HTTP request is synchronous (open up to 5 minutes, corresponding to the time for the payment).
Drawback: The terminal must be connected to a local network with a fix IP (small handling in the Android settings). The local network must have a stable internet connexion.
Typical use case: Onboarded POS without web synchronization with websocket.
- API Android Intent (doc)
Perk: The POS is onboarded directly on the terminal.
Drawback: We need to program on mobile (Java/Kotlin/react native...) and the APK must be approved by the terminal constructor.
Typical use case : POS on smartphone (order taking at the table, food truck, itinerant merchants).
If you have an Android app and wish to deploy directly on the Yavin terminals, it's possible :) Contact us to make a sponsorship.
Login / Authentification
Before triggering payments on the Yavin Pay application, we must ensure that the merchant is identified.
Concerning the local API and the Android Intent API, you'll need to login manually to Yavin Pay using the same credentials as those of My Yavin https://my.yavin.com
Concerning the cloud API, the authentification is done via Yavin token.
API Cloud
Authentification
curl -XPOST "https://api.yavin.com/api/v4/pos/payment/" \
--header 'Yavin-Secret: YAVIN_API_KEY' \
--data '{
...
}'
import requests
url = 'https://api.yavin.com/api/v4/pos/payment/'
headers = {
'Content-Type': 'application/json',
'Yavin-Secret': 'YAVIN_API_KEY'
}
params = {
...
}
r = requests.post(url=url, json=params, headers=headers)
Yavin uses API keys to restrict data and services access to the right users. You can find your API key on my.yavin.com in the API tab.
All the requests must be identified. To do so, your API key must be in the headers of the POST request:
Errors
The Yavin API uses the following error codes:
Code | Explication |
---|---|
400 | Bad Request -- The request is invalid. |
401 | Unauthorized -- The API key is invalid or the terminal cannot be access with this API key |
404 | Not Found -- The link doesn't exist. |
405 | Method Not Allowed -- You are trying to access a link with an invalid HTTP method. |
500 | Internal Server Error -- There is an issue with our server. Please try again later. Contact the support team if the problem persists. |
Start a transaction
This API is used to initiate a payment on a Yavin terminal via the HTTP REST framework. It will work from a computer, a tablet or Android, or any objects connected to the internet
Request
POST https://api.yavin.com/api/v4/pos/payment/
curl -XPOST "https://api.yavin.com/api/v4/pos/payment/" \
--header 'Yavin-Secret: YAVIN_API_KEY' \
--data '{
"serialNumber": "123456789",
"amount": 1000,
"transactionType": "debit",
"vendor": {
"softwareVersion": "1.0",
"softwareName": "name"
},
"customer": {
"firstName": "John",
"lastName": "Doe",
"email": "john@yavin.com"
},
"receiptTicket": {
"data": "This is the receipt ticket\nto print",
"format": "text"
},
"receiptTicketJson": "{\"transactionId\": \"123456\", \"amount\": 3500 }"
}'
import requests
import json
url = 'https://api.yavin.com/api/v4/pos/payment/'
headers = {
'Content-Type': 'application/json',
'Yavin-Secret': 'YAVIN_API_KEY'
}
params = {
"serialNumber": "123456789",
"amount": 1000,
"transactionType": "debit",
"vendor": {
"softwareVersion": "1.0",
"softwareName": "name"
},
"customer": {
"firstName": "John",
"lastName": "Doe",
"email": "john@yavin.com"
},
"receiptTicket": {
"data": "This is the receipt ticket\nto print",
"format": "text"
},
"receiptTicketJson": json.dumps({ "transactionId": "123456", "amount": 3500 })
}
r = requests.post(url=url, json=params, headers=headers)
Parameters | Type | Default | Description |
---|---|---|---|
serialNumber | String | (mandatory) | Terminal serial number. It can be found on the back of the terminal next to S/N acronym |
amount | Integer | Amount in cents. 1€ => 100. This does not include tips. This amount should always be positive even for transactionType=Reversal or transactionType=Refund. | |
giftAmount | Integer | 0 | Tips or donation in cents |
medium | String | card |
card = Classical card transaction. (Other payment methods will be available soon). [card, qrcode, 2x, 3x, 4x,ancv, wechat, alipay, lydia, restoflash,...] |
transactionType | String | debit |
debit = classical card transaction.reversal = reversal of a paymentrefund = refund to a customer (not linked to previous payment)[debit, reversal, refund, preauthorisation, closingbatch] |
customer | Customer | Pre-field customer info to send via SMS or Email. See object Customer |
|
vendor | Vendor | Software editor info to identify it. See object Vendor |
|
reference | String | Free field that the merchant can see in his My Yavin backoffice | |
receiptTicket | ReceiptTicket | Data to print receipt ticket in the same time as the card ticket. See object ReceiptTicket |
|
receiptTicketJson | Ecommerce Object | Takes a json object consisting of the same data required for ecommerce api | |
cartId | String | Cart id associated to the transaction. This will be useful to link a payment and a receipt ticket if the receipt ticket wasn't filled initially |
Customer
Parameters | Type | Default | Description |
---|---|---|---|
String | |||
firstName | String | First name | |
lastName | String | Last name | |
phone | String | Phone number international format starting with + symbol (e.g: +33612345678) |
ReceiptTicket
Parameters | Type | Default | Description |
---|---|---|---|
format | String | text |
Format of data to print. Possible values : [text , escpos ] |
data | String | (mandatory) | The data to print. If format = text , data will be printed as it is. If format = escpos , then data must be the ESCPOS output encoded to a hex string (e.g: 1b401d6210...) which is the output received by the printer.We currently support ESCPOS package in Android, Javascript, Python, look at Yavin github for examples |
Vendor
Parameters | Type | Default | Description |
---|---|---|---|
softwareName | String | Name of cashier software | |
softwareVersion | String | Version of cashier software. This will be useful to help track and identify bugs as quickly as possible |
Response
{
"status": "ok",
"transactionId": "nvfkkFGFXr4Ew"
}
Parameters | Type | Description |
---|---|---|
status | String | ok if the transaction has been received successfully . Else ko |
transactionId | String | Unique id of the transaction |
Webhook Response
{
"status": "ok",
"trs_id": "nvfkkFGFXr4Ew",
"app_version": "5.0.1",
"asked_amount": 100,
"gift_amount": 0,
"total_amount": 100,
"card_token": "F12345678",
"cartId": "2",
"client_ticket": "Client Ticket\n\nStatus: OK\n\nPAN: 4444...4444\n\nCard token: 6767709988762\n\nAmount: € 1.00\n",
"company_ticket": "Company Ticket\n\nStatus: OK\n\nPAN: 4444...4444\n\nCard token: 6767709988762\n\nAmount: € 1.00\n",
"receiptTicket": {
"data": "This is the receipt ticket\nto print",
"format": "text"
},
"currencyCode": "EUR",
"device_datetime": "2022-09-26T11:11:29.148",
"device_timestamp": 1664183489148,
"medium": "card",
"reference": "YOUR-REF-01",
"serial_number": "bf075053ef08078a",
"server_timestamp": 1664183496498,
"type": "Debit",
"vendor": {
"apiVersion": "v1"
}
}
Paramètres | Type | Description |
---|---|---|
status | String | [ok / ko] Transaction successful or not |
trs_id | String | Unique id of the transaction |
app_version | String | Yavin Pay app version |
asked_amount | Integer | Amount in cents. 1€ => 100 |
gift_amount | Integer | Tips or donation in cents |
total_amount | Integer | Total amount of the transaction (=gift_amount + asked_amount) |
cartId | String | Cart id associated to the transaction |
client_ticket | String | Client transaction card ticket |
company_ticket | String | Merchant transaction card ticket |
receipt_ticket | ReceiptTicket | Data to print receipt ticket in the same time as the card ticket. See object ReceiptTicket |
currencyCode | String | Currency Code as ISO 4217 in which the payment will be done (available with activation) |
device_datetime | String | Date and time of the terminal when the transaction was made |
device_timestamp | String | Timestamp of the terminal |
medium | String | card = Classical card transaction. (Other payment methods will be available soon). [card, qrcode, 2x, 3x, 4x,ancv, wechat, alipay, lydia, restoflash,...] |
reference | String | Free field that the merchant can see in his My Yavin backoffice |
serial_number | String | Serial number of the terminal |
server_timestamp | String | Timestamp of the server |
type | String | debit = classical card transaction.reversal = cancellation of a payment.[debit, reversal, preauthorisation, closingbatch] |
vendor | Vendor | Software editor info to identify it. See object Vendor |
card_token | String | Unique card token |
Print a receipt ticket
Request
POST https://api.yavin.com/api/v4/pos/print/
curl -XPOST "https://api.yavin.com/api/v4/pos/print/" \
--header 'Yavin-Secret: YAVIN_API_KEY' \
--data '{
"serialNumber": "123456789",
"format": "text",
"data": "This is a ticket\nto print !"
}'
import requests
url = 'https://api.yavin.com/api/v4/pos/print/'
headers = {
'Content-Type': 'application/json',
'Yavin-Secret': 'YAVIN_API_KEY'
}
params = {
"serialNumber": "123456789",
"format": "text",
"data": "This is a ticket\nto print !"
}
r = requests.post(url=url, json=params, headers=headers)
Parameters | Type | Default | Description |
---|---|---|---|
serialNumber | String | (mandatory) | Terminal serial number. It can be found on the back of the terminal next to S/N acronym |
format | String | text |
Format of data to print. Possible values : [text , escpos ] |
data | String | (mandatory) | The data to print. If format = text , data will be printed as it is. If format = escpos , then data must be the ESCPOS output encoded to a hex string (e.g: 1b401d6210...) which is the output received by the printer.We currently support ESCPOS package in Android, Javascript, Python, look at Yavin github for examples |
Response
{
"status": "ok"
}
Parameters | Type | Description |
---|---|---|
status | String | ok / ko |
Share a receipt ticket
This API allows to share a receipt ticket via a specific medium (sms, email, print). If the customer field Customer
is present in
the request we can send the ticket directly to them. Otherwise the needed customer field will be asked through the terminal.
Request
POST https://api.yavin.com/api/v4/pos/share-receipt
curl -XPOST "https://api.yavin.com/api/v4/pos/share-receipt" \
--header 'Yavin-Secret: YAVIN_API_KEY' \
--data '{
"serialNumber": "123456789",
"receiptTicket": {
"data": "This is the receipt ticket\nto print",
"format": "text"
},
"transactionId": "fsOv53g7wxZ",
"medium": "email",
"customer": {
"firstName": "John",
"lastName": "Doe",
"email": "john@yavin.com"
}
}'
import requests
url = 'https://api.yavin.com/api/v4/pos/share-receipt'
headers = {
'Content-Type': 'application/json',
'Yavin-Secret': 'YAVIN_API_KEY'
}
params = {
"serialNumber": "123456789",
"receiptTicket": {
"data": "This is the receipt ticket\nto print",
"format": "text"
},
"transactionId": "fsOv53g7wxZ",
"medium": "email",
"customer": {
"firstName": "John",
"lastName": "Doe",
"email": "john@yavin.com"
}
}
r = requests.post(url=url, json=params, headers=headers)
Parameters | Type | Default | Description |
---|---|---|---|
serialNumber | String | (mandatory) | Terminal serial number. It can be found on the back of the terminal next to S/N acronym |
receiptTicket | ReceiptTicket | (mandatory) | Receipt ticket to share. See object ReceiptTicket |
transactionId | String | (mandatory) | The transaction ID corresponding to the ticket to be shared. It must be the one used from the Payment API |
medium | String | yavin |
The medium used to share ticket. Possible values are [yavin , sms , email , print ]. If yavin then we will store and share the receipt ticket according to the user notification preferences |
customer | Customer | Pre-field customer info to send via SMS or Email. See object Customer |
Customer
Parameters | Type | Default | Description |
---|---|---|---|
String | |||
firstName | String | First name | |
lastName | String | Last name | |
phone | String | Phone number international format starting with + symbol (e.g: +33612345678) |
ReceiptTicket
Parameters | Type | Default | Description |
---|---|---|---|
format | String | text |
Format of data to share. Possible values : [text , escpos ] |
data | String | (mandatory) | The receipt ticket to share. If format = text , data will be printed as it is. If format = escpos , then data must be the ESCPOS output encoded to a hex string (e.g: 1b401d6210...) which is the output received by the printer.We currently support ESCPOS package in Android, Javascript, Python, look at Yavin github for examples |
Response
{
"status": "ok"
}
Parameters | Type | Description |
---|---|---|
status | String | ok / ko |
Fetch transactions
curl -XPOST "https://api.yavin.com/api/v4/pos/transactions/" \
--header 'Yavin-Secret: YAVIN_API_KEY' \
--data '{
"serialNumbers": ["123456789"],
"timezone": "Europe/Paris",
"startDate": "2022-01-01",
"endDate": "2022-02-01",
"startTime": "00:00:00",
"endTime": "23:59:59",
"limit": 100
}'
import requests
url = 'https://api.yavin.com/api/v4/pos/transactions/'
headers = {
'Content-Type': 'application/json',
'Yavin-Secret': 'YAVIN_API_KEY'
}
params = {
"serialNumbers": ["123456789"],
"timezone": "Europe/Paris",
"startDate": "2022-01-01",
"endDate": "2022-02-01",
"startTime": "00:00:00",
"endTime": "23:59:59",
"limit": 100
}
r = requests.post(url=url, json=params, headers=headers)
The above request returns the below JSON response :
{
"total": 356,
"limit": 100,
"offset": 0,
"count": 100,
"transactions": [
{
"amount": 100,
"createdAt": "2022-05-10T14:09:06",
"giftAmount": 0,
"issuer": "BNP",
"scheme": "CB",
"status": "ok",
"transactionId": "IEqoLmjuRqfq",
"type": "debit",
"serialNumber": "123456789"
},
{
"amount": 300,
"createdAt": "2022-05-10T14:08:25",
"giftAmount": 0,
"issuer": "EDENRED",
"reference": "",
"scheme": "CB",
"status": "ok",
"transactionId": "8tPuSUIN6AaP",
"type": "debit",
"serialNumber": "123456789"
},
...
]
}
Request
POST https://api.yavin.com/api/v4/pos/transactions/
Parameters | Type | Default | Description |
---|---|---|---|
serialNumbers | Array of String | (optional) | Terminal serial numbers. It can be found on the back of the terminal next to S/N acronym |
timezone | String | (optional) | Timezone ID of the caller (e.g: "Europe/Paris"). We strongly advise to set the timezone in order to get correct data |
startDate | String | (optional) | Start date (yyyy-MM-dd format) |
endDate | String | (optional) | End date (yyyy-MM-dd format) Note: is exclusive |
startTime | String | (optional) | Start time (hh:mm:ss format) |
endTime | String | (optional) | End time (hh:mm:ss format) |
limit | Integer | 20 | Limit of the number of transactions to receive with a request (max = 200) |
offset | Integer | 0 | Offset of transactions in the request |
By default, if no date/time filters are set then the last 30 days are fetched.
Response
The transaction object contains the following fields: (see example)
Parameters | Type | Description |
---|---|---|
status | String | [ok / ko ] Transaction successful or not |
transactionId | String | Transaction id |
amount | Integer | Amount in cents. 1€ => 100. Does not include tips |
giftAmount | Integer | Tips or donation in cents |
currencyCode | String | Currency Code as ISO 4217 in which the payment will be done (available with activation) |
issuer | String | Issuer of the payment |
scheme | String | Network used to validate the transaction (CB,CBSC (contactless),VISA,MASTERCARD,CONECS...) |
transactionType | String | debit = classical card transaction.reversal = reversal of a paymentrefund = refund to a customer (not linked to previous payment)[debit, reversal, refund, preauthorisation, closingbatch] |
reference | String | Free field that the merchant can see in his My Yavin backoffice |
cartId | String | Cart id associated to the transaction |
appVersion | String | Yavin Pay app version |
createdAt | String | Datetime of the transactions at UTC timezone (ex: 2022-10-21T12:45:30.000Z) |
serialNumber | String | Serial number of the transaction that collected the transaction. |
Abort a transaction
This endpoint is designed to allow the aborting of an ongoing payment on your terminal. When this action is triggered, all screens associated with the ongoing payment are closed, and the terminal goes back to its main screen. Important Recommendation: It's strongly advised to avoid cancelling a payment during the card reading phase. A cancellation at this stage could lead to the unintended closure of the payment gateway screen. This action might result in data inconsistencies, as the payment information would not be correctly relayed.
Request
POST https://api.yavin.com/api/v4/pos/abort/
curl -XPOST "https://api.yavin.com/api/v4/pos/abort/" \
--header 'Yavin-Secret: YAVIN_API_KEY' \
--data '{
"serialNumber": "123456789",
"idempotentUuid": "dbcb384c-7d8d-4d2b-b367-133bfdf5c9c"
}'
import requests
url = 'https://api.yavin.com/api/v4/pos/abort/'
headers = {
'Content-Type': 'application/json',
'Yavin-Secret': 'YAVIN_API_KEY'
}
params = {
"serialNumber": "123456789",
"idempotentUuid": "dbcb384c-7d8d-4d2b-b367-133bfdf5c9c"
}
r = requests.post(url=url, json=params, headers=headers)
Parameters | Type | Default | Description |
---|---|---|---|
serialNumber | String | (mandatory) | Terminal serial number. It can be found on the back of the terminal next to S/N acronym |
idempotentUuid | String | (optional but recommended) | UUID of the transaction you want to cancel if there is one in progress. If no idempotentUuid is sent, then we will force cancel any transaction in progress on the terminal |
Response
{
"status": "ok"
}
Parameters | Type | Description |
---|---|---|
status | String | ok / ko depending on if the request was sent or no |
API Local
This API allows you to initiate a payment, print a ticket or fetch transactions history from the Yavin terminal connected to a local network.
You can either use local IP or Network Service Discovery compatible with Apple Bonjour. (see example here)
Don't forget the port number 16125
in the URL. It's easy to remember:
- P :
16
st letter of the alphabet - A :
1
st letter of the alphabet - Y :
25
st letter of the alphabet
Ping the terminal
curl -XGET 'http://<LOCAL_IP>:16125/localapi/v4/ping'
Request
GET 'http://<LOCAL_IP>:16125/localapi/v4/ping
Make the above request to check if your configuration is correct.
You can append a query parameter showMessage
that will display a message on the terminal saying "Hello there" if the value is true
.
By default showMessage
is false
.
E.g: GET 'http://<LOCAL_IP>:16125/localapi/v4/ping?showMessage=true
Response
{
"status": "ok"
}
Parameters | Type | Description |
---|---|---|
status | String | ok / ko |
Start a transaction
Request
For a simple request (with only the amount):
Simple request
curl -XGET "http://<LOCAL_IP>:16125/localapi/v4/payment/1000"
GET http://<IP_LOCALE>:16125/localapi/v4/payment/<AMOUNT>
For a more complex request (with other fields), a POST request must be sent with JSON formatted input:
Complete request
curl -X POST 'http://<LOCAL_IP>:16125/localapi/v4/payment' \
--header 'Content-Type: application/json' \
--data '
{
"amount": 1000,
"vendor": {
"softwareVersion": "1.0",
"softwareName": "name"
},
"receiptTicket": {
"data": "This is the receipt ticket\nto print",
"format": "text"
},
"customer": {
"firstName": "John",
"lastName": "Doe",
"email": "john@yavin.com"
},
"receiptTicketJson": "{\"transactionId\": \"123456\", \"amount\": 3500 }"
}'
import requests
import json
url = 'http://<IP_LOCALE>:16125/localapi/v4/payment'
params = {
"amount": 1000,
"vendor": {
"softwareVersion": "1.0",
"softwareName": "name"
},
"receiptTicket": {
"data": "This is the receipt ticket\nto print",
"format": "text"
},
"customer": {
"firstName": "John",
"lastName": "Doe",
"email": "john@yavin.com"
},
"receiptTicketJson": json.dumps({ "transactionId": "123456", "amount": 3500 })
}
r = requests.post(url=url, json=params)
Customer structure
{
"customer": {
"firstName": "John",
"lastName": "Doe",
"phone": "+33612345678",
"email": "john@yavin.com"
}
}
ReceiptTicket structure
{
"receiptTicket": {
"data": "Receipt ticket here to print if needed",
"format": "text"
}
}
Vendor structure
{
"vendor": {
"softwareVersion": "1.0",
"softwareName": "Cool Name"
}
}
POST http://<LOCAL_IP>:16125/localapi/v4/payment
Parameters | Type | Default | Description |
---|---|---|---|
amount | Integer | Amount in cents. 1€ => 100. This does not include tips. This amount should always be positive even for transactionType=Reversal or transactionType=Refund. | |
giftAmount | Integer | 0 | Tips or donation in cents |
medium | String | card |
card = Classical card transaction. (Other payment methods will be available soon). [card, qrcode, 2x, 3x, 4x,ancv, wechat, alipay, lydia, restoflash,...] |
transactionType | String | debit |
debit = classical card transaction.reversal = reversal of a paymentrefund = refund to a customer (not linked to previous payment)[debit, reversal, refund, preauthorisation, closingbatch] |
customer | Customer | Pre-field customer info to send via SMS or Email. See object Customer |
|
vendor | Vendor | Software editor info to identify it. See object Vendor |
|
reference | String | Free field that the merchant can see in his My Yavin backoffice | |
receiptTicket | ReceiptTicket | Data to print receipt ticket in the same time as the card ticket. See object ReceiptTicket |
|
receiptTicketJson | Ecommerce Object | Takes a json object consisting of the same data required for ecommerce api | |
cartId | String | Cart id associated to the transaction. This will be useful to link a payment and a receipt ticket if the receipt ticket wasn't filled initially | |
idempotentUuid | String | Idempotent unique identifier for the payment. If the terminal knows a transaction with this UUID in the last 24 hours then the terminal will respond with the corresponding transaction. Otherwise, if no transaction is associated to the UUID a new payment will be initiated and associated with the UUID once the payment completed. Note: if a transaction failed (status "ko") and the idempotent UUID stays the same, the terminal will respond with the failed transaction. You may want to change the idempotent UUID in this case. | |
acceptedMediumType | String | all | When the medium = card , acceptedMediumType can be used to specify which cards to accept. By selecting all cards, or leaving it empty, the terminal will accept all authorized cards by the merchant. Otherwise, the terminal will accept either lunch_vouchers_only or bank_cards_only . |
Customer
Parameters | Type | Default | Description |
---|---|---|---|
String | |||
firstName | String | First name | |
lastName | String | Last name | |
phone | String | Phone number international format starting with + symbol (e.g: +33612345678) |
ReceiptTicket
Parameters | Type | Default | Description |
---|---|---|---|
format | String | text |
Format of data to print. Possible values : [text , escpos ] |
data | String | (mandatory) | The data to print. If format = text , data will be printed as it is. If format = escpos , then data must be the ESCPOS output encoded to a hex string (e.g: 1b401d6210...) which is the output received by the printer.We currently support ESCPOS package in Android, Javascript, Python, look at Yavin github for examples |
Vendor
Parameters | Type | Default | Description |
---|---|---|---|
softwareName | String | Name of cashier software | |
softwareVersion | String | Version of cashier software. This will be useful to help track and identify bugs as quickly as possible |
Response
TransactionResponse
{
"amount": 1000,
"appVersion": "3.2.8",
"cardToken": "1234567890",
"clientCardTicket": "Sandbox Fake ticket\n\nStatus: OK\n\nPAN: 42424242....4242\n\nCard token: 1234567890\n\nAmount: 1.0\n\nTotal Amount: 10.0\n",
"currencyCode": "EUR",
"giftAmount": 0,
"scheme": "CB",
"customer": {
"firstName": "John",
"lastName": "Doe",
"email": "john@yavin.com"
},
"status": "ok",
"transactionId": "xPUyi4fmdibD",
"transactionType": "Debit"
}
Paramètres | Type | Description |
---|---|---|
status | String | [ok / ko ] Transaction successful or not |
transactionId | String | Transaction id |
amount | Integer | Amount in cents. 1€ => 100. This does not include gift amount |
giftAmount | Integer | Tips or donation in cents |
currencyCode | String | Currency Code as ISO 4217 in which the payment will be done (available with activation) |
issuer | String | Issuer of the payment |
scheme | String | Network used to validate the transaction (CB,CBSC (contactless),VISA,MASTERCARD,CONECS...) |
transactionType | String | debit = classical card transaction.reversal = reversal of a paymentrefund = refund to a customer (not linked to previous payment)[debit, reversal, refund, preauthorisation, closingbatch] |
customer | Customer | Pre-field customer info to send via SMS or Email. See object Customer |
reference | String | Free field |
cartId | String | Cart id associated to the transaction |
clientCardTicket | String | Client transaction card ticket |
merchantCardTicket | String | Merchant transaction card ticket |
appVersion | String | Yavin Pay app version |
idempotentUuid | String | Idempotent unique identifier from the request |
cardToken | String | Unique card token |
message | String (optional) | The error message if there is one |
Print a receipt ticket
curl -XPOST 'http://<IP_LOCALE>:6125/localapi/v4/print' \
--header 'Content-Type: application/json' \
--data '
{
"data": "This is the text\nto print",
"format": "text"
}'
import requests
url = 'http://<IP_LOCALE>:16125/localapi/v4/print'
params = {
"data": "This is the text\nto print",
"format": "text"
}
r = requests.post(url=url, json=params)
Request
POST http://<IP_LOCALE>:6125/localapi/v4/print
Parameters | Type | Default | Description |
---|---|---|---|
format | String | text |
Format of data to print. Possible values : [text , escpos ] |
data | String | (mandatory) | The data to print. If format = text , data will be printed as it is. If format = escpos , then data must be the ESCPOS output encoded to a hex string (e.g: 1b401d6210...) which is the output received by the printer.We currently support ESCPOS package in Android, Javascript, Python, look at Yavin github for examples |
Response
{
"status": "ok"
}
Parameters | Type | Description |
---|---|---|
status | String | ok / ko |
message | String | Additional information |
Share a receipt ticket
This API allows to share a receipt ticket via a specific medium (sms, email, print). If the customer field Customer
is present in
the request we can send the ticket directly to them. Otherwise the needed customer field will be asked through the terminal.
Request
curl -X POST 'http://<IP_LOCALE>:16125/localapi/v4/share-receipt' -d '{
"receiptTicket": {
"data": "This is the receipt ticket\nto print",
"format": "text"
},
"transactionId": "fsOv53g7wxZ",
"medium": "email",
"customer": {
"firstName": "John",
"lastName": "Doe",
"email": "john@yavin.com"
}
}'
import requests
url = 'http://<IP_LOCALE>:16125/localapi/v4/share-receipt'
params = {
"receiptTicket": {
"data": "This is the receipt ticket\nto print",
"format": "text"
},
"transactionId": "fsOv53g7wxZ",
"medium": "email",
"customer": {
"firstName": "John",
"lastName": "Doe",
"email": "john@yavin.com"
}
}
r = requests.post(url=url, json=params)
Parameters | Type | Default | Description |
---|---|---|---|
receiptTicket | ReceiptTicket | (mandatory) | Receipt ticket to share. See object ReceiptTicket |
transactionId | String | (mandatory) | The transaction ID corresponding to the ticket to be shared. It must be the one used from the Payment API |
medium | String | yavin |
The medium used to share ticket. Possible values are [yavin , sms , email , print ]. If yavin then we will store and share the receipt ticket according to the user notification preferences |
customer | Customer | Pre-field customer info to send via SMS or Email. See object Customer |
Customer
Parameters | Type | Default | Description |
---|---|---|---|
String | |||
firstName | String | First name | |
lastName | String | Last name | |
phone | String | Phone number international format starting with + symbol (e.g: +33612345678) |
ReceiptTicket
Parameters | Type | Default | Description |
---|---|---|---|
format | String | text |
Format of data to share. Possible values : [text , escpos ] |
data | String | (mandatory) | The receipt ticket to share. If format = text , data will be printed as it is. If format = escpos , then data must be the ESCPOS output encoded to a hex string (e.g: 1b401d6210...) which is the output received by the printer.We currently support ESCPOS package in Android, Javascript, Python, look at Yavin github for examples |
Response
{
"status": "ok"
}
Parameters | Type | Description |
---|---|---|
status | String | ok / ko |
Fetch transactions
curl -XPOST 'http://<LOCAL_IP>:16125/localapi/v4/transactions' \
--header 'Content-Type: application/json' \
--data '{
"startDate": "2022-01-01",
"endDate": "2022-02-01",
"startTime": "00:00:00",
"endTime": "23:59:59",
"limit": 50
}'
import requests
url = 'http://<IP_LOCALE>:16125/localapi/v4/transactions'
params = {
"startDate": "2022-01-01",
"endDate": "2022-02-01",
"startTime": "00:00:00",
"endTime": "23:59:59",
"limit": 50
}
r = requests.post(url=url, json=params)
Request
POST 'http://<LOCAL_IP>:16125/localapi/v4/transactions
Parameters | Type | Default | Description |
---|---|---|---|
startDate | String | (optional) | Start date (yyyy-MM-dd format) |
endDate | String | (optional) | End date (yyyy-MM-dd format) Note: is exclusive |
startTime | String | (optional) | Start time (hh:mm:ss format) |
endTime | String | (optional) | End time (hh:mm:ss format) |
limit | Integer | 20 | Limit of the number of transactions to receive with a request (max = 200) |
offset | Integer | 0 | Offset of transactions in the request |
By default, if no date/time filters are set then the last 30 days are fetched.
Response
See example.
Parameters | Type | Description |
---|---|---|
status | String | [ok / ko ] Transaction successful or not |
transactionId | String | Transaction id |
amount | Integer | Amount in cents. 1€ => 100 |
giftAmount | Integer | Tips or donation in cents. Does not include tips |
currencyCode | String | Currency Code as ISO 4217 in which the payment will be done (available with activation) |
issuer | String | Issuer of the payment |
scheme | String | Network used to validate the transaction (CB,CBSC (contactless),VISA,MASTERCARD,CONECS...) |
transactionType | String | debit = classical card transaction.reversal = reversal of a paymentrefund = refund to a customer (not linked to previous payment)[debit, reversal, refund, preauthorisation, closingbatch] |
customer | Customer | See object Customer |
reference | String | Free field that the merchant can see in his My Yavin backoffice |
cartId | String | Cart id associated to the transaction |
appVersion | String | Yavin Pay app version |
createdAt | String | Datetime of the transactions at UTC timezone (ex: 2022-10-21T12:45:30.000Z) |
Customer
Parameters | Type | Description |
---|---|---|
String | ||
firstName | String | First name |
lastName | String | Last name |
phone | String | Phone number |
{
"count": 50,
"limit": 50,
"offset": 3,
"total": 156,
"transactions": [
{
"amount": 100,
"createdAt": "2022-05-10T14:09:06",
"customer": {
"email": "",
"phone": "0612345687"
},
"giftAmount": 0,
"issuer": "BNP",
"scheme": "CB",
"status": "ok",
"transactionId": "IEqoLmjuRqfq",
"type": "debit"
},
{
"amount": 100,
"createdAt": "2022-05-10T14:08:25",
"customer": {},
"giftAmount": 0,
"issuer": "EDENRED",
"reference": "",
"scheme": "CB",
"status": "ok",
"transactionId": "8tPuSUIN6AaP",
"type": "debit"
},
...
]
}
Abort a request
This endpoint is designed to allow the aborting of an ongoing payment on your terminal. When this action is triggered, all screens associated with the ongoing payment are closed, and the terminal goes back to its main screen. Important Recommendation: It's strongly advised to avoid cancelling a payment during the card reading phase. A cancellation at this stage could lead to the unintended closure of the payment gateway screen. This action might result in data inconsistencies, as the payment information would not be correctly relayed.
curl -X POST 'http://<LOCAL_IP>:16125/localapi/v4/abort' \
--header 'Content-Type: application/json' \
--data '
{
"idempotentUuid": "dbcb384c-7d8d-4d2b-b367-133bfdf5c9c"
}'
Request
POST 'http://<LOCAL_IP>:16125/localapi/v4/abort
Parameters | Type | Default | Description |
---|---|---|---|
idempotentUuid | String (optional but recommended) | UUID of the transaction you want to cancel if there is one in progress. If not idempotentUuid is sent, then we will force cancel any transaction in progress on the terminal |
Response
{
"status": "ok"
}
Parameters | Type | Description |
---|---|---|
status | String | ok / ko |
message | String (optional) | The error message if there is one |
idempotentUuid | String (optional) | May not be present in the response. The idempotentUuid of the transaction in progress on the terminal |
API Android
The Android Yavin Pay app allows Android Intent
to initiate a payment or print some text.
Check the kotlin
section on the right.
Start a transaction
Request
To trigger a payment by Intent, use the following code:
Check kotlin section
Check kotlin section
val request = TransactionRequest(
amount = 100,
customer = Customer("John", "Doe", "john@yavin.com"),
vendor = Vendor("Awesome Partner", "1.2.3"),
receiptTicket = ReceiptTicket(data = "This is a wonderful\n receipt ticket to print", format = "text"),
receiptTicketJson = JSONObject("{\"transactionId\": \"123456\", \"amount\": 3500 }").toString()
)
val jsonData = Gson().toJson(request)
val queryParams = Uri.encode(jsonData)
val intent = Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse("yavin://com.yavin.macewindu/v4/payment?data=$queryParams")
}
startActivityForResult(intent, REQUEST_CODE_PAYMENT)
TransactionRequest request = new TransactionRequest();
request.amount = 100;
request.customer = new Customer("John", "Doe", "john@yavin.com");
request.vendor = new Vendor("Awesome Partner", "1.2.3");
request.receiptTicket = new ReceiptTicket("This is a wonderful\n receipt ticket to print", "text");
request.receiptTicketJson = new JSONObject("{\"transactionId\": \"123456\", \"amount\": 3500 }").toString();
String queryParams = new Gson().toJson(request);
Uri uri = Uri.parse("yavin://com.yavin.macewindu/v4/payment?data=" + queryParams);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
startActivityForResult(intent, REQUEST_CODE_PAYMENT);
A payment is triggered on the terminal by Intent using the defined format in the kotlin
section.
Below is the structure of the input data TransactionRequest
:
TransactionRequest.kt
Check kotlin section
Check kotlin section
data class TransactionRequest(
@SerializedName("amount")
var amount: Int,
@SerializedName("cartId")
var cartId: String?,
@SerializedName("customer")
var customer: Customer?,
@SerializedName("giftAmount")
var giftAmount: Int?,
@SerializedName("medium")
var medium: String?,
@SerializedName("receiptTicket")
var receiptTicket: ReceiptTicket?,
@SerializedName("receiptTicketJson")
var receiptTicketJson: String?,
@SerializedName("reference")
var reference: String?,
@SerializedName("transactionType")
var transactionType: String?,
@SerializedName("vendor")
var vendor: Vendor?,
@SerializedName("idempotentUuid")
var idempotentUuid: String?
)
Parameters | Type | Default | Description |
---|---|---|---|
amount | Integer | Amount in cents. 1€ => 100. This does not include tips. This amount should always be positive even for transactionType=Reversal or transactionType=Refund. | |
giftAmount | Integer | 0 | Tips or donation in cents |
medium | String | card |
card = Classical card transaction. (Other payment methods will be available soon). [card, qrcode, 2x, 3x, 4x,ancv, wechat, alipay, lydia, restoflash,...] |
transactionType | String | debit |
debit = classical card transaction.reversal = reversal of a paymentrefund = refund to a customer (not linked to previous payment)[debit, reversal, refund, preauthorisation, closingbatch] |
customer | Customer | Pre-field customer info to send via SMS or Email. See object Customer |
|
vendor | Vendor | Software editor info to identify it. See object Vendor |
|
reference | String | Free field that the merchant can see in his My Yavin backoffice | |
receiptTicket | ReceiptTicket | Data to print receipt ticket in the same time as the card ticket. See object ReceiptTicket |
|
receiptTicketJson | Ecommerce Object | Takes a json object consisting of the same data required for ecommerce api | |
cartId | String | Cart id associated to the transaction. This will be useful to link a payment and a receipt ticket if the receipt ticket wasn't filled initially | |
idempotentUuid | String | Idempotent unique identifier for the payment. If the terminal knows a transaction with this UUID in the last 24 hours then the terminal will respond with the corresponding transaction. Otherwise, if no transaction is associated to the UUID a new payment will be initiated and associated with the UUID once the payment completed. Note: if a transaction failed (status "ko") and the idempotent UUID stays the same, the terminal will respond with the failed transaction. You may want to change the idempotent UUID in this case. |
Customer.kt
Check kotlin section
Check kotlin section
data class Customer(
@SerializedName("email")
var email: String?,
@SerializedName("firstName")
var firstName: String?,
@SerializedName("lastName")
var lastName: String?,
@SerializedName("phone")
var phone: String?
)
Customer
Parameters | Type | Default | Description |
---|---|---|---|
String | |||
firstName | String | First name | |
lastName | String | Last name | |
phone | String | Phone number international format starting with + symbol (e.g: +33612345678) |
ReceiptTicket.kt
Check kotlin section
Check kotlin section
data class ReceiptTicket(
@SerializedName("data")
var `data`: String?,
@SerializedName("format")
var format: String?
)
ReceiptTicket
Parameters | Type | Default | Description |
---|---|---|---|
format | String | text |
Format of data to print. Possible values : [text , escpos ] |
data | String | (mandatory) | The data to print. If format = text , data will be printed as it is.If format = escpos , then data must be the ESCPOS output encoded to a hex string (e.g: 1b401d6210...) which is the output received by the printer.We currently support ESCPOS package in Android, Javascript, Python, look at Yavin github for examples |
Vendor.kt
Check kotlin section
Check kotlin section
data class Vendor(
@SerializedName("softwareName")
var softwareName: String?,
@SerializedName("softwareVersion")
var softwareVersion: String?
)
Vendor
Parameters | Type | Default | Description |
---|---|---|---|
softwareName | String | Name of cashier software | |
softwareVersion | String | Version of cashier software. This will be useful to help track and identify bugs as quickly as possible |
Response
When your application receives the transaction response back in onActivityResult()
, get the serialized JSON transaction output
from the data
Intent using the key response
from the extras Bundle.
To get the transaction response, use this code:
Check kotlin section
Check kotlin section
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_CODE_PAYMENT) {
// handle post payment response from Yavin PAY
val json = data.extras?.getString("response")
val response = Gson().fromJson(json, TransactionResponse::class.java)
}
}
Here is the TransactionResponse
structure:
TransactionResponse.kt
Check kotlin section
Check kotlin section
data class TransactionResponse(
@SerializedName("appVersion")
var appVersion: String? = null,
@SerializedName("amount")
var amount: Int = 0,
@SerializedName("cardToken")
var cardToken: String? = null,
@SerializedName("cartId")
var cartId: String? = null,
@SerializedName("clientCardTicket")
var clientCardTicket: String? = null,
@SerializedName("merchantCardTicket")
var merchantCardTicket: String? = null,
@SerializedName("currencyCode")
var currencyCode: String? = null,
@SerializedName("customer")
var customer: Customer? = null,
@SerializedName("giftAmount")
var giftAmount: Int? = 0,
@SerializedName("scheme")
var scheme: String? = null,
@SerializedName("issuer")
var issuer: String? = null,
@SerializedName("reference")
var reference: String? = null,
@SerializedName("status")
var status: String? = null,
@SerializedName("transactionId")
var transactionId: String? = null,
@SerializedName("transactionType")
var transactionType: String? = null,
@SerializedName("idempotentUuid")
var idempotentUuid: String?
)
Parameters | Type | Description |
---|---|---|
status | String | [ok / ko ] Transaction successful or not |
transactionId | String | Transaction id |
amount | Integer | Amount in cents. 1€ => 100. This does not include gift amount |
giftAmount | Integer | Tips or donation in cents |
currencyCode | String | Currency Code as ISO 4217 in which the payment will be done (available with activation) |
issuer | String | Issuer of the payment |
scheme | String | Network used to validate the transaction (CB,CBSC (contactless),VISA,MASTERCARD,CONECS...) |
transactionType | String | debit = classical card transaction.reversal = reversal of a paymentrefund = refund to a customer (not linked to previous payment)[debit, reversal, refund, preauthorisation, closingbatch] |
customer | Customer | Pre-field customer info to send via SMS or Email. See object Customer |
reference | String | Free field that the merchant can see in his My Yavin backoffice |
cartId | String | Cart id associated to the transaction |
clientCardTicket | String | Client transaction card ticket |
merchantCardTicket | String | Merchant transaction card ticket |
appVersion | String | Yavin Pay app version |
idempotentUuid | String | Idempotent unique identifier from the request |
cardToken | String | Unique card token |
Print a receipt ticket
Request
To print by Intent, use this code:
Check kotlin section
Check kotlin section
val request = PrintRequest(
format = "text",
data = "Text to print"
)
val jsonData = Gson().toJson(request)
val queryParams = Uri.encode(jsonData)
val intent = Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse("yavin://com.yavin.macewindu/v4/print?data=$queryParams")
}
startActivityForResult(intent, REQUEST_CODE_PRINT)
PrintRequest.kt
Check kotlin section
Check kotlin section
data class PrintRequest(
@SerializedName("format")
var format: String?,
@SerializedName("data")
var `data`: String?
)
Parameters | Type | Default | Description |
---|---|---|---|
format | String | text |
Format of data to print. Possible values : [text , escpos ] |
data | String | (mandatory) | The data to print. If format = text , data will be printed as it is. If format = escpos , then data must be the ESCPOS output encoded to a hex string (e.g: 1b401d6210...) which is the output received by the printer.We currently support ESCPOS package in Android, Javascript, Python, look at Yavin github for examples |
Response
To get response :
Check kotlin section
Check kotlin section
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_CODE_PRINT) {
val json = data.extras?.getString("response")
val response = Gson().fromJson(json, PrintResponse::class.java)
}
}
PrintResponse.kt
Check kotlin section
Check kotlin section
data class PrintResponse(
@SerializedName("status")
var status: String?
)
Parameters | Type | Description |
---|---|---|
status | String | ok / ko |
Share a receipt ticket
This API allows to share a receipt ticket via a specific medium (sms, email, print). If the customer field Customer
is present in
the request we can send the ticket directly to them. Otherwise the needed customer field will be asked through the terminal.
Request
To share by Intent, use this code:
Check kotlin section
Check kotlin section
val request = ShareRequest(
receiptTicket = ReceiptTicket(format = "text", data = "Text to print"),
transactionId = "gks15fQSfw",
medium = "email",
customer = Customer("John", "Doe", email = "john@yavin.com")
)
val jsonData = Gson().toJson(request)
val queryParams = Uri.encode(jsonData)
val intent = Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse("yavin://com.yavin.macewindu/v4/share-receipt?data=$queryParams")
}
startActivityForResult(intent, REQUEST_CODE_SHARE)
ShareRequest.kt
Check kotlin section
Check kotlin section
data class ShareRequest(
@SerializedName("receiptTicket")
var receiptTicket: ReceiptTicket?,
@SerializedName("transactionId")
var transactionId: String?,
@SerializedName("medium")
var medium: String?,
@SerializedName("customer")
var customer: Customer?
)
Parameters | Type | Default | Description |
---|---|---|---|
receiptTicket | ReceiptTicket | (mandatory) | Receipt ticket to share. See object ReceiptTicket |
transactionId | String | (mandatory) | The transaction ID corresponding to the ticket to be shared. It must be the one used from the Payment API |
medium | String | yavin |
The medium used to share ticket. Possible values are [yavin , sms , email , print ]. If yavin then we will store and share the receipt ticket according to the user notification preferences |
customer | Customer | Pre-field customer info to send via SMS or Email. See object Customer |
Customer.kt
Check kotlin section
Check kotlin section
data class Customer(
@SerializedName("email")
var email: String?,
@SerializedName("firstName")
var firstName: String?,
@SerializedName("lastName")
var lastName: String?,
@SerializedName("phone")
var phone: String?
)
Customer
Parameters | Type | Default | Description |
---|---|---|---|
String | |||
firstName | String | First name | |
lastName | String | Last name | |
phone | String | Phone number international format starting with + symbol (e.g: +33612345678) |
ReceiptTicket.kt
Check kotlin section
Check kotlin section
data class ReceiptTicket(
@SerializedName("data")
var `data`: String?,
@SerializedName("format")
var format: String?
)
ReceiptTicket
Parameters | Type | Default | Description |
---|---|---|---|
format | String | text |
Format of data to share. Possible values : [text , escpos ] |
data | String | (mandatory) | The receipt ticket to share. If format = text , data will be printed as it is.If format = escpos , then data must be the ESCPOS output encoded to a hex string (e.g: 1b401d6210...) which is the output received by the printer.We currently support ESCPOS package in Android, Javascript, Python, look at Yavin github for examples |
Response
To get the response :
Check kotlin section
Check kotlin section
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_CODE_SHARE) {
val json = data.extras?.getString("response")
val response = Gson().fromJson(json, ShareResponse::class.java)
}
}
ShareResponse.kt
Check kotlin section
Check kotlin section
data class ShareResponse(
@SerializedName("status")
var status: String?
)
Parameters | Type | Description |
---|---|---|
status | String | ok / ko |
Fetch transactions
Request
To fetch transaction from the terminal by Intent, use this code:
Check kotlin section
Check kotlin section
val request = TransactionsRequest(
startDate = "2022-01-01",
endDate = "2022-02-01",
startTime = "00:00:00",
endTime = "23:59:59",
limit = 50
)
val jsonData = Gson().toJson(request)
val queryParams = Uri.encode(jsonData)
val intent = Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse("yavin://com.yavin.macewindu/v4/transactions?data=$queryParams")
}
startActivityForResult(intent, REQUEST_CODE_TRANSACTIONS)
TransactionsRequest.kt
Check kotlin section
Check kotlin section
data class TransactionsRequest(
@SerializedName("startDate")
var startDate: String? = null,
@SerializedName("endDate")
var endDate: String? = null,
@SerializedName("startTime")
var startTime: String? = null,
@SerializedName("endTime")
var endTime: String? = null,
@SerializedName("limit")
var limit: Int? = 20,
@SerializedName("offset")
var offset: Int? = 0,
)
Parameters | Type | Default | Description |
---|---|---|---|
startDate | String | (optional) | Start date (yyyy-MM-dd format) |
endDate | String | (optional) | End date (yyyy-MM-dd format) Note: is exclusive |
startTime | String | (optional) | Start time (hh:mm:ss format) |
endTime | String | (optional) | End time (hh:mm:ss format) |
limit | Integer | 20 | Limit of the number of transactions to receive with a request (max = 200) |
offset | Integer | 0 | Offset of transactions in the request |
By default, if no date/time filters are set then the last 30 days are fetched.
Response
To get response :
Check kotlin section
Check kotlin section
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_CODE_TRANSACTIONS) {
val json = data.extras?.getString("response")
val response = Gson().fromJson(json, TransactionsResponse::class.java)
}
}
TransactionsResponse.kt
Check kotlin section
Check kotlin section
data class TransactionsResponse(
@SerializedName("total")
var total: Int? = null,
@SerializedName("count")
var count: Int? = null,
@SerializedName("limit")
var limit: Int? = null,
@SerializedName("offset")
var offset: Int? = null,
@SerializedName("transactions")
var transactions: List<ItemTransactionResponse>? = null
)
Where
ItemTransactionResponse
is :
data class ItemTransactionResponse(
@SerializedName("appVersion")
var appVersion: String? = null,
@SerializedName("createdAt")
var createdAt: String? = null,
@SerializedName("amount")
var amount: Int? = null,
@SerializedName("giftAmount")
var giftAmount: Int? = null,
@SerializedName("status")
var status: String? = null,
@SerializedName("currencyCode")
var currencyCode: String? = null,
@SerializedName("transactionId")
var transactionId: String? = null,
@SerializedName("scheme")
var scheme: String? = null,
@SerializedName("issuer")
var issuer: String? = null,
@SerializedName("cartId")
var cartId: String? = null,
@SerializedName("transactionType")
var transactionType: String? = null,
@SerializedName("reference")
var reference: String? = null,
@SerializedName("customer")
var customer: Customer? = null
)
Parameters | Type | Description |
---|---|---|
status | String | [ok / ko ] Transaction successful or not |
transactionId | String | Transaction id |
amount | Integer | Amount in cents. 1€ => 100. Does not include tips |
giftAmount | Integer | Tips or donation in cents |
currencyCode | String | Currency Code as ISO 4217 in which the payment will be done (available with activation) |
issuer | String | Issuer of the payment |
scheme | String | Network used to validate the transaction (CB,CBSC (contactless),VISA,MASTERCARD,CONECS...) |
transactionType | String | debit = classical card transaction.reversal = reversal of a paymentrefund = refund to a customer (not linked to previous payment)[debit, reversal, refund, preauthorisation, closingbatch] |
customer | Customer | See object Customer |
reference | String | Free field that the merchant can see in his My Yavin backoffice |
cartId | String | Cart id associated to the transaction |
appVersion | String | Yavin Pay app version |
createdAt | String | Datetime of the transactions at UTC timezone (ex: 2022-10-21T12:45:30.000Z) |
Customer.kt
Check kotlin section
Check kotlin section
data class Customer(
@SerializedName("email")
var email: String?,
@SerializedName("firstName")
var firstName: String?,
@SerializedName("lastName")
var lastName: String?,
@SerializedName("phone")
var phone: String?
)
Customer
Parameters | Type | Description |
---|---|---|
String | ||
firstName | String | First name |
lastName | String | Last name |
phone | String | Phone number |
Read NFC tag via Yavin Pay
The purpose of this document is to describe how to get NFC tag data from yavinPay.
This feature able you to retrieve tag serial number for cashless application for example.
The api timeout after 1 minute 30 seconds by default.
Request
The parameters for this request are optional, for now you can just control the timeout and a customizable text to display when reading the card.
To trigger NFC Reader by Intent, use this code:
Check kotlin section
Check kotlin section
val request = NFCReaderRequestV4(10000, "Pass your card here)
val jsonData = Gson().toJson(request)
val queryParams = Uri.encode(jsonData)
val intent = Intent(Intent.ACTION_VIEW).apply {
val url = StringBuilder("yavin://com.yavin.macewindu/v4/nfc-reader").apply {
append("?data=$queryParams") // optionnal
}
data = Uri.parse(url.toString())
}
startActivityForResult(intent, REQUEST_CODE_READ)
NFCReaderRequestV4.kt
Check kotlin section
Check kotlin section
data class NFCReaderRequestV4(
@SerializedName("timeout")
val timeout: Long,
@SerializedName("readerIncentive")
val readerIncentive: String
)
Parameters | Type | Default | Description |
---|---|---|---|
timeout | Long | 90000 | timeout for reading in milliseconds. Must be above 10000 |
readerIncentive | String | text to display when reading card |
Response
To get the response :
Check kotlin section
Check kotlin section
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_CODE_READ) {
// handle post read response from Yavin PAY
val json = data.extras?.getString("response")
val response = Gson().fromJson(json, NFCReadResponse::class.java)
}
}
NFCReadResponse.kt
Check kotlin section
Check kotlin section
data class NFCReadResponse(
@SerializedName("status")
val status: Boolean,
@SerializedName("tagInfo")
var tagInfo: TagInfo?
)
Parameters | Type | Default | Description |
---|---|---|---|
status | Boolean | (mandatory) | Tell if the reading is successful: true or false |
tagInfo | TagInfo | Hold the tag info, for now only the serial number is available. |
TagInfo.kt
Check kotlin section
Check kotlin section
data class TagInfo(
@SerializedName("serialNumber")
var serialNumber: String
)
TagInfo
Parameters | Type | Description |
---|---|---|
serialNumber | String | Represent the tag serial number |
Ecommerce
Introduction
The API ecommerce provides a url which can be used to redirect a user to a customisable payment screen.
The displayed payment page will provide some additional information to the user (this could, for instance, be an itemised breakdown of the order). Upon successful payment, or cancellation by the user, a response is sent to a specified return url with the status of the payment. If the payment is unsuccessful the customer will be given the opportunity to try again.
Flow
- User selects item(s) on your website and clicks on button to pay, notifying your server of intent.
- Your server handles the request and makes request to Yavin api to generate a payment link
- Yavin server generates a unique payment link and sends it in the response.
- Your server sends redirect response to the user's client, redirecting them to the payment link url (Yavin powered page)
- Customer is presented with a widget to provide their payment information and make the payment
- The payment is processed and a response is sent to your server at the return url supplied, with a cartId and status in the query params.
- Your server handles response and displays relavent information to the user.
Authentification
curl -XPOST "https://api.yavin.com/api/v4/ecommerce/generate_link/" \
--header 'Yavin-Secret: YAVIN_API_KEY' \
--data '{
...
}'
import requests
url = 'https://api.yavin.com/api/v4/ecommerce/generate_link/'
headers = {
'Content-Type': 'application/json',
'Yavin-Secret': 'YAVIN_API_KEY'
}
params = {
...
}
r = requests.post(url=url, json=params, headers=headers)
Yavin uses API keys to restrict data and services access to the right users.
You can find your API key on my.yavin.com in the settings>API
tab.
All the requests must be identified. To do so, your API key must be in the headers of the POST request:
Errors
The Yavin API uses the following error codes:
Code | Explication |
---|---|
400 | Bad Request -- The request is invalid. |
401 | Unauthorized -- The API key is invalid or the endpoint cannot be access with this API key |
404 | Not Found -- The link doesn't exist. |
405 | Method Not Allowed -- You are trying to access a link with an invalid HTTP method. |
500 | Internal Server Error -- There is an issue with our server. Please try again later. Contact the support team if the problem persists. |
Key Information
Payment Link lifetime
Unused Links:
Payment links that have no payments associated with them will remain active for a maximum of 72 hours. After this period, the cart and the link will be canceled.
Partially Paid Carts:
Carts that have been partially paid will be systematically canceled when the script runs to ensure that funds are released back to the customer, especially if they have paid with titres restaurants.
If a payment is still required after a link has been canceled, a new payment link must be generated through the
/generate_link/
endpoint.Cart Status
There is no notion of a 'failed' status. Here's a breakdown of the possible statuses: -
pending
: Awaiting payment. -ok
: Successfully paid. -authorised
: Paid but contains one or more authorised transactions that require capturing. -ko
: The cart has been cancelled.snake_case Convention
- All keys have been converted from camelCase to snake_case for better legibility. However, the camelCase convention is still also accepted.
- The query params in the response_url_success and response_url_cancel will remain cameCase in order to prevent introducing breaking changes.
Cart Representation
- A cart represents a single payment request. It can contain one or more transactions, allowing users to pay in part with meal vouchers and top up the rest with another card.
- Whenever the notion of
cart
is used, it is referring to a payment request initiated by the/generate_link/
endpoint.Carts with auto_capture set to False
Every day at 05:00 GMT we run a script which will: - Automatically capture all transactions for fully paid carts with a status of
authorised
. - Cancel all transactions for any partially paid cart (status ofpending
). This is to ensure that we are releasing funds back to the customers for incomplete orders (this is particularly valuable for Titres Restaurants which have hard limits on their spending allowance)
Generate Link
Description
This endpoint is used to generate an e-commerce link for a new payment request.
Request
Parameters
body = {
"cart_id": "my_custom_cart_id_001",
"amount": 3000,
"gift_amount": 300,
"amount_without_tax": 2400,
"tax_amount": 600,
"return_url_success": "https://mydomain.com/ecommerce/success",
"return_url_cancelled": "https://mydomain.com/ecommerce/cancelled",
"is_instant_capture": False,
"capture_min_delay": 8,
"order_source": "pay_at_table",
"webhook_url": "https://mydomain.com/ecommerce/webhook",
"message": "Thank you for shopping with us",
"datetime": "2023-10-16 14:35:15",
"currency": "EUR",
"reference": "Luke",
"client_reference": "aoj239uvn2ca"
}
Name | Type | Description | Required |
---|---|---|---|
cart_id |
String | Unique identifier for the cart. If the provided cart_id already exists in the system, the response will include the error message "This cart_id already exists" along with the link to the existing cart at index 1 |
Yes |
return_url_success |
String | URL to redirect to on successful payment. | Yes |
return_url_cancelled |
String | URL to redirect to if payment is cancelled. | Yes |
amount |
Integer | The initial amount to pay that is excluding any tip or gift (gift_amount) | Yes |
gift_amount |
Integer | The amount of the tip or gift, excluding the initial amount (amount). If you are proposing to your client to leave a tip / gift on your platform directly, and not using our built-in tips feature, then use this field so that we have the correct amount reported back in our backoffice (turnover vs tips / gifts) | No |
is_instant_capture |
Boolean | Default: True , if set to False, transactions will be pre-authorised and the funds will not be collected until the /capture_transactions/ endpoint has been called |
No |
capture_min_delay |
Integer | Default: 0 , Specifies the minimum number of hours to wait after a cart has been fully paid before attempting to capture the payment. This setting is relevant only if auto_capture is set to False. The script uses this value to ensure that the specified time has elapsed before capturing transactions. Accepted Values: 0 to 72 hours (any value greater than 72 will be defaulted to 72) |
No |
order_source |
String | Default: ecommerce , Must be one of the following options: pay_at_table , click_and_collect , delivery and ecommerce |
No |
webhook_url |
String | URL for webhook notifications. Must start with "http". | No |
amount_without_tax |
Integer | The initial amount to pay excluding tax (excluding any tip or gift (gift_amount)) | No |
tax_amount |
Integer | The tax amount (excluding any tip or gift (gift_amount)) | No |
message |
String | Additional message or note. | No |
datetime |
String | Datetime of the cart creation. | No |
currency |
String | Currency code (e.g., USD). | No |
vendor |
Object | Vendor details. See Vendor Object. | No |
customer |
Object | Customer details. See Customer Object. | No |
items |
Array | List of items. See Item Object. | No |
reference |
String | Additional reference information. | No |
client_reference |
String | Client reference information. | No |
features |
Object | Additional features. See Features Object. | No |
return_url_cancelled & return_url_success
These two parameters are used for redirecting the users once a payment has been paid in full or cancelled. These are GET
requests with the cartId and status included in the query params.
- There is no concept of a failed payment since users will always have the opportunity to try again. In the event of an order cancellation, the
return_url_cancelled
will be invoked.
Validations
cart_id
: Must be a unique identifier, and it should not already exist in the system for the given company.webhook_url
: Must start with "http" or "https".features
: Additional features are mapped from camelCase keys to snake_case keys.
Responses
This API provides 2 types of responses:
- Synchronous: This is the initial response when requesting a payment link, which contains the payment link to forward the client to.
- Asynchronous This is the response sent to the return_url_success / return_url_cancelled. These notification urls are called either when a successful payment has been made, or if a payment link has been cancelled
Asynchronous response
Both notification url responses provide the cartId in the query params to be used as reference, as well as the cart's status (i.e. https://mydomain/yavinPaymentLink/success?cartId=abcde12345&status=ok)
Synchronous responses
Success response
Status Code: 201
Response Body:
{ "payment_link": "https://yav.in/example" }
Error response
Status Code: 400
Response Body:
{ "errors": { "cart_id": [ "This cart_id already exists", "https://yav.in/example ] } }
Screen example + breakdown
Objects breakdown
Vendor Object
vendor = {
"brand_name": "VendorXYZ",
"country": "US",
"store": {
"store_id": "ABC123",
"address": {
"address": "123 Main St",
"postcode": "10001",
"city": "New York"
}
}
}
Name | Type | Description | Required |
---|---|---|---|
brand_name |
String | Brand name of the vendor. | Yes |
legal_name |
String | Legal name of the vendor. | No |
country |
String | Two-letter country code (ISO 3166-1 alpha-2) | No |
merchant_id |
String | Merchant ID. | No |
merchant_category_code |
String | Merchant category code. | No |
software_name |
String | Software name. | No |
software_version |
String | Software version. | No |
store |
Object | Store details. See Store Object. | No |
Store Object
store = {
"store_id": "ABC123",
"address": {
"address": "123 Main St",
"postcode": "10001",
"city": "New York"
}
}
Name | Type | Description | Required |
---|---|---|---|
store_id |
String | Store identifier. | Yes |
address |
Object | Store address. See Address Object. | No |
Address Object
Name | Type | Description | Required |
---|---|---|---|
address |
String | Store address. | Yes |
postcode |
String | Store postcode. | Yes |
city |
String | Store city. | Yes |
Customer Object
customer = {
"first_name": "Luke",
"last_name": "Skywalker",
"email": "luke.skywalker@yavin.com",
"telephone": "0612345678",
"address": "456 Oak St",
"city": "Paris",
"postcode": "20002"
}
Name | Type | Description | Required |
---|---|---|---|
first_name |
String | Customer's first name. | Yes |
last_name |
String | Customer's last name. | Yes |
email |
String | Customer's email address. | No |
telephone |
String | Customer's telephone number. | No |
address |
String | Customer's address. | No |
city |
String | Customer's city. | No |
postcode |
String | Customer's postcode. | No |
Item Object
items = [
{
"name": "Item1",
"total_amount": 200,
"quantity": 2,
"tax": {
"amount": 20,
"rate": 10
},
"items": [
{
"name": "SubItem1",
"total_amount": 100
},
{
"name": "SubItem2",
"total_amount": 100
}
]
},
{
"name": "Item2",
"total_amount": 300
}
]
Name | Type | Description | Required |
---|---|---|---|
name |
String | Name of the item. | Yes |
total_amount |
Integer | Total amount for the item. | Yes |
total_amount_without_tax |
Integer | Amount without tax for the item. | No |
category |
String | Item category. | No |
eligible_titre_restaurant |
Boolean | Eligibility for Titre Restaurant. | No |
free_note |
String | Free-form note for the item. | No |
quantity |
Integer | Quantity of the item. | No |
unit_price |
Integer | Unit price of the item. | No |
unit_price_without_tax |
Integer | Unit price without tax for the item. | No |
tax |
Object | Tax details. See Tax Object. | No |
items |
Array | Nested items. See Item Object. | No |
Tax Object
Name | Type | Description | Required |
---|---|---|---|
amount |
Integer | Tax amount. | Yes |
rate |
Integer | Tax rate as a decimal integer. | Yes |
Features Object
features = {
"tips": True,
"customer_contacts": True,
"meal_vouchers": True,
"share_link": {
"method": "email",
"destination": "luke@yavin.com"
},
}
Name | Type | Description | Default |
---|---|---|---|
tips |
Boolean | Indicates whether tips are active. | True |
customer_contacts |
Boolean | Indicates whether company clients are active. | True |
meal_vouchers |
Boolean | Indicates whether meal vouchers are active. | True |
share_link |
Object | See Share Link Object. | None |
Share Link Object
share_link = {
{
"method": "email",
"destination": "luke@yavin.com",
}
}
Name | Type | Description | Required |
---|---|---|---|
method |
String | Indicate method for sharing `email | sms` |
destination |
String | Provide either an email address or phone number depending on the 'method' defined above | Yes |
Webhook
If a webhook_url has been provided when generating a new link, a webhook will be send whenever any 'action' has taken place. This could be one of the following:
payment_received
- A payment has been made by the customer. This may be for part or all of the amount requestedcapture
- The transactions for the cart have all been captured, and the cart status has passed to 'ok'cancel
- The cart has been cancelled
webhook_data = {
"action": "capture",
"reason": "triggered by daily script",
"cart_id": "12345",
"payment_link": "https://yav.in/example",
"requested_amount": 2000,
"asked_amount": 2500,
"paid_amount": 2500,
"gift_amount": 500,
"status": "ok",
"transactions": [
{
"total_amount": 2500,
"gift_amount": 500,
"currency_code": "EUR",
"date_of_payment": "2023-10-16",
"gateway": "conecs",
"issuer": "UP FRANCE (CHÈQUE DÉJEUNER)",
"transaction_id": "abcd123",
"pan": "4575******1234",
"status": "ok"
}
]
}
If the webhook_url
is provided, then anytime a transaction happens (as it is possible that a single cart can have multiple transactions), the webhook_url
will be called via a POST request with the following information:
Key | Type | Description |
---|---|---|
action | String | This field indicates what action has taken place that triggered this webhook. |
reason | String | This field provides additional information about the current action taken. For instance, it could explain the reason for a cart being canceled. This field will typically be empty if the action has been triggered by calling one of the endpoints. |
cart_id | String | This is the cart_id you have provided in the original request. |
payment_link | String | The payment link for this cart |
requested_amount | Integer | The total amount requested in the original request (amount + gift_amount (if used)), in cents. |
asked_amount | Integer | The initial amount requested in the original request to be captured (value provided in the field amount , without including the gift_amount (if used)), in cents. In most cases this will be the same as requested_amount, however this will be different in the case where an authorisation payment has been requested, and the /capture_transactions endpoint has been called with an amount inferior to the orignal amount requested, or when the gift_amount field has been used |
paid_amount | Integer | The total amount paid by the customer, in cents. |
gift_amount | Integer | The amount of tip left by the customer (if activated), in cents. |
status | String | The status of the requested order. Possible values are: "ok" (order has been paid), "ko" (order has been cancelled), and "pending" (order is still active but not yet paid in full). |
transactions | Array | A list of Transaction Object containing information relating to any payments made for this order. |
Transaction Object
Parameters | Type | Description |
---|---|---|
total_amount | Integer | Amount which has been paid in cents. |
gift_amount | Integer | The tip amount, if one has been left, in cents. |
currency_code | String | The currency code in ISO-4217 format (i.e., EUR ). |
date_of_payment | String | The date and time the payment was made. The datetime string will be provided in the following format: YYYY-MM-DD HH:MM:SS and is in GMT. |
gateway | String | The gateway of the transaction that has been made. |
issuer | String | The name of the card's issuer. |
transaction_id | String | Unique ID for this transaction. |
pan | String | The first and last numbers of the card used joined by asterix characters. |
status | String | The status of the transaction |
Cancel Link
Description
This endpoint is used to cancel a payment request. Cancellation is possible only if the cart meets certain criteria. The response will indicate if the cancellation was successful or provide detailed error information.
Request
Parameters
request_body = {
"cart_id": "12345"
}
Name | Type | Description | Required |
---|---|---|---|
cart_id |
String | Unique identifier for the cart. | Yes |
Responses
Success
{
"message": "Cart has been cancelled"
}
Upon successful cancellation, the response will include the following information:
Name | Type | Description |
---|---|---|
message |
String | Indicates that the cart has been cancelled. |
Error
{
"error": "Cart contains a non-cancellable transaction",
"cart_data": {
"cart_id": "12345",
"requested_amount": 3000,
"asked_amount": 3000,
"amount_paid": 2500,
"status": "pending",
"transactions": [
{
"total_amount": 2500,
"gift_amount": 0,
"currency_code": "EUR",
"date_of_payment": "2023-10-16",
"gateway": "conecs",
"issuer": "UP FRANCE (CHÈQUE DÉJEUNER)",
"transaction_id": "abcd123",
"pan": "4575******1234"
}
]
}
}
If cancellation is not possible, the error message will be constructed as follows:
Name | Type | Description |
---|---|---|
error |
String | Reason why cancellation is not possible cart.status == 'ok': "Cart has already been paid in full" cart.status == 'ko': "Cart has already been cancelled". cart contains a non-cancellable transaction: "Cart contains a non-cancellable transaction" |
webhook_data |
Object | Information on the cart and its transactions. See webhook_data Object in the Webhook page for its definition |
Capture Transactions
Description
This endpoint is used to capture transactions for a given cart. This endpoint also allows capturing a partial amount if specified.
Important - This endpoint is only available for payment links generated with the cb_instant_capture
feature set to False
.
Request
{
"cart_id": "12345",
"amount_to_capture": 400
}
Parameters
Name | Type | Description | Required |
---|---|---|---|
cart_id |
String | Unique identifier for the cart. | Yes |
amount_to_capture |
Integer | Amount to capture, in cents. a value of 0 will cancel the payment link. However it is recommended that you use the /cancel_link/ endpoint instead. |
No |
Validations
cart_id
: Must be a valid cart identifier. If the cart status is not 'authorised', an error response will be provided.amount_to_capture
: Optional. If provided, must be an integer value and cannot exceed the original amount requested. (value provided in the fieldamount
, without including thegift_amount
(if used))
Responses
success_body = {
"message": "ok",
"data": {
"cart_id": "12345",
"amount_requested": 400,
"amount_paid": 400,
"tip_amount": 0,
"status": "ok",
"transactions": [
{
"amount_paid": 400,
"currency_code": "EUR",
"date_of_payment": "2023-10-16",
"gateway": "payline",
"issuer": "CB",
"transaction_id": "abcd123",
"pan": "4575******1234"
}
]
}
}
Successful
Upon successful capture, the response will include the following information:
Name | Type | Description |
---|---|---|
message |
String | ok Indicates that the capture was successful |
data |
Object | Data object with the same structure as the webhook response from the generate_link endpoint. |
error_body = {
"message": "The capture of one or more transaction(s) was not possible",
"errors": [
{
"transaction_id": "abcd123",
"reason": "The issuer has declined the request"
}]
}
Errors
- If any other errors are encountered during processing (e.g., bank/issuer refusal), the response will include a message indicating the capture of one or more transactions was not possible, along with detailed error information.
Name | Type | Description |
---|---|---|
message |
String | Message explaining why we were not able to fulfil your demand cart.status == 'ok': This link has already been validated and has no transactions that require capturing cart.status == 'ko': This link has already been cancelled and does not have any transactions that require capturing cart.status == 'pending': This link has not yet been paid in full Any other error will have a custom message outlining the reason for the error. |
errors |
List | If there is an error returned by the issuer whilst attempting to capture a transaction, the error information will be displayed here |
Get Cart Information
{
"cart_id": "12345",
"payment_link": "https://yav.in/example",
"requested_amount": 2000,
"asked_amount": 2500,
"paid_amount": 2500,
"gift_amount": 500,
"status": "ok",
"transactions": [
{
"total_amount": 2500,
"gift_amount": 500,
"currency_code": "EUR",
"date_of_payment": "2023-10-16",
"gateway": "conecs",
"issuer": "UP FRANCE (CHÈQUE DÉJEUNER)",
"transaction_id": "abcd123",
"pan": "4575******1234"
}
]
}
Description
This endpoint is used to obtain information about a cart based on its unique identifier. The response will provide detailed information about the cart.
Request
Parameters
Name | Type | Description | Required |
---|---|---|---|
cart_id |
String | Unique identifier for the cart. | Yes |
Response
The response will be identical to the information provided in the webhooks. Please refer to the Webhook
section for more detailed information