Introduction
Welcome to the VoucherCart API!
Authentication
# With shell, you can just pass the correct header with each request
curl https://api.vouchercart.com/v1/{endpoint}
-H "Authorization: Bearer VCaccessToken"
VoucherCart uses API key to allow access to the API. You can generate your own API in Client dashboard in Settings / API section.
Almost all VoucherCart endpoints require authorization using the API key (or JWT token), which is expected to be included in all API requests to the server in a header that looks like the following:
Authorization: Bearer VCaccessToken
Get JWT token
VoucherCart uses JWT authentication described in RFC-7519 specification.
HTTP Request
curl -X POST "https://api.vouchercart.com/v1/authorize" \
-u "staffuser@example.com:password" \
--data "subdomain=my-sales-page"
POST http://api.vouchercart.com/v1/authorize
Authorization header should consist base64-encoded combination of staff member’s email (login) and password separated by colon.
Sample header may look like this: Authorization: Basic base64(concat(login, :, password))
Parameter | Type | Description |
---|---|---|
subdomain |
string, required | Name of the domain |
HTTP Response
{
"accessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI5MmEyMjgwOC1iZDU1LTQxMzQtODc4Mi04MjUwNWFkMTZkNjMiLCJpYXQiOiIxNDgxMDI2OTk3IiwiZXhwIjoiMTQ4MTExMzM5NyIsImF1ZCI6ImNsaWVudDEiLCJ1c2VyIjoxfQ.5KIC2E_KC9garXNxAxgf_GGVjuTRyU_nddwChxjVWbw",
"identifiedBy": "92a22808-bd55-4134-8782-82505ad16d63",
"profile": {
"email": "tom+client@vouchercart.com",
"fullName": "VoucherCart2 Demo",
"id": 1,
"locale": "en"
},
"refreshToken": "RTZmQzZjc0MzU1NDdlYzcxYTk3NGEwM2FjNTNlY2YxMDg5YWYxNjcwNw",
"status": "authenticated"
}
If you will be authenticated successfully you will retrieve a JSON response with an accessToken
- a JWT token.
JWT token can be used as authorization key which should be added to Authorization
header.
Most of API endpoints requires Bearer
method to authorize, so you will need to supply JWT token in header: Authorization: Bearer eyJ0eXAiOiJKV...
Parameter | Type | Description |
---|---|---|
accessToken |
string | A JWT token |
identifiedBy |
string | ID of the generated token |
profile |
Profile Object | Look for Profile Object section for more details |
refreshToken |
string | Refresh token |
status |
string | Should return authenticated , otherwise request has failed. |
Profile Object
Parameter | Type | Description |
---|---|---|
email |
string | Address e-mail of the staff member |
fullName |
string | Full name |
id |
integer | ID of the staff member object |
locale |
string | Language code used by staff member |
Get user domains
In previous request you will need to provide a subdomain
parameter consisting name of one the sales pages where the staff member is already registered. If you do not know that parameter, you may ask for e-mail address which user use to get list of domains where staff member use given mail.
HTTP Request
curl "https://api.vouchercart.com/v1/user-domains?email=staffmember@example.com"
GET http://api.vouchercart.com/v1/user-domains
Parameter | Type | Description |
---|---|---|
email |
string, required | An email address |
HTTP Response
{
"status": "success",
"domains": [
{
"id": 8,
"name": "hello-world",
"url": "https://hello-world.vouchercart.com/"
}
]
}
Parameter | Type | Description |
---|---|---|
domains |
Array<Domain object> | - |
status |
string | Should return refreshed , otherwise request has failed. |
Domain object
Parameter | Type | Description |
---|---|---|
id |
number | ID |
name |
string | sales page subdomain |
url |
string | link to sales page subdomains |
Refresh token
JWT technique used short-lived tokens, it means that the JWT will be valid only by short duration time (1 day) after authentication. With refresh tokens your application may delay expiration of the session.
HTTP Request
curl -X PUT "https://api.vouchercart.com/v1/refresh" \
--data "accessToken=my-jwt-token&refreshToken=RTrefreshToken"
PUT http://api.vouchercart.com/v1/refresh
Parameter | Type | Description |
---|---|---|
accessToken |
string, required | A JWT token supposed to expired (or already expired) |
refreshToken |
string, required | Refresh token acquired during authorization. Starts with RT letters. |
HTTP Response
{
"accessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI5MmEyMjgwOC1iZDU1LTQxMzQtODc4Mi04MjUwNWFkMTZkNjMiLCJpYXQiOiIxNDgxMDI4NzIxIiwiZXhwIjoiMTQ4MTExNTEyMSIsImF1ZCI6ImNsaWVudDEiLCJ1c2VyIjoxfQ.pkxwkokz5tHXtUthRHH-hdkDd9wxaTliRebtAbmyBuw",
"identifiedBy": "92a22808-bd55-4134-8782-82505ad16d63",
"refreshToken": "RTZjgwYzhkMmFhZjU5OWRlOTdmNzIzNjY2ZGMzYTcxODEwOWJjMjJiMw",
"status": "refreshed"
}
N.B.
refreshToken
andaccessToken
will slightly change with each/refresh
request (they are rotating). In the next refresh request you cannot userefreshToken
which have been already used.
Parameter | Type | Description |
---|---|---|
accessToken |
string | A JWT token |
identifiedBy |
string | ID of the generated token |
refreshToken |
string | Refresh token |
status |
string | Should return refreshed , otherwise request has failed. |
Domain
Get list of domains
HTTP Request
GET https://api.vouchercart.com/v1/domains
Make sure you replace
VCaccessToken
with your API key.
curl "https://api.vouchercart.com/v1/domains" \
-H "Authorization: Bearer VCaccessToken"
HTTP Response
Sample response:
{
"status": "success",
"domains": [
{
"id": 8,
"name": "hello-world",
"url": "https://hello-world.vouchercart.com/"
},
{
"id": 1337,
"name": "other-sales-page",
"url": "https://other-sales-page.vouchercart.com/"
}
]
}
Parameter | Type | Description |
---|---|---|
status |
string | Should return "success" |
domains |
Array<Domain object> | - |
Domain object
Parameter | Type | Description |
---|---|---|
id |
number | ID |
name |
string | sales page subdomain |
url |
string | link to sales page subdomains |
Redeem voucher
Voucher status
GET https://api.vouchercart.com/v1/status
Make sure to replace
VCaccessToken
with your API key.
curl "https://api.vouchercart.com/v1/status?code=AAAA-BBBB-CCCC-DDDD" \
-H "Authorization: Bearer VCaccessToken"
Parameter | Type | Description |
---|---|---|
code |
string, required | Voucher code |
domain |
integer, required | Client’s sales page domain ID |
HTTP Response
Sample response (fixed, single-use):
{
"code": "AAAA-BBBB-CCCC-DDDD",
"current": 0,
"expirations": [
{
"from": "2016-12-02T07:57:29+0000",
"to": "2017-03-02T07:57:29+0000"
}
],
"monetary": false,
"multiUsable": false,
"order": {
"buyer": {
"city": null,
"country": null,
"county": null,
"email": "buyer@example.com",
"guest": true,
"handDelivery": true,
"house": null,
"id": null,
"name": "Buyer Name",
"phone": null,
"postcode": null,
"street": null,
"town": null
},
"currency": "GBP",
"product": {
"currency": "GBP",
"deliveryType": "electronic",
"description": "Fixed desc",
"hiddenPriceOnVoucher": true,
"id": 7,
"image": null,
"imageNoPrice": null,
"isDeliveryDateSet": true,
"message": "Happy birthday\nMy dear friend!",
"name": "Fixed voucher: Meal for two",
"price": 100,
"priceOnVoucher": "£1.30",
"type": "voucher",
"voucherType": "fixed"
},
"purchasedAt": "2016-12-02T07:57:29+0000",
"recipient": {
"city": null,
"comment": "<p>Happy birthday</p>\n<p>My dear friend!</p>",
"country": null,
"county": null,
"email": "buyer@example.com",
"from": null,
"houseName": null,
"name": "Buyer Name",
"postcode": null,
"streetName": null
},
"redeemedDate": null,
"reference": "OWHCNE-1GB-1",
"refund": null,
"shippingTotal": 0,
"subTotal": 80,
"taxTotal": 20,
"total": 100
},
"redeemableOn": [
1
],
"redeemed": false,
"redeemHistory": [],
"remainingString": "1 time left",
"status": "in_progress",
"stock": 1
}
Sample response (monetary, multi-use, $1.00 / $20.00 used):
{
"code": "AAAA-BBBB-CCCC-DDDD",
"current": 100,
"expirations": [ ... ],
"monetary": true,
"multiUsable": true,
"order": { ... },
"redeemableOn": [ ... ],
"redeemed": false,
"redeemHistory": [ ... ],
"status": "in_progress",
"stock": 2000
}
Sample response (redeemed completely):
{
"code": "AAAA-BBBB-CCCC-DDDD",
"current": 1,
"expirations": [ ... ],
"monetary": false,
"multiUsable": false,
"order": { ... },
"redeemableOn": [ ... ],
"redeemed": true,
"redeemHistory": [ ... ],
"status": "completed",
"stock": 1
}
Parameter | Type | Description |
---|---|---|
code |
string | Voucher code |
current |
integer | Current spent value. |
expirations |
Array<Expiration object> | - |
monetary |
boolean | Is it the type of monetary voucher? |
multiUsable |
boolean | Can voucher be redeemed multiple times? |
order |
Order object | - |
redeemableOn |
Array<integer> | Consists ID of domains (sales pages) where voucher can be redeemed |
redeemed |
boolean | Has voucher been redeemed already? |
redeemHistory |
Array<RedeemHistory object> | - |
status |
string | Voucher status (can be: in_progress , completed , refunded , expired , regenerated ) |
stock |
integer | Value of voucher. |
Expiration object
Parameter | Type | Description |
---|---|---|
from |
datetime | ISO8601 format |
to |
datetime | ISO8601 format |
Redeem history
Parameter | Type | Description |
---|---|---|
amount |
integer | units used |
redeemAt |
datetime | ISO8601 format |
Order object
Parameter | Type | Description |
---|---|---|
buyer |
Product object | - |
currency |
string | - |
product |
Product object | - |
purchasedAt |
datetime | - |
recipient |
Recipient object | - |
redeemedDate |
datetime (optional) | - |
reference |
string | - |
refund |
integer (optional) | - |
shippingTotal |
integer | - |
subTotal |
integer | - |
taxTotal |
integer | - |
total |
integer | - |
Buyer object
Parameter | Type | Description |
---|---|---|
city |
string (optional) | - |
country |
string (optional) | - |
county |
string (optional) | - |
email |
string | - |
guest |
string (optional) | - |
handDelivery |
string (optional) | - |
house |
string (optional) | - |
id |
string (optional) | - |
name |
string | - |
phone |
string (optional) | - |
postcode |
string (optional) | - |
street |
string (optional) | - |
town |
string (optional) | - |
Recipient object
Parameter | Type | Description |
---|---|---|
city |
string (optional) | - |
comment |
string (optional) | - |
country |
string (optional) | - |
county |
string (optional) | - |
email |
string (optional) | - |
from |
string (optional) | - |
houseName |
string (optional) | - |
name |
string (optional) | - |
postcode |
string (optional) | - |
streetName |
string (optional) | - |
Product object
Parameter | Type | Description |
---|---|---|
currency |
string | - |
deliveryType |
string | - |
description |
string | - |
hiddenPriceOnVoucher |
boolean | - |
id |
integer (optional) | - |
image |
string (optional) | - |
imageNoPrice |
string (optional) | |
isDeliveryDateSet |
boolean | - |
message |
string | - |
name |
string | - |
price |
integer | - |
priceOnVoucher |
string | - |
type |
string | - |
voucherType |
string | - |
Redeem voucher
Notes:
- In this request you can only redeem one voucher (one code).
- Parameter
code
must be exact voucher code. - Voucher must be redeemable on specified sales page.
HTTP Request
POST https://api.vouchercart.com/v1/redeem
Make sure to replace
VCaccessToken
with your API key.
curl "https://api.vouchercart.com/v1/redeem" \
-X POST \
--data "code=AAAA-BBBB-CCCC-DDDD&domain=1" \
-H "Authorization: Bearer VCaccessToken"
You may also specify additional parameters like
reductor
orredeemDate
:
curl "https://api.vouchercart.com/v1/redeem" \
-X POST \
--data "code=AAAA-BBBB-CCCC-DDDD&domain=1&reductor=2&redeemDate=2015-12-05 13:37" \
-H "Authorization: Bearer VCaccessToken"
Parameter | Type | Description |
---|---|---|
code |
string, required | Voucher code |
domain |
integer, required | Client’s sales page domain ID |
reductor |
integer, optional | How many units (value) should be reduced from the voucher (used in multi-use vouchers. Default: redeem completely. |
redeemDate |
datetime, optional | Format: YYYY-MM-DD HH:SS . Default: now. |
HTTP Response
Sample response (fixed, single-use):
{
"code": "AAAA-BBBB-CCCC-DDDD",
"current": 1,
"expirations": [
{
"from": "2016-12-02T07:57:29+0000",
"to": "2017-03-02T07:57:29+0000"
}
],
"monetary": false,
"multiUsable": false,
"order": {
"buyer": {
"city": null,
"country": null,
"county": null,
"email": "buyer@example.com",
"guest": true,
"handDelivery": true,
"house": null,
"id": null,
"name": "Buyer Name",
"phone": null,
"postcode": null,
"street": null,
"town": null
},
"currency": "GBP",
"product": {
"currency": "GBP",
"deliveryType": "electronic",
"description": "Fixed desc",
"hiddenPriceOnVoucher": true,
"id": 7,
"image": null,
"imageNoPrice": null,
"isDeliveryDateSet": true,
"message": "Happy birthday\nMy dear friend!",
"name": "Fixed voucher: Meal for two",
"price": 100,
"priceOnVoucher": "£1.30",
"type": "voucher",
"voucherType": "fixed"
},
"purchasedAt": "2016-12-02T07:57:29+0000",
"recipient": {
"city": null,
"comment": "<p>Happy birthday</p>\n<p>My dear friend!</p>",
"country": null,
"county": null,
"email": "buyer@example.com",
"from": null,
"houseName": null,
"name": "Buyer Name",
"postcode": null,
"streetName": null
},
"redeemedDate": "2016-12-02T13:32:48+0000",
"reference": "OWHCNE-1GB-1",
"refund": null,
"shippingTotal": 0,
"subTotal": 80,
"taxTotal": 20,
"total": 100
},
"redeemableOn": [
1
],
"redeemed": true,
"redeemHistory": [
{
"redeemAt": "2016-12-02T13:32:48+0000",
"amount": 1
}
],
"remainingString": "0 time left",
"status": "completed",
"stock": 1
}
Sample response (fixed, multi-use):
{
"code": "AAAA-BBBB-CCCC-DDDD",
"current": 2,
"expirations": [ ... ],
"monetary": false,
"multiUsable": true,
"order": { ... },
"redeemableOn": [ ... ],
"redeemed": false,
"redeemHistory": [ ... ],
"status": "in_progress",
"stock": 5
}
Parameter | Type | Description |
---|---|---|
code |
string | Voucher code |
current |
integer | Current spent value. |
expirations |
Array<Expiration object> | - |
monetary |
boolean | Is it the type of monetary voucher? |
multiUsable |
boolean | Can voucher be redeemed multiple times? |
order |
Order object | - |
redeemableOn |
Array<integer> | Consists ID of domains (sales pages) where voucher can be redeemed |
redeemed |
boolean | Has voucher been redeemed already? |
redeemHistory |
Array<RedeemHistory object> | - |
status |
string | Voucher status (can be: in_progress , completed , refunded , expired , regenerated ) |
stock |
integer | Value of voucher. |
Users
The user object
Attributes
Parameter | Type | Description |
---|---|---|
id |
int | |
email |
string | |
password |
string | Write only |
fullName |
string | |
phone |
optional string | |
createdAt |
string|date | Read only, format dd/MM/yyyy HH:mm |
permissions |
array<permission> | User assigned permissions for each domain. To get list of domains refer to Domain > Get list of domains |
Password rules
- at least 6 characters
- at least one lowercase or uppercase letter
- at least one digit or special sign
The permission object
Attributes
Parameter | Type | Description |
---|---|---|
domainId |
int | To get list of domains refer to Domain > Get list of domains |
roleId |
int|enum | |
customPermissions |
array<string> | list of custom permissions granted to user - effective only while roleId = 3 (Custom) |
available roleId values
1
: Administrator2
: Redeem Only3
: Custom4
: Packaging and Shipping
available customPermissions
redeem.voucher
manage.orders
manage.products
manage.promotions
manage.settings
manage.account
manage.products.refund
cancel.redeem.voucher
manage.vcard
manage.discount
process.postal.delivery
Create a user
HTTP Request
Make sure you replace
VCaccessToken
with your API key.
curl "https://api.vouchercart.com/v1/users" \
-X POST \
-H "Authorization: Bearer VCaccessToken" \
-H "Accepts: application/json" \
-H "Content-Type: application/json" \
--data "
{
\"fullName\": \"Test User\",
\"email\": \"test@example.com\",
\"password\": \"sEcret9\",
\"phone\": \"+1 123 456 789\",
\"permissions\": [
{
\"domainId\": 1,
\"roleId\": 0,
\"customPermissions\": []
},
{
\"domainId\": 2,
\"roleId\": 0,
\"customPermissions\": []
}
]
}"
POST https://api.vouchercart.com/v1/users
Arguments
Parameter | Type |
---|---|
email |
string |
password |
string |
fullName |
string |
phone |
optional string |
permissions |
array<permission> |
HTTP Response
Sample response:
{
"userId": 9
}
Object with created user’s id
Errors
Return Code | Description |
---|---|
302 |
Data validation not passed - check if email & password as correct and required fields present |
500 |
Error that most often is caused by permissions array not containing permissions for all domains |
Retrieve a user
HTTP Request
Make sure you replace
VCaccessToken
with your API key.
curl "https://api.vouchercart.com/v1/users/9" \
-X GET \
-H "Authorization: Bearer VCaccessToken" \
-H "Accepts: application/json"
POST https://api.vouchercart.com/v1/users/{user-id}
HTTP Response
Sample response:
{
"id": 9,
"fullName": "Test User",
"email": "test@example.com",
"phone": "+1 123 456 789",
"createdAt": "20/11/2018 06:22",
"permissions": [
{
"domainId": 1,
"roleId": 0,
"customPermissions": []
},
{
"domainId": 2,
"roleId": 0,
"customPermissions": []
}
]
}
A user object
Update a user
HTTP Request
Make sure you replace
VCaccessToken
with your API key.
curl "https://api.vouchercart.com/v1/users/9" \
-X PUT \
-H "Authorization: Bearer VCaccessToken" \
-H "Accepts: application/json" \
-H "Content-Type: application/json" \
--data "
{
\"fullName\": \"Test User Changed\",
\"email\": \"test_changed@example.com\",
\"phone\": \"+1 987 654 321\",
\"permissions\": [
{
\"domainId\": 1,
\"roleId\": 3,
\"customPermissions\": [
\"manage.orders\",
\"redeem.voucher\"
]
},
{
\"domainId\": 2,
\"roleId\": 0,
\"customPermissions\": []
}
]
}"
PUT https://api.vouchercart.com/v1/users/{user-id}
Arguments
Parameter | Type |
---|---|
email |
string |
fullName |
string |
phone |
optional string |
permissions |
array<permission> |
HTTP Response
204
No Content
Errors
Return Code | Description |
---|---|
302 |
Data validation not passed - check if email & password as correct and required fields present |
500 |
Error that most often is caused by permissions array not containing permissions for all domains |
Change user’s password
HTTP Request
Make sure you replace
VCaccessToken
with your API key.
curl "https://api.vouchercart.com/v1/users/9/password" \
-X PATCH \
-H "Authorization: Bearer VCaccessToken" \
-H "Accepts: application/json" \
-H "Content-Type: application/json" \
--data "
{
\"password\": \"SEcreT123\",
\"password2\": \"SEcreT123\"
}"
PATCH https://api.vouchercart.com/v1/users/{user-id}/password
Arguments
Parameter | Type | Description |
---|---|---|
password |
string | |
password2 |
string | has to match password |
HTTP Response
204
No Content
Errors
Return Code | Description |
---|---|
302 |
Data validation not passed - check if password is correct |
Delete a user
HTTP Request
Make sure you replace
VCaccessToken
with your API key.
curl "https://api.vouchercart.com/v1/users/9" \
-X DELETE \
-H "Authorization: Bearer VCaccessToken" \
-H "Accepts: application/json"
DELETE https://api.vouchercart.com/v1/users/{user-id}
HTTP Response
204
No Content
Errors
Return Code | Description |
---|---|
422 |
Invalid user id |
List all users
HTTP Request
GET https://api.vouchercart.com/v1/users
Make sure you replace
VCaccessToken
with your API key.
curl "https://api.vouchercart.com/v1/users" \
-X GET \
-H "Authorization: Bearer VCaccessToken" \
-H "Accepts: application/json"
HTTP Response
Sample response:
[
{
"id": 1,
"fullName": "John Doe",
"email": "john@example.com",
"phone": "",
"createdAt": "19/11/2018 14:46",
"permissions": [
{
"domainId": 1,
"roleId": 1,
"customPermissions": []
},
{
"domainId": 2,
"roleId": 1,
"customPermissions": []
}
]
},
{
"id": 2,
"fullName": "Meghan Smith",
"email": "meghan@example.com",
"phone": "",
"createdAt": "19/11/2018 14:46",
"permissions": [
{
"domainId": 1,
"roleId": 3,
"customPermissions": [
"manage.orders",
"redeem.voucher"
]
},
{
"domainId": 2,
"roleId": 0,
"customPermissions": []
}
]
}
]
An array of user objects
Errors
Sample response containing an error
> GET /v0/teapot HTTP/1.1
> Accept: application/json
> ...
< HTTP/1.1 422 Unprocessable Entity
< Content-Type: application/json
{
"code": 1000,
"errors": {
"email": ["We do not recognize given email address."]
},
"message": "Incorrect request",
"status": "failed"
}
HTTP | Error Code | Description |
---|---|---|
422 | 1000 | Incorrect request |
401 | 1001 | Unauthorized - API key is incorrect |
405 | 1002 | Method not allowed |
403 | 1003 | Access denied for resource |
404 | 1004 | Requested resource has been not found |
401 | 1006 | JWT token has expired |
401 | 1007 | JWT token is not yet valid |
401 | 1008 | JWT token is malformed |
401 | 1009 | JWT token is invalid |
404 | 1010 | Voucher with given code has been not found on specified domain |
422 | 1011 | We cannot realize reduction on this voucher |
422 | 1012 | Expired - If you would like to redeem it regardless, please set redeemDate to match the redeem window |
422 | 1013 | Voucher has been fully redeemed (Completed) |
422 | 1014 | Voucher has been cancelled |
422 | 1015 | ‘Coupon not exist’, |
422 | 1016 | ‘Generation for that status is not allowed’, |
422 | 1017 | ‘Generation not exist’, |
422 | 1018 | ‘Required parameter missing’, |