Introduction

The Wizypay Coupon API enables the creation and consumption of coupons for pre-paid and gift cards.

The API is based on an HTTP/JSON webservice located at the following endpoints:

Production: https://coupon.api.wizypay.com

Staging: http://coupon-staging.api.wizypay.com

The Coupon API, as all Wizypay APIs, follows RESTful principles. In brief, it uses GET requests to show the values of coupons and related operations, and POST or PUT requests to create or modify resources.

POST or PUT requests should be form-encoded and the Content-Type request header should be set to application/x-www-form-urlencoded.

Please refer to the Authentication section to understand how the API is secured.

API Profiles

Clients of the Coupon API are organized in profiles. Each profile have acces exclusively to a distinct subset of the API that limits its authorized scope of actions. Here are the publicily available coupon API profiles:

  • Consumer The consumer client is typically an e-commerce website. Users of the website enter a coupon code at the checkout to allow them to use the credit on their coupon to pay for goods and services. The website interacts with the Wizypay coupon API to check and debit the coupon value.

  • Point of Sale The POS client is typically a cafe, tabac or other local business where a user can buy a coupon. This business is connected to a Point Of Sale network that interacts with the Wizypay coupon API to create a coupon of the specified value.

  • Issuer Back Office The Issuer back office profile exists to allow access to an endpoint for reporting on all the coupons generated for a particular coupon issuer.

  • Point of Sale Back Office The POS back office profile exists to allow access to an endpoint for reporting on all the coupons generated for the point of sale network.

Coupon Consumer Profile

Show Coupon

Coupon consumers can query coupon data using the coupon’s 16 alphanumeric code. It allows clients to check, for instance, the current coupon balance. Using this action. consumers are only allowed to view coupons eligible for debit transactions: querying an expired, deactivated, or cancelled coupon will amount to an error.

Request

URL
GET /issuers/:issuer_name/coupons/:code
Parameters
Parameter Required Type Format Description
issuer_name string 1<length≤36 The name of the coupon issuer. Alpha-numeric case-insensitive.
code string length=16 The coupon code. This code is required for coupon debit/refund transactions.

Response

On Success

A HTTP status code 200 is returned with a full coupon object as body. The coupon has the following fields:

Field Type Format Description
id string 0<length≤36 An internal identifier for the coupon.
balance numeric precision:10, scale:2 The current coupon balance.
face_value numeric precision:10, scale:2 The initial coupon balance.
currency string ISO 4217 code The coupon currency code.
code string length=16 The coupon code. The coupon code is required for coupon debit/refund transactions. Alphanumeric case-insensitive
state enum The coupon state. Possible values are activated, deactivated, cancelled
expires_at datetime ISO 8601 The coupon expiry date.
created_at datetime ISO 8601 The coupon creation date.
On Error
Message Offending Parameter HTTP Status Code Description
no_data_found 404 No coupon has been found with the provided code.
cancelled_coupon 422 The coupon has been cancelled.
deactivated_coupon 422 The coupon has not been activated yet.
expired_coupon 422 The coupon has expired.

See also: common errors cases.

Example

Get coupon with code XYA1B2C3D4E5F6G7 issued by the Wizypay issuer:

URL: GET /issuers/Wizypay/coupons/XYA1B2C3D4E5F6G7

Response: HTTP status code 200 with the following body:

{
  "data": {
    "id": "1064905337",
    "code": "XYA1B2C3D4E5F6G7",
    "balance": "33.22",
    "face_value": "200.00",
    "currency": "EUR",
    "state": "activated",
    "expires_at": "2016-09-263T15:39:49Z",
    "created_at": "2015-06-26T15:39:49Z"
  },
  "meta":{
    "type":"coupons"
  }
}

Debit Coupon(s)

Allows coupon consumers to debit a desired amount from the balance of one or multiple coupons in a transactional way (all or nothing).

The coupons are successively debited in the order they are provided until the desired amount is reached. If the sum of the provided coupon balances is lower than the desired amount, the debit operation is rolled back and all coupon balances are left unchanged.

As an example, let’s suppose the client wants to debit three coupons C1, C2 and C3 with respective balances 100, 120 and 150.

  1. Debiting an amount of 270 from the coupon list [C1, C2, C3] will leave the coupons with the following balances:
    • C1 balance: 0 (100 debited)
    • C2 balance: 0 (120 debited)
    • C3 balance: 100 (50 debited)
  2. Debiting an amount of 120 from the coupon list [C1, C2, C3] will leave the coupons with the following balances:
    • C1 balance: 0 (100 debited)
    • C2 balance: 100 (20 debited)
    • C3 balance: 150 (0 debited)
  3. Debiting an amount of 60 from the coupon list [C1, C2, C3] will leave the coupons with the following balances:
    • C1 balance: 40 (60 debited)
    • C2 balance: 120 (0 debited)
    • C3 balance: 150 (0 debited)
  4. Debiting an amount of 500 from the coupon list [C1, C2, C3] will amount to an error and leave the coupon balances unchanged.

