Introduction
Welcome to Revo API! You can use our API's to access Xef, Retail, Flow and InTouch Endpoints.
You will be able to fetch records, update or fetch the catalog, create new orders and manage stock.
Feel free to navigate through the docs and tell us if you feel that something can be improved.
Xef (Deprecated)
Even this api
is still working, it has been deprecated in favor of the new REST
one
See Xef Catalog section one instead
Basic Request
{
"auth":{
"tenant" :"account",
"password":"password"
},
"action":"action",
"data":data
}
To work with Revo external api
a POST
or GET
request is required to the following url:
https://revoxef.works/apiExternal
With a variable named message
that has to be a json
with the following information
Field | Type | Description |
---|---|---|
account | string |
is the account (same name used to login) |
password | string |
is the app password (not the backend password) |
action | string |
the action to perform (explained below) |
data | json |
data required for the action (explained below) |
The api has a limit of 60 requests every minute so the best practice is to cache for x time the fetched information done with the
getXXX
actions.
Get
Returns the full data for an specific model and id.
"data":{
"model":"model",
"id":"id"
}
Field | Description |
---|---|
model | is the model to fetch within MenuGroup MenuCategory MenuItem ModifierGroup ModifierCategory Modifier |
id | is the id of the model to fetch |
https://revoxef.works/apiExternal?message=
{
"auth" : {"tenant":"account","password":"password"},
"action" : "get",
"data" : {"model":"MenuItem","id":"236"}
}
getMenuGroups
https://revoxef.works/apiExternal?message=
{
"auth":{"tenant":"account","password":"password"},
"action":"getMenuGroups",
"data":{}
}
Since maybe we want to create an online shop that starts with menu groups, we can get them all using the action getMenuGroups
with empty data.
This will return a list of all the groups (with their ID
). With this Id we can fetch the categories.
getChildren
"data":{
"model":"parentModel",
"id":id
}
This action returns all the children for an specific model
Field | Type | Description |
---|---|---|
parentModel | string |
is the model we want its children. MenuGroup MenuCategories ModifierCategory |
id | int |
the id of the model we want its children. |
https://revoxef.works/apiExternal?message=
{
"auth":{"tenant":"account","password":"password"},
"action":"getChilds",
"data":{"model":"MenuGroup","id":2}
}
It will return all the childs of the menuGroup
with ID
2.
getInventory
https://revoxef.works/apiExternal?message=
{
"auth":{"tenant":"account","password":"password"},
"action":"getInventory",
"data":{"warehouse_id":1,"items":[2,4,10]}
}
Gets the current inventory for an Item in a Warehouse.
Field | Type | Description |
---|---|---|
warehouse_id | int |
Is the ID of the warehouse to get the quantity from |
items | array int |
Array of the ids of the items to get the quantity |
decreaseInventory
Decreases the inventory for an Item in a Warehouse.
https://revoxef.works/apiExternal?message=
{
"auth":{"tenant":"account","password":"password"},
"action":"decreaseInventory",
"data":{"warehouse_id":1,"item_id":2, "quantity":1}
}
Field | Type | Description |
---|---|---|
warehouse_id | int |
Is the ID of the warehouse to decrease the quantity from |
item_id | int |
Is the ID of the item to decrease |
quantity | int |
Is the quantity to decrease |
Get images
To get the image, you need to do a get request the ideal thing for the images is to store it in your server and only request the image if the path changed,
https://a89f683ae563759322a9-3330e0d085d4ba4fd7f5395ee3f3cd7a.ssl.cf3.rackcdn.com/{account}/images/{image_path}
or
https://a89f683ae563759322a9-3330e0d085d4ba4fd7f5395ee3f3cd7a.ssl.cf3.rackcdn.com/{account}/images/resized_100_{image_path}
For a thumbnail
Field | Type | Description |
---|---|---|
account | string |
Is your account name, same name used for login into the app |
image_path | string |
is the photo variable of the model |
Revo Display Images
Returns an array of paths for each Revo Display ads image.
To get the image
https://a89f683ae563759322a9-3330e0d085d4ba4fd7f5395ee3f3cd7a.ssl.cf3.rackcdn.com/{account}/banners/{image_path}
Field | Type | Description |
---|---|---|
account | string |
the account name |
image_path | string |
the image path returned in the array |
Xef
Prerequisites
To be able to use the external api you need a revo xef
account and a access token
and your integrator token
- Login into the desired account
- Go to account management
- Create a new token
- To get your integration token, contact us
Basic usage
The main URL for the external api is
https://revoxef.works/api/external/v2/
And you should provide the mandatory headers for the authentication
Header | Value |
---|---|
tenant | {account-username} |
Authorization | Bearer {the-token} |
client-token | {your-integrator-token} |
Contact us to get your client-token
Payment Methods
GET PaymentMethods
GET https://revoxef.works/api/external/v2/paymentMethods
Response is an array of payment methods with the following fields:
"id": 1,
"name": "Payment method name",
"active": true,
Orders
GET Orders
GET https://revoxef.works/api/external/v2/orders?from=2017-01-02&to=2017-01-04
Response is paginated for every 50
"id": 4,
"opened": "2017-12-15 08:40:52",
"closed": "2017-01-03 00:00:00",
"merged": null,
"canceled": null,
"guests": "4",
"status": "0",
"orderDiscountAmount": "0",
"sum": "0",
"discountAmount": "0",
"subtotal": "0",
"taxAmount": "0",
"total": "14.5",
"alreadyPaid": "0.0",
"tenantUser_id": null,
"tenantUserName": null,
"discount": null,
"table_id": null,
"tableName": null,
"margin": null,
"delivery_id": null,
"orderInvoices": [],
"delivery": null,
"orderContents": [
{
"id": 1,
"order_id": "4",
"item_id": "1",
"dishOrder": "0",
"seat": "0",
"quantity": "2",
"weight": "0",
"itemName": "Oran Cartwright",
"itemPrice": "17.49",
"alreadyPaidQuantity": "0",
"alreadyPrintedQuantity": "0",
"modifiers": null,
"discount": null,
"taxPercentage": "0",
"discountAmount": "79.84",
"taxAmount": "85.91",
"total": "98.98",
"extrasAmount": "12.96",
"subtotal": "74.96",
"priceWithExtrasIndividual": "66.52",
"notes": null,
"price_id": null,
"optional_modifiers": null,
"format_pivot_id": null,
"margin": null,
"menuMenuContents": [],
}
],
}
Field | Required | Description |
---|---|---|
from |
optional | The starting date of the orders fetched |
to |
optional | The ending date of the orders fetched |
page |
optional | As the orders are paginated, use this parameter to select the page to fetch |
You can add
?withPayments
parameter. This way apart fromorderContents
another array will be loaded calledorderInvoices
, it will contain an array of invoices and each invoice will contain an array oforderPayments
.
"orderContents": [{…}, {…}, …],
"orderInvoices": [
{
"orderPayments": [
{
"payAmount": 10,
"paymentMethod": 1,
…
}, {…}, …
], …
}, {…}, …
]
You can add ?withRooms parameter. This way apart from
orderContents
another array will be loaded calledtable
which will contain aroom
.
"orderContents": [{…}, {…}, …],
"table": {
"id" : <table_id>,
"name" : <tableName>,
"room_id" : <room_id>,
"room" : {
"id" : <room_id>,
"name" : <roomName>
},
}
Rooms
GET Rooms
GET https://revoxef.works/api/external/v2/rooms
Response is paginated for every 20 rooms
"id": 1,
"name": "Room 1",
"order": "0",
"active": "1",
You can add
?withTables
parameter. This way apart fromrooms
another array will be loaded calledtables
, it will contain a tables array within each room.
"tables": [
{
"id": 1,
"name": "Table 1",
"x": "0",
"y": "0",
"width": "100",
"height": "100",
"baseX": "0",
"baseY": "0",
"isJoined": "0",
"baseWidth": "100",
"baseHeight": "100",
"color": "#dddddd",
"type_id": "2",
"room_id": "1",
"price_id": null,
}
]
GiftCards
POST GiftCards
Query parameter | Description | |
---|---|---|
balance | required | Card amount |
uuid | required | Unique identifier for the card |
campaign_id | optional | Campaign ID when giftcard should be linked with a campaign (get ID from backend) |
GET https://revoxef.works/api/external/v2/giftCards
Response
{
"balance": 1.25,
"uuid": "123456"
"campaign_id": "3"
}
Responses
Value | Meaning | Description |
---|---|---|
201 | HTTP_CREATED | Call succeed |
422 | HTTP_UNPROCESSABLE_ENTITY | Call failed |
Use Gift Card
Response
{
"balance": 1.25,
"customer_id": "3"
}
POST GiftCards/{uuid}
Query parameter | Description | |
---|---|---|
uuid | required | Unique identifier for the card |
Post parameter | Description | |
---|---|---|
amount | required | The amount to discount |
Customers
GET Customers
GET https://revoxef.works/api/external/v2/customers
GET https://revoxef.works/api/external/v2/customers/<customer_id>
POST https://revoxef.works/api/external/v2/customers
Create a customer: {"name": "Customer 1", "active": 1}
Update a customer: {"id":2, "name": "Customer 1 updated", "active": 0}
Create multiple customers: [
{"name": "Customer 1", "active": 1},
{"name": "Customer 2", "active": 1}
]
DELETE https://revoxef.works/api/external/v2/customers/<customer_id>
Response is a groups paginated array with the following fields:
'id',
'name',
'active',
'tax_id',
'photo',
'super_group_id',
'printer_id',
'printer_group_id',
Xef Catalog
Inside catalog there are many resources; items, categories, groups, modifiers and sellingFormats.
To explore those resources as a paginated list we can use a GET request with the following pattern. GET https://revoxef.works/api/external/v2/catalog/{resource}
replacing the desired resource on this url.
Prerequisistes
To be able to use the external api you need a revo xef
account and a access token
- Login into the desired account
- Go to account management
- Create a new token
Basic usage
The main URL for the external api
https://revoxef.works/api/external/v2/catalog
And you should provide the mandatory headers for the authentication
Header | Value |
---|---|
tenant | {account-username} |
Authorization | Bearer {the-token} |
client-token | {client-token} |
Items
Can list, show, create, update and delete Items`
GET https://revoxef.works/api/external/v2/catalog/items
or
GET https://revoxef.works/api/external/v2/catalog/categories/<category_id>/items
Response for GET items is an items paginated array with the following fields:
"id"
"name"
"price"
"photo"
"order"
"active"
"info"
"type"
"hasInventory"
"usesWeight"
"category_id"
"tax_id"
"printer_id"
"printer_group_id"
"modifier_group_id"
"modifier_category_id"
"isMenu"
"shouldAppearInMenuList"
"super_group_id"
"isOpen"
"nameKitchen"
"costPrice"
"displayInventory"
"isLinked"
"allergies"
"dish_order_id"
"barcode"
"unit_id"
"extra_id"
"useAverageCostPrice"
"cookDuration"
"buttonName"
"minQuantity"
"report_category_id"
"config"
GET https://revoxef.works/api/external/v2/catalog/items/<item_id>
POST https://revoxef.works/api/external/v2/catalog/items
Create a item (POST)
catalog/items
{"name": "Product 1", "active": 1, "category_id": 2}
Update a item (POST)
catalog/items
{"id":2, "name": "Product 1 updated", "active": 0, "category_id": 2}
Create multiple items (POST)
catalog/items
{"items": [
{"name": "Product 1", "active": 1, "category_id": 2},
{"name": "Product 2", "active": 1, "category_id": 1}
]}
DELETE https://revoxef.works/api/external/v2/catalog/items/<item_id>
Categories
Can list, show, create, update and delete Categories
GET https://revoxef.works/api/external/v2/catalog/categories
or
GET https://revoxef.works/api/external/v2/catalog/groups/<group_id>/categories
Response for GET categories is a categories paginated array with the following fields:
'id',
'name',
'group_id',
'active',
'tax_id',
'photo',
'super_group_id',
'printer_id',
'printer_group_id',
'modifier_category_id',
'modifier_group_id',
'dish_order_id'
GET https://revoxef.works/api/external/v2/catalog/categories/<category_id>
POST https://revoxef.works/api/external/v2/catalog/categories
Create a category (POST)
catalog/categories
{"name": "Category 1", "active": 1, "group_id": 2}
Update a category (POST)
catalog/categories
{"id":2, "name": "Category 1 updated", "active": 0, "group_id": 2}
Create multiple categories (POST)
catalog/categories
{"categories": [
{"name": "Category 1", "active": 1, "group_id": 2},
{"name": "Category 2", "active": 1, "group_id": 1}
]}
DELETE https://revoxef.works/api/external/v2/catalog/categories/<category_id>
Groups
Can list, show, create, update and delete Groups
GET https://revoxef.works/api/external/v2/catalog/groups
Response is a groups paginated array with the following fields:
'id',
'name',
'active',
'tax_id',
'photo',
'super_group_id',
'printer_id',
'printer_group_id',
GET https://revoxef.works/api/external/v2/catalog/groups/<group_id>
POST https://revoxef.works/api/external/v2/catalog/groups
Create a group (POST)
catalog/groups
{"name": "Group 1", "active": 1}
Update a group (POST)
catalog/groups
{"id":2, "name": "Group 1 updated", "active": 0}
Create multiple groups (POST)
catalog/groups
{"groups": [
{"name": "Group 1", "active": 1},
{"name": "Group 2", "active": 1}
]}
DELETE https://revoxef.works/api/external/v2/catalog/groups/<group_id>
Warehouses
GET Warehouses https://revoxef.works/api/external/v2/warehouses
Response is a warehouses paginated array with the following fields:
'id',
'name',
'order',
GET Warehouses stocks https://revoxef.works/api/external/v2/warehouses/<warehouse_id>
Response for a warehouse is a stocks paginated array with the following fields:
'id',
'quantity',
'defaultQuantity',
'alert',
'warehouse_id',
'item_id',
'unit_id'
POST https://revoxef.works/api/external/v2/warehouses/<warehouse_id>/addStock
Add a stock to a warehouse (POST)
warehouses/<warehouse_id>/addStock
{"item_id": <item_id>, "quantity": <quantity_to_add>}
POST https://revoxef.works/api/external/v2/warehouses/<warehouse_id>/setStock
Set a item stock to a warehouse (POST)
warehouses/<warehouse_id>/setStock
{"item_id": <item_id>, "quantity": <quantity_to_set>}
Set multiple stocks to a warehouse (POST)
warehouses/<warehouse_id>/setStock
{"stocks": [
{"item_id": <item_id>, "quantity": <quantity_to_set>},
{"item_id": <item_id>, "quantity": <quantity_to_set>},
]}
Purchases
GET Purchase orders https://revoxef.works/api/external/v2/purchaseOrders
Response is a purchase orders paginated array with the following fields:
'id',
'vendor_order_id',
'reference',
'subtotal',
'tax',
'total',
'status',
'vendor_id',
'vendorName',
'contentsArray'
GET Purchase order contents https://revoxef.works/api/external/v2/purchaseOrders/{purchase_order_id}
Response is a purchase order contents paginated array with the following fields:
'id',
'status',
'quantity',
'received',
'price',
'subtotal',
'tax',
'total',
'order_id',
'item_vendor_id',
'itemName',
'itemBarcode',
'item_id'
Flow Api
Prerequisistes
To be able to use the Flow api you need a revo xef
account and a access token
- Login into the desired account
- Go to account management
- Create a new token
Basic usage
The main URL for the external api is
https://revoxef.works/apiFlow
Creating an order with customer
POST
shell script
POST message={
"auth":{
"tenant":"account",
"token":"account_token"
},
"action":"newOrder",
"data":{
"customer":{
"name":"customer name",
"email":"email2@example.com",
"notes":"{\"note1\":\"text1\",\"note2\":\"text2\"...}
},
"table_id":[
1,
2,
3
],
"guests":"8",
"contents":[
],
"payments":[
]
}
}
Response with the created order identifier
shell script
{
"result" : true,
"errorMessage" : null,
"data" : {
"id" : 1
}
}
Xef Loyalty
Base URL
https://revoxef.works/api/loyalty/
Create an order
Data can be passed as show in the example. Although it can also be passed as form params, passing Content-Type: application/json
header.
curl -XPOST -H 'tenant: {tenant}' -H 'Authorization: Bearer {token}' -d 'customer={
"name":"Jordi",
"email":"jordi.p@revo.works"
}&order={
"subtotal" : 1336,
"sum" : 1336,
"table_id" : null, // Optional (In case you want it into a table in xef)
"tableName" : // Optional (In case you want to give another table name)
"total" : 1460,
"taxAmount" : 124,
"notes" : "You can send some optional notes",
"contents":[{
"item_id" : 949,
"quantity" : 1.000,
"menuContents" : null,
"id" : null,
"subtotal" : 910,
"itemPrice" : 1000,
"tax" : 1000,
"modifiers" : [],
"total" : 1000,
"taxAmount" : 90,
"dishOrder" : 2, //Optional
"notes" : "You can also send optional notes here"
},{
"item_id" : 2041,
"quantity" : 1,
"menuContents" : null,
"id" : null,
"subtotal" : 153,
"itemPrice" : 160,
"tax" : 2000,
"modifiers" : [],
"total" : 160,
"taxAmount" : 7
},{
"item_id" : 927,
"quantity" : 1,
"menuContents" : null,
"id" : null,
"subtotal" : 273,
"itemPrice" : 300,
"tax" : 1000,
"modifiers" : [],
"total" : 300,
"taxAmount" : 27
}
]}&delivery={ // Optional; object to specify delivery info.
"channel": null, // Optional; Code according to Delivery plarform (Deliveroo, Ubereats, Deliverect, Just Eats, etc.)
"address":"Carrer del Bruc, 23, 1er, 08241 pis, Barcelona", // Full address
"phone": "666666666", // Optional
"date": "2020-09-23 14:01:59"
}¬ification_hook="service:http://www.example.com"' 'https://revoxef.works/api/loyalty/orders'
POST orders
Headers:
Parameter | Value |
---|---|
tenant | account name |
Authorization | Bearer {token} |
client-token | {client-token} |
Body:
Parameter | Type | Description |
---|---|---|
order | json |
Json encoded order |
customer | array |
optional Of name and email ["name" => "The name", "email" => "theEmail@example.com"] |
delivery | json |
optional Delivery object ["address" => "The address ('Pickup' if delivery not needed)", "date" => "Datetime when order should be delivered", "phone" => "The phone", "channel" => "The delivery channel, if neeeded"] |
notification_hook | string |
optional An url where to notify the order status changes prefixed with the service id service:https://notificationurl.com/notify |
skipMerge | bool |
optional if you don't want the order to be merged if there is another one already opened |
warehouse_id | integer |
optional Send the xef revo warehouse_id if you want the stock to be discounted |
Response:
{
"total" : 12.23,
"taxAmount" : 1.23,
"subtotal" : 10,
"sum" : 10,
"contents" : [
[
"item_id" : 1,
"total" : 7,
"taxAmount" : 2,
"subtotal" : 5,
"itemPrice" : 7,
"taxPercentage" : 10,
], [
"item_id" : 2,
"total" : 7,
"taxAmount" : 2,
"subtotal" : 5,
"itemPrice" : 7,
"taxPercentage" : 10,
]
]
}
Order with payment
order={
"contents" : [{
...
}],
"payment" : {
"amount" : 12.40,
"tip" : 0.50,
"payment_reference" : "your-payment-reference",
"payment_method_id" : 1
}
"emailToSendInvoice" : "anemail@example.com",
"locale" : "en"
}
You can send a payment while creating the order as well by adding the payment
element inside the order
Field | Required | Description |
---|---|---|
amount |
yes | The payment amount |
tip |
no | The tip for that payment |
payment_reference |
no | A info field that references your payment id |
payment_method_id |
no | In case you want it to match with a revo payment, or don't send to use the standard InTouch payment |
emailToSendInvoice |
no | If you want to send the invoice to an email |
locale |
no | The locale to use when sending the email |
Standalone payment
payment={
"amount" : 12.40,
"tip" : 0.40,
"payment_reference" : "your-payment-reference",
"payment_method_id" : 1
}
Otherwise, you might need the order id before doing the payment, so you can add it afterwards with another call, where the parameters follow the same rules as the above call
POST orders/{orderId}/payments
Fetch an Order
GET orders/{orderId}
You can fetch an order information using this endpoint
Fetch an Order with Table Id
If you want to fetch an order for an specific table you can use this endpoint.
GET tables/{tableId}/order
It will return a 404 if there is no open order at that table at the moment
Fetch multiple Order with list of tables id
If you want to fetch an order for an specific table you can use this endpoint.
It will return the open
orders paginated by 50.
GET orders?table_id[]=5&table_id[]=6&table_id[]=7
You can send the array using the body as well instead of the query
It will return a 404 if there is no open order at that table at the moment
Cancel Order
curl -XDELETE -H 'tenant: {tenant}' -H 'Authorization: Bearer {token}' \
-d 'reason="Payment Failed"' \
'https://revoxef.works/api/loyalty/orders/123456'
During the next 5 minutes after an order has been place, you can cancel it (for example, if the defeered payment failed)
DELETE orders/{orderId}
Field | Required | Description |
---|---|---|
reason |
yes | The reason why the order is canceled |
Fetch Invoice details
You can use this endpoint to fetch an specific invoice details
GET invoices/{invoiceId}
Fetch tables
Get all the tables with is name and id
GET tables
Tables availability
{
"available" : true
}
Use this method to know if a table is available or not (there is no open order on it)
GET tables/{tableId}/available
Xef Reports
Authentication
curl --header "tenant: {myaccount}" \
--header "authorization: Bearer {token}" \
--header 'client-token: {client-token}' \
https://revoxef.works/api/external/v3
Base endpoint
https://revoxef.works/api/external/v3
You should send the headers tenant
with your account username and authorization
with the token created at account > tokens
Get your token at https://revoxef.works/account/tokens
Request
curl --header "tenant: {myaccount}" --header "authorization: Bearer {token}" \ --header 'client-token: {client-token}' \
https://revoxef.works/api/external/v3/reports/{reportName}?start_date=2018-01-01&end_date=2018-01-29
GET reports/{reportName}
Field | Type | Description |
---|---|---|
start_date |
YYYY-mm-dd | The initial date for the report |
end_date |
YYYY-mm-dd | The final date for the report |
Response
{
"current_page": 1,
"data": {"HERE WILL GO THE SPECIFIC REPORT DATA"},
"from": 1,
"last_page": 4,
"next_page_url": "https://revoxef.works/api/external/v2/reports/{reportName}?page=2",
"path": "https://revoxef.works/api/external/v2/reports/{reportName}",
"per_page": 50,
"prev_page_url": null,
"to": 50,
"total": 190
}
All responses will have this header
Available reports
Here is a list of all available reports
- actionLog
- categories
- contentDiscounts
- cookDurations
- customers
- discounts
- groupedInvoices
- hours
- channels
- invoices
- menuProducts
- menus
- openOrders
- orderContents
- orders
- payments
- presences
- products
- rooms
- receipts
- stocks
- stockMovements
- inventoryContents
- taxes
- turns
- tenantUsers
- warehouses
- allProducts
- canceledContents
- canceledOrders
Filters
Filter | Type | Description |
---|---|---|
start_date |
YYYY-mm-dd | (required) The initial date for the report |
end_date |
YYYY-mm-dd | (required) The final date for the report |
start_time |
HH:mm | The start time for the report |
end_time |
HH:mm | The end time for the report |
room |
int | Room id |
dayofweek |
int | Where Sunday is 1 and Saturday is 7 |
priceRate |
int | Price rate id |
withContents |
Append contents | |
withItem |
Append item details | |
withInvoices |
Append invoices |
Master
In case you have a master account you can create a token for the master account and use it to access all the chain reports as well as get a list of all the accounts within the master account
Get Accounts
GET https://revoxef.works/api/external/v2/accounts
Chain reports
GET https://revoxef.works/api/external/v2/accounts/reports/{reportName}
And you have to add a new header that defines the chain to connect to
Header | Value | Description |
---|---|---|
tenant | account | Master account name, |
authorization | Bearer {token} | The token created at backoffice |
chain | chain | chain username returned in the accounts GET method |
Xef Webhooks
Introduction
Revo Xef comes with webhooks. You can add as many as you need in the webhooks
page https://revoxef.works/account/webhooks
Once you create your first webhook a secret key will be generated and this will be used to create a hash that we will send in every webhook call so you can verify it is us who send it.
We will send the header.
X-Revo-Hmac-SHA256
With the body hashed with the SHA256
algorithm and using the secret key
generated when creating the first webhook.
The payload will always have the keys
{
"event" : "order.closed",
"data" : {
"id" : 298
"table_id" : 12
"guests" : 4
}
}
Key | Description |
---|---|
event | One of the available webhook events |
data | the data depending on the event |
Available webhooks
Model | Events |
---|---|
Product | updated, deleted |
Customer | created, updated, deleted |
Order | created, closed |
There is the `{model}.` event that means that you want to receive all the available events for the model*
When creating a new webhook
you will have the following options
Option | Description |
---|---|
Active | If you want the event to be sent or not |
Url | The url it should call |
Event | The event that will triger it |
Product
// Updated
{
"event" : "product.updated"
"data" : {
"id" : {id},
"type" : {type},
"name" : {name},
"price" : {photo}
}
}
// Deleted
{
"event" : "product.deleted"
"data":{
"id" : {id}
}
}
Customer
// Created
{
"event" : "customer.created"
"data" : {
"id" : {id},
"active" : {active},
"name" : {name},
"address" : {address},
"city" : {city},
"state" : {state},
"country" : {country},
"postalCode" : {postalCode},
"nif" : {nif},
"web" : {web},
"email" : {email},
"phone" : {phone},
"notes" : {notes},
"extra_id" : {extra_id},
"created_at" : {created_at},
"updated_at" : {updated_at},
"deleted_at" : {deleted_at},
}
}
// Updated
{
"event" : "customer.updated"
"data" : {
"id" : {id},
"active" : {active},
"name" : {name},
"address" : {address},
"city" : {city},
"state" : {state},
"country" : {country},
"postalCode" : {postalCode},
"nif" : {nif},
"web" : {web},
"email" : {email},
"phone" : {phone},
"notes" : {notes},
"extra_id" : {extra_id},
"created_at" : {created_at},
"updated_at" : {updated_at},
"deleted_at" : {deleted_at},
}
}
// Deleted
{
"event" : "customer.deleted"
"data":{
"id" : {id}
}
}
Order
// Created
{
"event" : "order.created"
"data" : {
"id" : {id},
"opened" : {opened},
"closed" : {closed},
"merged" : {merged},
"guests" : {guests},
"orderDiscountAmount" : {orderDiscountAmount},
"sum" : {sum},
"discountAmount" : {discountAmount},
"subtotal" : {subtotal},
"taxAmount" : {taxAmount},
"total" : {total},
"alreadyPaid" : {alreadyPaid},
"tenantUser_id" : {tenantUser_id},
"tenantUserName" : {tenantUserName},
"discount" : {discount},
"customer_id" : {customer_id},
"table_id" : {table_id},
"tableName" : {tableName},
"status" : {status},
"notes_sent" : {notes_sent},
"delivery_id" : {delivery_id},
"margin" : {margin},
"gratuity" : {gratuity},
"offline_id" : {offline_id},
"notes" : {notes},
"refunded_order_id" : {refunded_order_id},
"orderContents" : [
{
"id" : {id},
"order_id" : {order_id},
"item_id" : {item_id},
"dishOrder" : {dishOrder},
"seat" : {seat},
"quantity" : {quantity},
"weight" : {weight},
"itemPrice" : {itemPrice},
"alreadyPaidQuantity" : {alreadyPaidQuantity},
"alreadyPrintedQuantity" : {alreadyPrintedQuantity},
"modifiers" : [
{
"category_id" : {category_id},
"id" : {id},
"order" : {order},
"name" : {name},
"photo" : {photo},
"price" : {price},
}, {
"category_id" : {category_id},
"id" : {id},
"order" : {order},
"name" : {name},
"photo" : {photo},
"price" : {price},
},
],
"discount" : null,
"discountAmount" : "0.00",
"taxAmount" : "0.10",
"taxPercentage" : "10.00",
"total" : "1.15",
"extrasAmount" : "0.00",
"subtotal" : "1.05",
"priceWithExtrasIndividual" : "1.15",
"notes" : null,
"cancelReason" : null,
"created_at" : "2016-10-25 12:43:25",
"updated_at" : "2016-10-25 13:08:34",
"itemName" : "Café",
"optional_modifiers" : null,
"format_pivot_id" : null,
"margin" : null,
"price_id" : null,
"tenantUser_id" : null,
"menuMenuContents" : [],
"orderContentCombination" : null,
}
],
"orderInvoices" : [
{
"id" : {id},
"order_id" : {order_id},
"customer_id" : {customer_id},
"customerJSON" : {customerJSON},
"date" : {date},
"paymentMode" : {paymentMode},
"sum" : {sum},
"discountAmount" : {discountAmount},
"orderDiscountAmount" : {orderDiscountAmount},
"taxAmount" : {taxAmount},
"subtotal" : {subtotal},
"total" : {total},
"cancelReason" : {cancelReason},
"number" : {number},
"notAccountable" : {notAccountable},
"orderPayments" : [
{
"id" : {id},
"invoice_id" : {invoice_id},
"tenantUser_id" : {tenantUser_id},
"tenantUserName" : {tenantUserName},
"date" : {date},
"tipAmount" : {tipAmount},
"payAmount" : {payAmount},
"totalCollected" : {totalCollected},
"change" : {change},
"paymentMethod" : {paymentMethod},
"voidReason" : {voidReason},
"turn_id" : {turn_id},
"cancelReason" : {cancelReason},
"gratuity" : {gratuity},
"provider_id" : {provider_id},
},
]
}
],
"delivery": null
}
}
// Closed
{
"event" : "order.closed"
"data":{
"id" : {id},
"table_id" : {table_id},
"total" : {total},
"guests": {guests}
}
}
Retail
Prerequisistes
To be able to use the external api you need a revo retail
account and an access token
- Login into the desired account
- Go to account management
- Create a new token
Authorization
The main URL for the external api is
https://revoretail.works/api/external
And you should provide the mandatory headers for the authentication
Header | Value |
---|---|
username |
{account-username} |
Authorization |
Bearer {the-token} |
Generic list response
{
"current_page" : 1,
"from" : 1,
"last_page" : 2,
"next_page_url" : "https://revoretail.works/api/external/[resource]?page=2",
"path" : "http://revoretail.works/api/external/[resource]",
"per_page" : 50,
"prev_page_url" : null,
"to" : 50,
"total" : 10,
"data": []
}
Available resources
Get list of groups
Get a list of groups
GET https://revoretail.works/api/external/catalog/groups
[
{
"id": 1,
"name", "Shoes",
"photo" : "",
"order" : 0,
"active" : 1,
"group_id" : 1,
"tax_id" : 1
},
{
"id": 2,
"name", "Pants",
"photo" : "",
"order" : 0,
"active" : 1,
"group_id" : 1,
"tax_id" : 1
}
]
Get list of categories
Get a list of categories, can filter by group
GET https://revoretail.works/api/external/catalog/categories?group=
[
{
"id": 1,
"name", "Trousers",
"photo" : "",
"order" : 0,
"active" : 1,
"group_id" : 1,
"tax_id" : 1
},
{
"id": 2,
"name", "Shorts",
"photo" : "",
"order" : 0,
"active" : 1,
"group_id" : 1,
"tax_id" : 1
}
]
Get list of products
Get a list of products, can filter by category
GET https://revoretail.works/api/external/catalog/products?category=
[
{
"id": 1,
"name", "new nike xl"
"reference" : "",
"info" : "",
"shortInfo" : "",
"brand" : "",
"season" : "",
"photo" : "",
"order" : "0",
"active" : "1",
"featured" : "0",
"isOpen" : "0",
"type" : "0",
"price" : "",
"costPrice" : "",
"barcode" : "",
"category_id" : 1,
"tax_id" : 1,
"main_product_id" : null,
"usesStockManagement" : false,
"usesWeight" : false,
"unit_id" : "1"
}, {
"id": 2,
"name", "new nike m"
"reference" : "",
"info" : "",
"shortInfo" : "",
"brand" : "",
"season" : "",
"photo" : "",
"order" : "0",
"active" : "1",
"featured" : "0",
"isOpen" : "0",
"type" : "0",
"price" : "",
"costPrice" : "",
"barcode" : "",
"category_id" : 1,
"tax_id" : 1,
"main_product_id" : null,
"usesStockManagement" : false,
"usesWeight" : false,
"unit_id" : "1" }
]
If we add withStocks
parameter we'll get an stocks list within each product.
For example:
[
{
"id": 1,
"name", "new nike xl",
...
"stocks": [{
"id": 1,"warehouse_id": 1, "quantity": 10
},{
"id": 2,"warehouse_id": 3, "quantity": 15
}]
}
]
Variants
RevoRetail uses variants to store product sizes, colors, etc..
It has 3 objects kinds to represent them
** 1. Variant Set ** Variant kind, for example, size or color.
GET https://revoretail.works/api/external/catalog/variantSets
[
{"id": 1, "name": "Color"},
{"id": 1, "name": "Size"}
]
** 2. Variant **
Variants
are every variantSet variant, so blue, red, yellow,… for colors or L, XL,… for sizes.
GET https://revoretail.works/api/external/catalog/variants
[
{
"id": 1,
"name": "Red",
"order": 2,
"variant_set_id": 1,
"color": null
},
{
"id": 2,
"name": "Blue",
"order": 1,
"variant_set_id": 1,
"color": null
},
{
"id": 3,
"name": "L",
"order": 1,
"variant_set_id": 2,
"color": null
},
{
"id": 4,
"name": "XL",
"order": 1,
"variant_set_id": 2,
"color": null
}
]
** 3. Product Variants ** Then we have product variants that are variants linked to products.
GET https://revoretail.works/api/external/catalog/productsVariants
[
{
"id": 1,
"product_id": 23,
"variant_1_id": 1,
"variant_2_id": 3
},
{
"id": 2,
"product_id": 23,
"variant_1_id": 2,
"variant_2_id": 3
},
{
"id": 3,
"product_id": 25,
"variant_1_id": 2,
"variant_2_id": 4
},
{
"id": 4,
"product_id": 25,
"variant_1_id": 1,
"variant_2_id": 4
}
]
Get list of taxes
Get a list of available taxes
GET https://revoretail.works/api/external/config/taxes
[
{
"id": 1,
"name": "10%",
"taxPercentage": 10.00
},
{
"id": 2,
"name": "21%",
"taxPercentage": 21.00
}
]
Catalog generation
In order to generate a catalog via API we can create groups, group's categories and category's products. in any of these cases we can send a dictionary with the desired object to create (group, category or product) or we can send a list of dictionaries to create multiple objects at the same time. e.g.:
POST https://revoretail.works/api/external/catalog/groups
// BODY Dictionary:
{
"name": "Group 1",
"active": 1, // Optional, defaults to 1
"tax_id": 1 // Optional, defaults to null
}
// BODY List of dictionaries:
[
{
"name": "Group 1",
"active": 1, // Optional, defaults to 1
"tax_id": 1 // Optional, defaults to null
}, {
"name": "Group 2"
"active": 1, // Optional, defaults to 1
"tax_id": 1 // Optional, defaults to null
}
]
In any case its responses are a 200 JSON with 2 fields (success and errors):
{
"success": 1, // Amount of created objects
"errors": [{"name": "Group 1"}] // List of object that couldn't be created
}
Create a category
POST https://revoretail.works/api/external/catalog/categories
{
"name": "Category 1",
"group_id": 1,
"active": 1, // Optional, defaults to 1
"tax_id": 1 // Optional, defaults to null
}
Create a product
POST https://revoretail.works/api/external/catalog/products
{
"name": "Product 1",
"category_id": 1,
"id": // Optional, defaults autoincrement
"active": 1, // Optional, defaults to 1
"tax_id": 1, // Optional, defaults to null
"reference": "", // Optional
"info": "", // Optional
"shortInfo": "", // Optional
"brand": "", // Optional
"season": "", // Optional
"order": "", // Optional
"featured": "", // Optional
"isOpen": "", // Optional
"price": "", // Optional
"costPrice": "", // Optional
"barcode": "", // Optional
"main_product_id": "", // Optional
"usesStockManagement": "", // Optional
"usesWeight": "", // Optional
"unit_id": 1 // Optional
}
Update a product
PUT https://revoretail.works/api/external/catalog/products/{item_id}
{
"name": "Product 1",
"price": 15,
"info": "",
"id": // Optional, defaults autoincrement
"active": 1, // Optional, defaults to 1
"tax_id": 1, // Optional, defaults to null
"reference": "", // Optional
"shortInfo": "", // Optional
"brand": "", // Optional
"season": "", // Optional
"order": "", // Optional
"featured": "", // Optional
"isOpen": "", // Optional
"costPrice": "", // Optional
"barcode": "", // Optional
"main_product_id": "", // Optional
"usesStockManagement": "", // Optional
"usesWeight": "", // Optional
"unit_id": 1 // Optional
}
Get stocks list
Get an stock list.
GET https://revoretail.works/api/external/catalog/stocks
[
{
"id": 1,
"item_id": "1",
"warehouse_id": "1",
"quantity": 10.00
},
{
"id": 2,
"item_id": "1",
"warehouse_id": "2",
"quantity": 20.00
},
{
"id": 3,
"item_id": "2",
"warehouse_id": "2",
"quantity": 15.00
}
]
Generate stock movement.
We can generate stock movements with the following POST (required parameters: warehouse id, product id and quantity to move)
POST https://revoretail.works/api/external/stocks/add
{
"product_id": 1,
"warehouse_id": 1,
"quantity": 22.5
}
The answer is a 200 JSON with the current warehouse stock quantity
.
Create Order
Store an order.
POST https://revoretail.works/api/external/orders
{
"notes": "",
"shippingAmount": 0,
"sum": 71.5,
"subtotal": 59.09,
"discount": 17.5,
"orderDiscount": 6.5,
"tax": 1,
"total": 65,
"discountObject": {
"amount": 1.1,
"id": null,
"isPercentage": true,
"name": "Without iva"
},
"customer_id": null,
"shipping_id": null,
"employee_id": 1,
"closed_at": "2017-12-31 13:00:00",
"order_contents": [
{
"name": "Dark shoes XL",
"quantity": 2,
"weight": null,
"price": 27,
"sum": 54,
"discount": 11,
"subtotal": 40,
"tax": 4,
"total": 44,
"taxPercentage": 10,
"discountObject": {
"amount": 1.1,
"id": null,
"isPercentage": false,
"name": "2nd unit 50%"
},
"notes": "",
"margin": 0,
"product_id": 1
}, {
"name": "Red shoes M",
"quantity": 1,
"weight": null,
"price": 27.5,
"sum": 27.5,
"discount": 0,
"subtotal": 25,
"tax": 2.75,
"total": 27.5,
"taxPercentage": 10,
"discountObject": {},
"notes": "",
"margin": 0,
"product_id": 2
}
]
}
This will return an order. As relevant fields we do get the order id which will be used to make payments and create an invoice.
{"id": 1, "status": 0, ...}
Create an order payment
Create order payments with its invoice.
POST https://revoretail.works/api/external/orders/{order_id}/invoices
{
"payments": [
{
"amount": 65,
"change": 0,
"extra": 0,
"payment_method_id": 1
}
]
}
This will return an order invoice. As new relevant fields we can get the id.
{"id": 1, "number": "E-1", ...}
Get list of Payments Methods
Get a list of available payment methods (card, cash, others...)
GET https://revoretail.works/api/external/config/payment_methods
[
{
"id": 1,
"name": "Card",
},
{
"id": 2,
"name": "Cash",
}
]
Sync chains
Sync account chains data
POST https://revoretail.works/api/external/chains/sync
Response
{
"data": {"message": Synced},
}
Retail Reports
Authentication
curl --header "username: {myaccount}" \
--header "authorization: Bearer {token}" \
https://revoretail.works/api/external/reports
Base endpoint
https://revoretail.works/api/external/reports
You should send the headers username
with your account username and authorization
with the token created at account > tokens
Get your token at https://revoretail.works/admin/account/tokens
Header | Value |
---|---|
username | {account} |
authorization | Bearer {token} |
The token
it obtained at Account managment section of RevoRetail. You just need to create a new token givin it a descriptive name. For example api acess
.
Response format
{
"current_page": 1,
"data": [ [Report data will go here] ],
"from": 1,
"last_page": 4,
"next_page_url": "https://revoretail.works/api/external/reports/{reportName}?page=2",
"path": "https://revoretail.works/api/external/reports/{reportName}",
"per_page": 50,
"prev_page_url": null,
"to": 50,
"total": 190
}
All requests will return the info following this template.
This format is paginated to avoid the system collapse. The object data
contains the lines of the requested report.
Available reports
Here you have a list of the available filters.
- categories
- categorySales
- contentsDiscounts
- customerOrderContents
- customersList
- customers
- deliveryNoteContents
- fullProductSales
- groups
- hours
- inOuts
- inventories
- inventoryContents
- marketingAnswers
- orderDiscounts
- orderInvoices
- ordersByCustomer
- orders
- payments
- presences
- productList
- productSales
- products
- stockCategories
- stockGroups
- stockMovements
- stocks
- targets
- taxes
- turns
- vendorItems
Available filters
A parte de start_date
y end_date
se puede filtrar por otros campos (siempre que tengan sentido con el informe). A continuación les dejamos una lista:
Filter | Value | Description |
---|---|---|
start_date |
YYYY-MM-DD | Required The start date of the report |
end_date |
YYYY-MM-DD | Required The end date of the report |
start_time |
HH:mm | The start time of the report |
end_time |
HH:mm | The end time of the report |
employee |
int | Id of the employee to filter with |
room |
int | Id of the room to filter with |
dayofweek |
int | Where Sunday is 1 and Saturday is 7 |
priceRate |
int | The id of the price rate |
cashier |
int | The id of the cashier |
discount |
int | The id of the cashier |
dateField |
string | The date field that'll be used on filters query (created_at, updated_at, closed_at, opened_at) |
RevoFlow
Base URL
https://revoflow.works/api/v1/
Authorization
The authorization is send inside request headers using the following fields:
Field | Value |
---|---|
Tenant | {username} |
Authorization | Bearer {token} |
Response JSON:
{
"ok": true/false, (shows wether request succeded or not).
"message": "", (when error occurs, an error message is sent)
"data": {}/[]
}
Bookings
Start and End dates must be sent. Response is an array of bookings inside requested dates.
https://revoflow.works/api/v1/bookings?start=2017-01-01&end=2017-01-31
{
"ok": true,
"message": "",
"data": [
{
"id": 1,
"date": "2017-01-19",
"time": "12:30:00",
"duration": "02:00:00",
"status": 1,
"guests": 3,
"shift_id": 1,
"origin": 3,
"customer_id": 1,
"notes": "",
"employee_id": null,
"employeeUserName": "Widget",
"booking_reference_id": null,
"tables": "[1]",
"isMailSent": false,
"isOrderSent": false,
"room_id": null,
"cancelation_reason_id": null,
"sentToRevo": null,
"token": null,
"total": "0.00",
"worker_id": null,
"order_id": null,
"pre_assigned_tables": null,
"payments": [
{
"id": 1,
"name": "pepito",
"amount": "12.50",
"payment_method_id": 1,
"booking_id": 1,
"employee_id": 1
}
],
"products": [
{
"id": 1,
"name": "Product 1",
"product_id": 1,
"revo_id": 1,
"price": "12.50",
"quantity": 1,
"booking_id": 1,
"employee_id": 1,
"duration": null,
"spacing": null,
"type": null
}
]
},
...]
}
Finds a booking by its ID (in that example, the booking id is 1)
https://revoflow.works/api/v1/bookings/1
Save Booking (POST)
https://revoflow.works/api/v1/bookings
{
data: {
"booking": {
"date": "2017-01-19",
"time": "12:30:00",
"duration": "02:00:00",
"guests": 3,
"shift_id": 1,
"notes": ""
}
"customer": {
"name": "John Tree",
"email": "john@email.com",
"phone": "458234923",
"notes": "Notes"
}
}
}
Update booking (PUT)
https://revoflow.works/api/v1/bookings/{id}
{
data: {
"booking": {
"date": "2017-01-19",
"time": "12:30:00",
"duration": "02:00:00",
"guests": 3,
"shift_id": 1,
"notes": "",
...
}
}
}
Customers
Gets the a list of paginated customers. The page and limit must be set in request.
https://revoflow.works/api/v1/customers?page=1&limit=10
{
"ok": true,
"message": "",
"data": {
"currentPage": "1",
"customers": [
{
"id": 1,
"name": "asdfa",
"address": "Address",
"city": "City",
"state": "State",
"country": "Country",
"postalCode": "Postal Code",
"nif": null,
"web": null,
"email": "eduard@revo.works",
"phone": "asdfasdf",
"notes": null,
"password": null,
"remember_token": null,
"created_at": "2017-01-17 00:10:12",
"updated_at": "2017-01-17 00:10:12",
"deleted_at": null
}
],
"pages": 1,
"left": 0
}
}
Products
Get products list
https://revoflow.works/api/v1/products
{
"ok": true,
"message": "",
"data": [
{
"id": 1,
"name": "Patatas Picantes",
"revo_id": 956,
"price": "4.50",
"startDate": null,
"endDate": null,
"photo": "FlKi6IoWZ8.png",
"duration": "00:00:00",
"spacing": "00:00:00",
"type": 0,
"order": 0
},
...]
}
Get product by its ID
https://revoflow.works/api/v1/products/1
Shifts
Get shifts list
https://revoflow.works/api/v1/shifts
{
"ok": true,
"message": "",
"data": [
{
"id": 1,
"name": "Comida 1",
"startTime": "12:00:00",
"slotTime": "02:00:00",
"endTime": "14:00:00",
"weekdays": "[1,1,1,1,1,1,1]",
"deleted_at": null,
"weekday": null
},
...]
}
Tables
Get tables by day and shift.
https://revoflow.works/api/v1/tables?date=2017-02-01&shift_id=1
{
"ok": true,
"message": "",
"data": [
{"id":1,"name":"Table 1","isJoined":"0","room_id":"1"},
{"id":2,"name":"Table 2","isJoined":"0","room_id":"1"},
}
]
}
Availabillity
Get the availabillity between requested dates.
https://revoflow.works/api/v1/availability?from=2017-02-01&to=2017-02-15
{
"ok": true,
"message": "",
"data": [
{
"2017-01-30": {
"1": {
"capacity": 114,
"available": 114,
"shift_id": 1
},
"2": {
"capacity": 114,
"available": 114,
"shift_id": 2
},
"3": {
"capacity": 114,
"available": 114,
"shift_id": 3
}
}
}
]
}
Time Available
Get the available time on each shift.
https://revoflow.works/api/v1/shiftsTime?date=2017-02-01&guests=5
{
"ok": true,
"message": "",
"data": [
{
"name": "Dinner",
"id": 1,
"time" : [
"20:00:00",
"20:15:00",
"20:30:00",
"20:45:00",
"21:00:00",
"21:15:00",
"21:30:00",
"21:45:00",
"22:00:00"
]
}
]
}
Next bookings
Get next bookings inside interval ["-1h" - "+2h"].
https://revoflow.works/api/v1/nextBookings
{
"ok": true,
"message": "",
"data": [
{
"id": 1,
"date": "2017-01-19",
"time": "12:30:00",
"duration": "02:00:00",
"status": 1,
"guests": 3,
"shift_id": 1,
"origin": 3,
"customer_id": 1,
"notes": "",
"employee_id": null,
"employeeUserName": "Widget",
"booking_reference_id": null,
"tables": "[1]",
"isMailSent": false,
"isOrderSent": false,
"room_id": null,
"cancelation_reason_id": null,
"sentToRevo": null,
"token": null,
"total": "0.00",
"worker_id": null,
"order_id": null,
"pre_assigned_tables": null,
"payments": [
{
"id": 1,
"name": "pepito",
"amount": "12.50",
"payment_method_id": 1,
"booking_id": 1,
"employee_id": 1
}
],
"products": [
{
"id": 1,
"name": "Product 1",
"product_id": 1,
"revo_id": 1,
"price": "12.50",
"quantity": 1,
"booking_id": 1,
"employee_id": 1,
"duration": null,
"spacing": null,
"type": null
}
],
"start": "2018-02-03 17:00:00"
"end": "2018-02-03 19:00:00"
},
...]
}
Close Booking
Closes booking by Order ID
https://revoflow.works/api/v1/bookings/closeWithOrder/{id}
{
"ok": true,
"message": "",
"data": []
}
Closes booking by ID
https://revoflow.works/api/v1/bookings/close/{id}
{
"ok": true,
"message": "",
"data": []
}
``
RevoFlow integration API
Basic Request
{
"auth":{
"tenant" :"account",
"password":"password"
},
"action":"action",
"data":data
}
To work with Revo external api
a POST
or GET
request is required to the following url:
https://admin.revo.works/apiFlow
With a variable named message
that has to be a json
with the following information
Field | Type | Description |
---|---|---|
account | string |
is the account (same name used to login) |
password | string |
is the app password (not the backend password) |
action | string |
the action to perform (explained below) |
data | json |
data required for the action (explained below) |
The api has a limit of 60 requests every minute so the best practice is to cache for x time the fetched information done with the
getXXX
actions.
Sync
Returns the full data for an specific model and id.
"data":{
"model":"TableTable"
"fromDate:"yyyy/mm/dd HH:mm:ss",
}
Field | Description |
---|---|
model | is the model to sync in TableRoom TableTable |
fromDate | the date from which changes to sync |
https://admin.revo.works/apiFlow?message=
{
"auth":{
"tenant" :"user1",
"password":"user1"
},
"action":"sync",
"data":{
"model":"TableRoom",
"fromDate":"2016/12/01 16:05:20"
}
}
searchProducts
This action searches and returns the products where the name is like the text you ask for
"data": {
"text": "burger"
}
Text needs to be at least of 3 characters
updateTables
"data": {
"tables": [
{'id':1,'x':10,'y':10,'width':100,'height':100,'isJoined':false},
{'id':2,'x':20,'y':20,'width':100,'height':100,'isJoined':true},
{'id':3,'x':30,'y':30,'width':100,'height':100,'isJoined':false}
]
}
This action updates the tables Layout (not the original one)
newOrder
"data": {
"table_id": 3,
"guests": 4,
"contents": [
{
"itemPrice": 10.2,
"itemName": "product name",
"item_id": 5,
"quantity": 2
},
{
"itemPrice":7,
"itemName": "product name 2",
"item_id": 2,
"quantity": 4
}
]
"payments":[
{
"payment_method_id:1,
"amount":10.10,
}
]
}
updateOrder
"data": {
"table_id": 2,
"guests": 4,
"payments":[
{
"payment_method_id:1,
"amount":10.10,
}
]
}
Use this function to create a new Order to Revo,
You can send payments where payment_method_id
is 1
(Card) or 2
(Cash)
InTouch
Basic request
POST/GET/PUT {username}.revointouch.works/api/v1/customer
Authorization: Bearer {token}
curl -X GET
--header "Authorization: Bearer K2YBo90R2bil1mVKTkHh9cRlzstQYHIqYjX3oAYFT9HWluGcq9DaDh4LxVUI"
myaccount.revointouch.works/api/v1/customer/cards
Revo-InTouch comes with an easy to use REST
API Interface.
All requests will have the same structure.
With the autorization header when calling authenticated based resources
Images
https://a89f683ae563759322a9-3330e0d085d4ba4fd7f5395ee3f3cd7a.ssl.cf3.rackcdn.com/{xef-account}/images/{url}
Login
// Response
{
"data" : {
"api_token" : "token",
"info" : {
"points" : 378,
"id" : 1,
"postalCode" : "08240",
"email" : "jordi.p@revo.works",
"name" : "Jordi Puigdellívol"
}
}
}
POST login
Parameters
Parameter | Description |
---|---|
string User email | |
password | string User password |
Register
POST register
Same response as login
Field | Type | Example |
---|---|---|
name | string |
Bruce |
lastName | string |
Wayne |
password | string |
batman |
postalCode | string |
08240 |
birthDate | date |
1950-12-23 |
email |
bruce@wayne.com | |
subscribe | bool |
1 |
Cards
GET cards
{
// GET cards
"data" : [
{
"active" : 1,
"amount" : 0,
"id" : 8,
"uuid" : "58b194cc08bfa",
"photo" : "hi5bOD",
"customer_id" : 1,
"name" : "My gift card",
},
{
"active" : 1,
"amount" : 0,
"id" : 7,
"uuid" : "5876009347306",
"photo" : "O6Magz",
"customer_id" : 1,
"name" : "My gift card",
},
]
}
GET cards/{card_uuid}
// GET cards/{card_uuid}
{
"data" : {
"active" : 1,
"amount" : 0,
"id" : 8,
"uuid" : "58b194cc08bfa",
"photo" : "hi5bOD",
"customer_id" : 1,
"name" : "My gift card",
}
}
PUT cards/{card_uuid}
To reload a gift card
Field | Description |
---|---|
amount | int amount in cents |
payment_token | string (optional) the stripe payment token. If null or not present it will use customer's default credit card |
// `PUT cards/{card_uuid}` To reload a gift card
{
"data" : {
"newAmount" : 1000
}
}
POST cards
Field | Description |
---|---|
name | string the name of the new card |
// `POST cards`
{
"data" : {
"amount" : 0,
"id" : 9,
"uuid" : "58c2b978bb6ca",
"photo" : "IWtdZ6",
"name" : "My gift card",
"customer_id" : 1
}
}
Syncable models
Doing a get request with a from
parameter will return the objects to sync from them. Ideally you can store those objects into your system to be more responsive and sync when something changes
Stores
GET stores
{
"data" : {
"new" : [
{
"id" : 1,
"phone" : "669 68 65 61",
"geo" : "41.7268582,1.8211535",
"address" : "Arquitecte Oms 2",
"token" : "ctzHxM48wBbRzZFM",
"city" : "Manresa",
"username" : "user1",
"country" : "Spain",
"name" : "An store"
}
],
"updated" : null,
"deleted" : null
}
}
Categories
GET categories
"data" : {
"new" : [
{
"deleted_at" : null,
"id" : 1,
"name" : "Category 1",
},
{
"deleted_at" : null,
"id" : 2,
"name" : "Category 2",
}
],
"updated" : null,
"deleted" : null
}
}
Shifts
GET shifts
{
"data" : {
"new" : [
{
"end" : "23:59:00",
"start" : "00:00:00",
"id" : 1,
"daysOfWeek" : [
1,
2,
3,
4,
5,
6,
0
],
}
],
"updated" : null,
"deleted" : null
}
}
DeliveryShifts
These only should be used when store.use_delivery_shifts
is true, if it is false, use the standard shifts for deliveries as well
GET deliveryShifts
{
"data" : {
"new" : [
{
"end" : "23:59:00",
"start" : "00:00:00",
"id" : 1,
"daysOfWeek" : [
1,
2,
3,
4,
5,
6,
0
],
}
],
"updated" : null,
"deleted" : null
}
}
Products
GET products
{
"data" : {
"new" : [
{
"points" : 150,
"product_category_id" : 1,
"id" : 1,
"price" : 1240,
"tax" : 1000,
"pointsRequired" : null,
"deleted_at" : null,
"photo" : "cGs3lw7I6H.png",
"name" : "Product 1"
},
{
"points" : 250,
"product_category_id" : 1,
"id" : 2,
"price" : 652,
"tax" : 1000,
"pointsRequired" : null,
"deleted_at" : null,
"photo" : "JmXM9ft8aV.png",
"name" : "Product 2"
},
{
"points" : 350,
"product_category_id" : 2,
"id" : 3,
"price" : 1840,
"tax" : 1000,
"pointsRequired" : null,
"deleted_at" : null,
"photo" : "aaHwaf1Bql.png",
"name" : "Product 3"
},
],
"updated" : null,
"deleted" : null
}
}
Menu Categories
GET menuCategories
{
{
"id" : 1
"name" : "Drinks",
"product_id" : 1,
"order" : 2
},
{
"name" : "Take away",
"product_id" : 2,
"order" : 1
}
}
Menu Products
GET menuProducts
{
{
"product_id" : 1,
"menu_category_id" : 1
"order" : 2,
"price" : 0,
},
{
"product_id" : 15,
"menu_category_id" : 1
"order" : 1,
"price" : 1500,
}
}
Modifier Categories
GET modifierCategories
{
"data" : {
"new" : [
{
"id" : 1,
"deleted_at" : null,
"type" : 1,
"name" : "Size",
"isMandatory" : 1
},
{
"id" : 2,
"type" : 2,
"name" : "Toppings",
"isMandatory" : 0
}
],
"updated" : null,
"deleted" : null
}
}
Modifiers
GET modifiers
{
"data" : {
"new" : [
{
"id" : 1,
"price" : 0,
"modifier_category_id" : 1,
"name" : "Small"
},
{
"id" : 2,
"price" : 1050,
"modifier_category_id" : 1,
"name" : "XL"
},
],
"updated" : null,
"deleted" : null
}
}
Product - Modifier Cateogires
GET productModifierCategories
{
"data" : {
"new" : [
{
"product_id" : 1,
"id" : 1,
"deleted_at" : null,
"modifier_category_id" : 1,
},
{
"product_id" : 1,
"id" : 2,
"deleted_at" : null,
"modifier_category_id" : 1,
}
],
"updated" : null,
"deleted" : null
}
}
Credit Cards
POST creditCards
Parameters:
Field | Description |
---|---|
token | The stripe card token |
{
"data" : {
"address_line1_check" : null,
"dynamic_last4" : null,
"last4" : "4242",
"address_line2" : null,
"metadata" : [
],
"address_city" : null,
"address_zip_check" : null,
"address_zip" : null,
"country" : "US",
"object" : "card",
"address_line1" : null,
"address_state" : null,
"brand" : "Visa",
"cvc_check" : "pass",
"exp_month" : 4,
"name" : null,
"fingerprint" : "R92NDa6Z6u42Srgc",
"funding" : "credit",
"id" : "card_19vovPJVS7gfpCD2mGY750mu",
"tokenization_method" : null,
"customer" : "cus_AGLc0pme4PvRyf",
"address_country" : null,
"exp_year" : 2024
}
}
Orders
Last Order
GET lastOrder
{
"data" : {
"lastContents" : [
{
"id" : 16,
"quantity" : 1,
"tax" : 1000,
"total" : 1240,
"order_id" : 102,
"subtotal" : 1128,
"price" : 1240,
"product_id" : 1,
"pointsSpent" : null,
"customer_id" : 1,
"taxAmount" : 112
},
{
"id" : 11,
"quantity" : 1,
"tax" : 1000,
"total" : 1240,
"order_id" : 98,
"subtotal" : 1128,
"price" : 1240,
"product_id" : 1,
"pointsSpent" : null,
"customer_id" : 1,
"taxAmount" : 112
},
],
"lastOrder" : {
"closed_at" : "2017-01-09 11:33:27",
"id" : 102,
"subtotal" : 1128,
"created_at" : "2017-01-05 11:47:15",
"contents" : [
{
"id" : 16,
"quantity" : 1,
"tax" : 1000,
"created_at" : "2017-01-05 11:47:15",
"total" : 1240,
"order_id" : 102,
"subtotal" : 1128,
"price" : 1240,
"product_id" : 1,
"pointsSpent" : null,
"taxAmount" : 112
}
],
"pointsEarned" : 124,
"total" : 1240,
"customer_id" : 1,
"taxAmount" : 112
}
}
}
Create an order
order={
"subtotal" : 1673,
"id" : null,
"total" : 1840,
"taxAmount" : 167
}
delivery={
"address" : "Central perk, 12",
"city" : "New York",
"phone" : "555-555-555",
"time" : "12:30",
"geolocation" : "41.5500976,2.0964411"
}
contents = [{
"product_id" : 1,
"quantity" : 1,
"id" : null,
"subtotal" : 0,
"price" : 1240,
"tax" : 1000,
"pointsSpent" : 150,
"total" : 0,
"taxAmount" : 0
},{
"product_id" : 3,
"quantity" : 1,
"id" : null,
"subtotal" : 1673,
"price" : 1840,
"tax" : 1000,
"pointsSpent" : null,
"total" : 1840,
"taxAmount" : 167
"modifiers" : [
[
"name" : "topping 1",
"price": 500
],
[
"name" : "topping 2",
"price": 0
],
]
},{
"product_id" : 1,
"quantity" : 1,
"id" : null,
"subtotal" : 0,
"price" : 1240,
"tax" : 1000,
"pointsSpent" : 150,
"total" : 0,
"taxAmount" : 0,
"menuContents" : [
"product_id" : 4,
"price" : 120
"modifiers" : []
]
}]
POST orders
Parameters:
Field | Type | Description |
---|---|---|
order | json |
the order json following the format below |
contents | array json |
the array of contents json following the format below |
card | string |
the customer gift card to use to do the charge |
store | int |
(optional) the store id to to create the order (it can be ignored if there is only one store) |
delivery | json |
(optional) The delivery information it should contain address city phone geolocation and time fields |
Contents can have optional parameters such as modifiers
and menuContents
Field | Type | Description |
---|---|---|
modifiers | array json |
the array of modifiers |
menuContents | array json |
the array of menuContents |
Other routes
Verb | Route |
---|---|
GET | / |
PUT | / |
GET | cards |
GET | cards/{uuid} |
POST | cards |
PUT | cards/{uuid} |
POST | cards/{card}/associate |
POST | cards/{card}/transfer |
GET | orders |
POST | orders |
PUT | orders/{id} |
GET | points |
GET | creditCards |
POST | creditCards |
DELETE | creditCards/{id} |
PUT | creditCards/{id} |
POST | invoices/{id}/points/obtain |
Overview
Prerequisistes
To be able to use the external api you need a revo xef
account and a access token
- Request an organization token at support@revo.works
Basic usage
The main URL for this api is
http://overview.revo.works/api
And you should provide the mandatory headers for the authentication
Header | Value |
---|---|
username | {organization-name} |
Authorization | Bearer {the-token} |
Accept | application/json |
Create lead
Create a lead end point.
POST leads
http://overview.revo.works/api/leads
Following fields can be passed (all of them are optional):
{
'user_id' : null, // unsignedInteger, operator_id if known
'probability' : null, // tinyInteger [1 => VERY_LOW, 2 => LOW, 3 => MEDIUM, 4 => HIGH, 5 => VERY_HIGH]
'total' : 0.0, // decimal
'total_devices' : 10, // decimal
'trade_name' : "Testing business", // string
'channel' : "thoughApi", // string (the way to know where the request comes from) (OPTIONAL)
'fiscal_name' : "Testinig INC.", // stringº
'name' : "John", // string
'cif' : "39393938", // string
'surname1' : "Snow", // string
'surname2' : "White", // string
'email' : "john@revo.works", // string
'phone' : "+34 668686854", // varchar(255)
'city' : "Manchester", // string
'product' : 2, // tinyInteger [1 => Xef, 2 => Retail]
'type_segment' : 1, // [1 => SEGMENT_SMALL, 2 => SEGMENT_MEDIUM, 3 => SEGMENT_LARGE]
'general_typology' : 1, // GENERAL TYPOLOGIES IDS ARE SPECIFIED BELOW*
'specific_typology' : [1, 2] // SPECIFIC TYPOLOGIES IDS ARE SPECIFIED BELOW**
'property_spaces' : 4, // PROPERTY SPACES IDS ARE SPECIFIED BELOW***
'property_quantity' : 3, // How many properties does the lead have
'property_capacity' : 99, // Local Max capacity
'property_franchise' : 1, // Is a franchise
'devices' : 6, // How many devices has?. integer
'devices_current' : "", // Specify device names
'xef_pos_critical_quantity' : 4, // Nº de comanderos entorno crítico. integer
'xef_cash_quantity' : 1, // Cashier number. integer
'xef_printers_quantity' : 1, // Kitchen printers. integer
'xef_kds' : 1, // Would likes KDS? boolean
'xef_kds_quantity' : 1, // How many KDS? integer
'pos' : -2, // Current POS. -2 means None. tinyInteger
'pos_other' : "", // If -1 one specified, here an other pos name can be written. string
'retail_sale_mode' : 1, // Require a sale in front of customer? boolean
'retail_sale_location' : 2 // [1 => onLocal, 2 => onMobility] Sale location. bool
'can_use_another_pos' : 0, // tinyInteger
'xef_pms' : -1, // Current PMS. -1 means Other. tinyInteger
'xef_pms_other' : "", // If -1 one specified, here an other pms name can be written. string
'erp' : -2, // Current ERP. -2 means None. tinyInteger
'erp_other' : "", // If -1 one specified, here an other erp name can be written. string
'soft_other' : "", // If -1 one specified, here an other soft name can be written. string
'status' : 1, // tinyInteger [1 => NEW, 2 => FIRST_CONTACT, 3 => VISITED, 4 => COMPLETED, 5 => FAILED]
'offer_status' : 1, // tinyInteger [1 => PENDING, 2 => IN_CURSE, 3 => PRESENTED, 4 => COMPLETED, 5 => EXPIRED]
'soft' => [ -2 ], Current SOFTS. -2 means None. array of tinyIntegers SOFTS IDS ARE SPECIFIED BELOW****
}
Response is a json with created lead:
{"id": 1, "status": 0, ...}
Some Organizations can have custom fields, like it is shown in the following example:
{
'is_already_customer' : 1, // boolean
'is_already_using_organization_tpv' : 0, // boolean
'share_bandwith_with_customers' : 2, // tinyInteger [1 => 'yes', 0 => 'no', 3 => 'yesButDontKnowMega' ]
'is_smart_business_wired' : 1, // tinyInteger [1 => 'yes', 0 => 'no', 3 => 'dontKnow' ]
}
Tips
* General typologies
Key | Value |
---|---|
1 | Cafetería |
2 | Bar |
3 | Restaurante |
4 | Discoteca |
5 | Take away |
6 | Delivery |
7 | Hotel |
9 | Panadería |
10 | Foodtruck |
11 | Comida al peso |
12 | Solo eventos |
13 | Retail store |
14 | Distribución de productos y Fuerza comercial |
15 | Autoventa / movilidad |
16 | Peluquería / estética |
17 | Panadería |
18 | Venta a granel |
19 | Aviación / transporte |
20 | Eventos / corners |
21 | Espectáculos |
** Specific typologies
Key | Value |
---|---|
1 | Carta |
2 | Eventos |
3 | Menú |
4 | Retail store |
5 | Distribución de productos y Fuerza comercial |
6 | Autoventa / movilidad |
7 | Peluquería / estética |
8 | Panadería |
9 | Venta a granel |
10 | Aviación / transporte |
11 | Eventos / corners |
12 | Espectáculos |
*** Property spaces
Key | Value |
---|---|
1 | Una única Sala |
2 | Sala + Terraza |
3 | Multiples Salas y/o Terrazas |
4 | Estándar |
5 | Diferentes áreas / plantas |
6 | Locales separados |
**** Softs
Key | Value |
---|---|
1 | Gstock |
2 | CHef Control |
3 | Distrito K |
4 | GIRnet |
5 | Revo Flow |
6 | CoverManager |
7 | ElTenedor |
8 | Restoo |
9 | Deliveroo |
10 | Glovo |
11 | tSpoonLab |
12 | GIRnet |
13 | PrestaShop |
14 | WooCommerce |
Responses
Value | Meaning | Description |
---|---|---|
201 | HTTP_CREATED | Call succeed |
422 | HTTP_UNPROCESSABLE_ENTITY | Call failed |