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.
API Changelog
In this section, we will list a deployment record for API changes and improvements.
This records have been maintained since date 16/10/2024.
Xef (Deprecated)
Although 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 120 requests every minute so the best practice is to cache for x time the fetched information done with the
getXXX
actions.
Get (Deprecated)
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 (Deprecated)
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 (Deprecated)
"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 (Deprecated)
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 (Deprecated)
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 |
Revo Display Images (Deprecated)
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 |
Orders (Deprecated)
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 | Type | Required | Description |
---|---|---|---|
from |
YYYY-mm-dd | required | The starting date of the orders fetched. |
to |
YYYY-mm-dd | required | The ending date of the orders fetched. |
page |
number | optional | As the orders are paginated, use this parameter to select the page to fetch. |
pagination |
number | optional | Number of objects per page. The default value is 50 and the max allowed is 200. |
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>
},
}
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} |
The API has a data size límit of 2MB for each request.
The API has a limit of 120 requests every minute so the best practice is to cache for x time the fetched information done with the
getXXX
actions.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,
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
Data must be sent as an array.
Create a customer: [{"name": "Customer 1", "active": 1}]
"name" is required
Update a customer: [{"id": 2, "name": "Customer 1 updated", "active": 0}]
"id" and "name" are required
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',
Others
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.
Normal size:
https://storage.googleapis.com/revo-cloud-bucket/xef/{account}/images/{image_path}
Thumbnail size:
https://storage.googleapis.com/revo-cloud-bucket/xef/{account}/images/resized_100_{image_path}
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 |
The image_path is the photo name (with the extension). You can get the photos in the catalog.
Sync Resources
POST https://revoxef.works/api/external/chains/sync
With this endpoint, you will be able to sync some resources from the master account to each child account.
The 'tenant' must be from the master account.
The resources that will be synced, are the next ones:
- Tax
- Unit
- MenuSuperGroup
- ModifierCategory
- Modifier
- ModifierGroup
- ModifierPivot
- MenuGroup
- MenuCategory
- MenuItem
- LinkedItemPivot
- MenuItemInventory
- MenuMenuCategory
- MenuMenuPivot
- SellingFormat
- Combination
- CombinationGroup
- CombinationPivot
- ItemSellingFormatPivot
More info about Master Accounts.
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.
The API has a data size límit of 2MB for each request.
The API has a limit of 120 requests every minute so the best practice is to cache for x time the fetched information done with the
getXXX
actions.
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
The URL for the integrations API environment:
https://integrations.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} |
Content-Type | application/json |
URL parameters
You can add the next URL parameters for the paginated responses:
Key | Type | Required | Description |
---|---|---|---|
page |
number | optional | As the data is paginated, use this parameter to select the page to fetch. |
pagination |
number | optional | Number of objects per page. The default value is 50 and the max allowed is 200. |
At the bottom of the request, it is specified information about the current page and pagination.
Catalog structure
The main catalog structure is the following:
Groups => Categories => Items
Items cannot exist without Categories, and Categories cannot exists without Groups.
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:
Field | Type | Required | Extra info |
---|---|---|---|
id | number | - | autoincrement |
name | string | required | |
photo | string | optional | |
active | boolean | optional | default: 1 |
tax_id | number | optional | |
printer_id | number | optional | |
printer_group_id | number | optional | |
super_group_id | number | optional | |
extra_id | string | optional |
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
All parameters are optional.
{
"name": "Group 1",
"active": 1
...
}
Update a group (POST)
catalog/groups
{
"id": 2, // required to update
"name": "Group 1 updated",
"active": 0
...
}
Create/update multiple groups (POST)
catalog/groups
{
"groups": [
{
"id": 1, // only required to update
"name": "Group 1",
...
},
{
"id": 2, // only required to update
"name": "Group 2",
...
}
...
]
}
DELETE https://revoxef.works/api/external/v2/catalog/groups/<group_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:
Field | Type | Required | Extra info |
---|---|---|---|
id | number | - | autoincrement |
name | string | required | |
photo | string | optional | |
active | boolean | optional | default: 1 |
group_id | number | required | |
tax_id | number | optional | |
printer_id | number | optional | |
printer_group_id | number | optional | |
modifier_category_id | number | optional | |
modifier_group_id | number | optional | |
super_group_id | number | optional | |
dish_order_id | number | optional | |
extra_id | string | optional |
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": 1
...
}
Update a category (POST)
catalog/categories
{
"id": 1, // required to update
"name": "Category 1 updated",
"active": 0
...
}
Create/update multiple categories (POST)
catalog/categories
{
"categories": [
{
"id": 1, // only required to update
"name": "Category 1",
...
},
{
"id": 2, // only required to update
"name": "Category 2",
...
}
...
]
}
DELETE https://revoxef.works/api/external/v2/catalog/categories/<category_id>
Items
For the Items, there are the following types:
- Normal Items: item.type = 0
- Menu Items: item.type = 1
- Selling format Items: item.type = 4
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:
Field | Type | Required | Extra info |
---|---|---|---|
id | number | - | autoincrement |
name | string | required | |
price | decimal | required | |
photo | string | optional | |
active | boolean | optional | default: 1 |
info | string | optional | |
type | number | required | normal = 0, menu = 1, selling format = 4 |
hasInventory | boolean | optional | default: 0 |
usesWeight | boolean | optional | default: 0 |
category_id | number | required | |
tax_id | number | optional | |
printer_id | number | optional | |
printer_group_id | number | optional | |
modifier_group_id | number | optional | |
modifier_category_id | number | optional | |
isMenu | boolean | optional | default: 0 |
shouldAppearInMenuList | boolean | optional | default: 0 |
super_group_id | number | optional | |
isOpen | boolean | optional | default: 0 |
nameKitchen | string | optional | |
costPrice | decimal | required | |
displayInventory | boolean | optional | default: 0 |
isLinked | boolean | optional | default: 0 |
allergies | string | optional | see Allergies |
dish_order_id | number | optional | |
barcode | string | optional | |
unit_id | number | optional | |
extra_id | string | optional | |
useAverageCostPrice | boolean | optional | default: 0 |
cookDuration | number | optional | |
buttonName | string | optional | |
minQuantity | number | optional | |
report_category_id | number | optional | |
config | string | optional |
Allergies
There are the following allergies:
Allergies | Value |
---|---|
eggs | 1 |
sesame | 2 |
lupin | 3 |
mustard | 4 |
fish | 5 |
celery | 6 |
crustaceans | 7 |
peanuts | 8 |
mollusks | 9 |
soy | 10 |
nuts | 11 |
sulfites | 12 |
dairy | 13 |
To save (POST) the allergies, you must send the values split by ';' Example: "2;3;6;10"
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",
"price": 8.50,
"active": 1,
"category_id": 1
...
}
Update a item (POST)
catalog/items
{
"id": 1, // required to update
"name": "Category 1 updated",
"active": 0
...
}
Create/update multiple items (POST)
catalog/items
{
"items": [
{
"id": 1, // only required to update
"name": "Item 1",
...
},
{
"id": 2, // only required to update
"name": "Item 2",
...
}
...
]
}
DELETE https://revoxef.works/api/external/v2/catalog/items/<item_id>
Selling Formats
Can list, show, create, update and delete Selling Formats
GET https://revoxef.works/api/external/v2/catalog/sellingFormats
Response for GET selling formats is a selling formats paginated array with the following fields:
Field | Type | Required | Extra info |
---|---|---|---|
id | number | - | autoincrement |
name | string | required | |
photo | string | optional | |
order | number | optional | |
active | boolean | optional | default: 1 |
GET https://revoxef.works/api/external/v2/catalog/sellingFormats/<format_id>
POST https://revoxef.works/api/external/v2/catalog/sellingFormats
Create a selling format (POST)
catalog/sellingFormats
{
"name": "Selling format 1",
"active": 1
...
}
Update a selling format (POST)
catalog/sellingFormats
{
"id": 1, // required to update
"name": "Selling format 1 updated",
"active": 0
...
}
Create/update multiple selling formats (POST)
catalog/sellingFormats
{
"sellingFormats": [
{
"id": 1, // only required to update
"name": "Selling format 1",
...
},
{
"id": 2, // only required to update
"name": "Selling format 2",
...
}
...
]
}
DELETE https://revoxef.works/api/external/v2/catalog/sellingFormats/<format_id>
Selling Format Pivots
An Item can be of Selling format type.
This can be distinguished by item.type = 4.
The Selling format item can manage different Selling formats, with different prices and quantities, for its TPV selling.
Can list, show, create, update and delete Selling Format Pivots
GET https://revoxef.works/api/external/v2/catalog/sellingFormatPivots
Response for GET selling format pivots is a selling format pivots paginated array with the following fields:
Field | Type | Required | Extra info |
---|---|---|---|
id | number | - | autoincrement |
quantity | decimal | required | |
price | decimal | required | |
order | number | optional | |
format_id | number | required | selling format |
item_id | number | required | item.type = 4 |
combination_group_id | number | optional | |
unit_id | number | optional |
GET https://revoxef.works/api/external/v2/catalog/sellingFormatPivots/<format_pivot_id>
POST https://revoxef.works/api/external/v2/catalog/sellingFormatPivots
Create a selling format pivot (POST)
catalog/sellingFormatPivots
{
"price": 5.00,
"quantity": 1,
"format_id": 1,
"item_id": 1,
...
}
Update a selling format pivot (POST)
catalog/sellingFormatPivots
{
"id": 1, // required to update
"quantity": 2
...
}
Create/update multiple selling format pivots (POST)
catalog/sellingFormatPivots
{
"sellingFormatPivots": [
{
"id": 1, // only required to update
"quantity": 1,
"format_id": 1,
"item_id": 1,
...
},
{
"id": 2, // only required to update
"quantity": 2,
"format_id": 2,
"item_id": 2,
...
}
...
]
}
DELETE https://revoxef.works/api/external/v2/catalog/sellingFormatPivots/<format_pivot_id>
Modifiers
The Modifiers structure is the following:
Modifier groups (<= Modifier pivot =>) Modifier categories => Modifiers.
Modifiers must exist in a Modifier category, and Modifier categories can exist independently or in a Modifier group.
Both Modifier groups and Modifier categories can be linked to catalog Categories and Items.
Can list, show, create, update and delete Modifiers
GET https://revoxef.works/api/external/v2/catalog/modifiers
Response for GET modifiers is a modifiers paginated array with the following fields:
Field | Type | Required | Extra info |
---|---|---|---|
id | number | - | autoincrement |
name | string | required | |
price | decimal | required | |
photo | string | optional | |
order | number | optional | |
category_id | number | required | modifier category |
cookDuration | number | optional | |
active | boolean | optional | default: 1 |
extra_id | string | optional |
GET https://revoxef.works/api/external/v2/catalog/modifiers/<modifier_id>
POST https://revoxef.works/api/external/v2/catalog/modifiers
Create a modifier (POST)
catalog/modifiers
{
"name": "Modifier 1",
"price": 1.00,
"category_id": 1,
"active": 1
...
}
Update a modifier (POST)
catalog/modifiers
{
"id": 1, // required to update
"price": 2.00
...
}
Create/update multiple modifiers (POST)
catalog/modifiers
{
"modifiers": [
{
"id": 1, // only required to update
"name": "Modifier 1",
...
},
{
"id": 2, // only required to update
"name": "Modifier 2",
...
}
...
]
}
DELETE https://revoxef.works/api/external/v2/catalog/modifiers/<modifier_id>
Modifier Categories
Can list, show, create, update and delete Modifier Categories
GET https://revoxef.works/api/external/v2/catalog/modifierCategories
Response for GET modifier categories is a modifier categories paginated array with the following fields:
Field | Type | Required | Extra info |
---|---|---|---|
id | number | - | autoincrement |
name | string | required | |
order | number | optional | |
isChoice | boolean | optional | 0 for select one, 1 (default) for multiple choice |
isOptional | boolean | optional | default: 1 |
active | boolean | optional | default: 1 |
GET https://revoxef.works/api/external/v2/catalog/modifierCategories/<modifier_category_id>
POST https://revoxef.works/api/external/v2/catalog/modifierCategories
Create a modifier category (POST)
catalog/modifierCategories
{
"name": "Modifier category 1"
...
}
Update a modifier category (POST)
catalog/modifierCategories
{
"id": 1, // required to update
"isChoice": 0
...
}
Create/update multiple modifier categories (POST)
catalog/modifierCategories
{
"modifierCategories": [
{
"id": 1, // only required to update
"name": "Modifier category 1",
...
},
{
"id": 2, // only required to update
"name": "Modifier category 2",
...
}
...
]
}
DELETE https://revoxef.works/api/external/v2/catalog/modifierCategories/<modifier_category_id>
Modifier Groups
Can list, show, create, update and delete Modifier Groups
GET https://revoxef.works/api/external/v2/catalog/modifierGroups
Response for GET modifier groups is a modifier groups paginated array with the following fields:
Field | Type | Required | Extra info |
---|---|---|---|
id | number | - | autoincrement |
name | string | required | |
order | number | optional | |
dont_show_automatically | boolean | optional | default: 0 |
GET https://revoxef.works/api/external/v2/catalog/modifierGroups/<modifier_group_id>
POST https://revoxef.works/api/external/v2/catalog/modifierGroups
Create a modifier group (POST)
catalog/modifierGroups
{
"name": "Modifier group 1"
...
}
Update a modifier group (POST)
catalog/modifierGroups
{
"id": 1, // required to update
"name": "Modifier group updated 1"
...
}
Create/update multiple modifier groups (POST)
catalog/modifierGroups
{
"modifierGroups": [
{
"id": 1, // only required to update
"name": "Modifier group 1",
...
},
{
"id": 2, // only required to update
"name": "Modifier group 2",
...
}
...
]
}
DELETE https://revoxef.works/api/external/v2/catalog/modifierGroups/<modifier_group_id>
Modifier Pivot
The next pivot endpoints define the (optional) relationship between Modifier Categories and Modifier Groups.
Can list, show, create, update and delete Modifier Pivots
GET https://revoxef.works/api/external/v2/catalog/modifierPivots
Response for GET modifier pivots is a modifier pivots paginated array with the following fields:
Field | Type | Required | Extra info |
---|---|---|---|
id | number | - | autoincrement |
order | number | optional | |
group_id | number | required | modifier group |
category_id | number | required | modifier category |
GET https://revoxef.works/api/external/v2/catalog/modifierPivots/<modifier_pivot_id>
POST https://revoxef.works/api/external/v2/catalog/modifierPivots
Create a modifier pivot (POST)
catalog/modifierPivots
{
"group_id": 1,
"category_id": 1
...
}
Update a modifier pivot (POST)
catalog/modifierPivots
{
"id": 1, // required to update
"group_id": 2
...
}
Create/update multiple modifier pivots (POST)
catalog/modifierPivots
{
"modifierPivots": [
{
"id": 1, // only required to update
"category_id": 1,
...
},
{
"id": 2, // only required to update
"category_id": 1,
...
}
...
]
}
DELETE https://revoxef.works/api/external/v2/catalog/modifierPivots/<modifier_pivot_id>
Menu Categories
An Item can be of Menu type.
This can be distinguished by item.type = 1.
Each Menu Item can contain different Menu Categories and each Menu Category can have multiple Normal Items (item.type = 0):
Menu Item => Menu Categories => Normal Items
Can list, show, create, update and delete Menu Categories
GET https://revoxef.works/api/external/v2/catalog/menuMenuCategories
Response for GET menu categories is a menu categories paginated array with the following fields:
Field | Type | Required | Extra info |
---|---|---|---|
id | number | - | autoincrement |
name | string | required | |
order | number | optional | |
isMultipleChoice | number | optional | Select One: 0, Multiple choice: 1 (default), Select one mandatory: 2, Select by default (min-max): 3, Custom (min-max): 4 |
max | number | optional | default: 1 |
min | number | optional | default: 0 |
item_id | number | required | item.type = 1 |
dish_order_id | number | optional |
GET https://revoxef.works/api/external/v2/catalog/menuMenuCategories/<menu_category_id>
POST https://revoxef.works/api/external/v2/catalog/menuMenuCategories
Create a menu category (POST)
catalog/menuMenuCategories
{
"name": "First dishes",
"item_id": 1
"isMultipleChoice": 2,
...
}
Update a menu category (POST)
catalog/menuMenuCategories
{
"id": 1, // required to update
"isMultipleChoice": 2
...
}
Create/update multiple menu menu categories (POST)
catalog/menuMenuCategories
{
"menuMenuCategories": [
{
"id": 1, // only required to update
"name": "Menu category 1",
"item_id": 1,
...
},
{
"id": 2, // only required to update
"name": "Menu category 2",
"item_id": 2,
...
}
...
]
}
DELETE https://revoxef.works/api/external/v2/catalog/menuMenuCategories/<menu_category_id>
Menu Item-Category Pivot
This endpoint links the Normal Items, from the menu, with their Menu Category.
Can list, show, create, update and delete Menu Item-Category Pivot
GET https://revoxef.works/api/external/v2/catalog/menuMenuItemCategoryPivots
Response for GET menu item-category pivots is a menu item-category pivots paginated array with the following fields:
Field | Type | Required | Extra info |
---|---|---|---|
id | number | - | autoincrement |
active | boolean | optional | default: 1 |
order | number | optional | |
price | decimal | required | |
addModifiersPrice | boolean | optional | default: 1 |
item_id | number | required | item.type = 0 |
category_id | number | required | menu category |
separatorName | string | optional | |
modifier_group_id | number | optional | |
format_pivot_id | number | optional |
GET https://revoxef.works/api/external/v2/catalog/menuMenuItemCategoryPivots/<menu_item_category_pivot_id>
POST https://revoxef.works/api/external/v2/catalog/menuMenuItemCategoryPivots
Create a menu item-category pivot (POST)
catalog/menuMenuItemCategoryPivots
{
"item_id": 1,
"category_id": 1
...
}
Update a menu item-category pivot (POST)
catalog/menuMenuItemCategoryPivots
{
"id": 1, // required to update
"price": 1.00
...
}
Create/update multiple menu item-category pivots (POST)
catalog/menuMenuItemCategoryPivots
{
"menuMenuItemCategoryPivots": [
{
"id": 1, // only required to update
"item_id": 1,
"category_id": 1
...
},
{
"id": 2, // only required to update
"item_id": 2,
"category_id": 1
...
}
...
]
}
DELETE https://revoxef.works/api/external/v2/catalog/menuMenuItemCategoryPivots/<menu_item_category_pivot_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'
Vendors
GET https://revoxef.works/api/external/v2/vendors
GET ...vendors
{
"current_page": 1,
"data": [
{
"id": 1,
"name": "RevoVendor",
"address": "Address",
"city": "City",
"state": "State",
"country": "Country",
"postalCode": "00000",
"nif": "000000000B",
"web": null,
"email": null,
"phone": "111222333",
"notes": null,
"shouldBeNotified": 0
},
...
GET https://revoxef.works/api/external/v2/vendors/{vendor_id}
GET ...vendors/{vendor_id}
{
"id": 1,
"name": "RevoVendor",
"address": "Address",
"city": "City",
"state": "State",
"country": "Country",
"postalCode": "00000",
"nif": "000000000B",
"web": null,
"email": null,
"phone": "111222333",
"notes": null,
"shouldBeNotified": 0
}
POST https://revoxef.works/api/external/v2/vendors
POST ...vendors
{
"name": "RevoVendor", // required
"address": "Address", // required
"city": "City",
"state": "State",
"country": "Country",
"postalCode": "00000",
"nif": "000000000B", // required | unique
"web": null,
"email": null,
"phone": "111222333",
"notes": null,
"shouldBeNotified": 0
}
PUT https://revoxef.works/api/external/v2/vendors/{vendor_id}
PUT ...vendors/{vendor_id}
{
"name": "RevoVendor",
"address": "Address",
"city": "City",
"state": "State",
"country": "Country",
"postalCode": "00000",
"nif": "000000000B", // unique
"web": null,
"email": null,
"phone": "111222333",
"notes": null,
"shouldBeNotified": 0
}
DELETE https://revoxef.works/api/external/v2/vendors/{vendor_id}
Vendor Items
GET https://revoxef.works/api/external/v2/vendors/{vendor_id}/items
GET ...items
{
"current_page": 1,
"data": [
{
"item_id": 1,
"reference": "",
"costPrice": "1.00",
"unit_id": 1,
"pack": 1,
"tax_id": null
},
...
POST https://revoxef.works/api/external/v2/vendors/{vendor_id}/items
POST ...items
With this endpoint you can create or update, if the vendor.item_id already exists.
{
"items": [
{
"item_id": 1, // required
"costPrice": "1.00", // required
"pack": 2, // required
"tax_id": 2,
"unit_id": 1
},
{
"item_id": 2, // required
"costPrice": "2.00", // required
"pack": 2, // required
"reference": "Reference"
}
]
}
DELETE https://revoxef.works/api/external/v2/vendors/{vendor_id}/items
DELETE ...items
All items_id must exist to delete their relation to vendor.
{
"items": [ item1_id, item3_id, item10_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
Basic usage
The main URL for the external API:
https://revoxef.works/api/loyalty
The API has a data size límit of 2MB for each request.
The API has a limit of 120 requests every minute so the best practice is to cache for x time the fetched information done with the
getXXX
actions.
The URL for the integrations API environment:
https://integrations.revoxef.works/api/loyalty
And you should provide the mandatory headers for the authentication
Header | Value |
---|---|
tenant | {account-username} |
Authorization | Bearer {the-token} |
client-token | {client-token} |
Content-Type | application/json |
Create an order
POST https://revoxef.works/api/loyalty/orders
The payload to create the order, must be sent as a JSON.
The parameters for the payload, are the following:
Field | Type | Required | Extra info |
---|---|---|---|
order | JSON | required | see Order payload |
customer | JSON | optional | see Customer payload |
delivery | JSON | optional | see Delivery payload |
skipMerge | boolean | optional | default: false. If you don't want the order to be merged if there is another one already opened. |
warehouse_id | number | optional | Send the Revo XEF warehouse_id if you want the stock to be discounted. |
emailToSendInvoice | string | optional | Email where the invoice will be sent. |
General payload example:
{
"order": {
...
},
"customer": {
...
},
"delivery": {
...
}
}
Response:
{
"order_id": 1
}
Order payload
Most of the parameters are recalculated when the order is processed in the POS.
Field | Type | Required | Extra info |
---|---|---|---|
total | decimal | required | must be the sum of the order contents with their extra modifiers. Discounts must be applied too. |
table_id | number | optional | If not sent, order is set as a delivery. |
tableName | string | optional | default: 'InTouch'. If table_id sent, gets real tableName, otherwise gets payload data. |
guests | number | optional | default: 1 |
notes | string | optional | |
extraId | string | optional | Used to register an external order_id/reference. |
orderDiscount | JSON | optional | see Order discount payload |
contents | array | required | Must be an array of JSON. see Contents payload |
payment | JSON | optional | see Payment payload |
Order payload example:
{
"order": {
"total": 10.50,
"table_id": 1,
"tableName": "TableName",
"guests": 1,
"notes": "Notes",
"extraId": "Ext-1",
"orderDiscount": {
...
},
"contents": [
{
...
},
...
],
"payment": {
...
},
}
...
}
Order discount payload
Field | Type | Required | Extra info |
---|---|---|---|
name | string | optional | default: 'Discount' |
amount | decimal | required | Must have negative sign. |
Order discount payload example:
{
"order": {
"total": 8.00, // discount subtracted
...
"orderDiscount": {
"name": "Discount",
"amount": -2.50
},
...
}
...
}
Contents payload
Field | Type | Required | Extra info |
---|---|---|---|
item_id | number | required | Existing item ID. It can be a normal item, a selling format item or a menu item. |
itemPrice | decimal | required | Individual item price. |
quantity | number | optional | default: 1 |
modifiers | array | optional | Only for normal and selling format items. Must be an array of JSON. see Modifiers payload |
menuContents | array | optional | Only for menu items. Must be an array of JSON. see MenuContents payload |
Content payload example:
{
"order": {
"total": 13.00
...
"contents": {
"item_id": 1,
"itemPrice": 6.50,
"quantity": 2,
"modifiers" or "menuContents": [
{
...
},
...
],
}
...
}
...
}
Modifiers payload
Only for normal and selling format items.
For normal items (item.type = 0):
There is no quantity and each modifier must be sent idividually.
Field | Type | Required | Extra info |
---|---|---|---|
id | number | optional | Existing modifier ID. |
name | string | required | If modifier ID is found, it is set the modifier name. |
price | decimal | required | - |
Modifier (normal item) payload example:
{
"order": {
"total": 17.80
...
"contents": {
"itemPrice": 6.50,
"quantity": 2,
...
"modifiers": [
{
"id": 1, // modifier ID exists ("name": "Nuts")
"price": 1.20
},
{
"name": "Nuts",
"price": 1.20
},
...
]
}
...
}
...
}
For selling format items (item.type = 4):
Normal modifiers cannot be set.
Field | Type | Required | Extra info |
---|---|---|---|
id | number | required | Existing format pivot ID. |
price | decimal | optional | default: 0 |
Modifier (selling format item) payload example:
{
"order": {
...
"contents": {
...
"modifiers": [ // only 1 modifier to set the selling format
{
"id": 1,
}
]
}
...
}
...
}
MenuContents payload
Only for menu items (item.type = 1):
Field | Type | Required | Extra info |
---|---|---|---|
item_id | number | required | Existing item ID. It can be a normal menu item or a selling format menu item. |
name | string | required | Menu ittem name. |
price | decimal | required | Item menu price. |
quantity | number | optional | Only can be set 1 quantity. |
dishOrder | number | optional | Must be an existing Menu Item-Category Pivot. |
modifiers | array | optional | Only for normal and selling format items. Must be an array of JSON. see Modifiers payload |
MenuContents (menu item) payload example:
{
"order": {
"total": 25.70
...
"contents": {
"item_id": 12, // menu item
"itemPrice": 10.00,
...
"menuContents": [
{
"item_id": 1, // normal item
"price": 6.50,
"quantity": 1,
"modifiers": [
{
"name": "Nuts",
"price": 1.20
},
...
]
},
{
"item_id": 2, // selling format item
"itemPrice": 7,
"quantity": 1,
"modifiers": [
{
"id",
"price": 1.00
}
]
}
...
]
}
...
}
...
}
Payment payload
Field | Type | Required | Extra info |
---|---|---|---|
amount | decimal | required | The amount to pay. Must not exceed the order total amount - order already paid amount. |
payment_method_id | number | optional | Existing payment method ID. default: channel payment method is used or created. |
payment_reference | string | optional | The reference of the payment. |
tip | decimal | optional | |
contents | array | optional | Only for Standalone payment section. Pay per items. Array of content IDs. The amount must match contents+modifiers sum amount. |
Regarding the payment methods, there are 2 fix payment methods for all accounts:
Card => "payment_method_id": 1
Cash => "payment_method_id": 2
Payment payload example:
{
"order": {
"total": 12.20,
...
"payment": {
"amount": 12.20
"payment_method_id": 1,
"payment_reference": "QR code payment.",
...
}
}
...
}
Customer payload
If a customer is found with the email or phone from this section, respectively, we will get the existing customer, and the other fields will not be updated.
If the customer is not found, we will create one with all the fields sent.
The customer info and the delivery info are not the same. Customer object is the customer itself, the customer data linked to the invoice. The delivery object is a complement data only linked to the delivery order. It is up to you if you want to match customer and delivery fields, in case of non existing customer.
We recommend to manage customers using the specific endpoints. Check the customer section
Field | Type | Required | Extra info |
---|---|---|---|
name | string | required | |
string | required | ||
phone | string | optional | |
nif | string | optional | |
web | string | optional | |
address | string | optional | |
postalCode | string | optional | |
city | string | optional | |
state | string | optional | |
extra_id | string | optional | |
notes | string | optional |
Customer payload example:
{
"order": {
...
},
"customer": {
"name": "Customer Name",
"email": "customer@revo.test"
}
...
}
Delivery payload
The delivery info and the customer info are not the same.
The delivery data is the info for the delivery/pickup order. This info will not be saved in the customer data.
Field | Type | Required | Extra info |
---|---|---|---|
phone | number | required | The phone for the delivery/pickup order. |
date | string | optional | Date when the order has to be prepared. "YYYY-MM-DD HH:MM:SS" - default: current time. |
address | string | optional | Set address for delivery orders. NO address for pickup orders. |
city | string | optional | |
channel | number | optional | default: REVO channel (InTouch) |
Delivery payload example:
{
"order": {
...
},
"delivery": {
"phone": 123456789,
"date": "2009-05-02 21:45:00",
...
}
...
}
Standalone payment
If you only want to make a payment for an existing order, you must use the following endpoint:
POST orders/{orderId}/payments
The payload structure is the same as the payment done in the order creation, but sent as a form-data body request. See again the details.
Standalone payload example:
# Must be sent as a form-data body request.
"payment": {
"amount": 12.20
"payment_method_id": 1,
"payment_reference": "QR code payment.",
"contents": [1,2,3]
...
}
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'
This endpoint makes a refund (a new order with negatives values).
There is a limit time to cancel the order. If the account has configured the Previous delivery minutes, the limit to cancel the order will be the Delivery date subtract the Delivery minutes. Otherwise, you will have 5 minutes after an order has been place.
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 Loyalty WebView
Introduction
Since Revo Xef 4.1 we include a new integration that lets you manipulate the current order through a webview and a powerful Javascript Api.
You can enable it by adding the integration called RevoLoyalty WebView
and providing your URL
.
When this integration is enabled in the edit order screen, there will appear a new action that will open your site and inject the RevoLoyaltyJs
framework for you to be able to interact with the current order.
This api includes a few methods described below
To be able to interact with iOS all the function will have a callback parameter that will be called when the action is finished in the POS
GET ORDER
Gets all the information of the current order
RevoLoyalty.getOrder(function(json) {
var order = JSON.parse(json)
const total = order["total"]
})
GET ACCOUNT
Gets the account id and the account name
RevoLoyalty.getAccount(function(json) {
var items = JSON.parse(json)
document.getElementById("text").innerHTML = json
document.getElementById("orderTotal").innerHTML = "Account id: "+ account["id"]
})
GET ITEMS
Gets all the information of the items requested by its ids, array of ints. If there is no item with a requested id, it won't be in the response
RevoLoyalty.getItems([itemId1, itemId2, itemId3], function(json) {
var items = JSON.parse(json)
document.getElementById("text").innerHTML = json
document.getElementById("orderTotal").innerHTML = "Account id: "+ account["id"]
})
ADD EXISTING DISCOUNT
Adds a discount that exists in the database to the whole order
RevoLoyalty.addExistingDiscount({id}, function(error) {
})
Parameter | Type | Description |
---|---|---|
id | int |
The id of the discount on the database |
Result: Error if the discount does not exist
ADD PERCENTAGE DISCOUNT
Adds a new discount with percentage to the whole order
RevoLoyalty.addPercentageDiscount({name}, {percentage}, function() {
})
Parameter | Type | Description |
---|---|---|
name | string |
The name of the discount to show on the ticket |
percentage | number |
The percentage for the discount |
ADD AMOUNT DISCOUNT
Adds a new discount with amount to the whole order
RevoLoyalty.addAmountDiscount({name}, {amount}, function() {
})
Parameter | Type | Description |
---|---|---|
name | string |
The name of the discount to show on the ticket |
amount | number |
The amount for the discount |
ADD EXISTING CONTENT DISCOUNT
Adds a discount that exists in the database to the whole order
RevoLoyalty.addContentExistingDiscount({line}, {id}, function(error) {
})
Parameter | Type | Description |
---|---|---|
line | int |
The index of the array of the content received in the getOrder to apply the discount |
id | int |
The id of the discount on the database |
Result: Error if the discount does not exist
ADD CONTENT PERCENTAGE DISCOUNT
Adds a new discount with percentage to the whole order
RevoLoyalty.addContentPercentageDiscount({line}, {name}, {percentage}, {withoutExtras}, function() {
})
Parameter | Type | Description |
---|---|---|
line | int |
The index of the array of the content received in the getOrder to apply the discount |
name | string |
The name of the discount to show on the ticket |
percentage | number |
The percentage for the discount |
withoutExtras | bool |
If the discount should be applied to the extras or not (ex: modifiers) |
ADD CONTENT AMOUNT DISCOUNT
Adds a new discount with amount to the whole order
RevoLoyalty.addContentAmountDiscount({line}, {name}, {amount}, {withoutExtras}, function() {
})
Parameter | Type | Description |
---|---|---|
line | int |
The index of the array of the content received in the getOrder to apply the discount |
name | string |
The name of the discount to show on the ticket |
amount | number |
The amount for the discount |
withoutExtras | bool |
If the discount should be applied to the extras or not (ex: modifiers) |
ADD PRODUCT
Adds a new content to the order, the product must me of type standard
as no popups can be shown
RevoLoyalty.addProduct({id}, {price}, function(error) {
})
Parameter | Type | Description |
---|---|---|
id | int |
The id of the product |
price | number |
optional The price of the product, send null to use the database price |
Error when the product does not exists or is not standard
ADD Payment
Adds a payment to the order, it will create an invoice there isn't one yet
RevoLoyalty.addPayment({id}, {amount}, function(error) {
})
Parameter | Type | Description |
---|---|---|
id | int |
The id of the payment method |
amount | number |
The amount paid |
error when the payment method does not exist
CLOSE
Closes the webview
RevoLoyalty.close()
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
The API has a data size límit of 2MB for each request.
The API has a limit of 120 requests every minute so the best practice is to cache for x time the fetched information done with the
getXXX
actions.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 | Required | Description |
---|---|---|---|
start_date |
YYYY-mm-dd | optional | The initial date for the report. Default: start of month. |
end_date |
YYYY-mm-dd | optional | The final date for the report. Default: today. |
page |
number | optional | As the data is paginated, use this parameter to select the page to fetch. |
pagination |
number | optional | Number of objects per page. The default value is 50 and the max allowed is 200. |
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/v3/reports/{reportName}?page=2",
"path": "https://revoxef.works/api/external/v3/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
All filters and flags must be used as a query parameters.
Filter/Flag | Type | Belongs to report/resource | Description |
---|---|---|---|
start_date |
YYYY-mm-dd | All | (required) The initial date for the report |
end_date |
YYYY-mm-dd | All | (required) The final date for the report |
start_time |
HH:mm | All | The start time for the report |
end_time |
HH:mm | All | The end time for the report |
dayofweek |
int | All | Where Sunday is 1 and Saturday is 7 |
room |
int | Orders | Room id |
priceRate |
int | Contents | Price rate id |
forTurn |
int | Orders | Filter orders for turn_id (forTurn=turn_id). This filter already includes withInvoices and withPayments filters. Date filters (start_date and end_date) do nothing with forTurn filter |
table |
int | Orders / Contents | Filter orders/contents for table_id (table=table_id). |
fullPrecision |
bool | All | Displays all possible numeric fields with their complete decimal precision when ?fullPrecision=true is applied |
withInvoices |
- | Orders | Append invoices resource |
withContents |
- | Orders | Append contents resource |
withDelivery |
- | Orders | Append delivery resource |
withPayments |
- | Invoices | Append payments resource |
withFiscal |
- | Invoices | Append fiscal data resource |
withItem |
- | Contents | Append item resource |
withSubContents |
- | Contents | Append subContents (menu contents) resource |
withModifiers |
- | Contents | Append modifier resource |
withPriceRate |
- | Contents | Append price rate resource ("type": 0(percentage)/1(price)) |
withAppliedTaxes |
- | Contents / Invoices | Append taxes information applied to the resource (JSON example in the lateral shell screen) |
Example:
Using order reports endpoint, if you want PriceRates resource, as it belongs to Contents, you will also need withContents filter.
?withAppliedTaxes
{
...
"RESOURCE": [ // "invoices", "contents", "sub_contents"
{
...
"applied_taxes": [
{
"id": 1, // register ID
"tax_id": 3, // tax ID
"tax_name": "IVA 21%",
"tax_percentage": 21.00,
"base_amount": 0.8264, // up to 4 decimal precision
"tax_amount": 0.1736 // up to 4 decimal precision
}
],
...
}
]
}
Fields with fullPrecision
This section lists all fields that can have their decimal precision increased by using the "?fullPrecision=true" flag.
Field | Resource | Precision without flag | Precision with flag |
---|---|---|---|
subtotal |
Contents | 2 | 4 |
tax |
Contents | 2 | 4 |
discount_amount |
Contents | 2 | 4 |
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 V3
GET https://revoxef.works/api/external/v3/accounts
Using the optional query parameter ?withBusiness=true
in the endpoint, we can retrieve information about the business account.
V3 accounts endpoint
{
"data": [
{
"id": 1,
"tenant": "accountname",
"business": { // only with withBusiness flag
"name": "Name",
"legal_name": "Legal Name",
"slogan": "Sloga",
"phone": "123456789",
"address": "Address",
"city": "City",
"state": "State",
"country": "Country",
"postal_code": "01234",
"nif": "B123456789",
"logo": "abcdefg123.png",
"web": "https://www.revo.works",
"tax_included": true, // bool
"opening_time": "05:00:00",
"cash_control_type": "SIMPLE", // "NONE", "SIMPLE", "FULL" or "AUTO"
"blind_cashier": false, // bool
"presence_control": true, // bool
"currency": "EUR",
"second_currency": "USD",
"exchange_rate": 0, // 4 decimal precision
"currency2_cash_payment_method_id": 8,
"currency2_card_payment_method_id": 9,
"comma_decimal": true, // bool
"languages": [ // "ca", "en", "es", "eu", "fr", "pt", "it", "zh", "de"
"ca"
]
}
},
...
]
}
Get Accounts V2 (old)
GET https://revoxef.works/api/external/v2/accounts
V2 endpoint (old)
{
"IDTenant": "Tenant/AccountName"
}
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 |
Chain fetch order
GET https://revoxef.works/api/external/v2/accounts/orders/{id}
You can fetch one (or multiple orders) for an specific chain using the same header as in the previous example.
The
id
field can be a single order id or multiple orders separated by , such asid1,id2,id3
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 (Deprecated)
Authentication
curl --header "username: {account-username}" \
--header "Authorization: Bearer {token}" \
--header "Content-Type: application/json" \
https://revoretail.works/api/external/reports
The main URL for the external API:
https://revoretail.works/api/external/reports
The URL for the integrations API environment:
https://integrations.revoretail.works/api/external/reports
And you should provide the mandatory headers for the authentication
Header | Value |
---|---|
username | {account-username} |
Authorization | Bearer {token} |
Content-Type | application/json |
The token
is obtained at Account managment section of RevoRetail.
Response format
{
"current_page": 1,
"data": [ [Report data will go here] ],
"first_page_url": "https://revoretail.works/api/external/reports/{reportName}?page=1",
"from": 1,
"last_page": 4,
"last_page_url": "https://revoretail.works/api/external/reports/{reportName}?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 (Deprecated)
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 (Deprecated)
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) |
Retail
Prerequisistes
To be able to use the external api you need a REVO Retail
.
- Login into the desired account
- Go to account management
- Create a new token
Authorization
The main URL for the external API:
https://revoretail.works/api/external
The URL for the integrations API environment:
https://integrations.revoretail.works/api/external
And you should provide the mandatory headers for the authentication
Header | Value |
---|---|
username | {account-username} |
Authorization | Bearer {token} |
Content-Type | application/json |
Generic list response
{
"current_page": 1,
"data": [ [Response data will go here] ],
"first_page_url": "https://revoretail.works/api/external/{resource}?page=1",
"from": 1,
"last_page": 2,
"last_page_url": "https://revoretail.works/api/external/{resource}?page=2",
"next_page_url": "https://revoretail.works/api/external/{resource}?page=2",
"path": "https://revoretail.works/api/external/{resource}",
"per_page": 50,
"prev_page_url": null,
"to": 50,
"total": 75
}
Available resources
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
GET 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
GET 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
GET 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
GET taxes
[
{
"id": 1,
"name": "10%",
"taxPercentage": 10.00
},
{
"id": 2,
"name": "21%",
"taxPercentage": 21.00
}
]
Get stocks list
Get an stock list.
GET https://revoretail.works/api/external/catalog/stocks
GET 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
POST 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
POST 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
POST 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
GET payment_methods
[
{
"id": 1,
"name": "Card",
},
{
"id": 2,
"name": "Cash",
}
]
Customers
GET Customers
Get a list of paginated customers
GET https://revoretail.works/api/external/config/customers
GET customers
Response:
{
"current_page": 1,
"data": [
{
"id": 1,
"name": "Name",
"address": "Address",
"city": "City",
"state": "State",
"country": "ES",
"postalCode": "00008",
"nif": "12345678A",
"web": null,
"email": "test@test.test",
"phone": "123456789",
"notes": null,
"maxCredit": "0.00",
"extra_id": null,
}
],
"first_page_url": "https://revoretail.works/api/external/config/customers?page=1",
"from": 1,
"last_page": 1,
"last_page_url": "https://revoretail.works/api/external/config/customers?page=1",
"next_page_url": null,
"path": "https://revoretail.works/api/external/config/customers",
"per_page": 50,
"prev_page_url": null,
"to": 1,
"total": 1
}
POST Customers
Create a customer
POST https://revoretail.works/api/external/config/customers
POST customers
{
"name": "Name", // required
"address": "Address", // required
"city": "City",
"state": "State",
"country": "ES",
"postalCode": "00008",
"nif": "12345678A",
"web": null,
"email": "test@test.test",
"phone": "123456789",
"notes": null,
"maxCredit": "0.00",
"extra_id": null,
}
Error for required params:
HTTP request status 422
{
"error": "The given data was invalid."
"code": 0,
"data": []
}
PATCH Customers
Update a customer
PATCH https://revoretail.works/api/external/config/customers/{customer_id}
PATCH customers/{customer_id}
{
"name": "Name Updated"
}
Sync chains
Sync account chains data
POST https://revoretail.works/api/external/chains/sync
Response
{
"data": {"message": Synced},
}
Retail Catalog
Inside catalog there are many resources: groups, categories and resources.
The api has a limit of 40 requests every minute so the best practice is to cache for x time the fetched information done with the
getXXX
actions.
Prerequisistes
To be able to use the external api you need a REVO Retail
.
- Login into the desired account
- Go to account management
- Create a new token
Authorization
The main URL for the external API:
https://revoretail.works/api/external/{resource}
The URL for the integrations API environment:
https://integrations.revoretail.works/api/external/{resource}
And you should provide the mandatory headers for the authentication
Header | Value |
---|---|
username | {account-username} |
Authorization | Bearer {token} |
Content-Type | application/json |
Generic list response
{
"current_page": 1,
"data": [ [Response data will go here] ],
"first_page_url": "https://revoretail.works/api/external/{resource}?page=1",
"from": 1,
"last_page": 2,
"last_page_url": "https://revoretail.works/api/external/{resource}?page=2",
"next_page_url": "https://revoretail.works/api/external/{resource}?page=2",
"path": "https://revoretail.works/api/external/{resource}",
"per_page": 50,
"prev_page_url": null,
"to": 50,
"total": 75
}
URL parameters
You can add the next URL parameters for the paginated responses:
Key | Type | Required | Description |
---|---|---|---|
page |
number | optional | As the data is paginated, use this parameter to select the page to fetch. |
pagination |
number | optional | Number of objects per page. The default value is 50 and the max allowed is 200. |
At the bottom of the request, it is specified information about the current page and pagination.
Catalog structure
The main catalog structure is the following:
Groups => Categories => Items
Items cannot exist without Categories, and Categories cannot exists without Groups.
Groups
Can list, show, create, update and delete Groups.
GET https://revoretail.works/api/external/catalog/groups
Response is a groups paginated array with the following fields:
Field | Type | Required | Extra info |
---|---|---|---|
id | number | ReadOnly | autoincrement |
name | string | required | |
photo | string | optional | |
order | number | optional | |
active | boolean | optional | default: 1 |
tax_id | number | optional | |
tax | object | ReadOnly |
tax object (optional):
Field | Type |
---|---|
id | number |
name | string |
percentage | string |
shouldStack | boolean |
GET https://revoretail.works/api/external/catalog/groups/<group_id>
POST https://revoretail.works/api/external/catalog/groups
Create groups (POST)
catalog/groups
[
{
"name": "Test Group 1",
...
},
{
"name": "Test Group 2",
...
},
...
]
Update a group (POST)
catalog/groups/<group_id>
{
"name": "Super Test Group 1",
...
}
DELETE https://revoretail.works/api/external/catalog/groups/<group_id>
Categories
Can list, show, create, update and delete Categories.
GET https://revoretail.works/api/external/catalog/categories
Response is a groups paginated array with the following fields:
Field | Type | Required | Extra info |
---|---|---|---|
id | number | ReadOnly | autoincrement |
name | string | required | |
group_id | number | required | |
photo | string | optional | |
order | number | optional | |
active | boolean | optional | default: 1 |
extra_id | string | optional | |
tax_id | number | optional | |
tax | object | ReadOnly |
tax object (optional):
Field | Type |
---|---|
id | number |
name | string |
percentage | string |
shouldStack | boolean |
GET https://revoretail.works/api/external/catalog/categories/<category_id>
POST https://revoretail.works/api/external/catalog/categories
Create categories (POST)
catalog/categories
[
{
"name": "Test Category 1",
"group_id": 1,
...
},
{
"name": "Test Category 2",
"group_id": 1,
...
},
...
]
Update a category (POST)
catalog/category/<category_id>
{
"name": "Super Test Category 1",
...
}
DELETE https://revoretail.works/api/external/catalog/categories/<category_id>
Products
Can list, show, create, update and delete Products.
GET https://revoretail.works/api/external/catalog/products
Response is a groups paginated array with the following fields:
Field | Type | Required | Extra info |
---|---|---|---|
id | number | ReadOnly | autoincrement |
name | string | required | |
category_id | number | required | |
photo | string | optional | |
order | number | optional | |
active | boolean | optional | default: 1 |
extra_id | string | optional | |
reference | string | optional | |
info | string | optional | |
shortInfo | string | optional | |
brand | string | optional | |
season | string | optional | |
featured | boolean | optional | default: 0 |
isOpen | boolean | optional | default: 0 |
weight | number | optional | default: 0 |
type | number | optional | 0 = NORMAL (default), 1 = KIT, 2 = TICKET, 3 = CONTAINER, 4 = GIFT_CARD, 5 = VARIANT_MASTER, 6 = VARIANT, 7 = MANAGEMENT_ONLY, 8 = VOUCHER |
price | decimal | optional | default: 0.00 |
costPrice | decimal | optional | default: 0.00 |
barcode | string | optional | default: 0.00 |
main_product_id | number | optional | |
complementary_product_id | number | optional | |
discountinued_at | date | optional | YYYY-MM-DD |
traceability | boolean | optional | default: 0 |
usesStockManagement | boolean | optional | default: 0 |
usesWeight | boolean | optional | default: 0 |
unit_id | number | optional | |
tax_id | number | optional | |
tax | object | ReadOnly | |
variant_master | object | ReadOnly | Same product structure (optional) |
ecommerce_info | object | ReadOnly | Showed with filter withECommerce. |
stocks | array (objects) | ReadOnly | Showed with filter withStocks or ECommerce module enabled + filter withECommerceStocks. |
variant_info | object | ReadOnly | Showed with filter withVariantInfo or ECommerce module enabled + filter withECommerceStocks.. |
tax object (optional):
Field | Type |
---|---|
id | number |
name | string |
percentage | string |
shouldStack | boolean |
ecommerce_info object (optional):
Field | Type |
---|---|
id | number |
product_id | number |
active | boolean |
weight | number |
sizes | object (width, height and depth) |
price | string |
discount_amount | string |
discount_percentage | string |
stocks array (optional):
Field | Type |
---|---|
id | number |
quantity | string |
alert | boolean |
warehouse_id | number |
item_id | number |
unit_id | number |
variant_info object (optional):
Field | Type |
---|---|
id | number |
product_id | number |
variant_1_id | number |
variant_2_id | number |
GET https://revoretail.works/api/external/catalog/products/<product_id>
POST https://revoretail.works/api/external/catalog/products
Create products (POST)
catalog/products
[
{
"name": "Test Category 1",
"category_id": 1,
...
},
{
"name": "Test Category 2",
"category_id": 1,
...
},
...
]
Update a product (POST)
catalog/products/<product_id>
{
"name": "Super Test Product 1",
...
}
DELETE https://revoretail.works/api/external/catalog/products/<product_id>
Stocks
Can list and create/update Stocks
GET https://revoretail.works/api/external/catalog/stocks
List Stocks (GET)
catalog/stocks
# Response
[
{
"quantity": 20,
"defaultQuantity": 10,
"alert": 4,
"warehouse_id": 1,
"item_id": 1,
"unit_id": 1
},
{
"quantity": 15,
"defaultQuantity": 5,
"alert": 4,
"warehouse_id": 1,
"item_id": 2,
"unit_id": 1
},
]
POST https://revoretail.works/api/external/stocks/add
Create/Update a Stock (POST)
api/external/stocks/add
If the warehouse_id has a product_id already registered, it will update the record. If not, it will create a new stock record.
# Body
{
"warehouse_id" : 1, // Required
"product_id" : 1, // Required
"quantity": 20 // Required
}
# Response
{
"quantity": 20
}
Retail Reports
Authentication
curl --header "username: {account-username}" \
--header "Authorization: Bearer {token}" \
--header "Content-Type: application/json" \
https://revoretail.works/api/external/v3/reports/{reportName}
The main URL for the external API:
https://revoretail.works/api/external/v3/reports/{reportName}
The URL for the integrations API environment:
https://integrations.revoretail.works/api/external/v3/reports/{reportName}
And you should provide the mandatory headers for the authentication
Header | Value |
---|---|
username | {account-username} |
Authorization | Bearer {token} |
Content-Type | application/json |
The token
is obtained at Account managment section of RevoRetail.
Field | Type | Required | Description |
---|---|---|---|
start_date |
YYYY-mm-dd | optional | The initial date for the report. Default: start of month. |
end_date |
YYYY-mm-dd | optional | The final date for the report. Default: today. |
page |
number | optional | As the data is paginated, use this parameter to select the page to fetch. |
pagination |
number | optional | Number of objects per page. The default value is 50 and the max allowed is 200. |
Response format
{
"current_page": 1,
"data": [ [Report data will go here] ],
"first_page_url": "https://revoretail.works/api/external/v3/reports/{reportName}?page=1",
"from": 1,
"last_page": 4,
"last_page_url": "https://revoretail.works/api/external/v3/reports/{reportName}?page=4",
"next_page_url": "https://revoretail.works/api/external/v3/reports/{reportName}?page=2",
"path": "https://revoretail.works/api/external/v3/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,
"shifts": [1, 2]
},
...
]
}
You can also filter products by shift ids. Remember that products without shifts ([]) means that they have all shifts associated, so if you filter by shifts you will get all products that have the shifts of the filter + all products without shifts ([]).
https://revoflow.works/api/v1/products?shifts=shift_id1,shift_id2
Filter by shift ids (query parameter):
https://revoflow.works/api/v1/products?shifts=1,2
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,
"shifts": [1, 2]
},
...
]
}
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 120 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
The Intouch API is an API made for the Intouch App and SOLO environment, an app made for customers to earn and spend loyalty points.
In the InTouch API there are different types of requests. The ones that use an API token authorization, the ones that use a Customer token auth with POS connection and the public ones that only need a POS connection.
InTouch - API authorization type request
Revo-InTouch comes with an easy to use REST
API Interface.
All requests will have the same structure.
Prerequisites
To be able to use this type of request you need a Revo InTouch
account and an access token
available in the Back-Office.
- Login in the desired account
- Go to Others > Development and get the Api Token
Basic usage
The main URL for the InTouch API is
https://revointouch.works/api/v1/
And you should provide the mandatory headers for the authentication:
Header | Value |
---|---|
account | {account-username} |
Authorization | Bearer {api-token} |
The api-token
is a unique token generated for each account and can be found in the Back-Office (Prerequisites).
curl --location --request GET 'https://revointouch.works/api/v1/' \
--header 'Authorization: Bearer {api-token}' \
--header 'account: {account-username}' \
Stores
GET stores
Returns a list of the stores from a specified POS username.
URL(query) parameter | Description |
---|---|
username | Username from POS integration |
GET stores?username=USERNAME
{
"data": [
{
"id": 1,
"name": "An store"
},
{
"id": 2,
"name": "Test Store"
}
]
}
Store Status
GET stores/{store}/status
Returns the status of the specified store.
{
"data": {
"status": "paused"
}
}
POST stores/{store}/status
Returns previous and current updated status after call.
Body Field | Description |
---|---|
status | string status to send. |
{
"data": {
"previousStatus": "online",
"currentStatus": "paused"
}
}
Store products availability
With this endpoint, you can activate/deactivate products in a specific store
POST catalog/updateStatus
If the request is processed, we return status OK (200).
All request parameters must be sent as a query string:
Body Field | Required | Description |
---|---|---|
products | required | Array of product_ids. |
store | required | The store_id. |
active | required | 1/0 - the status for all the products from the request |
until | optional | datetime: 'YYYY/MM/DD HH:mm'. In the case of deactivation, when to reactivate. |
alsoNested | optional | default: 0. True (1), to also change the status of the passed products that are inside menus. |
reactivateInNested | optional | default: 0. 'alsoNested' must be 1, to reactivate the products that are inside menus (only in the case they have been deactivated). |
curl --location --request POST 'https://revointouch.works/api/v1/catalog/updateStatus?active=0&store=1&products=[product_ids]&until=2024/02/22' \
--header 'account: {account-username}' \
--header 'Authorization: Bearer {customer-token}' \
Customers Points
This endpoint is an exception to the rule. To get the {customer-token} you need to login with a customer. Explained in the next section (Customer Authorization type request).
GET customers/{customer-token}/points
Returns the points of a customer + the points spent with the specified product.
Body Field | Description |
---|---|
products | Json id of the product in Json format. |
Body example:
json
{
"products": "[1,2]"
}
Response:
sh
{
"data": {
"leftPoints": 8000,
"productPoints": []
}
}
POST customers/{customer-token}/points
Returns the left points of a customer + the points spent for a specified product.
Body Field | Description |
---|---|
products | Json id of the product in Json format. |
{
"data": {
"spentPoints": 0,
"leftPoints": 8000
}
}
SOLO URLs
With this endpoint you can get all the SOLO access URLs.
GET solo/urls
You can use the following optional URL parameter:
Parameter | Type | Required | Extra info |
---|---|---|---|
stores | array | optional | Filter by stores. Example: [store_1_id, store_2_id] |
cURL request example:
curl --location --request GET 'https://revointouch.works/api/v1/solo/urls' \
--header 'account: {account-username}' \
--header 'Authorization: Bearer {customer-token}' \
--header 'Accept: application/json' \
Response example:
{
"data": {
"delivery_url": "https://delivery_url",
"pickup_url": "https://pickup_url",
"stores": [
{
"id": 1,
"name": "Store 1",
"pickup_asap": "https://pickup_asap",
"delivery_or_pickup": "https://delivery_or_pickup",
"digital_menu": "https://digital_menu",
"tables": [
{
"id": 3,
"name": "12 ",
"url": "https://url"
},
{
"id": 4,
"name": "13 ",
"url": "https://url"
}
...
]
}
...
]
}
}
InTouch - Customer Authorization type request
Also, for this type of request, you will need a POS integration (Xef account). This can be done in the InTouch Back-Office (Settings > POS Integrations).
Prerequisites
To be able to use this type of request you must need a Revo InTouch
account and a POS integration
.
- Login into the desired account
- Go to Settings > POS Integrations.
- Create a New POS Integration with the Xef Account Token.
Basic usage
The base url:
https://revointouch.works/api/v1/customer
In the customer authorization type request, you will need to login with a customer to get the Bearer {customer-token}.
Login
POST login
Logs in with Email and specified password.
Parameters
Body Field | Description |
---|---|
string User email | |
password | string User password |
And you should provide the mandatory headers for the login
Header | Value |
---|---|
account | {account-username} |
Then you will get the Bearer {customer-token} in the response.
Response:
sh
{
"data" : {
"api_token" : "customer-token",
"info" : {
"points" : 378,
"id" : 1,
"postalCode" : "08240",
"email" : "jordi.p@revo.works",
"name" : "Jordi Puigdellívol"
}
}
}
Register
POST register
Registers user with the specified fields.
Same response as login
Body Field | Type | Example |
---|---|---|
name | string |
Bruce |
email |
bruce@wayne.com | |
password | string |
batman |
postalCode | string |
08240 |
birthDate | date |
1950-12-23 |
subscribe | bool |
1 |
For the rest of the Customer Authorization type request endpoints...
Header | Value |
---|---|
account | {account-username} |
Authorization | Bearer {customer-token} |
curl --location --request GET 'https://revointouch.works/api/v1/customer' \
--header 'account: {account-username}' \
--header 'Authorization: Bearer {customer-token}' \
Customer
GET /
Returns the current customer info.
{
"data": {
"id": 1,
"name": "Customer Name",
"postalCode": null,
"city": null,
"address": null,
"birthDate": "2000-01-01",
"points": 0,
"email": "customer@revo.works",
"phone": "123456789",
"stripe_id": null,
"payment_token": null,
"vip": 0,
"photo": "photo.png",
"language": "es",
"authCode": null,
"extra_id": null,
"created_at": "2000-01-01 00:00:00",
"updated_at": "2000-01-01 00:00:00",
"customer_group_id": 1,
"discount_percentage": 0,
"group": {
"id": 1,
"name": "Group Name",
"discount": 0,
"created_at": "2000-01-01 00:00:00"
}
}
}
PUT /
Updates the current customer info.
Body data to send in Json format (mandatory parameters):
sh
{
"name": "Customer Name",
"postalCode" : "Customer postalCode",
"address" : "Customer address",
"city": "Customer city",
"phone": "Customer phone"
}
UploadProfilePhoto
POST uploadProfilePhoto
Uploads specified profile photo to the current customer.
Body Field | Example |
---|---|
Photo | /9j/4AAQSkZJRgABA... |
Photo must be in base64 encoded format.
{
"data": {
"result": "OK",
"photoName": "ovrA7mVcSQ.jpg"
}
}
Cards
GET cards
Returns all the cards data.
{
"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}
Gets the specified card's data by the card_uuid
sh
{
"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
Body 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 --> |
{
"data" : {
"newAmount" : 1000
}
}
POST cards
Creates a new gift card with the desired name.
Body Field | Description |
---|---|
name | string the name of the new card |
{
"data" : {
"amount" : 0,
"id" : 9,
"uuid" : "58c2b978bb6ca",
"photo" : "IWtdZ6",
"name" : "My gift card",
"customer_id" : 1
}
}
AssociateCustomerGroup
POST associateCustomerGroup
Associates a customer to a customerGroup.
Body Field | Description |
---|---|
id | string Id of the group to associate |
{
"data": {
"id": 2,
"name": "Revo",
"discount": 10000,
"created_at": "2021-06-14 15:54:53"
}
}
Orders
Create an order
POST orders
Parameters:
Key | Value | 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
Body Field | Type | Description |
---|---|---|
modifiers | array json |
the array of modifiers |
menuContents | array json |
the array of menuContents |
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" : []
]
}]
Get an order
GET orders
Returns the orders of the current customer.
{
"data" :
[
{
"id": 7041,
"store_id": 18,
"customer_id": 1,
"delivery_id": 744,
"subtotal": 210,
"taxAmount": 20,
"total": 230,
"pointsEarned": 2,
"closed_at": "2022-02-24 10:00:02",
"created_at": "2022-02-23 08:54:56",
"status": 5,
"pos_id": 819,
"discountAmount": 0,
"contact": null,
"paid": 0,
"delivery":
} {
"id": 744,
"address": "Carrer del Bruc, 23",
"city": "Manresa",
"phone": "678984278",
"time": "2022-02-23 09:30:00",
"geolocation": "41.722687,1.817833",
"created_at": "2022-02-23 08:54:56",
"tableId": null,
"job_id": null,
"notes": null,
"delivery_zone_id": null
},
"contents": [
{
"id": 2318,
"order_id": 7041,
"product_id": 913,
"modifiers": null,
"pointsSpent": null,
"price": 230,
"subtotal": 210,
"taxAmount": 20,
"tax": 1000,
"quantity": 1,
"total": 230,
"created_at": "2022-02-23 08:54:56",
"notes": null,
"menu_contents": []
}
]
},
]
}
Close an Order
PUT orders/{id}
It closes the order with the specified id.
Returns the order info: ```sh { "data": { "id": 1, "store_id": 1, "customer_id": 1, "delivery_id": null, "subtotal": 8, "taxAmount": 2, "discountAmount": 0, "total": 10, "pointsEarned": 0, "pos_id": 1, "status": 5, } }
### Get Last Order
#### `GET lastOrder`
Returns the last order for the customer.
```sh
{
"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
}
}
}
Points
GET points
Returns points for the current customer.
{
"data": {
"points": 58013
}
}
Theme
GET theme
Returns app theme.
{
"data": {
"theme": {
"account": "revosupport",
"appName": "Awesome App",
"accent": "#d7771d",
"accentInverse": "#fafafa",
"onlyPayWithGiftCard": "no",
"payment_method": 1,
"payment_method_config": {
"stripe": {
"key": "sk_test_Cme93TuYaEI8bieyEInbVoW1002vB0Oix4",
"publishable_key": null
},
"sipay": {
"key": null,
"resource": null,
"secret": null
}
},
"stripe_publishable_key": null,
"delivery_agency": 1,
"delivery_agency_config": null,
"rewards_enabled": "no",
"online_ordering": "no",
"has_slides": "no",
"enable_barcode_scan": "no",
"only_show_near_store": "no",
"minimum_delivery_price": 100,
"required_delivery_product_id": "",
"disable_gift_card": "no",
"points_to_money": "no",
"rewards_order": "asc",
"enable_invitations": "no",
"tables": {
"5": {
"3": "12 ",
"4": "13 ",
},
"6": {
"3": "12 ",
"4": "13 ",
},
"7": {
"3": "12 ",
"4": "13 ",
},
"9": {
"1": "Table 1",
"2": "Table 2",
},
"10": [],
"11": {
"3": "12 ",
"4": "13 ",
}
}
}
}
}
Invoices
POST invoices/{id}/points/obtain
Return the points for the specific invoice.
InTouch - Public Customer type request
Prerequisites
To be able to use this type of request you must need a Revo InTouch
account and a POS integration
.
- Login into the desired account
- Go to Settings > POS Integrations.
- Create a New POS Integration with the Xef Account Token.
Basic usage
The base url is:
https://revointouch.works/api/v1/customer
Header | Value |
---|---|
account | {account-username} |
curl --location --request GET 'https://revointouch.works/api/v1/customer' \
--header 'account: {account-username}' \
Stores
GET stores
Returns all the stores data.
{
"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
Returns all categories data.
"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
Returns all 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
Returns all delivery 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
}
}
Products
GET products
Returns all 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
Returns all menuCategories
{
{
"id" : 1
"name" : "Drinks",
"product_id" : 1,
"order" : 2
},
{
"name" : "Take away",
"product_id" : 2,
"order" : 1
}
}
Menu Products
GET menuProducts
Returns all menuproducts
{
{
"product_id" : 1,
"menu_category_id" : 1
"order" : 2,
"price" : 0,
},
{
"product_id" : 15,
"menu_category_id" : 1
"order" : 1,
"price" : 1500,
}
}
Modifiers
GET modifiers
Returns all 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
}
}
Modifier Categories
GET modifierCategories
Returns all modifier categories.
{
"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
}
}
Product - Modifier Categories
GET productModifierCategories
Returns all 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
}
}
TableAvailable
GET table/{id}/available
Returns if the table (of the first store with a POS Integration) with the specified id is available.
{
"data": {
"available": true
}
}
ProductStore
GET productStore
Returns productStore for current customer.
{
"data" : {
"new" : [
{
"id": 3,
"product_id": 2152,
"store_id": 7,
"active": 1,
"price": 70,
"deleted_at": null,
"created_at": "2021-01-20T14:50:41.000000Z",
"updated_at": "2022-01-03T09:12:39.000000Z",
"config": null
},
{
"id": 5,
"product_id": 914,
"store_id": 5,
"active": 0,
"price": 110,
"deleted_at": null,
"created_at": "2021-02-10T10:43:57.000000Z",
"updated_at": "2021-10-29T09:26:10.000000Z",
"config": null
}
]
}
}
SellingFormatStore
GET sellingFormatStore
Returns sellingFormatStore for current customer.
{
"data" : {
"new" : [
{
"id": 2,
"selling_format_id": 182,
"store_id": 5,
"active": 1,
"price": 200,
"deleted_at": null,
"created_at": "2021-04-09T08:30:47.000000Z",
"updated_at": "2021-04-09T08:30:49.000000Z"
},
{
"id": 3,
"selling_format_id": 330,
"store_id": 5,
"active": 1,
"price": 1000,
"deleted_at": null,
"created_at": "2021-04-12T15:41:53.000000Z",
"updated_at": "2021-10-29T09:26:15.000000Z"
}
]
}
}
Kiosk
GET kiosk
Returns kiosk Data.
{
"data": {
"new": [
{
"id": 1,
"pin": null,
"payment_modes": [
"1",
"5"
],
"languages": null,
"payment_gateway_type": 3,
"payment_gateway_config": {
"adyen": {
"poiid": "S1F2-000158213300423"
}
},
"theme": null,
"created_at": "2021-11-15 11:42:35",
"name": "Kiosk",
"printer_ip": "10.0.1.236",
"store_id": 7,
"printer_driver": 1,
"config": "{\"stop_service_on_print_error\":\"0\"}"
},
{
"id": 2,
"pin": null,
"payment_modes": [
"1",
"5"
],
"languages": null,
"payment_gateway_type": 3,
"payment_gateway_config": {
"adyen": {
"poiid": "S1F2-000158213300423"
}
},
"theme": null,
"created_at": "2022-03-04 12:20:47",
"name": "KIOSK OSKAR",
"printer_ip": "10.0.1.236",
"store_id": 11,
"printer_driver": 2,
"config": "{\"stop_service_on_print_error\":\"0\"}"
}
],
"updated": [],
"deleted": []
}
}
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