Request

URL
POST /issuers/:issuer_name/debits
Parameters
Parameter Required Type Format Description
issuer_name string 1<length≤36 The name of the coupon issuer. Alpha-numeric case-insensitive.
coupons array The coupon code list. The codes are ordered as they appear in the parameter list.
amount numeric precision:10, scale:2 The amount to debit the coupon(s) by. The coupons are debited in the order listed until the total debit amount is reached.
transaction_ref string 0<length≤36 The client reference that identifies this coupon operation. May be used to rollback the debit request. Case-sensitive. Must be unique for a given (issuer, client) pair.

Response

On Success

A HTTP status code 200 is returned with a debit object as body. The coupon has the following fields:

  • id: an internal identifier for the debit transaction.
  • amount: the debit transaction amount.
  • currency: the currency that the coupon is denominated in.
  • refunded: true if the debit operation has been rolled back (refunded), false otherwise.
  • created_at: the creation date.
  • coupon_debits: the list of debited coupons. Each debit object has the following attributes:
    • id: the coupon level debit identifier.
    • code: the debited coupon.
    • amount: the amount debited from the coupon.
    • created_at: the creation date.
On Error
Message Offending Parameter HTTP Status Code Description
no_data_found 404 No coupon has been found with the provided code.
cancelled_coupon 422 The coupon has been cancelled.
deactivated_coupon 422 The coupon has not been activated yet.
expired_coupon 422 The coupon has expired.

Example

URL: /issuers/Wizypay/debits

Payload: amount=60&coupons[]=XY3TE9573E3VJACY&coupons[]=XYUBQYZKKAWM7NKD&coupons[]=XYK0AQW7CMB5QRGP

Response: HTTP status code 200 with the following body:

{
  "data": {
    "id": "34255323456",
    "amount": "200.00",
    "coupon_debits": {
      "data": [
        { 
          "id": "81", 
          "code":"XY3TE9573E3VJACY",
          "amount":"40.00", 
          "created_at": "2015-05-29T12:16:15Z"
        },
        { 
          "id": "82", 
          "code":"XYUBQYZKKAWM7NKD",
          "amount":"20.00", 
          "created_at": "2015-05-29T12:16:15Z"
        }
      ]
    },
    "refunded":false,
    "created_at": "2015-05-29T12:16:15Z"
  }
}

Refund Coupon(s) Debit

Coupon consumers can refund a previous coupon debit transaction with the following API call:

Request

URL
DELETE /issuers/:issuer_name/debits/:debit_id
Parameters
  • issuer_name: the name of the coupon issuer, a case-insensitive string.
  • debit_id: the debit transaction identifier.

Response

On Success

A HTTP status code 200 is returned with an empty body.

On Failure
Message Offending Parameter HTTP Status Code Description
no_data_found 404 No debit has been found with the provided debit_id.
cancelled_coupon 422 One of the coupons involved in the debit operation has been cancelled.
expired_coupon 422 One of the coupons involved in the debit operation has expired.

See also: common errors cases.

Example

Refund a previously debited Wizypay issued coupon. The debit id returned on the debit operation is 345923465:

URL: DELETE /issuers/Wizypay/debits/345923465 Payload: empty Response: HTTP status code 200 with an empty body.

Coupon Point of Sale Profile

Create Coupon

Coupon POS clients can create coupons for a desired issuer, face value and currency.

A unique identifier must be provided in order to identify the coupon creation request. In case no response is received for the coupon creation request (e.g. due to network issues), the client reference should be used to rollback the coupon.

In most cases generating coupons is limited by a per client quota (please refer to your contract or liaise with support for details).

A coupon may optionally be generated in a deactivated state for later activation. A coupon generated in a deactivated state cannot be used for any debit operation until activated by a separate API call. This two step coupon activation can be useful in situations like:

  • Coupons are pre-generated and printed on physical cards to be sold on customer accessible stands. Coupons are generated in deactivated states. They get activated on cash machines on payment.
  • Coupons are generated and sold on mobile/web platforms. Coupons add to customer basket are generated on checkout with deactivated state. On electronic payment validation, the customer coupons can be activated.

Note: Physical point of sales that generate and print coupon tickets on-demand using cash machines should not generate coupons in a deactivated state.

