Payment API v1
The Payment API can be used to initialize web payments using the Enviso Payment Widget and verify if the payment was successful.
The Payment API can be used to initialize web payments using the Enviso Payment Widget and verify if the payment was successful.
The Payment API is a REST API solution and attempts to conform to the RESTful design principles.
Important to know
All connections must be made over HTTPS, not HTTP.
All the query parameters are to be passed in lower case.
All date and time data in the API request passed/response received are in the UTC-00:00 format.
yyyy-MM-ddTHH:mm:ssZ (Eg.: 1994-11-05T13:15:30Z)
The following HTTP status codes are used within the Payment API.
Code | Description |
---|---|
200 | OK The request was successful, resulting in everything working as expected. |
201 | Created The request was successful, resulting in the creation of new resource. |
202 | Accepted The server has successful received the request and will start processing it. |
400 | Bad Request The server was unable to understand the request. The request is most likely malformed or a mandatory parameter is missing. TipIt is recommended to make modifications in the current request and repeat the request. |
401 | Unauthorised The request has not been processed because it lacks valid authentication credentials for the target resource. If the request included valid authentication credentials, then the 401 response indicates that authorisation has been refused for the target resource. |
403 | Forbidden The server understood the request but refuses to authorize it. This probably means you did not pass the API Key (x-api-key) in your request headers. |
404 | Not Found The requested resource does not exist. However, the resource may be available in the future. Subsequent requests by the client are permissible. |
410 | Gone The received request is already processed. |
422 | Unprocessable Entity The server understands the content type of the request entity, but was unable to process the contained instructions. For example, this error condition may occur if validation rules to process the entity failed. |
429 | Too Many Requests The server received too many request in a given amount of time. |
500 | Internal Server Error The server encountered an unexpected error, which prevented it from fulfilling the request. |
502 | Bad Gateway The server, while acting as a gateway or proxy, received an invalid response from the upstream server. |
503 | Service Unavailable The server is currently unable to handle the request due to a temporary overloading or maintenance of the server. |
The request and response data is sent as JSON.
content-type: application/json
The API Key is required to be passed in the HTTP Request Headers.
x-api-key: your_api_key
All the Requests made towards the Payment API must have a correct API Key in the header.
The following sequence schema shows a high-level overview of the payment process when integrating Enviso Pay.
The following sequence schema shows a high-level overview of the refund process when integrating Enviso Pay.
Contact GANTNER support to obtain the Tenant key, API key and API secret key, which you need to start communicating to the API.
Once you have the needed information, you need to authenticate first before you'll be able to call the Payment API.
For this, you'll need to use the Authentication API.
When going from the staging environment to the production environment:
Use the production environment API key and API secret key of the Authentication API.
Use the production environment API Key and Tenant key of the Payment API.
Contact GANTNER support to get your production environment keys of the Authentication API and Payment API.
Change the base URL from the staging environment to the production environment.
Production environment: https://api.enviso.io/paymentapi
Staging environment: https://api.staging-enviso.io/paymentapi
Parameter | Type | Required | Description |
amount | Number | Yes | The amount of this payment, as a floating-point number. Eg: 10.23 NoteThe currency is determined by the tenant settings in Enviso. |
originUrl | String | Yes | The URL of the web origin where the web payment is taking place. It is required for security reasons. Eg: https://my-webshop.com (not: http://mywebshop.com/tickets/pay.html?...) NoteThe origin does not include any path or query string! |
returnUrl | String | Yes | The URL of the page (including path + query string) where the visitor should be redirected, after completing the payment with a payment method that involves redirects. Eg: https://my-webshop.com/tickets/paymentcomplete.html |
countryCode | String | Yes | The ISO 3166 2-letter country code of the person who is making the payment. This determines the available payment methods. Eg: BE |
language | String | Yes | The ISO 639 2-letter language code of the preferred language of the person who is making the payment. This will result in the proper localization of the payment widget. Eg: nl |
String | No (but recommended) | The e-mail address of the person who is making the payment. It is required by some payment methods. Eg: someshopper@gmail.com | |
postbackUrl | String | Yes | An https endpoint pointing to the integrator's web server, to which Enviso Pay can postback the final result of the payment (using http POST). Eg: https://my-webshop.com/envisopayresult |
expiresOn | String (date) | No | A DateTime (in UTC) that indicates when the payment expires. If not specified, it is 2 days from the request. An expired payment cannot be completed. If authorization of the payment happens beyond this time, it will automatically be refunded. It is recommended to use an ISO 8601 format to pass the date. Eg: 2021-06-21T11:25:47.000Z |
Success response code: 200 OK
Response details
Parameter | Type | Description |
---|---|---|
reference | string | The unique payment reference |
sessionToken | string | The token that is used to initialize the Enviso Payment Widget |
var client = new RestClient("https://api.staging-enviso.io/paymentapi/v1/payments/web"); var request = new RestRequest(Method.POST); request.AddHeader("Content-Type", "application/json-patch+json"); request.AddHeader("Accept", "text/plain"); request.AddHeader("Authorization", "string"); request.AddHeader("x-tenantsecretkey", "string"); request.AddHeader("origin", "string"); request.AddHeader("x-api-key", "API_KEY"); request.AddParameter("undefined", "{\"amount\":0,\"originUrl\":\"string\",\"returnUrl\":\"string\",\"countryCode\":\"string\",\"language\":\"string\",\"email\":\"string\",\"postbackUrl\":\"string\",\"expiresOn\":\"2019-08-24T14:15:22Z\"}", ParameterType.RequestBody); IRestResponse response = client.Execute(request);
HttpResponse<String> response = Unirest.post("https://api.staging-enviso.io/paymentapi/v1/payments/web") .header("Content-Type", "application/json-patch+json") .header("Accept", "text/plain") .header("Authorization", "string") .header("x-tenantsecretkey", "string") .header("origin", "string") .header("x-api-key", "API_KEY") .body("{\"amount\":0,\"originUrl\":\"string\",\"returnUrl\":\"string\",\"countryCode\":\"string\",\"language\":\"string\",\"email\":\"string\",\"postbackUrl\":\"string\",\"expiresOn\":\"2019-08-24T14:15:22Z\"}") .asString();
const data = "{\"amount\":0,\"originUrl\":\"string\",\"returnUrl\":\"string\",\"countryCode\":\"string\",\"language\":\"string\",\"email\":\"string\",\"postbackUrl\":\"string\",\"expiresOn\":\"2019-08-24T14:15:22Z\"}"; const xhr = new XMLHttpRequest(); xhr.withCredentials = true; xhr.addEventListener("readystatechange", function () { if (this.readyState === this.DONE) { console.log(this.responseText); } }); xhr.open("POST", "https://api.staging-enviso.io/paymentapi/v1/payments/web"); xhr.setRequestHeader("Content-Type", "application/json-patch+json"); xhr.setRequestHeader("Accept", "text/plain"); xhr.setRequestHeader("Authorization", "string"); xhr.setRequestHeader("x-tenantsecretkey", "string"); xhr.setRequestHeader("origin", "string"); xhr.setRequestHeader("x-api-key", "API_KEY"); xhr.send(data);
import http.client conn = http.client.HTTPSConnection("https://api.staging-enviso.io/paymentapi") payload = "{\"amount\":0,\"originUrl\":\"string\",\"returnUrl\":\"string\",\"countryCode\":\"string\",\"language\":\"string\",\"email\":\"string\",\"postbackUrl\":\"string\",\"expiresOn\":\"2019-08-24T14:15:22Z\"}" headers = { 'Content-Type': "application/json-patch+json", 'Accept': "text/plain", 'Authorization': "string", 'x-tenantsecretkey': "string", 'origin': "string", 'x-api-key': "API_KEY" } conn.request("POST", "/v1/payments/web", payload, headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8"))
{ "paymentReference": "string", "sessionToken": "string" }
{ "errors": [ { "code": 0, "message": "string", "propertyName": "string", "trace": "string" } ] }
Parameter | Type | Required | Description | Example |
---|---|---|---|---|
Amount | Number | Yes | The amount of this payment, as a floating point number.Note: the currency is determined by the tenant settings in Enviso. | 10.23 |
OriginUrl | String | Yes | The URL of the web origin where the web payment is taking place.Required for security reasons. Note: the origin does not include any path or query string! | (not:http://mywebshop.com/tickets/pay.html?...) |
ReturnUrl | String | Yes | The URL of the page (including path + query string) where the visitor should be redirected, after completing the payment with a payment method that involves redirects. | |
CountryCode | String | Yes | The ISO 3166 2-letter country code of the person who is making the payment. This determines the available payment methods. | "BE" |
Language | String | Yes | The ISO 639 2-letter language code of the preferred language of the person who is making the payment. This will result in proper localization of the payment widget. | "nl" |
String | No(but recommended) | The e-mail address of the person who is making the payment. Required by some payment methods. | "someshopper@gmail.com" | |
PostbackUrl | String | Yes | An https endpoint pointing to the integrator's web server, to which Enviso Pay can postback the final result of the payment (using http POST). | |
ExpiresOn | String (date) | No | A datetime (in UTC) that indicates when the payment expires. If not specified, it's 21 days from the request. An expired payment cannot be completed. If an authorization of the payment happens beyond this time, it will automatically be refunded. It is recommended to use an ISO 8601 format to pass the date. | "2021-06-21T11:25:47.000Z" |
Success response code: 200 OK
Response details
Parameter | Type | Description |
---|---|---|
paymentReference | string | The unique payment reference (ID) in Enviso. |
paymentLink.url | string | The URL to the payment provider to pay the payment. |
var client = new RestClient("https://api.staging-enviso.io/paymentapi/v1/payments/weblink"); var request = new RestRequest(Method.POST); request.AddHeader("Content-Type", "application/json"); request.AddHeader("Accept", "application/json"); request.AddHeader("x-tenantsecretkey", "string"); request.AddHeader("Authorization", "string"); request.AddHeader("origin", "string"); request.AddHeader("x-api-key", "API_KEY"); request.AddParameter("application/json", "{\"amount\":0,\"originUrl\":\"string\",\"returnUrl\":\"string\",\"countryCode\":\"string\",\"language\":\"string\",\"email\":\"string\",\"postbackUrl\":\"string\",\"expiresOn\":\"2019-08-24T14:15:22Z\"}", ParameterType.RequestBody); IRestResponse response = client.Execute(request);
HttpResponse<String> response = Unirest.post("https://api.staging-enviso.io/paymentapi/v1/payments/weblink") .header("Content-Type", "application/json") .header("Accept", "application/json") .header("x-tenantsecretkey", "string") .header("Authorization", "string") .header("origin", "string") .header("x-api-key", "API_KEY") .body("{\"amount\":0,\"originUrl\":\"string\",\"returnUrl\":\"string\",\"countryCode\":\"string\",\"language\":\"string\",\"email\":\"string\",\"postbackUrl\":\"string\",\"expiresOn\":\"2019-08-24T14:15:22Z\"}") .asString();
const data = JSON.stringify({ "amount": 0, "originUrl": "string", "returnUrl": "string", "countryCode": "string", "language": "string", "email": "string", "postbackUrl": "string", "expiresOn": "2019-08-24T14:15:22Z" }); const xhr = new XMLHttpRequest(); xhr.withCredentials = true; xhr.addEventListener("readystatechange", function () { if (this.readyState === this.DONE) { console.log(this.responseText); } }); xhr.open("POST", "https://api.staging-enviso.io/paymentapi/v1/payments/weblink"); xhr.setRequestHeader("Content-Type", "application/json"); xhr.setRequestHeader("Accept", "application/json"); xhr.setRequestHeader("x-tenantsecretkey", "string"); xhr.setRequestHeader("Authorization", "string"); xhr.setRequestHeader("origin", "string"); xhr.setRequestHeader("x-api-key", "API_KEY"); xhr.send(data);
import http.client conn = http.client.HTTPSConnection("api.staging-enviso.io") payload = "{\"amount\":0,\"originUrl\":\"string\",\"returnUrl\":\"string\",\"countryCode\":\"string\",\"language\":\"string\",\"email\":\"string\",\"postbackUrl\":\"string\",\"expiresOn\":\"2019-08-24T14:15:22Z\"}" headers = { 'Content-Type': "application/json", 'Accept': "application/json", 'x-tenantsecretkey': "string", 'Authorization': "string", 'origin': "string", 'x-api-key': "API_KEY" } conn.request("POST", "/paymentapi/v1/payments/weblink", payload, headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8"))
{ "paymentReference": "string", "expiresOn": "2019-08-24T14:15:22Z", "paymentLinkUrl": "string" }
{ "errors": [{ "message": "string", "code": "number" }] }
Success response code: 200 OK
Response details
Parameter | Type | Description |
---|---|---|
id | string | The unique payment reference. |
amount.value | string | The amount of the payment (as a floating-point number). |
amount.currency | string | The currency code of the payment. |
topic.type | string | The topic to which the payment is linked. For the moment only one topic is supported, that is, 'order'. |
topic.id | integer | The unique reference of the topic to which the payment is linked. |
status.tentative | boolean | Defines whether or not the payment is in the final status. |
status.value | string | The payment status can be:
For "open" and "requested", the payment is awaiting action from the end-user. "Success" and "failed" are reached after feedback from the payment provider. "Cancelled" usually means the payment is expired (by default, after 60 minutes). For internal Enviso orders, the payment is also cancelled when the order is cancelled. |
pspReference | string | The unique payment reference within the payment provider. |
paymentMethod | string | The payment method that was used during the payment process Eg: BCMC, Visa, iDEAL, etc. NoteAvailable only after the payment method has been selected and submitted by the end-user. |
postbackUrl | string | The URL to be used for pushing notifications related to the payment. Eg: https://my-webshop.com/envisopayresult NoteThis is filled only for third-party payments and not for internal Enviso payments. |
var client = new RestClient("https://api.staging-enviso.io/paymentapi/v1/payments/string"); var request = new RestRequest(Method.GET); request.AddHeader("Accept", "text/plain"); request.AddHeader("Authorization", "string"); request.AddHeader("x-tenantsecretkey", "string"); request.AddHeader("origin", "string"); IRestResponse response = client.Execute(request);
HttpResponse<String> response = Unirest.get("https://api.staging-enviso.io/paymentapi/v1/payments/string") .header("Accept", "text/plain") .header("Authorization", "string") .header("x-tenantsecretkey", "string") .header("origin", "string") .asString();
const data = null; const xhr = new XMLHttpRequest(); xhr.withCredentials = true; xhr.addEventListener("readystatechange", function () { if (this.readyState === this.DONE) { console.log(this.responseText); } }); xhr.open("GET", "https://api.staging-enviso.io/paymentapi/v1/payments/string"); xhr.setRequestHeader("Accept", "text/plain"); xhr.setRequestHeader("Authorization", "string"); xhr.setRequestHeader("x-tenantsecretkey", "string"); xhr.setRequestHeader("origin", "string"); xhr.send(data);
import http.client conn = http.client.HTTPSConnection("https://api.staging-enviso.io/paymentapi") headers = { 'Accept': "text/plain", 'Authorization': "string", 'x-tenantsecretkey': "string", 'origin': "string" } conn.request("GET", "/v1/payments/string", headers=headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8"))
{ "id": "string", "amount": { "currency": "string", "value": 0 }, "topic": { "type": "string", "id": 0 }, "status": { "tentative": bool, "value": "string" }, "pspReference": "string", "paymentMethod": "string", "postbackUrl": "string", "lastNotificationDate": "2020-10-16T09:52:18.830Z", "lastModified": "2020-10-16T09:52:18.830Z" }
{ "errors": [ { "code": 0, "message": "string", "propertyName": "string", "trace": "string" } ] }
Parameter | Type | Required | Description |
---|---|---|---|
postbackUrl | string | Yes | The URL to be used for pushing notifications related to the payment. Eg: https://my-webshop.com/envisopayresult NoteThis is filled only for third-party payments and not for internal Enviso payments. |
Success response code: 202 Accepted
Response details
Parameter | Type | Description |
---|---|---|
refundReference | string | An identifier for this refund. Guaranteed to be unique among all refunds for a particular payment.Useful for the postback integration to correlate the feedback to this refund. |
URL obj = new URL("/v1/payments/{id}/refund"); HttpURLConnection con = (HttpURLConnection) obj.openConnection(); con.setRequestMethod("PUT"); int responseCode = con.getResponseCode(); BufferedReader in = new BufferedReader( new InputStreamReader(con.getInputStream())); String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); System.out.println(response.toString());
const inputBody = '{ "postbackUrl": "string", "amount": 0 }'; const headers = { 'Content-Type':'application/json-patch+json', 'Accept':'text/plain', 'Authorization':'string', 'x-tenantsecretkey':'string', 'origin':'string', 'x-api-key':'API_KEY' }; fetch('/v1/payments/{id}/refund', { method: 'PUT', body: inputBody, headers: headers }) .then(function(res) { return res.json(); }).then(function(body) { console.log(body); });
import requests headers = { 'Content-Type': 'application/json-patch+json', 'Accept': 'text/plain', 'Authorization': 'string', 'x-tenantsecretkey': 'string', 'origin': 'string', 'x-api-key': 'API_KEY' } r = requests.put('/v1/payments/{id}/refund', headers = headers) print(r.json())
{ "refundReference": "string" }
{ "errors": [{ "message": "string", "code": "number" }] }
Parameter | Type | Required | Description |
---|---|---|---|
postbackUrl | string | true | The URL for the postback integration. See further, Postback integration Eg: https://my-webshop.com/envisopayresult |
amount | number | true | The amount to refund as a floating-point number. Eg: 10.23 NoteThe currency is determined by the tenant settings in Enviso. |
Success response code: 202 Accepted
Response details
Parameter | Type | Description |
---|---|---|
refundReference | string | An identifier for this refund. Guaranteed to be unique among all refunds for a particular payment. Useful for the postback integration to correlate the feedback to this refund. |
URL obj = new URL("/v1/payments/{id}/refunds"); HttpURLConnection con = (HttpURLConnection) obj.openConnection(); con.setRequestMethod("POST"); int responseCode = con.getResponseCode(); BufferedReader in = new BufferedReader( new InputStreamReader(con.getInputStream())); String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); System.out.println(response.toString());
const inputBody = '{ "postbackUrl": "string", "amount": 0 }'; const headers = { 'Content-Type':'application/json-patch+json', 'Accept':'text/plain', 'Authorization':'string', 'x-tenantsecretkey':'string', 'origin':'string', 'x-api-key':'API_KEY' }; fetch('/v1/payments/{id}/refunds', { method: 'POST', body: inputBody, headers: headers }) .then(function(res) { return res.json(); }).then(function(body) { console.log(body); });
import requests headers = { 'Content-Type': 'application/json-patch+json', 'Accept': 'text/plain', 'Authorization': 'string', 'x-tenantsecretkey': 'string', 'origin': 'string', 'x-api-key': 'API_KEY' } r = requests.post('/v1/payments/{id}/refunds', headers = headers) print(r.json())
{ "refundReference": "string" }
{ "errors": [{ "message": "string", "code": "number" }] }
When initializing a payment/refund, a postbackUrl
is passed. This is an HTTPS endpoint on the calling system, to which the Enviso Pay system can post the authorization result of the payment.
Parameter | Type | Description |
---|---|---|
reason | string | In case of non-successful payment, this property is present and contains an error message detailing the failure. |
paymentReference | string | The identification of the payment, as received upon initializing the payment. |
paymentMethod | string | The payment method used to complete the payment. |
isSuccess | boolean | Indicates whether the payment was processed successfully. |
{ "paymentReference": "string", "isSuccess": boolean, "paymentMethod": "string", "reason": "string" }
To ensure that your server is properly accepting the Enviso Pay postbacks, we require you to acknowledge every postback.
The postback mechanism has a fixed timeout of 15 seconds. If no valid response is received within this time frame, we will retry the postback later (see Delivery attempts below).
When your server receives a postback:
Store the postback data in your database.
Acknowledge the postback with a successful (2xx - eg. 200 OK) HTTP status.
Apply your business logic to process the postback data.
Make sure that you acknowledge the postback before applying any business logic, because a breakage in your business logic could otherwise prevent important updates from reaching your system.
The Enviso Payment system will keep trying to deliver the final payment result until a successful response code is received (2xx), during a reasonable time frame.
Currently, the system will do a total of 20 attempts, over a time frame of maximum 5 minutes (depending on HTTP timeouts occur or not).
Fault tolerance improvements
We are aware this might not be sufficient in certain scenarios and we are looking to increase this in an upcoming release of the Payment API.
In the meantime, if the final postback could not be received, due to a network outage or service outage at the side of the integrator, it is always possible to query the payment status via the API (Get payment endpoint).