Request

URL
POST /issuers/:issuer_name/coupons
Parameters
Parameter Required Type Format Description
issuer_name string 1<length≤36 The name of the coupon issuer. Alpha-numeric case-insensitive.
face_value numeric precision:10, scale:2 The desired coupon face value amount and initial balance. Must be greater then zero.
currency string ISO 4217 code The coupon currency code.
transaction_ref string 0<length≤36 The client reference that identifies the coupon creation transaction. May be used to rollback the coupon creation request. Case-sensitive. Must be unique for a given (issuer, client, coupon) tuple.
active   boolean   If true or omitted the generated coupon is activated. The coupon state is deactivated otherwise.
context_info   string JSON document Context data about the operation. The client should include the point of sale identifier with pos_ref as key.

Response

On Success

A HTTP status code 200 is returned with a full coupon object as body. The coupon has the following fields:

Field Type Format Description
id string 0<length≤36 An internal identifier for the coupon.
balance numeric precision:10, scale:2 The current coupon balance.
face_value numeric precision:10, scale:2 The initial coupon balance.
currency string ISO 4217 code The coupon currency code.
code string length=16 The coupon code. This code is required for coupon debit/refund transactions.
state enum The coupon state. Possible values are activated, deactivated, cancelled
expires_at datetime ISO 8601 The coupon expiry date.
created_at datetime ISO 8601 The coupon creation date.
On Error
Message Offending Parameter HTTP Status Code Description
quota_exceeded 503 The allocated coupon creation quota for the client –as specified in his contract– has been exceeded. Please liaise with support using your usual support channels.
duplicate_value transaction_ref 422 The client reference must be unique for each coupon creation request, for a given client and coupon issuer.
out_of_range face_value 422 The provided amount does not conform to the parameter numeric scale and/or precision.

See also: common errors cases.

Example

Create a Wizypay issued coupon with a 50 € face value, a8v9247c882 as transaction reference and {"pos_ref": 36567, "cashier_ref": 340001} as context data:

URL: POST /issuers/Wizypay/coupons

Payload: face_value=50&currency=EUR&transaction_ref=a8v9247c882& context_info=%7B%22pos_ref%22%3A36567%2C%22cashier_ref%22%3A340001%7D

Response: HTTP status code 200 with the following body:

{
  "data": {
    "id": "1064905067",
    "code": "XY7EG79R84RK3BU5",
    "balance": "50.00",
    "face_value": "50.00",
    "currency": "EUR",
    "state": "activated",
    "expires_at": "2016-06-23T15:39:49Z",
    "created_at": "2015-06-23T15:39:49Z"
  },
  "meta":{
    "type":"coupons"
  }
}

Rollback Coupon

Coupon rollback addresses the case where a coupon creation request does not receive a response due to system or network failures (e.g. timeouts, network outages, system downtimes etc.).

Coupon rollback allows the client to cancel the potentially created coupon by the failing coupon creation request.

The rollback is based on the transaction_ref parameter provided by the client in the coupon creation request.

Request

URL
POST /issuers/:issuer_name/coupons/:transaction_ref/rollback
Parameters
Parameter Required Type Format Description
issuer_name string 1<length≤36 The name of the coupon issuer. Alpha-numeric case-insensitive.
transaction_ref string 0<length≤36 The client reference that has been used in the coupon creation request.

Response

On Success

A HTTP status code 200 is returned with an empty body.

On Error
Message Offending Parameter HTTP Status Code Description
no_data_found 404 No coupon has been created with the provided transaction_ref.
cancelled_coupon 422 The coupon has been already cancelled.
expired_coupon 422 The coupon has expired.
debited_coupon 422 The coupon has been debited and cannot be rolledback.

See also: common errors cases.

Example

Rollback a previously created coupon with transaction_ref equal to a8ee0f82-5474-4bd5-b467-907504435d64 for the Wizypay issuer:

URL: POST /issuers/Wizypay/coupons/a8ee0f82-5474-4bd5-b467-907504435d64/rollback

Payload: Empty

Response: HTTP status code 200 with an empty body.

Cancel Coupon

Allows POS clients to cancel a coupon. A cancelled coupon can no longer be used by coupon consumers in any transaction, such as debit or refund.

Request

URL
POST /issuers/:issuer_name/coupons/:id/cancel
Parameters
Parameter Required Type Format Description
issuer_name string 1<length≤36 The name of the coupon issuer. Alpha-numeric case-insensitive.
id string 0<length≤36 The internal coupon identifier. It is the same as the id field in the JSON document returned when a coupon is created.

Response

On Success

A HTTP status code 200 is returned with an empty body.

On Error
Message Offending Parameter HTTP Status Code Description
no_data_found 404 No coupon matches the provided id.
cancelled_coupon 422 The coupon has been already cancelled.
expired_coupon 422 The coupon has expired.

See also: common errors cases.

Example

Cancel a Wizypay issued coupon with id equal to 937397:

URL: POST /issuers/Wizypay/coupons/937397/cancel

Payload: Empty

Response: HTTP status code 200 with an empty body.

Activate Coupon

Coupon POS clients can activate a previously generated coupon in a deactivated state. Activation allows a coupon to be used for transactions by coupon consumers.

Request

URL
POST /issuers/:issuer_name/coupons/:id/activate
Parameters
Parameter Required Type Format Description
issuer_name string 1<length≤36 The name of the coupon issuer. Alpha-numeric case-insensitive.
id string 0<length≤36 The internal coupon identifier. It is the same as the id field in the JSON document returned when a coupon is created.

Response

On Success

A HTTP status code 200 is returned with an empty body.

On Error
Message Offending Parameter HTTP Status Code Description
no_data_found 404 No coupon matches the provided id.
cancelled_coupon 422 The coupon has been already cancelled.
activated_coupon 422 The coupon has been already activated.
expired_coupon 422 The coupon has expired.

See also: common errors cases.

Example

Activation of coupon with issuer Wizypzy and id 3430023533:

URL: POST /issuers/Wizypay/coupons/3430023533/activate

Payload: Empty

Response: HTTP status code 200 with an empty body.

Coupon Issuer Back Office

Reporting: Coupons per Issuer

Clients with the Issuer Back Office profile can list coupons for a specific issuer:

GET /issuers/:issuer_name/coupons?date_start=:date_start&date_end=:date_end&page=:page_number
  • The parameter :issuer_name is the name of the coupon issuer, a case-insensitive string
  • The optional parameter date_start is the earliest date of the coupons to include in the report. It is inclusive. The date format is yyyy-mm-dd
  • The optional parameter date_end is the latest date of the coupons to include in the report. It is exclusive. The date format is yyyy-mm-dd
  • The optional parameter page is used for paginating the list of coupons. The page size is 20 coupons, and the first page is page 1

Example request

GET /issuers/Wizypay/coupons?date_start=2015-01-01&date_end=2015-02-01&page=4

This request will return a page of coupons (61 to 80) generated in January 2015 for the issuer Wizypay.

Example response

{
  "data": [
    {
      "id": "34255323456",
      "code": "XYHTKMPNUSVF480L",
      "balance": "50.00",
      "face_value": "50.00"
      "currency": "EUR",
      "created_at":"2015-01-12T09:32:27Z"
    },
    {
      "id": "34255323457",
      "code": "XYTD18D92Q7B3N54",
      "balance": "83.00",
      "face_value": "100.00",
      "currency": "EUR",
      "created_at":"2015-01-13T09:32:27Z"
    },
    ...
  ]
}

The API response is a JSON document representing an array of all the coupons created for the specified issuer.

Coupon Point of Sale Back Office

Reporting: Coupons per Client

Clients with the Point of Sale Back Office profile can list coupons for a specific issuer:

GET /clients/:client_id/coupons
  • The parameter :client_id_ is the ID of the client
  • The optional parameter date_start is the earliest date of the coupons to include in the report. It is inclusive. The date format is yyyy-mm-dd
  • The optional parameter date_end is the latest date of the coupons to include in the report. It is exclusive. The date format is yyyy-mm-dd
  • The optional parameter page is used for paginating the list of coupons. The page size is 20 coupons, and the first page is page 1

Example request

GET /clients/1234/coupons?date_start=2015-03-17&date_end=2015-03-18&page=2

This request will return a page of coupons (21 to 40) generated on 17th March 2015 for the client ID 1234.

Example response

{
  "data": [
    {
      "id": "34255323456",
      "code": "XYHTKMPNUSVF480L",
      "balance": "50.00",
      "face_value": "50.00"
      "currency": "EUR",
      "created_at":"2015-01-12T09:32:27Z"
    },
    {
      "id": "34255323457",
      "code": "XYTD18D92Q7B3N54",
      "balance": "83.00",
      "face_value": "100.00",
      "currency": "EUR",
      "created_at":"2015-01-13T09:32:27Z"
    },
    ...
  ]
}

The API response is a JSON document representing an array of all the coupons created for the specified client id. The balance is the current coupon balance, face_value is the initial coupon balance, id is an internal identifier for the coupon, currency is the currency that the coupon is denominated in and code is the coupon code.

Errors

HTTP Status Codes

Error responses in Wizypay APIs must return a HTTP status code in one of the 4XX or 5XX status code families. The 4XX and 5XX statuses indicate, respectively, client and server errors.

In particular:

  • Access to the API without prior authentication will return a 401 Unauthorized status code.
  • Access to a non-existing resource will amount to a 404 Not Found status code.
  • Access to a unauthorized resources will also amount to a 404 Not Found status code (no distinction is made between access to non-existing and unauthorized resource).
  • Exceeding any of the client imposed quotas will return a 503 Service Unavailable status code (please refer to your contract or liaise with support to get your specific quotas).

Error Object

Whenever possible, Wizypay APIs return a JSON object HTTP body for errors. The error object maps each offending request parameters to a list of errors that it has triggered. If some errors cannot be linked directly to a particular input parameter, they are associated to a special field base.

The JSON error has the following format:

{ 
  "errors": { 
    "base": ["error_1", "error_2", ...],
    "paramater_1": ["error_1", "error_2", ...],
    "paramater_2": ["error_1", "error_2", ...],
    "paramater_3": ["error_1", "error_2", ...],
    ...
  }
}

The error list for a given field must not be empty.

When a required parameter is missing, a missing_value error should be set for the offending parameter.

When a parameter violates format and/or constraint specification, an invalid_input error should be set for for the offending parameter.

Examples

HTTP response 503 with body:

{ 
  "errors": { 
    "base": ["quota_exceeded"]
  }
}

HTTP response 422 with body:

{ 
  "errors": { 
    "user_name": ["duplicate_value"],
    "email": ["missing_value"]
  }
}

HTTP response 404 with body:

{ 
  "errors": { 
    "id": ["no_data_found"]
  }
}

Resources and Paging

In Wizypay APIs, the returned json has two top-level fields:

  • data: mandatory field that points to the actual data being requested, be it an array of resources or a single resource.
  • meta: optional field containing additional information about the returned data. It contains for instance paging information for collections or type information when it is not obvious from the context.

For resource collections, the paging information in the meta object indicates the current page, the page size and the total elements count with, respectively, page, per_page and total_count.

Example: Assuming the API endpoint being requested returns list of resources, the response is a json object having the following structure:

{
  "data": [ {...}, {...}, ... ],
  "meta": {
    "page": 1,
    "per_age": 25,
    "total": 4704
  }
}

Authentication

Wizypay APIs are secured by default. An API key and secret are mandatory to get access and interact with our APIs. If you don’t already have an API key/secret pair (or if you have lost them) you can request new credentials.

Access to Wizypay APIs are secured with the Hashed Message Authentication Mode with SHA-256 as underlying hashing function (a.k.a. HMAC-SHA256 see RFC 4846 and the wikipeda entry).

Required HTTP headers

Each request to the API endpoint needs the following HTTP headers to be set in order to be authenticated by the API server:

  • An Authorization header containing the API key concatenated to the authentication code computed from the request data combined with your API secret using the HMAC-SHA256 function. The Authorization header should have the following format:
    Authorization: WIZYPAY {Your Api Key}:{HMAC Authentication Code}
    Example with an API key of 1789:
    Authorization: WIZYPAY 1789:y3iZqjnAjw8D0Y2S5lzT+yAc0Y2S5ZqjnAlzrqk=
  • A Date header. The date should be within 15 minutes from the current time.
  • A Content-Type header, e.g.: text/html or application/x-www-form-urlencoded.

Computing the HMAC Authentication Code

The authentication code is derived from the following data:

  • http_verb is upper case string of the http method of the request. e.g.: GET, POST, PUT etc.
  • content_md5 is the request body MD5 digest computed as described in the Content-MD5 header specification (please notice that the digest value is needed for the computation but the HTTP header can be omitted).
  • content_type is the request content type as set in the required HTTP header Content-Type above.
  • resource_path is the request URL path, query string and anchor part. e.g.: The URL: https://example.com/users/324?name=Joe&age=55#profile has the a resource_path: /users/324?name=Joe&age=55#profile
  • date is the request date as set in the required HTTP header Date above.
  • your_api_secret your private API secret.
string_to_sign = http_verb     + "\n" +
                 content_type  + "\n" +
                 content_md5   + "\n" +
                 resource_path + "\n" +
                 date

authentication_code = Base64(Hmac_Sha256(your_api_secret, UTF8_Encoding_Of(string_to_sign)))

authorization_http_header = "Authorization: WIZYPAY " + your_api_key + ":" + authentication_code

A reference implementation is available on github.