home Introduction

link Try now

Try out how the Espago API works. Charge your first client followind these steps.

In the first step an iFrame is created, which serves the purpose of sending credit card information to the Espago Gateway. It then fetches the credit card token and submits it to a form.
You can use a mock credit card: 4242 4242 4242 4242, with the expiry date of 02/2025. The CVV code does not matter.
Try it on your own
<!-- iFrame Configuration -->
<script 
  async=""
  data-id="EspagoFrameScript"
  data-key="VrYVaA1CjmRooKh63YYv"
  data-live="false"
  data-button="Pay"
  src="https://js.espago.com/iframe-1.0.js">
</script>

<!-- Form with the credit card token -->
<form id="espago_form" 
      action="/charge_client" 
      accept-charset="UTF-8" 
      method="post">
</form>
Next, the true request is sent to the Espago gateway. It consists of user information, the charged amount and currency among other information. Card input contains the credit card token generated by the IFrame.
curl -i https://sandbox.espago.com/api/charges \
 -H "Accept: application/vnd.espago.v3+json" \
 -u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
 -d "amount=10" \
 -d "currency=pln" \
 -d "card=[card_token]" \
 -d "description=Espago docs"
Here is how the response will look like. It is sent using JSON formatting. Id and state are pivotal. More on back requests
{
 "id":"pay_7715NocOaPcNTL9O",
 "description":"Espago docs", 
 "channel":"elavon",
 "amount":"10.00",
 "currency":"pln",
 "state":"executed",
 [...]
}

link Gateway Description

Security

In order to ensure a certain level of security is maintained, it is highly advised to use SSL (HTTPS) certificates on the merchants site. In every viable way of integrating, sensitive data regarding credit cards are sent directly from the client to the Espago gateway, excluding the Merchant’s site. This solution frees the Merchant from the responsibility associated with storing or processing credit card information, while PCI-DSS certification stays limited to filling out a questionnaire after sighning a contract with Elavon.

The Architecture of Our API

Our API follows the principles of the REST architectural style. Every operations related to payment managment (status checks etc) have to be perfomed using API Requests (Application Programming Interface) - this very documentation focuses on explaining how to make use of our API. UTF-8 encoding is required in sent data. The API always generates answers in the JSON format.

Request time

A 30 second timeout (the maximal amount of time your site will wait for a response from Espago) is recommended for API requests, although the large majority of payments get processed in less than 2 seconds. We suggest to avoid calling any recurring payments at 3:30-5:30 CEST (01:30- 03:30 UTC) on working days, since we may be performing maintanance work on the Espago gateway.

link Integration methods

There are three ways of integrating with the Espago gateway for payments:

Attaching the iFrame to the merchant’s site


Using the iFrame script (for gathering credit card data) or a form with the use of Espago JS and performing the necessary payment operations through API requests (Read more)

Redirecting clients to the Espago Secure Web Page


Redirecting clients with proper payment parameters. Receiving the response from the Espago gateway and taking care of the user, who’s redirected back to the mechant’s site. (Read more)

Integration through the Przelewy24 system

Espago/Elavon card payments can be one of many or the only payment method available for clients in Przelewy24. In this case integration with the Espago gateway is not necessary. The mechant has to integrate his site only with the Przelewy24 module.

This solution is greatly beneficient when:

  • The merchant is also interested in receiving payments through regular/fast bank transfers
  • The merchant uses a premade online store system (PrestaShop, Magento i inne) and is focused on quick and simple one-time payments
  • The mechant already uses Przelewy24

assignment Integration

link Integration process

Features which should be tested during the integration include:

  • the creation of tokens,
  • charging cards/creating payments
  • displaying the reason of rejection to customers, when the payment is not successful,
  • obtaining information about payment status,
  • Reversal and refunding of the transaction (no need to implement these features at the beginning, but it’s very useful to test curl queries),
  • The creation of customer profiles and managing them (if there is business need, for example in recurring payments or in stores where the customer returns and purchases can be repeated)
  • recieving back-requests

Transitioning to the second and at the same time the last integration step requires you to firstly test your web application in the test environment and submit it to our Support Team for further inspection of your integration (espacially concerning the payment form).
The list of technical and general requirements of Elavon is available in this documentation under the ‘Downloads’ section. A test environment that can be used for viewing and setting parameters or inspecting test payments, requests and responses is available here: https://sandbox.espago.com

In order to switch over to the production environment you have to alter the connection parameters - 5 of them need to be changed:

  1. Gateway address
  2. App ID
  3. API password
  4. Public key
  5. the value of the ‘live’ parameter in the Espago constructor

After integrating into the production environment, the test environment still remains available to use for our clients. At the request of the Seller, the Espago Team can:

  • Add a new service within the Seller’s account (eg. For any currencies)
  • Enable / disable the ability to create and use plans and subscriptions (disabled by default)
  • Enable / disable 3D-Secure (enabled by default) or DCC (disabled by default)
  • Create a new user with access to the panel
  • Provide answers and help solving problems associated with integration

In the case of problems with compability we recommend reading this: detailed compatibility requirements

link First steps

After gaining access to the Merchant Panel, the following steps should be taken:

  1. Navigate to this page:
  2. Click on the ‘Edit’ button to access the site editing panel
  3. Fill in the ‘API password’ and ‘API password confirmation’ inputs - their value is responsible for the correct authorisation of your account and must not be shared with unauthorised persons. You have to also fill in the ‘Email BOK’ field
  4. Accept the changes by clicking on ‘Submit’.

Clicking on the ‘Show’ button should yield a similar result:

link Required request headers

For correct API requests, the following HTTP headers are used:

Headers Required Value
Authorization1 Required Basic app_id:password
Accept Required application/vnd.espago.v3+json

Requests for token creation are authorised with the use of a Public Key and for most services it is handled by Espago JS.
A series of unsuccessful log in attempts results in the account getting temporarily blocked.


Authorization1 - with the parameters of: APP_ID and the password fetched in the “First Steps” section. It concerns all API requests except for token creation.

link Test Cards Data

While testing your integration you need to use the data of the test cards mentioned below. To acheive successful or declined transaction you have to indicate specific card validation date and CVV - see the second and the third table below.

The use of real credit cards is forbidden.

Card number Brand Currency 3-D Secure DCC Required use during integration
4012001037141112 Visa PLN Verified by Visa No Yes
5432670000041258 Mastercard PLN Mastercard SecureCode No Yes
4242424242424242 Visa PLN No No Yes
375987000000005 American Express PLN Amex SafeKey No If Amex cards expected
4012888888881881 Visa USD Verified by Visa Yes If DCC expected
5555555555554444 Mastercard HKD Mastercard SecureCode Yes If DCC expected
4242421111112239 Visa HKD No Yes If DCC expected
4917484589897107 Visa PLN No No If COF payments expected
- this card requires CVV code
usage in every transaction.
Not suited for the subscriptions
and COF=recurring payments



The year of expiry is not important as long as it is a future date. You control the outcome of the payment by altering the month of expiry. Thanks to this feature, you are able to test both positive and negative scenarios.

Month (expiration date) Result Issuer response code
01-05 Transaction accepted 00
06 Random outcome, 50% chance of succeeding.
Useful while testing recurring payments.
n/a
07 Transaction rejected 04, 07, 41, 43
08 Transaction rejected 51
09 Transaction rejected 13
10 Transaction rejected 00
11 Transaction rejected 54
12 Transaction rejected 05, 57, 61



CVV code Result in the test gateway
683 Incorrect CVV. Transaction will be rejected due to incorrect CVV.
Other CVVs Correct CVV.

link Test connection

To check your connection with Espago API You should send a request to https://sandbox.espago.com/api/test. In response you’ll get parameter state - value passed mean that your connection is configurated properly. Value failed means incorrect connection - then table warnings contains information about reasons of rejection.

Example request

curl -i https://sandbox.espago.com/api/test \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/test")
request = Net::HTTP::Get.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/test');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "state":"passed",
  "warnings":[]
}
{
  "state":"failed",
  "warnings":[
    {
      "title":"Access denied",
      "message":"Wrong app_id or password."
    },
    {
      "title":"Wrong request headers",
      "message":"Check your 'Accept' header."
    },
        . . .
  ]
}

exit_to_app Secure Web Page

link Example form

The Secure Web Page method of payment handles most of thew work for you by redirecting the client to the Espago Gateway where they will enter their credit card data. They then get charged the correct amount and get redirected back to your site. You can see a demo in action here: warzywko.espago.com

You can use a test card with the number: 4242 4242 4242 4242; and expiry date of 02/2025. The CVV number does not matter. (More on test cards)

link Functioning of Secure Web Page

1. Submitting the form

By clicking on the submit button clients send hidden parameters assiociated with the payment through the POST method to the Espago gateway and gets redirected to the Secure Web Page.

<form accept-charset="UTF-8" action="https://sandbox.espago.com/secure_web_page" id="espago_secure_web_page" method="post">
  <input name="api_version" type="hidden" value="3" />
  <input name="app_id" type="hidden" value="ms_771eUTliRiZ" />
  <input name="kind" type="hidden" value="sale" />
  <input name="session_id" type="hidden" value="1559655843622983577" />
  <input name="amount" type="hidden" value="10.00" />
  <input name="currency" type="hidden" value="PLN" />
  <input name="title" type="hidden" value="payment_id:294" />
  <input name="description" type="hidden" value="Platność - Jan Kowalski" />
  <input name="positive_url" type="hidden" value="http://example.com/payments/ok" />
  <input name="negative_url" type="hidden" value="http://example.com/payments/bad" />
  <input name="ts" type="hidden" value="1444044688" />
  <input name="checksum" type="hidden" value="938ee2f7729ac4ba1a7c98f5ead8b167" />
  <button name="button" type="submit" class="btn espago-blue pulse">Pay</button>
</form>

2. Charging the client

Clients submit their data for the Espago gateway to process and charge the client. At the same time a back request is sent to the shop with data concerning the payment.

3. Redirecting back to the shop

Depending upon the status of the transaction, the client gets redirected to one of the two URLs, one for positive results and the second one for failed transactions. It’s a good idea to use this step to inform the client about the payment status and the reason for rejections.

link Form parameters

Payment parameters are sent through the POST method on the following URL:

sandbox URL: https://sandbox.espago.com/secure_web_page
URL: https://secure.espago.com/secure_web_page

Parameter Description Required Notes
api_version API version done 3
app_id Application ID done
kind Type of transaction done sale or preauth(hold certain amount of money on customer’s card and charge it later)
session_id merchant session ID/transaction ID done Random, unique character string generated by the Merchant
amount transaction amount done two decimal places, separated by a dot
eg. 10.00, 1.23, 1.20
currency currency done
title transaction description done Payment description - will be displayed as a payment title at the top of payment card form, e.g. ‘Order 123/2019’.
Should be between 5 and 100 characters.

The ‘title’ parameter from the form will be available as the payment parameter ‘description’ (eg. in the back request).
description client description Description of the customer, not the payment.
email client’s email E-mail of the client. A confirmation email will be sent to this address.
positive_url URL URL to which the client will be forwarded after the correct transaction processing
negative_url URL URL to which the client will be forwarded in case of a transaction error
locale transaction language pl, en, da, ru, sv
reference_number reference number Trans ref text - visible in Elavon reports. Length up to 20 characters, only alphanumeric and -_ (minus and bottom bar).
channel Payment channel Payment channel for this payment request. Defaut value is “elavon_cc”
ts timestamp done
checksum checksum done MD5 checksum for a string comprised of payment parameters (app_id + kind + session_id + amount + currency + ts + checksum_key). The fields’ separator: “|”
Shopping cart details, where INDEX is a number 0-100 (optional)
shopping_cart_items [INDEX][description] item description done
shopping_cart_items [INDEX][quantity] item quantity done
shopping_cart_items [INDEX][value] item price done
shopping_cart_items [INDEX][image_url] Item image URL Has to be HTTPS/SSL




An example of the form:

<form id="espago_secure_web_page" action="https://sandbox.espago.com/secure_web_page" accept-charset="UTF-8" method="post">
  <input type="hidden" name="api_version" value="3" />
  <input type="hidden" name="app_id" value="ms_0CvDQqhnS" />
  <input type="hidden" name="kind" value="sale" />
  <input type="hidden" name="session_id" value="2HWSjEs5G4RcXZjqHqWA" />
  <input type="hidden" name="amount" value="42.94" />
  <input type="hidden" name="currency" value="PLN" />
  <input type="hidden" name="title" value="order_165" />
  <input type="hidden" name="description" value="Transaction - john@smith.com 42.94" />
  <input type="hidden" name="email" value="john@smith.com" />
  <input type="hidden" name="positive_url" value="http://example.com/payments/ok"  />
  <input type="hidden" name="negative_url" value="http://example.com/payments/bad"  />
  <input type="hidden" name="ts" value="1559230283" />
  <input type="hidden" name="checksum"value="532839977fb76ca06ea635c7a936c7db" />
  <input type="hidden" name="shopping_cart_items[0][description]" value="Orange Papaya" />
  <input type="hidden" name="shopping_cart_items[0][quantity]" value="2" />
  <input type="hidden" name="shopping_cart_items[0][value]" value="8.99" />
  <input type="hidden" name="shopping_cart_items[1][description]" value="Cauliflower" />
  <input type="hidden" name="shopping_cart_items[1][quantity]"value="1" />
  <input type="hidden" name="shopping_cart_items[1][value]" value="3.99" />
  <input type="hidden" name="shopping_cart_items[2][description]" value="Purple Bell Peppers" />
  <input type="hidden" name="shopping_cart_items[2][quantity]" value="3" />
  <input type="hidden" name="shopping_cart_items[2][value]" value="6.99" />
  <div class="button">
    <button name="button" type="submit">Buy now!</button>
  </div>
</form>

link Payment with Champion

To register a payment with Champion please send POST request to the following address https://sandbox.espago.com/api/secure_web_page_register`

(:service_client_id)` - client ID in a Merchant system, has to be uniq, because of using in a automatic logging in

(:redirect_url) - link, where a user should be redirected to pay

A result is sent by Back requests.

curl -i https://sandbox.espago.com/api/secure_web_page_register /
-X POST /
-H 'Accept: application/vnd.espago.v3+json' /
-u app_id:password /
-d 'amount=49.99' /
-d 'currency=PLN' /
-d 'description=Opis transakcji' /
-d 'kind=sale' /
-d 'service_client_id=xxxxxx' /
-d 'client_description=xxxxx'

require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/secure_web_page_register")
request = Net::HTTP::Post.new(uri)
request.basic_auth("app_id", "password")
request["Accept"] = "application/vnd.espago.v3+json"
request.body = "amount=49.99&currency=PLN&description=Opis transakcji&kind=sale&service_client_id=xxxxxx&client_description=xxxxx"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/secure_web_page_register');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "amount=49.99&currency=PLN&description=Opis transakcji&kind=sale&service_client_id=xxxxxx&client_description=xxxxx");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'app_id' . ':' . 'password');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "id": "pay_IZTq8l_qaHuOHH",
  "description": "Opis transakcji",
  "amount": "49.99",
  "currency": "PLN",
  "state": "new",
  "created_at": 1550224439,
  "transaction_id": "tn_CLN2HhetI",
  "redirect_url": "https://sandbox.espago.com/secure_web_page/tn_CLN2HhetI"
}

open_in_browser iFrame

link The functioning of Espago iFrame

EspagoFrame script creates an iframe with a modal window where the customer can enter his credit card data. Next, the data is sent to Espago, and the script returns the token ID to the Merchant’s.
An example of this method of integrating can be found on this test site warzywko.espago.com.

1. Calling the iFrame

In the first step the client calls the Espago iFrame clicking on a button (the call has to be made in your script, by the function called: showEspagoFrame()). Next, the client enters his credit card information, which get sent asynchronously to the Espago gateway in order to generate a token.

 <script src="https://js.espago.com/espago-1.2.js"></script>
 <script 
   async=""
   data-id="EspagoFrameScript"
   data-key="VrYVaA1CjmRooKh63YYv"
   data-live="false"
   data-button="Pay"
   src="https://js.espago.com/iframe-1.0.js">
 </script>

 <a id="pay_btn">Zapłać</a>
$('#pay_btn').click( () => {
  showEspagoFrame()
})

2. Receiving tokens

After receiving the token, the Espago script searches for a form with an id of: espago_form, and creates a new input therein: <input type="hidden" id="card_token" name="card_token" value="[TOKEN]">. The form is then submitted to the designated URL.

<form id="espago_form" 
      action="/charge_client" 
      accept-charset="UTF-8" 
      method="post">
</form>

If the token was not used, the CVV code from the token will be automatically removed after a maximum of 2 days from creation, and the entire token after 2 months.

3. Charges

After receiving the token, the Merchant’s server should send a request with the POST method to the following URL: https://sandbox.espago.com/api/charges.

curl -i https://sandbox.espago.com/api/charges \
 -H "Accept: application/vnd.espago.v3+json" \
 -u ms_771eUTliRiZ:SeCreT_P@ssw0rD \    # app_id:pass
 -d "amount=10" \
 -d "currency=pln" \
 -d "card=cc_772ahSzjmMnOt4eIk" \    # token
 -d "description=Espago docs"
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/charges")
request = Net::HTTP::Post.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"
request.body = "amount=10&currency=pln&card=cc_772ahSzjmMnOt4eIk&description=Espago docs"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "amount=10&currency=pln&card=cc_772ahSzjmMnOt4eIk&description=Espago docs");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);

More on charge parameters

4. The response from Espago

After a successful charge request, Espago returns data about the current payment in JSON formatting. The state parameter is key. executed means that the payment has succeded.
Example of a response from Espago:

{
 "id":"pay_772FThyrtalisvgk",
 "description":"Espago docs",
 "channel":"elavon",
 "amount":"10.00",
 "currency":"pln",
 "state":"executed",
 "client":"cli_772coQy1BaW3F0Zn",
 "created_at":1559649971,
 "card":
 {
  "company":"VI",
  "last4":"4242",
  "year":2020,
  "month":2,
  "first_name":"Adam",
  "last_name":"Kowalski",
  "authorized":null,
  "created_at":1559649956
 },
 "issuer_response_code":"00",
 "reversable":true,
 "transaction_id":"tr_7728ogw8v"
}
More on feedback

5. Response - information for the client

After completing the payment it is necessery to inform your clients about the status of their transaction, together with the reason of rejection (if that is the case). Error codes are available in the ‘Downloads’ section.

link iFrame parameters

Parameter Required? Default value Meaning
async done “” No other values are permitted
data-id done EspagoFrameScript No other values are permitted
src done Script URL No other values are permitted
data-key done String, Merchant’s public key
data-live true String, If ‘true’, then requests are sent to production environment. If set to ‘false’, requests are sent to test environment.
data-lang pl String, Form language (for default labels, placeholders) in ISO 639-1 standard. Available: en, pl, bg, cs, da, de, el, es, et, fi, fr, ga, hr, hu, it, lt, lv, mt, nl, no, pt, ro, ru, sk, sl, sv.
data-success function(data) {} A callback function called when the token gets generated. Caution, defining a callback function disables the default action of our script - the ‘card_token’ field will not be appended to the form.
data - string, a generated token from the Espago gateway.
data-error function(data) {} A callback function called when token generation failed.
data - string; Error code received from the Espago gateway together with a description.
data-onclose function() {} A function called when the user closes the dialogue window (by clicking on ‘x’ or pressing ‘Esc’).
data-target espago_form Name of the form to which the ‘card_token’ field will be appended.
Caution - if you decide to submit the form with the ‘success_callback’ parameter, this action will not take place. The token will be submited to this function.
data-title Add your card (en) Form title.
Note - The default value depends on the language value of ‘data-lang’.
data-subtitle The text displayed below the form title and store name (store name is taken automatically from the API Espago).
data-button Save (en) The label that will be displayed inside the form submitting button.
Note - The default value depends on the language value of ‘data-lang’.

attach_money One-time payment

link Charge parameters

A new charge is created after a POST request is send to https://sandbox.espago.com/api/charges. The transaction needs to be executed with the use of one of the afformentioned methods of passing on card details (make sure you are sending the apprioprate requests with correct parameters).

Parameter Description Details
description Transaction decription Has to consist of 5 to 99 characters.
amount Transaction amount Floating point number, np. 123.45
currency Currency Three-character long currency symbol, compatible with currently used MID
client client ID ID of a client (when charging an existing client)
card token ID ID of a token (in case of a one-time payment)
channel Payment channel Payment channel for this payment request. Defaut value is “elavon_cc”
recurring [optional] Adding parameter “recurring=true” enforces classification of transaction in bank as recurring transaction. This results in not checking the 3D-Secure. This parameter is needed in recurring payment (when CVV code is not used), because it significantly increase chances to accept transaction by bank (normal internet payments requier CVV code).
complete [optional] Adding parameter “complete=false” enforces making only reservation of payment. See details in separate chapter.
moto [opcjonalny] Adding parameter “moto=true” enforces classification of transaction as MOTO (Mail Order/Telephone Order). This results in the omission of 3D-Secure. Before using please contact the Espago Tech Team.
cvv [optional] Sending CVV in this format - “cvv=cv_xxxxxxxxxx” enables you to add CVV to a payment processed through an already existing client profile (when the original CVV has been “used”). Details in “CVV tokens”.
positive_url [optional] URL to which the client will be redirected to after successful payment processing
negative_url [optional] URL to which the client will be redirected to after unsuccessful payment processing
skip_3ds [optional] Adding the “skip_3ds=true” parameter results in the omission of 3D-Secure. Before using please contact the Espago Tech Team.
reference_number [optional] Trans ref text - visible in Elavon reports. Length up to 20 characters, only alphanumeric and - (minus and underscore).
locale [optional] Language code in ISO 639-1 standard. Two-letter string value. Language used in web page and/or in email notification. If language is not supported, english is used.
email [optional] E-mail address which the notification about this charge’s result should be sent to. If the parameter is used with a customer profile with an e-mail address, the address sent in this parameter has a priority and is used for sending notification. String variable.
skip_email [optional] Disables email notifications - even if you send a request charge with a customer profile with an email address. Boolean (false/true, default: false).
cof [optional] The use of “Card on file” mechanism. Possible parameter values: storing (saving card data in the form of a client profile, which can be used later for payments with tokens), recurring (information for the bank that this payment is a part of a subscription service, for use in payments processed with the use of a client profile).

link Charge example

curl -i https://sandbox.espago.com/api/charges \
 -H "Accept: application/vnd.espago.v3+json" \
 -u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
 -d "amount=10" \
 -d "currency=pln" \
 -d "card=cc_772ahSzjmMnOt4eIk" \
 -d "description=Espago docs"
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/charges")
request = Net::HTTP::Post.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"
request.body = "amount=10&currency=pln&card=cc_772ahSzjmMnOt4eIk&description=Espago docs"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "amount=10&currency=pln&card=cc_772ahSzjmMnOt4eIk&description=Espago docs");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
{
  "id":"pay_773ob8rbBtid0PYd",
  "description":"Espago docs",
  "channel":"elavon",
  "amount":"10.00",
  "currency":"pln",
  "state":"executed",
  "client":"cli_7733nQkDLdlhHmh-",
  "created_at":1561990343,
  "card":{
    "company":"VI",
    "last4":"4242",
    "year":2020,
    "month":2,
    "first_name":"Adam",
    "last_name":"Adam",
    "authorized":null,
    "created_at":1561990328
  },
  "issuer_response_code":"00",
  "reversable":true,
  "transaction_id":"tr_773OKuy0b"
}

More info about responses can be found here.

{
  "id": "pay_772LFdT3JG6KaAir",
  "description": "order_481",
  "channel": "elavon",
  "amount": "9.99",
  "currency": "PLN",
  "state": "new",
  "client": "cli_772mtwcEVYBfRCJ2",
  "created_at": 1560935536,
  "card": { ... },
  "issuer_response_code": "",
  "transaction_id": "tr_772atPpUX",
  "redirect_url": "https://sandbox.espago.com/3d-secure/tr_772atPpUX",
  "tds_redirect_form": { ... }
}

link 3D Secure

3D Secure is a transaction authorisation method used in the web. It redirects users to their bank’s site for additional authorisation (through SMS or submitting other credentials).

Proper handling of cards with 3D Secure is necessary for correct transaction flow. The Espago Support Team can disable 3D Secure on demand of the merchant. Nonetheless, it is highly unadvisable.


Charges for clients using 3D Secure have the status parameter set to new and an additional parameter - redirect_url. It’s value is equal to the URL to which the user should be redirected to (for authorisation on the bank’s site). After redirecting the transaction’s status will be set to tds_redirected.
After successfuly finishing the required authorisation process, the client will be redirected back to the appropriate merchant’s site (postitive URL / negative URL). Details concerning the transaction will be submitted to the back_request URL.

link eDCC

Dynamic Currency Conversion (DCC) is a service that enables international Visa® and MasterCard® cardholders the choice to pay the bill in their own currency rather than the local currency.

PDCC from Elavon can convert MasterCard® and Visa® credit and debit transactions in up to 45 currencies — more than any other payment processor — you have more opportunity to grow revenue with us.Your customers will be able to see the actual amount they will be charged before finishing the transaction.

The eDCC service will not be called for recurring payments (recurring = true). The cardholder does not take part in the recurring payment, so he can not make a DCC decision. In this case - when using card in a different currency than the currency of the service for recurring payments, currency conversion will be made by card issuer bank - and according to its rules.

1. Information about currency choice

The transaction begins as normal. If the merchant has got the eDCC service, the Espago gateway automatically discerns if the card qualifies for currency conversion.


If the card is suited for DCC transactions, the gateway responds and waits for the customer’s decision. The response in DCC transaction will always show the amount in the merchant’s currency, the conversion rate and the actual amount of charge (in customer’s currency). A payment waiting for the customer’s decision gets the parameter of status=dcc_decision.

If the card is not suited for DCC, the payment continues without interruptions.

curl -i https://sandbox.espago.com/api/charges \
-H "Accept: application/vnd.espago.v3+json" \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "amount=49.99" \
-d "currency=pln" \
-d "client=cli_772uWYtgJXnL_F9I" \ # A customer with a card with a different currency
-d "description=Description"
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/charges")
request = Net::HTTP::Post.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"
request.body = "amount=49.99&currency=pln&client=cli_772uWYtgJXnL_F9I&description=Description"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "amount=49.99&currency=pln&client=cli_772uWYtgJXnL_F9I&description=Opis transakcji");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "id": "pay_7724xNjCpNPWYevy",
  "description": "order_502",
  "channel": "elavon",
  "amount": "17.98",
  "currency": "PLN",
  "state": "dcc_decision",
  "client": "cli_772KDwdXQIbqpFp3",
  "created_at": 1560942887,
  "card": { ... },
  "issuer_response_code": "",
  "transaction_id": "tr_772_lDLkv",
  "dcc_decision_information": {
    "cardholder_currency_name": "HKD",
    "cardholder_amount": "39.74",
    "conversion_rate": "2.210174",
    "redirect_url": "https://sandbox.espago.com/secure_web_page/tr_772_lDLkv",
    "mark_up_percentage": "300"
  }
}

Parameter Description Notes
cardholder_currency_name Name of the cardholder’s currency in ISO 4217
cardholder_amount The amount in cardholder’s currency
conversion_rate Conversion rate
redirect_url eDCC decision made at Espago Redirect the customer to this URL if th eDCC decision is not to be made on merchant’s site
mark_up_percentage Mark up percentage

2. eDCC descision

To charge the user send a POST request to https://sandbox.espago.com/api/charges/(:id)/dcc_decision

(:id) - Id of the payment awaiting for a DCC decision

Responses are the same as in regular transactions (without eDCC) - only with additional information about the currency and amount.

curl -i https://sandbox.espago.com/api/charges/(ID_TRANSAKCJI)/dcc_decision \
-H "Accept: application/vnd.espago.v3+json" \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "decision=Y"
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/charges/")
request = Net::HTTP::Post.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"
request.set_form_data(
  "decision" => "Y",
)

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges/(ID_TRANSAKCJI)/dcc_decision');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "decision=Y");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "id": "pay_77219xeZ-8xvxUdE",
  "description": "order_523",
  "channel": "elavon",
  "amount": "39.96",
  "currency": "PLN",
  "state": "executed",
  "client": "cli_772KEkYX7Vq54DJe",
  "created_at": 1560949080,
  "issuer_response_code": "00",
  "reversable": true,
  "transaction_id": "tr_7722-YsY6",
  "multicurrency_indicator": "Z",
  "dcc_decision_information": {
    "cardholder_currency_name": "HKD",
    "cardholder_amount": "88.32",
    "conversion_rate": "2.210174"
  }
}

multicurrency_indicator - Information about the transaction currency. Field present only if the payment currency is different from the currency of the site.
N - Card without DCC
Y - DCC canceled by the user
Z - DCC is possible and accepted by the user

Sometimes a customer using 3D Secure may want to pay in another currency. For this reason, you need to take it into consideration the possibility of such a scenario - when a customer first makes a DCC decision and gets redirected to the URL with 3D Secure. After displaying the information about conversion, the Espago gateway responds with a 3D Secure redirection URL, while the payment gets the “tds_prtcpt” status.

Expample response

{
  "id": "pay_7724l5jFs9EP6Xr0",
  "description": "order_526",
  "channel": "elavon",
  "amount": "16.98",
  "currency": "PLN",
  "state": "tds_prtcpt",
  "client": "cli_772TVMYGxKECDKPZ",
  "created_at": 1560953142,
  "issuer_response_code": "",
  "transaction_id": "tr_772C5ke_m",
  "redirect_url": "https://sandbox.espago.com/3d-secure/tr_772C5ke_m",
  "tds_redirect_form": { ... },
  "multicurrency_indicator": "Z",
  "dcc_decision_information": {
    "cardholder_currency_name": "HKD",
    "cardholder_amount": "37.53",
    "conversion_rate": "2.210174"
  }
}

In some situations, when the Seller expects most customers to use eDCC, he can send a request for conversion rates to the Espago gateway. Thanks to this, there is a way to inform the customer about the conversion rate for his transaction before even starting it!

Conversion rates are updated every day at 6:30 PM.

In order to fetch the conversion rates send a GET request to https://sandbox.espago.com/api/dcc/rates.

curl -i https://sandbox.espago.com/api/dcc/rates \
-H "Accept: application/vnd.espago.v3+json" \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/dcc/rates")
request = Net::HTTP::Get.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/dcc/rates');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "timestamp":"2017-12-01T04:48:00.000+01:00",
  "mark_up_percentage":"300",
  "currency_name":"PLN",
  "currency_code":"985",
  "rates":{
    "USD":"0.285413",
    "ARS":"2.546572",
    "RON":"1.136708",
    "CZK":"6.997923",
    "EUR":"0.255955",
    "KWD":"0.085902",
    "MYR":"1.025983",
    "MXN":"4.372453",
    "GBP":"0.183134",
    ...
  }
}

link Possible payment states

Only state “executed” means that payment is done and money was taken from the customer’s account.

Status Description
new New payment, client’s account has not been charged
executed Payment executed, client’s account was successfuly charged.
Notice: It’s possible to return the whole amount or part of the transaction amount for all executed transactions.
rejected Payment was rejected.
Notice: In response of the rejected transaction, you receive reject_reason and issuer_response_code parameters.
failed Payment ended with a failure
preauthorized [Status available only when using the parameter complete=false] Money are reserved (holded) on the customer’s account but not yet charged.
tds_redirected [Status dostępny tylko w przypadku włączonej opcji 3D-Secure]. Klient został przekierowany na stronę 3D-Secure (stronę banku), oczekiwanie na jego powrót.
dcc_decision [State available only if 3D-Secure is enabled]. Customer is redirected to 3D-Secure page (bank/issuer site), Espago gateway is waiting for returning customer.
resigned Customer resigned from the autorization of payment or left payment [state available if enabled is 3D-Secure, DCC and/or MasterPass]. In case of leaving transaction with state “new”, “tds_redirected” or “dcc_decision” (no customer action during 1,5 hour) transactions will change state to “resigned”.
reversed Payment was reversed before settlement.
refunded Payment is refunded fully or partially.

link Possible rejection reasons

Parameter “reject_reason” can be used as additional information (parameter “issuer_response_code” is more usefull and complete).

Message Meaning Reason Comments
declined transaction rejected Unactivated type of service (MOTO, ecommerce), also lack of funds
card expired Card is not valid Card expiration date was exceeded
invalid amount Invalid amount It refers to the transactions amount limit or number of transactions limit.
invalid card invalid card number, card doesn’t exist
invalid profile invalid MID account Rejected by Elavon due to inactive MID Occurs with issuer_response_code=00
referral A / pick up card Card should be taken Card marked as stolen/lost/blocked. IMPORTANT NOTICE: It is forbidden to retry transactions that ended with this reason. It may be recogenized as fraud attempt!
referral B Transaction needs confirmation It requires contact with issuing bank to confirm transaction
serv not allowed Merchant does not support this particular type of a card For instance: American Express, Diners Club, in the case of no BRAM registration - also MasterCard
3ds_not_authorized rejected during 3D-Secure Rejection due to wrong client authentication in 3D-Secure or another error during 3D-Secure check.

The current table (MySQL dump) with the issuer_response_code and descriptions can be found in the “Download” section.

Error code Meaning Proposed message
00 Successful approval/completion Transaction approved, thank You!
00 Rejected transaction on acquier/Elavon level (We suggest contacting Espago/Elavon) REJECTED - An error occured. Transaction rejected by Elavon due to no response from issuer/bank, inactive Merchant account, used not supported card or incorrect card data. Please try again later or contact with the Espago Support Team.
01,02 Voice authorisation required REJECTED - Authorisation Error. Please contact your card issuer.
03 Invalid merchant or service provider REJECTED - Authorization’s Error. Please contact your card issuer and try again later.
04,07 Pickup card (special condition, other than lost/stolen card) REJECTED - Pickup card. Please contact your card issuer and try again later. IMPORTANT NOTICE: It is forbidden to retry transactions that ended with this code. It may be recogenized as fraud attempt!
05 MOTO/eCommerce/recurring inactive or not honoured REJECTED – The bank has declined the transaction due to security check (used card doesn’t support payment without CVV code / recurring payment), or the funds have been frozen, or card doesn’t support MOTO/internet transactions. Please check your card settings or use another card.
13,61 MOTO/eCommerce inactive or amount limit exceed REJECTED – Please check settings of your account and configurations of limits. Please contact your card issuer and try again later.
12 Invalid transaction REJECTED - no privileges to execute this transaction for your card. Please contact your card issuer to get more details and try again later.
14 Invalid card number REJECTED – Invalid card number. Check entered data, if card is still active and try again.
30 Invalid data format REJECTED – Please contact your card issuer to get more details and try again later.
41 Pickup card (lost) REJECTED – Please contact your card issuer to get more details and try again later. IMPORTANT NOTICE: It is forbidden to retry transactions that ended with this code. It may be recogenized as fraud attempt!
43 Pickup card (stolen) REJECTED – Please contact your card issuer to get more details and try again later. IMPORTANT NOTICE: It is forbidden to retry transactions that ended with this code. It may be recogenized as fraud attempt!
51 Insufficient funds REJECTED - Insufficient funds. Please check funds on your account and try again later.
54 Expired card REJECTED - Expired card. Please check your card or try another.
57 Function not permitted to cardholder REJECTED – Bank/Issuer has declined the transaction as this credit card cannot be used for this type of transaction (eccommerce, MOTO or recurring). Please check your card settings or use another card.
59 Suspected fraud REJECTED – Please contact your card issuer to get more details and try again later.
62 Restricted card, country exclusion. REJECTED – Your card can be not supported, e.g. due to country issuer exclusion or imposition an embargo. Please contact your card issuer.
65 Activity count limit exceeded REJECTED – Activity count limit exceeded. Change your limits settings or try again later.
75 Allowable number of PIN-entry tries exceeded. REJECTED – Invalid activity count limit exceeded. Please check your CVV/CVC/PIN code on your card.
78 Transaction from a new cardholder, card has not been unblocked. REJECTED – Inactive card. Please activate your card and try again later.
82, N7 Negative CVV results REJECTED - Negative CVV results. Check entered data and try again. IMPORTANT NOTICE: It is forbidden to retry transactions that ended with this code. It may be fraud attempt!
91,92,94,98 Please retry REJECTED - Refused by Issuer because Issuer is temporarily inoperative. Try again later.
E3 Incorrect 3D-Secure verification REJECTED - Incorrect 3D-Secure verification or another error. Please try again later.
E4 3D-Secure failure in bank. REJECTED - 3D-Secure failure in bank.
E5 3D-Secure error REJECTED - Temporary 3D-Secure error. Please try again later.

link Response for an incorrect request

When parameters in request are incorrect (ie. cc token already was used before) Espago gateway may reject a response with an HTTP code 422 or others. Such a situation should occur only in a test environment. Rejection of HTTP code 422 is a rejection of the incorrect request on API level, there is no payment attempt.

Response for an incorrect payment description

{
  "errors": [
    {
      "code": "null",
      "message": "Description is too short (minimum is 5 characters)",
      "param": "description",
      "type": "invalid_request_error"
    }
  ]
}

Response when the token has already been used

{
  "errors": [
    {
      "code": "null",
      "message": "Card token not found",
      "param": "card",
      "type": "card_error"
    }
  ]
}

Response when the client profile does not exist or is used with the incorrect account or the profile has no card data

{
  "errors": [
    {
      "code": "null",
      "message": "Card can't be blank",
      "param": "card",
      "type": "card_error"
    }
  ]
}

link Charge preauthorization

This is the function that allows you to hold certain amount of money on customer’s card and charge it later. To preauthorize a charge please send POST request to the following address: https://sandbox.espago.com/api/charges

Parameters, you have to send inside this request are almost the same as they are in a single charge. You can check them above (in the new charge section). The additional parameter you have to include is complete. The default value of this parameter is true - in this case the request is interpreted as the request of a normal charge. If the value is changed to false, then the request is interpreted as preauthorization and the set funds on customer’s card are blocked, but without further completion they will be released after few days.

Preauthorisation can be finished later, by completing the payment (“complete” request, which changes the payment’s status to “executed”) or cancelling (a “DELETE” request, which changes the payment’s status to “reversed”).

The maximum time of blocking funds is defined by institusion which issued the card. Usually, it is no longer than a week.

curl -i https://sandbox.espago.com/api/charges \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "card=cc_7724fuzWy0SYasoLV" \
-d "amount=49.99" \
-d "currency=pln" \
-d "description=Description" \
-d "complete=false"
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/charges")
request = Net::HTTP::Post.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"
request.body = "card=cc_7724fuzWy0SYasoLV&amount=49.99&currency=pln&description=Opis transakcji&complete=false"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "card=cc_7724fuzWy0SYasoLV&amount=49.99&currency=pln&description=Opis transakcji&complete=false");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "id":"pay_772Zm0D5saC0pEA9",
  "description":"Description",
  "channel":"elavon",
  "amount":"49.99",
  "currency":"pln",
  "state":"preauthorized",
  "client":"cli_772yY9NvH2Hyt2DM",
  "created_at":1561559076,
  "card":{ ... },
  "issuer_response_code":"00",
  "completed":false,
  "reversable":true,
  "transaction_id":"tr_772_88A0S"
}

link Preauthorized charge capture

To capture preauthorized charge please send POST request to the following address https://sandbox.espago.com/api/charges/(:id)/complete

(:id) - id of the preauthorized charge, which has to be captured


Notice
The request you send could contain an amount of the capture. If you do not set the amount of capture, it will capture the amount you set on preauthorization. You could capture the customer’s card on amount that is from 1% to 115% of amount you set on preauthorization.

curl -i https://sandbox.espago.com/api/charges/pay_772Zm0D5saC0pEA9/complete \
-X POST \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "amount=35"

require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/charges/pay_772Zm0D5saC0pEA9/complete")
request = Net::HTTP::Post.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"
request.set_form_data(
  "amount" => "35",
)

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges/pay_772Zm0D5saC0pEA9/complete');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "amount=35");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "id":"pay_772Zm0D5saC0pEA9",
  "description":"Description",
  "channel":"elavon",
  "amount":"35.00",
  "currency":"pln",
  "state":"executed",
  "client":"cli_772yY9NvH2Hyt2DM",
  "created_at":1561559076,
  "issuer_response_code":"00",
  "reversable":true,
  "transaction_id":"tr_772JlqSER"
}

link Reversal of an existing charge

Payment could be reversed only if it has not been settled yet and it’s possible only for the full amount of the transaction. In the sandbox environment settling is executed once per hour. In production environment payment becomes executed every 24 hours (between 10:30PM and 00:00). Only a refund is possible after this time.

Payment reversing is also way to cancel preauthorization. Preauthorizations could be reversed during 1-2 weeks, according to Bank (card’s issuer) politics.


When the payment is already settled in Elavon (a bank) the reversal attempt will fail.

To reverse an existing charge please send a DELETE request to the following address https://sandbox.espago.com/api/charges/(:id)

(:id) - Id of the transaction you want to reverse

curl -i https://sandbox.espago.com/api/charges/pay_772Zm0D5saC0pEA9 \
-X DELETE \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/charges/pay_772Zm0D5saC0pEA9")
request = Net::HTTP::Delete.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges/pay_772Zm0D5saC0pEA9');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "id":"pay_772Zm0D5saC0pEA9",
  "description":"Description",
  "channel":"elavon",
  "amount":"35.00",
  "currency":"pln",
  "state":"reversed",
  "client":"cli_772yY9NvH2Hyt2DM",
  "created_at":1561559076,
  "issuer_response_code":"00",
  "transaction_id":"tr_772JlqSER"
}

link Displaying charges

To fetch the data of a single charge send a GET request to https://sandbox.espago.com/api/charges/(:id)

(:id) - Id of the charge you want to fetch

curl -i https://sandbox.espago.com/api/charges/pay_771MKFI-15SIK1Pm \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/charges/pay_771MKFI-15SIK1Pm")
request = Net::HTTP::Get.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges/pay_771MKFI-15SIK1Pm');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);

{
  "id":"pay_771MKFI-15SIK1Pm",
  "description":"Espago docs",
  "channel":"elavon",
  "amount":"10.00",
  "currency":"pln",
  "state":"executed",
  "client":"cli_771Xsyr9GkpN8iTp",
  "created_at":1559130872,
  "issuer_response_code":"00",
  "transaction_id":"tr_771EQhf18"
}

You could display a group of charges with a specified number of charges per page. To display a specified group of charges send a GET request to the following address: https://sandbox.espago.com/api/charges?page=1&per=10&client=client_id

Available HTTP parameters

Parameter Description Default value
page Numebr of the page you want to fetch 1 (first page)
per Number of charges per page 25 (25 charges)
client ID of the client whose charges you want to fetch all clients
curl -i https://sandbox.espago.com/api/charges \
-X GET \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "page=1" \
-d "per=5" \
-d "client=cli_772YYE_98HM1DmAD"
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/charges")
request = Net::HTTP::Get.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"
request.set_form_data(
  "client" => "cli_772YYE_98HM1DmAD",
  "page" => "1",
  "per" => "5",
)

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "page=1&per=5&client=cli_772YYE_98HM1DmAD");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "count":4,
  "charges":[
    {
      "id":"pay_772xZV-3uSUTIxPz",
      "description":"Payment #88",
      "channel":"elavon",
      "amount":"79.00",
      "currency":"pln",
      "state":"executed",
      "client":"cli_772YYE_98HM1DmAD",
      "created_at":1561645210,
      "card":{ ... },
      "issuer_response_code":"00",
      "reversable":true,
      "transaction_id":"tr_772bk-yP2"
    },
    {
      "id":"pay_772X3bE9o9JHdpZt",
      "description":"Payment #23",
      "channel":"elavon",
      "amount":"19.99",
      "currency":"pln",
      "state":"executed",
      "client":"cli_772YYE_98HM1DmAD",
      "created_at":1561645191,
      "card":{ ... },
      "issuer_response_code":"00",
      "reversable":true,
      "transaction_id":"tr_772ZZm3Zt"
    },
    . . .
  ]
}

autorenew Recurring Payments

link Possible scenarios

The main goal of recurring payments is saving the client’s credit card data in the Espago gateway (in the Client profile) and using them for recurring payments (e.g. subscriptions) or payments on client’s demand (e.g. faster payments for clients registerd in the shop). It is possible to carry out charges in a few different ways. The two scenarios below are most notable:

Recurring payments handled by the merchant Recurring payments handled by Espago
  • When the amount and frequency of charges is fickle.
  • When apart from recurring payments clients are also capable of using singular payments.
  • When the Merchant already has the mechanisms necessary to manage payment dates.
  • When the Merchant wants to offer quick (one-click) payments to regular customers.
  • When the amount and frequency of charges is constant. (e.g. monthly subscription)

This chapter describes payments handled by the Merchant. More on Espago subscriptions can be found: here.

link How recurring payments work

  1. The merchant initiates a payments with cof=storing, (which creates a new client profile with the credit card data), and receives the client ID and confirmation of payment’s execution or a redirection URL (SCA: 3D-Secure).
  2. Optionally, It is a good idea to right after receiving the client’s ID initiate a client profile authorisation, in order to check if the card is suited for recurring payments (look: The problem of cards not suited for recurring payments).
  3. Then the Merchant may make charge requests (/api/charges with client ID and more) adding the information that the payment is recurring (cof=recurring parameter).

The cof=recurring parameter is required for proper marking of repeting/recurring payments (The CVV/CVC code is not required and 3D-Secure is not used) (More on client profile creation: Client profile). The cof=recurring parameter was introduced by Visa and MasterCard in 2019 and replaced the previous recurring=true parameter.

Notice: When this scenarios is used as a oneclick payment/recurring payment on demand of the client, then in charge requests (/api/charges) the cof=recurring parameter should be omitted, which will enable the client to be redirected to complete 3D-Secure. It would also be a good idea to use CVV sending, which makes it more secure and likely to end successfully.

link Requirements and good practises for recurring payments

Action Description
Before subscription customer should have at least one payment with 3D-Secure. 3D-Secure significantly increases the certainty that the client is the owner of the card.
Since September 2019 some banks may reject recurring payments if there were no 3D-Secure payments before them, since January 2021 all EU banks will do this way.
You should minimize the repetition of failed payments, especially if the customer has several outstanding payments. Visa recommends (in the future this may be a requirement) to avoid a situation where several outstanding payments result in multiple repetitions of multiple payments.
There should not be more than 1 attempt to charge the outstanding payment for the day, Visa recommends one try of payments per 4 days, and after few tries one per 16 days. In practice, if the customer has several outstanding payments, then if the attempt of one (eg with the lowest amount) is rejected, then usually others are also rejected.
Use preauthorisation if you expect the amount to be returned or the actual charge will only encompass a part of the preauthorisation.
Avoid preauthorisation if it’s not needed.
Preauthorisation enables you to reserve funds on a card without charging it.
Depending upon the contract with Elavon, Visa/MasterCard can charge a constant, small amount for every preauthorisation.

link The problem of cards not suitable for recurring payments

Most of cards suitable for one-time Internet/e-commerce payments and recurring payments (if cardholder turns on this type of payments in his bank and sets the appropriate limits). There are, however, some cards, which can make one-time payments online, but which are not suitable for recurring payments, eg. Maestro or a few card types from Polish banks: PEKAO and PKO S.A.



In a normal scenario (creating a customer, create a subscription with the first payment) there could be a situation, where at the moment the order/subscription payment is succesfull, but later (during the recurring) all payments are rejected. This is inconvenient for both the merchant and the customer.
To avoid this problem, it is worth to consider the use of scenario described below.



It is also important to ensure that recurring/cyclic transactions (where is no longer used CVV/CVC code) were marked with the parameter “recurring=true”. Many banks/issuers will reject normal internet payment if there is no CVV/CVC, but will accept recurring/cyclic payment without this code. Espago Support can also set an option, to make all payments seen by the bank as recurring, then there is no need to add this parameter every time.


Espago Support team can also set an option to make all payments appear as recurring to banks - then there is no need to add the parameter to every payment. This setting however, makes it impossible to make one-time payments with 3D-Secure or DCC.


Step Function Description
1 Creating a client profile Merchant creates customer profile (with card data) in the Espago gateway.
2 Authorization of the client Authorization on demand or automatic authorization during customer creation (you can enable it in web panel).
SUCCESS: customer’s card supports internet payments, you can go to step 3.
FAIL: customers’s card doesn’t support internet payment. It means that next (recurring) payments will also fail1,3
3 Creation of subscription

First charge

Second authorization
Create a subscription (with automatical charge) or making of the first payment (if recurring is handled by the Merchant) or requesting another authorization on demand (if Merchant wants to only check if the card supports recurring transactions.
SUCCESS: customer’s card supports internet and recurring payments. Subsequent payments will most likely also be successful2.
FAIL:
customer’s card doesn’t support recurring payments, so next payment attempts will most certainly also fail1.

1 - If the reason for the rejection is “card does not supported online/MOTO payment” or too low limits for this types of transactions, then after turning on these options/setting up this limits in the credit card options, next payments may be made successfully.

2 - In the case that the customer will not have sufficient money on account or card validity will expire, execution of payments will be no longer possible.

3 - If authorization (first transaction) was rejected due to invalid CVV/CVC (error codes 75, 82, N7) you shold not try more payments using this card! This situation could be fraud/using stolen card. Next payment may be accepted by bank because (invalid) CVV code is no more used, but it will be on Merchant responsibility.

link Recurring and repeating (one-click, extending) payments

What is card on file?

Card on file is a service that enables you to save credit card data in Espago - in order to charge the client without having the cardholder to enter his data again. Card on file as a term and the cof parameter function in the Espago gateway since July 2019.

To make use of card on file in Espago you should:

  • carry out a payment with strong SCA authentication (3D-Secure) and the cof=storing parameter (saving the card through card on file) in the API request. Data is saved in the Client Profile. The ID of this newly created profile will be returned with the gateway response. Carrying out a payment in the aforementioned way is necessary to be able to use this client profile for further charges.
  • Initiating more payments through the Client Profile in the*card on file* model. In the acquirer’s and bank’s point of view, these payments will be associated with the initiating payment.

Functionality

Data in the Client Profile can be updated, and the profile itself - if it’s needed - can be deleted through an API request. Card on file in Espago lets you make use of all the features devised by credit card companies, which is described in this chapter.
Charges using a saved card are divided into:

  • Merchant Initiated Transactions according to the contract (e.g. recurring payments, postponed, balance compensation)
  • Cardholder Initiated Transactions (e.g. one-click)

Merchant Initiated Transactions

After successfully processing the initiating payment with strong authentication (SCA), more charges can be made through a process initiated by the Merchant - according to the deal made with the cardholder. Example of such a charge:

  • monthly subscription for a service or a gym membership;
  • charge for a service initiated by the customer (e.g. taxi or car sharing)

Payments initiated by the cardholder

Payments initiated by the cardholder (e.g. one-click) have to be marked as cof=unscheduled. These are payments, carried out because of the cardholder’s actions:

  • confirming an online purchase by clicking the “Buy” or “Pay” button;
  • buying a service in a mobile app.

link CoF parameter - values

Value of the cof parameter is a string.

Initiating payment

storing - saves credit card data and returns the client profile, which can be used for subsequent payments.

Payments initiated by the merchant - standing instructions

instalment - installments for a service, according to the deal with the cardholder;
recurring - recurring payments with a constant interval (less than a year), within the period of providing the service;
unscheduled - payments using the saved credit card, with a constant or changing amount, which are not carried out according to any schedule (e.g. charge after a service on demand);

Payments initiated by the Merchant - industry-specific

delayed_charge - a delayed charge after finishing the service.
Useful in - hotels, vehicle rental.

no-show - a payment carried out according to the deal between the merchant and the cardholder, enabling the former to charge the latter when, because of the cardholder, the service could not be completed.
Useful when - a guest has not shown up.

reauthorisation - payment for a purchase made after initial authorisation, may reflect different scenarios (e.g. extending the service past the original authorisation amount)
Example:
* eCommerce - in split shipping or its delay
* when extending vehicle rental or a hotel stay;

resubmission - payment for a service, initiated once again due to unsuccessful authorisation in the first attempt of charging the card;

poll Espago subscriptions

link Espago subscriptions

Recurring payments are a way of charging the client automatically loads the specified frequency. In the Espago system recurring payments consist of two main components, these are: plans oraz subscriptions. To use recurring payments you must also create a Espago client object with assigned credit card data - based on the customer ID he is assigned to a specific subscription.

This system is very simple. You first define a plan, which encompasses the details of how frequently should the charges take place and the amount of these charges. To start these repeated payments, you need to create a new subscription with the use of client ID and plan ID.

Merchant defines Plan (or Plans), i.e. scheme indicating the amount and period. Next, for each client Merchant creates client profile with card data (using single payment with token and parameter “cof=storing”), and create subscription (using client ID and plan ID). When subscription is created, first payment is started. If first payment is successful, subscription is active, and next payment will be performed in time defined in the plan. Each payment’s attempt generates back-request with information about payment status.

Bank statements concerning recurring payments (states, charging attempts etc) are gathered in invoices. They’re available only through recurring payments handled by Espago.

link Configuration

After gaining access to the merchant panel you need to undertake the following actions:

  1. Access this subpage
  2. Click “Edit” to see the details
  3. Set up the back request URL (more on this under “Back request”)
  4. Fill in the field with time between charge attempts (after an unsuccessful one) and determine the state in case of exceeding the limits for additional charging attempts. In the production environment the possible values are: 1, 2, 3, 4 days, while in the test environment in minutes.



Possible states after exceeding the charging attempt limits:

State Description
Stop subscription Turns the subscription off preventing it from generating new charges. The subsciption status changes to “inactive”.
Do nothing The charges will be generated anyway.

link Plans

Plans define scheme of recurring payments, including information obout the amount and frequency of payment. Next, based on the defined plans, you can launch subscriptions for customers.


While creating a plan you define data like: type of charging frequency unit (day, month, etc), number of frequency units (in case of a period=7 and period_unit=day, we get a charge every 7 days) and the amount charged.

To create a plan send a POST request to https://sandbox.espago.com/api/plans with correct parameters.

Available HTTP methods

Parameter Description Notes
period_unit Period unit It defines the period unit, for example: day or month.
period amount of periods Integer number. It decides about the amount of periods beetwen charges i.e. if period_unit=month, period=2 will create charge every 2 months
amount Transaction amount Decimal number, i.e. 123.45
currency currency Currency symbol
description plan description It should contain at least 5 characters.

It is important to set the parameters “period” and “period_unit” in the right way. Their summary values are responsible for the frequency of charges.

Value of the 'period_unit' parameter Acceptable 'period' values Result
day 1-366 Plan, that charges client’s card every specified number of days
month 1-12 Plan that charges client’s card every specified number of months

Example of a plan creation request:

curl -i https://sandbox.espago.com/api/plans -H \
'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "description=description" \
-d "period_unit=month" \
-d "period=1" \
-d "amount=50" \
-d "currency=pln"


require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/plans")
request = Net::HTTP::Post.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"
request.body = "description=description&period_unit=month&period=1&amount=50&currency=pln"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end


$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/plans');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "description=description&period_unit=month&period=1&amount=50&currency=pln");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);

{
  "id":"pl_77299uAqqIu4a6eQB",
  "description":"description",
  "period":1,
  "period_unit":"month",
  "amount":"50.0",
  "currency":"pln",
  "created_at":1559739533
}


To fetch a current plan send a GET request to https://sandbox.espago.com/api/plans/(:id)
(:id) - Id of the plan you want to fetch

curl -i https://sandbox.espago.com/api/plans/ID \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD


require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/plans/ID")
request = Net::HTTP::Get.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end


$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/plans/ID');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);

{
  "id":"pl_77299uAqqIu4a6eQB",
  "description":"description",
  "period":1,
  "period_unit":"month",
  "amount":50.0,
  "currency":"pln",
  "created_at":1559739533
}


To delete a plan send a DELETE request to https://sandbox.espago.com/api/plans/(:id)
(:id) - Id of the plan you want to delete

curl -i https://sandbox.espago.com/api/plans/ID \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-X DELETE 

require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/plans/ID")
request = Net::HTTP::Delete.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end


$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/plans/ID');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);

In response: Status: 204 NoContent

By dokonać zmiany ustawień planu należy wysłać żądanie metodą PUT na adres: https://sandbox.espago.com/api/plans/(:id)
(:id) - Id of the plan you want to update

The rest of parameters and headers are identical to those sent when creating a new plan

Notice
Plan updates do not change any existing subscriptions - the changes apply only to newly created subscriptions (created after the change). As such we recommend creating new plans instead of updating old ones.

curl -i https://sandbox.espago.com/api/plans/ID \
-X PUT -u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "description=Plan update" \
-d "period_unit=month" \
-d "period=1" \
-d "amount=75" \
-d "currency=pln"


require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/plans/ID")
request = Net::HTTP::Put.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request.body = "description=Plan update&period_unit=month&period=1&amount=75&currency=pln"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end


$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/plans/ID');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "description=Plan update&period_unit=month&period=1&amount=75&currency=pln");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);

The response: Status: 204 No Content

Fetch a list of plans by sending a GET request to: https://sandbox.espago.com/api/plans

curl -i https://sandbox.espago.com/api/plans \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD 


require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/plans")
request = Net::HTTP::Get.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end


$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/plans');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);

{
  "count":3,
  "plans":[
  {
    "id":"pl_772F0N8AqpLJ8tUhK",
    "description":"Karnet EXCLUSIVE PRO",
    "period":1,
    "period_unit":"month",
    "amount":119.0,
    "currency":"pln",
    "created_at":1559745412
  },
  {
    "id":"pl_772eAqoP50JRfV3Fo",
    "description":"Karnet PRO",
    "period":1,
    "period_unit":"month",
    "amount":79.0,
    "currency":"pln",
    "created_at":1559745395
  },
  {
    "id":"pl_772tYQqPm5QaD9ye9",
    "description":"Karnet NORMAL",
    "period":1,
    "period_unit":"month",
    "amount":50.0,
    "currency":"pln",
    "created_at":1559745382
  }]
}


link Subscriptions

Subscriptions are objects which connect clients to plans.

By default, subscription is running since it is launched (it generates the first payment) and next payment are done after period defined in Pan. Time (hour) of execution of the next payment is similar to hour of creation of subscription (payment can be called max 4 hours later).
Subcription is stopped when:

  • the first payment (made during creation of subscription) is rejected. In this case subscription is not activated.
  • Merchant sends request to stop subscription,
  • one of next payments are failured (repeated three times or not repeated and if the stopping subscription in such a situation has been configured in the web panel).

There is also possibility for launching a subscription with the delayed start (ie. with a defined date of the first payment). In such a situation there is no automatic mechanism for deactivating the subscription in case of rejection of the first payment.

Create a new subscription by sending a POST request to https://sandbox.espago.com/api/subscriptions and choose the appriopriate client and plan.

Available HTTP parameters

Parameter Description Notice
client client ID required
plan plan ID required
start_time Time of starting the subscription Optional parameter. Format: unix time. By default (without this parameter) subscription is started in moment of sending request. Parameter require unix time: later than 12 hour after request and earlier than time of next period defined in plan. Details about delayed start in the next chapter.
curl -i https://sandbox.espago.com/api/subscriptions \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "client=client_id" \
-d "plan=plan_id"
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/subscriptions")
request = Net::HTTP::Post.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"
request.set_form_data(
  "client" => "client_id",
  "plan" => "plan_id",
)

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/subscriptions');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "client=client_id&plan=plan_id");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
In the response, aside from subscription details, we also send the data of the first charge(last_invoice).
{
  "id": "sub_i3CoQEnqX5IKve",
  "state": "active",
  "client": "cli_buoBpPrw6rU7iC",
  "plan": "pl_vGTGxa_Kf521Sdv",
  "created_at": 1373461486,
  "last_invoice": {
    "id": "in_MVt4vwsp7VvOTqa",
    "date": 1373461485,
    "client": "cli_buoBpPrw6rU7iC",
    "subscription": "sub_i3CoQEnqX5IKve",
    "amount": "7.00",
    "currency": "PLN",
    "paid": true,
    "issuer_response_code": "00",
    "attempts": 1,
    "next_payment_attempt": "null",
    "created_at": 1373461485
  }
}

Notice!
If during creation of the subscription first payment fails this subscription expires - this is security element against the creation of a subscription using the card, which for example does not support inernet transactions or MOTO transaction.
In this case, in response to a request for creating a subscription (/api/subscriptions) parameter "state" will have value "inactive".

Further responses

Aside from the subscription, the first subscription with the information about the transcation status will be created. Further informations regarding future charges will be sent as asynchronous back requests to the back request URL (more on that in the chapter: Back request) and are generated when a subscription is created or a charge is attempted. Example of a back request (more in Invoices):

{
  "id": "in_hS-KiS3N6YCzOhG",
  "date": 1371631155,
  "client": "cli_OU7k00vEMGi53C",
  "subscription": "sub_QyJzN4KdzNzvmZ",
  "amount": "7.00",
  "currency": "PLN",
  "paid": true,
  "attempts": 1,
  "next_payment_attempt": "null",
  "created_at": 1371500155
}

Back The response is sent for up to 24 hours of descending interval until a response 200 ‘OK’ from the client application.

There is a possibility to create subscription, which start time (first charge) will be declared by the Seller. To start a subscription with a delayed start, you need to use “start_time” parameter of the corresponding value in the request for creating a subscription (description above).

  • This option is usefull eg. when first period should be free.
  • After starting subscription with delayed start, it work as normal subscription.
  • You can stop the subscription before the first charge.

Subscription with the delayed start has some limitations:

  • During creation of subscription there is no first attempt of payment, so there is no mechanism for deactivating the subscription in case of rejection of the first payment. Thus it is possible to run a subscription for the card, which can not be charged, because, for example, it does not support online payments and/or recurring payments.
  • To avoid this problem, the Seller shall ensure that sooner or card supports recurring billing (described earlier).
  • Date and time of launch subscription defined in the parameter “start_time” must be later than 12 hours after the request, and earlier than the time period defined as a period of plan/subscription.

To fetch the data of a subscription send a GET request to https://sandbox.espago.com/api/subscriptions/(:id)
(:id) - Id of the subscription you want to fetch

curl -i https://sandbox.espago.com/api/subscriptions/ID \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/subscriptions/ID")
request = Net::HTTP::Get.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/subscriptions/ID');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
{
  "id": "sub_i3CoQEnqX5IKve",
  "state": "active",
  "client": "cli_buoBpPrw6rU7iC",
  "plan": "pl_vGTGxa_Kf521Sdv",
  "created_at": 1373461486,
  "last_invoice": {
    "id": "in_MVt4vwsp7VvOTqa",
    "date": 1373461485,
    "client": "cli_buoBpPrw6rU7iC",
    "subscription": "sub_i3CoQEnqX5IKve",
    "amount": "7.00",
    "currency": "PLN",
    "paid": true,
    "issuer_response_code": "00",
    "attempts": 1,
    "next_payment_attempt": "null",
    "created_at": 1373461485
  }
}

To stop a subscription send a DELETE request to https://sandbox.espago.com/api/subscriptions/(:id)
(:id) - Id of the subscription you want to delete

curl -i https://sandbox.espago.com/api/subscriptions/ID \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-X DELETE 
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/subscriptions/ID")
request = Net::HTTP::Delete.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/subscriptions/ID');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
Response: status: 204 No Content

To fetch the list of active subcriptions send a GET request to: https://sandbox.espago.com/api/subscriptions. It is possible to send additional parameters, but it is not required.

Parameter Description Default value
page Page number 1 (first page)
per Subscriptions per page 25 (25 subscriptions)
curl -i https://sandbox.espago.com/api/subscriptions \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "page=2" \
-d "per=5"
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/subscriptions")
request = Net::HTTP::Post.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"
request.set_form_data(
  "page" => "2",
  "per" => "5",
)

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/subscriptions');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "page=2&per=5");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);

{
  "count": 1,
  "subscriptions": [
    {
      "id": "sub_i3CoQEnqX5IKve",
      "state": "active",
      "client": "cli_buoBpPrw6rU7iC",
      "plan": "pl_vGTGxa_Kf521Sdv",
      "created_at": 1373461486,
      "last_invoice": {
        "id": "in_9d7xIbhzLMkxTFm",
        "date": 1373463196,
        "client": "cli_buoBpPrw6rU7iC",
        "subscription": "sub_i3CoQEnqX5IKve",
        "amount": "7.00",
        "currency": "PLN",
        "paid": true,
        "issuer_response_code": "00",
        "attempts": 1,
        "next_payment_attempt": "null",
        "created_at": 1373463196,
      }
    }
  ]
}

To fetch the list of active subscriptions of a client send a GET request to: https://sandbox.espago.com/api/clients/(:client_id)/subscriptions
(:client_id) - Id of the client whose subscriptions you want to fetch. It is possible to send additional parameters, but it is not mandatory.

Parameter Description Default value
page Page number 1 (first page)
per Number of subscriptions per page 25 (25 subscriptions)
curl -i https://sandbox.espago.com/api/clients/CLIENT_ID/subscriptions \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "page=2" \
-d "per=5"
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/clients/CLIENT_ID/subscriptions")
request = Net::HTTP::Post.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"
request.set_form_data(
  "page" => "2",
  "per" => "5",
)

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/clients/CLIENT_ID/subscriptions');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "page=2&per=5");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);

{
  "count": 2,
  "subscriptions": [
    {
      "id": "sub_WbAUbaC_7KB79V",
      "state": "active",
      "client": "cli_buoBpPrw6rU7iC",
      "plan": "pl_vGTGxa_Kf521Sdv",
      "created_at": 1373463500,
      "last_invoice": {
        "id": "in_I3iEPUZFxUsLUR-",
        "date": 1373463498,
        "client": "cli_buoBpPrw6rU7iC",
        "subscription": "sub_WbAUbaC_7KB79V",
        "amount": "7.00",
        "currency": "PLN",
        "paid": true,
        "issuer_response_code": "00",
        "attempts": 1,
        "next_payment_attempt": "null",
        "created_at": 1373463498
      }
    },
    {
      "id": "sub_FMw5DlPzK0dW9V",
      "state": "active",
      "client": "cli_buoBpPrw6rU7iC",
      "plan": "pl_vGTGxa_Kf521Sdv",
      "created_at": 1373463506,
      "last_invoice": {
        "id": "in_WtlQMDFdUDpIdSq",
        "date": 1373463504,
        "client": "cli_buoBpPrw6rU7iC",
        "subscription": "sub_FMw5DlPzK0dW9V",
        "amount": "7.00",
        "currency": "PLN",
        "paid": true,
        "issuer_response_code": "00",
        "attempts": 1,
        "next_payment_attempt": "null",
        "created_at": 1373463504,
      }
    }
  ]
}

link Invoices

Invoice is a kind of object which is used to store informations about recurring transaction state, number of attempts and date of next payment attempt if last was rejected/failed.

To display all invoices of a client send a GET request to: https://sandbox.espago.com/api/clients/(:client_id)/invoices
(:client_id) - Id of the client

curl -i https://sandbox.espago.com/api/clients/CLIENT_ID/invoices/ \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/clients/CLIENT_ID/invoices/")
request = Net::HTTP::Get.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/clients/CLIENT_ID/invoices/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);

{
  "count":1,
  "invoices":[
    {
      "id":"in_7728vjvj-BdSK0B64",
      "date":1559903458,
      "client":"cli_772YYE_98HM1DmAD",
      "subscription":"sub_772pHbFAL2vs-z8g",
      "amount":"119.00",
      "currency":"pln",
      "paid":true,
      "issuer_response_code":"00",
      "attempts":1,
      "next_payment_attempt":null,
      "created_at":1559903458,
      "last_payment":"pay_772Nkgo8MS-25osp"
    }
  ]
}

Meaning of fields in the response:

Field name Meaning Available values
Date Planned date of charge attempt Time in Unix Format
Paid Was invoice paid? True or False
Attempts Number of executed attempts Integer
Next payment attempt Data of execution next payment attempt Time in Unix format or null

If you want to enforce more retries of invoice charge you can send a special POST request to the following address: https://sandbox.espago.com/api/invoices/(:invoice_id)/pay
(:invoice_id) - Id of the invoice

Notice
Using this request when not all retry attempts were made will decrease number of attempts made by gateway automatically!

curl -i https://sandbox.espago.com/api/invoices/(:invoice_id)/pay \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/invoices/")
request = Net::HTTP::Post.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/invoices/(:invoice_id)/pay');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
{
  "id": "in_MUL7PeIUTDwOHx8",
  "date": 1371805245,
  "client": "cli_N7hldWZqSoBLva",
  "subscription": "sub_occMPm6-_284b3",
  "amount": "7.00",
  "currency": "PLN",
  "paid": true,
  "attempts": 2,
  "next_payment_attempt": "null",
  "created_at": 1371805245,
    "last_payment":"pay_772Nkgo8MS-25osp"
}

When the invoice has already been paid for, we send: 422 "Unprocessable Entity.

Display a single invoice by sending a GET request to: https://sandbox.espago.com/api/invoices/(:id)
(:id) - Id of the invoice

curl -i https://sandbox.espago.com/api/invoices/ID_FAKTURY \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/invoices/ID_FAKTURY")
request = Net::HTTP::Get.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/invoices/ID_FAKTURY');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
{
  "id":"in_7728vjvj-BdSK0B64",
  "date":1559903458,
  "client":"cli_772YYE_98HM1DmAD",
  "subscription":"sub_772pHbFAL2vs-z8g",
  "amount":"119.00",
  "currency":"pln",
  "paid":true,
  "issuer_response_code":"00",
  "attempts":1,
  "next_payment_attempt":null,
  "created_at":1559903458,
  "last_payment":"pay_772Nkgo8MS-25osp"
}

link Invoice Items

Invoice Items serve the purpose of providing information concerning a single payment, which is a part of a subscription cycle. It covers the details of an attempt to charge the client (to pay off an invoice). If it fails, another invoice item is created and the system attempts to charge the client once again. This proccess can be configured (to make a certain amount of charge attempts with certain intervals). More on configuring Espago subscriptions: Espago Subscriptions - Configuration

To create a new invoice item, send a POST request to: https://sandbox.espago.com/api/invoice_items

Parameters

Parameter Description Value Obligatory
amount Transaction amount A decimal number, eg. 123,45 Required
currency Currency The currency symbol compatible with your MID Required
date Date of charge A future date of charge in unix time Required
client client ID ID used to link this transaction to a created client Required
description Description Should consist of at least 5 characters. Optional
curl -i https://sandbox.espago.com/api/invoice_items \
-H 'Accept: application/vnd.espago.v3+json' \
-u app_id:password \
-d "currency=currency" \
-d "date=unix_time" \
-d "amount=100" \
-d "client=client_id" \
-d "description=Description"
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/invoice_items")
request = Net::HTTP::Post.new(uri)
request.basic_auth("app_id", "password")
request["Accept"] = "application/vnd.espago.v3+json"
request.body = "currency=currency&date=unix_time&amount=100&client=client_id&description=Description"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/invoice_items');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "currency=currency&date=unix_time&amount=100&client=client_id&description=Description");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'app_id' . ':' . 'password');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "id": "ii_1sbC2i-UHMWJXZH",
  "client": "cli_xNKNXh-_kWu6Qi",
  "description": "Description",
  "amount": "100.00",
  "currency": "PLN",
  "created_at": 1381755981
}

To fetch information about the items encompassed by a particular invoice send a GET request to: https://sandbox.espago.com/api/invoices/(:invoice_id)/line_items
(:invoice_id) - ID of the invoice

curl -i https://sandbox.espago.com/api/invoices/(:invoice_id)/line_items \
-H 'Accept: application/vnd.espago.v3+json' \
-u app_id:password
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/invoices/:invoice_id/line_items")
request = Net::HTTP::Get.new(uri)
request.basic_auth("app_id", "password")
request["Accept"] = "application/vnd.espago.v3+json"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/invoices/:invoice_id/line_items');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_USERPWD, 'app_id' . ':' . 'password');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);

{
  "count": 1,
  "invoice_items": [
    {
    "id": "ii_1KZ0VBahlukLI2X",
    "client": "cli_OU7k00vEMGi53C",
    "description": "Position 1",
    "amount": "7.00",
    "currency": "PLN",
    "created_at": 1371631057
    }
  ]
}

To delete an existing invoice item send a DELETE request to: https://sandbox.espago.com/api/invoice_items/(:id)
(:id) - ID of the invoice item

curl -i https://sandbox.espago.com/api/invoice_items/(:id) \
-X DELETE \
-H 'Accept: application/vnd.espago.v3+json' \
-u app_id:password
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/invoice_items/:id")
request = Net::HTTP::Delete.new(uri)
request.basic_auth("app_id", "password")
request["Accept"] = "application/vnd.espago.v3+json"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/invoice_items/(:id)');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');

curl_setopt($ch, CURLOPT_USERPWD, 'app_id' . ':' . 'password');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
The status returned with a response is: 204 "No content"

receipt Back requests

link Configuration

The Espago gateway sends asynchronous back requests to the merchant site in a few situations:

  • payment state info - after carrying out a payment in APIv3.0 (in a payment with 3D-Secure, the request is sent after the verification process and the bank’s response),
  • payment state info - after carrying out a subscription payment,
  • subscription state info - when the subscription state changes (e.g. when it gets deactivated),
  • created token info - disabled by default, used by certain Merchants.

Responses about transaction state changes are sent asynchronously to the URL specified in your configuration.
Back requests should make use of the HTTPS (port 443) protocol, but HTTP (port 80) is also possible.
In the Sandbox test environment, the server additionally may send back requests to ports 8002 and 8003.

Notice
In case of the lack of the “HTTP 200” response from the Merchant’s site, the action will be retried for 24h with an increasing interval.

After gaining access to the merchant panel, you should take the following steps:
1. Navigate to:
2. Click on “Edit”.
3. Fill in “Back request URL (application/json v. 3.0.)” - back requests will be sent to this address.
4. Fill in “Basic login (for Back request URL)” oraz “Basic password (for Back request URL)”. Espago back requests will be authorised through these values.

Notice
Login and password validation for back requests is not mandatory, however implementing it is highly recommended for security reasons.

link Back requests in payments

If the merchant uses APIv3.0, every initiated payment generates a back request.

If 3D-Secure is not used, receiving this request is not obligatory, since it has the same information as the ones returned with a gateway response. If 3D-Secure is turned on, the back request is sent after the client authorisation, and they are the main source of information for the Merchant about the payment’s state. If the client discards the payment on the 3DS verification step, after 1,5h the payment’s state will be changed to “resigned” and a back request confirming that will be sent.

Example (back request):

{
  "id": "pay_772sMqGEogv63CSk",
  "description": "order_263",
  "channel": "elavon",
  "amount": "56.94",
  "currency": "PLN",
  "state": "executed",
  "client": "cli_7725o4SHuhgnHAVe",
  "created_at": 1560160387,
  "card": {
    "company": "VI",
    "last4": "4242",
    "year": 2030,
    "month": 1,
    "first_name": "John",
    "last_name": "Smith",
    "authorized": null,
    "created_at": 1560160386
  },
  "issuer_response_code": "00",
  "reversable": true,
  "transaction_id": "tr_772b9YYzb"
}
Parameter Notes Description
id Payment ID. Enables one to find this payment later, check its status. Has the form of pay_xxxxxxxxxxxxxxxx and a length between 18 and 20 characters.
description Payment description sent to /api/charges.
channel Payment channel.
amount Transaction amount.
currency Transaction currency.
state Transaction state. Described in detail in “Possible payment states”
client Client ID used for this payment. In one time payments (requests with the “card” parameter) it’s just a temporary client’s ID, which can be ignored
created_at Payment creation date in unix.
card array Card parameters.
issuer_response_code Response code from banks. If the payment is on the 3D-Secure step, this parameter gains the 00 or NULL value, until it is finished.
transaction_id Transaction ID. Useful when searching for the payment in the Elavon panel, since only this value is visible in Elavon reports (There are no client ID or payment ID). Transaction is an “operation”. By default only payments have only one transaction, after returning a part all the enitre payment, the ID of the reversing transaction will be here.
redirect_url optional URL to which the user should be redirected to for 3D-Secure.
reversable optional The “reversable=true” parameter informs that the payment can be reversed before it’s settled. After the settlement this parameter has the value “false” and is no longer visible in payment’s properties.
tds_redirect_form optional/ array Parameters letting you redirect the client directly to the bank (instead of Espago through the use of redirect_url). In this case the user should be redirected through a form with the POST method, with PaReq, MD i TermUrl parameters. This option is not recommended, please contact Espago before implementing it.

link Back requests in subscriptions

Example of a back request with info regarding a successful payment (paid=true).

{
  "id": "in_hS-KiS3N6YCzOhG",
  "date": 1371631155,
  "client": "cli_OU7k00vEMGi53C",
  "subscription": "sub_QyJzN4KdzNzvmZ",
  "amount": "7.00",
  "currency": "PLN",
  "paid": true,
  "issuer_response_code": "00",
  "attempts": 1,
  "next_payment_attempt": "null",
  "created_at": 1371500155,
  "last_payment": "pay_iq1yCYmgieM_ct"
}

If the subscription state gets changed - if the option to cancel the subscription after unsuccessful charge attempts has been turned on - a back request communicating that will be sent.

{
  "id": "sub_WQO0vEpk0-SrqM",
  "state": "inactive",
  "client": "cli_MNXfMFpu8_j3ax",
  "plan": "pl_dxT6xBEo__fbb7y",
  "created_at": 1457559667,
  "last_invoice": {
    "id": "in_CjUBitNf9UpWdoQ",
    "date": 1460461811,
    "client": "cli_MNXfMFpu8_j3ax",
    "subscription": "sub_WQO0vEpk0-SrqM",
    "amount": "55.00",
    "currency": "pln",
    "paid": false,
    "issuer_response_code": "00",
    "attempts": 1,
    "next_payment_attempt": "null",
    "created_at": 1460461811,
    "last_payment": "pay_iq1yCYmgieM_ct"
  }
}

link Back requests in token creation

There is an option to turn on sending back requests with information about newly generated tokens. Using this option the merchant’s server could gather the information about a new token directly form Espago, and not from the client’s web browser

In order to turn on this option, you need to contact the Espago Support (through email).
To make Espago send the back request, the “card[description]” parameter (this should be unique for the merchant’s server) with a length of 5-60 characters should be added to the token creation request (POST /api/tokens).

Creating a token with back requests turned on:

  1. From the client’s web browser (using Espago JS) or a mobile app, a token creation request i sent to Espago. This request contains credit card data and the “card[description]” field.
  2. The client receives a response form the Espago gateway confirming that a new token has been generated. The response contains the token’s ID, which by default would be sent to the Merchant’s server by the client.
  3. The Espago gateway sends an asynchronous back request to the Merchant’s server, containing token’s ID, and (in the section about the credit card) the “description” field, enabling the Merchant to link the token to a certain client.
  4. Through the use of the token received from Espago (or from the client), the Merchant’s service can carry out a payment.

undo Refunds

link Reversal existing Charge

In current chapter described is only reversal existing charge. If you want to reverse pending charge, you can read more about it here.

To refund settled charge please send POST request to the following address https://sandbox.espago.com/api/charges/(:id)/refund where the (:id) is ID of selected Charge (“pay_xxxxxxxxxxxx”).

You can return the entire amount of the transaction or part of it. There is no possibility to undo/stop return.

Payment can be refunded in 12 months after it’s creation.

In the case of partial refund, payment can be repeatedly refunded payment until you pay the entire amount of the original payment. Parameter refunded_amount has value already refunded amount. If you need to return full amount of payment which is partial refunded you can calculate the rest of amount (rest of money = amount - refunded_amount) or make refund request without amount.

HTTP Parameters

Parameters Description Required? Comments
amount amount, that will be refunded No This parameter has to be less than or equal the amount of transaction. If you do not set this value, the entire transaction amount will be refunded.

Important parameters from response

Parameter Descriptions Comments
id id of payment Value unchanged
state status of payment After correct refund (partial or full) became “refunded”
refunded_amount amount already refunded After full refund, refunded_amount=amount. After partial refund, refunded_amount is sum of all returns already done on this payment.
transaction_id ID of refund transaction ID of transaction (operation) which is refunding payment. This ID is different than ID transaction made payment.

Example request

curl -i https://sandbox.espago.com/api/charges/(:id)/refund \
 -X POST \
 -H 'Accept: application/vnd.espago.v3+json' \
 -u app_id:password \
 -d "amount=n"
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/charges/")
request = Net::HTTP::Post.new(uri)
request.basic_auth("app_id", "password")
request["Accept"] = "application/vnd.espago.v3+json"
request.set_form_data(
  "amount" => "n",
)

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges/(:id)/refund');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "amount=n");
curl_setopt($ch, CURLOPT_USERPWD, 'app_id' . ':' . 'password');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "id": "pay_COy6zH9fLj1d7K",
  "description": "Opis transakcji",
  "channel": "elavon",
  "amount": "49.99",
  "refunded_amount": "15.00",
  "currency": "pln",
  "state": "refunded",
  "client": "cli_xNKNXh-_kWu6Qi",
  "created_at": 1381823580,
  "card": {
    "company": "VI",
    "last4": "4242",
    "year": 2017,
    "month": 2,
    "first_name": "Jan",
    "last_name": "Kowalski",
    "authorized": true,
    "created_at": 1381755890
  },
  "issuer_response_code": "00",
  "transaction_id": "tn_AKZ71ysMF"
}

accessibility_new Client Profile

link Cient Object

Client data can be stored in the client object (especially card data). A client profile with all attributes can be used in multiple charges.

It is possible to create a client profile without card data (only description and email), in order to add the details later

In our web panel there you can enable/disable automatic authorisation during client profile creation. If it is enabled, after a request to /api/client test authorization is done (charge and reversal of 1 PLN to check if the card supports Internet transactions), and in the “authorized” response parameter in client profile contain authorisation status (for detail see the chapter belowClient profile and card attributes.

link New customer profile

New customer creation is carried out by sending a POST request to https://sandbox.espago.com/api/clients/

Available HTTP parameters

Parameter Function Description Mandatory
description Should consist of at lest 5 characters. Optional
email Customer’s e-mail address Not required but necessary if Espago has to inform the customer about changes of payment’s state via email. Optional.
We check the email’s format after receiving it.
card Parameter with the ID of card token The ID of a previously created card token. Required
curl -i https://sandbox.espago.com/api/clients \
-H "Accept: application/vnd.espago.v3+json" \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "description=John Smith" \
-d "card=token_id"
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/clients")
request = Net::HTTP::Post.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"
request.body = "description=John Smith&card=token_id"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/clients');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "description=John Smith&card=token_id");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "email": "john@smith.com",
  "id": "cli_Yzij0t46pV88oR",
  "created_at": 1381825758,
  "description": "John Smith",
  "card": {
    "company": "VI",
    "last4": "4242",
    "year": 2017,
    "month": 2,
    "first_name": "John",
    "last_name": "Smith",
    "authorized": true,
    "created_at": 1381825758,
  },
  "deleted": false
}


Instead of sending card tokens, you can send card data directly, but for security’s sake using tokens is the preffered method. Sending complete data in parameters can be used for testing and certain appliances in the production environment (please contact Espago).

Card data can be sent according to the following draught (all fields are required):

Parameter Function Description
card[first_name] Card owner’s first name
card[last_name] Card owner’s last name
card[number] Credit card number
card[verification_value] CVV
card[year] Year of expiry In YYYY format
card[month] Month of expiry In MM format; values between 01-12

link Card token creation

In order to create a card token send a POST request to https://sandbox.espago.com/api/tokens

curl -i https://sandbox.espago.com/api/tokens \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "card[first_name]=John" \
-d "card[last_name]=Smith" \
-d "card[number]=4242424242424242" \
-d "card[verification_value]=123" \
-d "card[year]=2018" \
-d "card[month]=02"
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/tokens")
request = Net::HTTP::Post.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"
request.set_form_data(
  "card[first_name]" => "John",
  "card[last_name]" => "Smith",
  "card[month]" => "02",
  "card[number]" => "4242424242424242",
  "card[verification_value]" => "123",
  "card[year]" => "2018",
)

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
// Generated by curl-to-PHP: http://incarnate.github.io/curl-to-php/
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/tokens');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "card[first_name]=John&card[last_name]=Smith&card[number]=4242424242424242&card[verification_value]=123&card[year]=2018&card[month]=02");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "id": "cc_J_wDRKH6jmIEb_8",
  "created_at": 1550871516,
  "used": false,
  "card": {
    "company": "VI",
    "last4": "4242",
    "year": 2018,
    "month": 2,
    "first_name": "John",
    "last_name": "Smith",
    "authorized": "null",
    "created_at": 1550871586
  }
}

used parameter is of boolean type (true or false). If it’s value is set to false, the token has not been used yet.

link Checking token information

If you check information about tokens, you get this information:

  • issuer country
  • bank name (but only Polish banks)
  • card type

This check can take few seconds, so it may result in slower API response.

To check token info send a POST request to https://sandbox.espago.com/api/tokens/(:id)/check_type

(:id) - id of the token you want to check

curl -i https://sandbox.espago.com/api/tokens/cc_776Hzu24ArvnooVvq/check_type \
-X POST \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/tokens/cc_776Hzu24ArvnooVvq/check_type")
request = Net::HTTP::Post.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/tokens/cc_776Hzu24ArvnooVvq/check_type');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "email":"test@example.com",
  "id":"cli_772IYA6M52V4njJR",
  "created_at":1561373467,
  "description":"John Smith id:321",
  "card":{
    "company":"VI",
    "last4":"4242",
    "year":2020,
    "month":2,
    "first_name":"John",
    "last_name":"Smith",
    "authorized":true,
    "authorized_cvv_cvc":true,
    "issuer_response_code":"00",
    "card_type":"D",
    "country":"HKG",
    "bank":"U",
    "created_at":1561373520
  },
  "deleted":false
}

Parameter Function Description
card_type Type of card C - credit card
D - debet card
U - no info
country Card issuer country 3 characters, ISO_3166-1_alfa-3
U - no info
bank Bank’s name Bank’s name
U - no info

link Customer profile and card attributes

The customer profile is an object with certain parameters. They are usually returned directly after creating a client. They’re also available later when sending requests about a customer or his payments.

Description and possible card parameter values in customer’s profile:

Parameter Value Description
company VI, MC, MD Card Provider info: VI - Visa, MC - MasterCard, MD - Maestro, AX - American Express, DC - Diners Club, JC - JCB, SW - Switch, SO - Solo, LA - Laser. WARNING: more often than not a contract with Elavon encompasses only Visa and Mastercard cards. For this reason, in most scenarios, distinguishing between VI, MC, MD will be enough.
authorized null, true, false The value of last authorisation of the card, it’s a boolean value.
null - has not been authorised yet
true - card authorisation was successful and is active
false - unsuccessful card authorisation
authorized_cvv_cvc null, true, false This parameter is available while using the double authorisation feature. Returns information about the first card authorisation using CVV/CVC. It’s of boolean type, like “authorized”.
issuer_response_code (two characters) If authorized=false, then this parameter will contain the rejection code (issuer_response_code)
created_at (number) Time in unix format

link Profile editing

Delete any existing customer profiles by sending a DELETE request to the following URL: https://sandbox.espago.com/api/clients/(:id)

(:id) - Id of the customer you want to delete

curl -i https://sandbox.espago.com/api/clients/CLIENT_ID \
-X DELETE \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/clients/CLIENT_ID")
request = Net::HTTP::Delete.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/clients/CLIENT_ID');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);

We send a response of: Status 204: no content

Update an exisitng customer by sending a PUT request to
https://sandbox.espago.com/api/clients/(:id)

(:id) - Id of the client you want to udpate
Send the same parameters as when creating a customer profile.


WARNING
If any of the card’s details are updated, you need to send a complete set of this card’s data (Even if only a single parameter is changed). Just like in customer profile creation, submitting a card’s token id is the preferred method (created before sending an update request).
After updateing card data there is noway to get back to the previous card data. If you want to make it possible to submit a new card, only if it functions properly and deleting the old one thereafter, you might want to consider creating a new customer profile and deleting the old one.

curl -i https://sandbox.espago.com/api/clients/ID_KLIENTA \
-X PUT \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "description=John Smith" \
-d "email=client@example.com" \
-d "card[first_name]=John" \
-d "card[last_name]=Smith" \
-d "card[number]=4242424242424242" \
-d "card[verification_value]=123" \
-d "card[year]=2025" \
-d "card[month]=02"
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/clients/ID_KLIENTA")
request = Net::HTTP::Put.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"
request.body = "description=John Smith \
&email=client@example.com \
&card[first_name]=John \
&card[last_name]=Smith \
&card[number]=4242424242424242 \
&card[verification_value]=123 \
&card[year]=2025 \
&card[month]=02"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/clients/ID_KLIENTA');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "description=John Smith&email=client@example.com&card[first_name]=John&card[last_name]=Smith&card[number]=4242424242424242&card[verification_value]=123&card[year]=2025&card[month]=02");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "email":"client@example.com",
  "id":"cli_772q8GcejiQfRl4z",
  "created_at":1560960175,
  "description":"John Smith",
  "card":{
    "company":"VI",
    "last4":"4242",
    "year":2025,
    "month":2,
    "first_name":"John",
    "last_name":"Smith",
    "authorized":null,
    "created_at":1561125908
  },
  "deleted":false
}

Customer data will be updated only when their new card is suited for one-time and recurring payments. To update an existing customer send a PUT request to: https://sandbox.espago.com/api/clients/(:id)/update_if_authorized

(:id) - Chosen customer’s id

The request should posess similar parameters to a profile creation request.

curl -i https://sandbox.espago.com/api/clients/CLIENT_ID/update_if_authorized \
-X PUT \
-H "Accept: application/vnd.espago.v3+json" \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "card=TOKEN"
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/clients/CLIENT_ID/update_if_authorized")
request = Net::HTTP::Put.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"
request.set_form_data(
  "card" => "TOKEN",
)

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/clients/CLIENT_ID/update_if_authorized');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "card=TOKEN");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "updated":true,
  "client":{
    "email":"client@example.com",
    "id":"cli_772q8GcejiQfRl4z",
    "created_at":1560960175,
    "description":"John Smith",
    "card":{
      "company":"VI",
      "last4":"4242",
      "year":2022,
      "month":2,
      "first_name":"John",
      "last_name":"Smith",
      "authorized":true,
      "authorized_cvv_cvc":true,
      "issuer_response_code":"00",
      "created_at":1561126879
    },
    "deleted":false
  }
}

link Fetching profiles

Fetch the data of a formerly created customer by sending a GET request to https://sandbox.espago.com/api/clients/(:id)

(:id) - Id of the customer whose data you want to acquire

curl -i https://sandbox.espago.com/api/clients/CLIENT_ID \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/clients/CLIENT_ID")
request = Net::HTTP::Get.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/clients/CLIENT_ID');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);

{
  "email":"client@example.com",
  "id":"cli_772q8GcejiQfRl4z",
  "created_at":1560960175,
  "description":"John Smith",
  "card":{
    "company":"VI",
    "last4":"4242",
    "year":2022,
    "month":2,
    "first_name":"John",
    "last_name":"Smith",
    "authorized":true,
    "authorized_cvv_cvc":true,
    "issuer_response_code":"00",
    "created_at":1561126879
    },
  "deleted":false
}

Display a number of customers by sending a GET request to https://sandbox.espago.com/api/clients?page=1&per=10

Available HTTP methods

Parameter Description Mandatory Default value
page Page number Optional 1 (first page)
per Number of customers on a single page Optional 25 (25 klientów)
curl -i https://sandbox.espago.com/api/clients \
-X GET \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "page=2" \
-d "per=15"
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/clients")
request = Net::HTTP::Get.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"
request.set_form_data(
  "page" => "2",
  "per" => "15",
)

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/clients');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "page=2&per=15");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "count":19,
  "clients":[
    {
      "email":"client@example.com",
      "id":"cli_772q8GcejiQfRl4z",
      "created_at":1560960175,
      "description":"John Smith",
      "card":{
        "company":"VI",
        "last4":"4242",
        "year":2022,
        "month":2,
        "first_name":"John",
        "last_name":"Smith",
        "authorized":true,
        "authorized_cvv_cvc":true,
        "issuer_response_code":"00",
        "created_at":1561126879
      },
      "deleted":false
    },
    {
      "email":"test@example.com",
      "id":"cli_772psATGSdMbS8NS",
      "created_at":1560960154,
      "description":"John Smith id:321",
      "card":{
        "company":null,
        "last4":null,
        "year":null,
        "month":null,
        "first_name":null,
        "last_name":null,
        "authorized":null,
        "created_at":null
      },
      "deleted":false
    },
    (. . .)
  ]
}

link Authorising customers' cards on demand

Cards are authorised by reserving and immediately returning 1 PLN (or 1 EUR, etc). This process ensures that the card is suited for payments.

  • If authentication is successful, it means that the card supports online payments, has valid expiration date and currently has funds in bank account.
  • If authentication fails, it means that it is almost certain that the next payments will also fail (exception is the rejection due to temporary lack of funds or reached transaction limit of the day, but the most common reason for the rejection is not activated Internet payment or setting it’s limits to 0PLN).

In Espago’s web panel you can set automatic authorisation during the creation of a client profile. In that case, you will get authorisation information already in response to client creation (and update).

WARNING
If authorisation is the first process carried out on a card/customer, CVV has to be used. Any further transactions will be completed without CVV. Some cards may not support payments without CVV (and therefore do not support recurring payments) which may cause situations in which a card passes authorisation, but every other transactions fail. In order to avoid this, you could follow authorisation with a second one or a payment


Authorise clients’ card by sending a POST request to https://sandbox.espago.com/api/clients/(:id)/authorize

(:id) - Id of the client who will be authorised

curl -i https://sandbox.espago.com/api/clients/CLIENT_ID/authorize \
-X POST \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/clients/CLIENT_ID/authorize")
request = Net::HTTP::Post.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/clients/CLIENT_ID/authorize');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);

{
  "email":"client@example.com",
  "id":"cli_772q8GcejiQfRl4z",
  "created_at":1560960175,
  "description":"John Smith",
  "card":{
    "company":"VI",
    "last4":"2239",
    "year":2025,
    "month":2,
    "first_name":"John",
    "last_name":"Smith",
    "authorized":true,
    "issuer_response_code":"00",
    "created_at":1561369769
  },
  "deleted":false
}

link Secure web page for creating and updating client's card data

This is page where customer can be redirected for creating client profile with card data or updating card information in his profile. This way, Customer puts his credit card data on the Espago Website, not on the seller’s site (when using Espago JS or iFrame solution).

Additionaly by using ‘check’ and ‘store’ parameters you can declare the conditions under which an update shall take place. This is to prevent clients from replacing their working credit cards, with new ones, not suited for recurring payments.

In order to create the “client_card_page” - a secure page, to which the user can be redirected to securely enter his credit card data - send a POST request to:
https://sandbox.espago.com/api/clients/card_page
and redirect the customer to the received URL.

HTTP parameters

Parameter Required Function Description
client client/customer ID If used, this parameter should contain ID of customer/client created earlier.
client[description] check Short customer description Should have at least 5 characters.
card[email] check Customer e-mail address Not required but necessary if Espago has to inform customer about changes of payments state via email.
store Information when save card data: all
check Information how to test client’s credit card - nothing
positive_url URL the customer should be redirected to after saving his credit card details.
negative_url URL the customer should be redirected to when customers resign or an error occurs.
title Short description for what this card will be used for - it’ll be displayed on the page. At least 5 characters


If the merchant has the ‘Automatic client authorization’ option checked then ‘check’ is by default set to ‘recurring. Otherwise it’s set to 'nothing’.


curl -i https://sandbox.espago.com/api/clients/card_page \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "client[description]=John Smith id:321" \
-d "client[email]=test@example.com" \
-d "check=recurring" \
-d "store=recurring" \
-d "title=Card for future subscription for the radio ABC"
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/clients/card_page")
request = Net::HTTP::Post.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"
request.body = "client[description]=John Smith id:321&client[email]=test@example.com&check=recurring&store=recurring&title=Card for future subscription for the radio ABC"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/clients/card_page');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "client[description]=John Smith id:321&client[email]=test@example.com&check=recurring&store=recurring&title=Card for future subscription for the radio ABC");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "id":"cpl_772AUdz2l2DMHCvz",
  "url":"https://sandbox.espago.com/client_card_page/cpl_772AUdz2l2DMHCvz",
  "client":"cli_772IYA6M52V4njJR",
  "store":"recurring",
  "check":"recurring",
  "title":"Card for future subscription for the radio ABC",
  "valid_to":1561459867,
  "created_at":1561373467,
  "used":false,
  "positive_url":null,
  "negative_url":null
}

Now the (cli_772IYA6M52V4njJR) profile can be used as normal. They ‘URL’ parameter encapsulates the client_card_page URL for this client. Such a link is valid for one hour and expires after saving the card.
After saving the card, finish-true parameter is displayed on the last screen. It can trace this URL in WebView (in the mobile app) and close the window after credit card creation.

link Checking credit card information

If you check information about cardholder, you get this information:

  • issuer country
  • bank name (but only Polish banks)
  • card type

This check can take few seconds, so it may result in slower API response. The same case is during creating of client profile, when automatic check of card information is checked. In order to turn on this feature, please contact the Espago Team.

To check credit card info send a POST request to https://sandbox.espago.com/api/clients/(:id)/check_type

(:id) - id of the customer/client you want to check

curl -i https://sandbox.espago.com/api/clients/cli_772IYA6M52V4njJR/check_type \
-X POST \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/clients/cli_772IYA6M52V4njJR/check_type")
request = Net::HTTP::Post.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/clients/cli_772IYA6M52V4njJR/check_type');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
{
  "email":"test@example.com",
  "id":"cli_772IYA6M52V4njJR",
  "created_at":1561373467,
  "description":"John Smith id:321",
  "card":{
    "company":"VI",
    "last4":"4242",
    "year":2020,
    "month":2,
    "first_name":"John",
    "last_name":"Smith",
    "authorized":true,
    "authorized_cvv_cvc":true,
    "issuer_response_code":"00",
    "card_type":"D",
    "country":"HKG",
    "bank":"U",
    "created_at":1561373520
  },
  "deleted":false
}

Parameter Function Description
card_type Type of card C - credit card
D - debet card
U - no info
country Card issuer country 3 characters, ISO_3166-1_alfa-3
U - no info
bank Bank’s name Bank’s name
U - no info

vpn_key Submitting CVV Numbers

link Why should I send CVVs?

CVV can only be used once and after a successful first authorisation or payment, it is deleted from the Espago gateway. In order to make another payment with the use of a client profile and CVV, you need to fetch the CVV (through EspagoFrame or Espago JS and create a token for it) and send it as a payment parameter.


The feature of adding CVV is specially useful as an additional authentication method in multiple payments initiated by the customer. Sending CVV also increases the probability of the payment succeding, because it makes it possible to charge cards, which do not work without CVV (look: The problem of cards not suitable for recurring payments)

CVV token can be used in 24h after creating, there is no option to store CVV for later multiple payments.

link Creating CVV tokens

You can use EspagoIFrame (which enables the user to securely enter their credit card data, or in this instance, just CVV) to create CVV tokens. Then this data will be sent to Espago and a script will return the token ID back to the site. This token can be used later to securely send the CVV.

1. Calling the IFrame

The client calls our IFrame suited for gathering CVVs, enters his code and sends it to Espago

<script src="https://js.espago.com/espago-1.2.js"></script>
 <script 
   async=""
   data-id="EspagoFrameScript"
   data-key="VrYVaA1CjmRooKh63YYv"
   data-live="false"
     data-cvv-only="true"
   data-button="Pay"
   src="https://js.espago.com/iframe-1.0.js">
 </script>

 <a id="pay_btn">Pay</a>
$('#pay_btn').click( () => {
  showEspagoFrame()
})

Receiving the token

After the user filled in the form with his card details, the script sends this data directly to Espago Servers. In case of creating a token, the script (by default) returns it form of an input to a form named `espago_form` (this form has to be present on your site, for the script to work!).

You can change this behaviour in these parameters: data-target or data-success in IFrame.

<form id="espago_form">
  <input type="hidden" id="cvv_token" name="cvv_token" value="cvv_xxxxxx">
</form>

Creating a charge

Creating a charge with an additional parameter: cvv=cvv_token_id.

curl -i https://sandbox.espago.com/api/charges \
-H "Accept: application/vnd.espago.v3+json" \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "amount=10" \
-d "currency=pln" \
-d "client=cli_772IYA6M52V4njJR" \
-d "description=Espago docs" \
-d "cvv=cv_772oAPNIwkEZlEIPo"

link Parameters

Parameter Required Default values Description
async done “” Can not have a value different than default
data-id done EspagoFrameScript Can not have a value different than default
src done source of the script Can not have a value different than default
data-key done String, Merchant public key
data-cvv-only done String, if ‘true’, EspagoFrame is set in CVV mode - only CVV field will be displayed.
data-live true String, If ‘true’, then requests are sent to production environment. If set to ‘false’, requests are sent to test environment.
data-company String, indicates saved card company, this company logo will be displayed as card info next to CVV field. Available: AX, DC, DI, JC, MC, MD, UP, VI.
data-last4 String, indicates saved card number last 4 digits , will be displayed as card info next to CVV field.
data-valid-to String, format: MMYYYY, indicates saved card validation date, will be displayed as card info next to CVV field.
data-lang pl String, Form language (for default labels, placeholders) in ISO 639-1 standard. Available: da, de, en, et, fr, it, lt, lv, pl, ru, sv.
data-success function(data) {} A success callback. Action inside this function will be executed when token is received. Note: If given, default script action is disabled - field ‘card_token’ will not be added to form.
data - string; Espago token value.
data-error function(data) {} An error callback. Action inside this function will be executed when error occurred.
data - string; error code with description.
data-onclose function() {} An “on close” callback. This function is executed when user closes modal (using “x” button or “Esc” key).
data-target espago_form Form name, where ‘card_token’ hidden field will be added.
Note - if the ‘data-success’ parameter is specified, above action will not perform.
data-title Add your card (en) Form title.
Note - The default value depends on the language value of ‘data-lang’.
data-subtitle The text displayed below the form title and store name (store name is taken automatically from the API Espago)
data-button Save (en) The label of the submit button.
Note - The default value depends upon the ‘data-lang’ parameter

link Payments with CVV tokens

A CVV payment is executed just like a regular one, but posesses an aditional cvv parameter, with the id of the CVV token.

Request example

curl -i https://sandbox.espago.com/api/charges \
-H "Accept: application/vnd.espago.v3+json" \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "amount=10" \
-d "currency=pln" \
-d "client=cli_772IYA6M52V4njJR" \
-d "description=Espago docs" \
-d "cvv=cv_772oAPNIwkEZlEIPo"
require 'net/http'
require 'uri'

uri = URI.parse("https://sandbox.espago.com/api/charges")
request = Net::HTTP::Post.new(uri)
request.basic_auth("ms_771eUTliRiZ", "SeCreT_P@ssw0rD")
request["Accept"] = "application/vnd.espago.v3+json"
request.body = "amount=10&currency=pln&client=cli_772IYA6M52V4njJR&description=Espago docs&cvv=cv_772oAPNIwkEZlEIPo"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "amount=10&currency=pln&client=cli_772IYA6M52V4njJR&description=Espago docs&cvv=cv_772oAPNIwkEZlEIPo");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, 'ms_771eUTliRiZ' . ':' . 'SeCreT_P@ssw0rD');

$headers = array();
$headers[] = 'Accept: application/vnd.espago.v3+json';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);

link Using Espago.js to create CVV tokens

To accept the CVV code and create a token CVV, please use the form using JS script espago-1.2. This script sends the CVV code directly from the form (client browser) into the gateway Espago, next recieve CVV token and sends its ID (as parameter “cvv_token” with the value like “cv_xxxxxxxx”) with the form to the merchant website.

URL of the actual script: https://js.espago.com/espago-1.2.js
Demo: https://github.com/espago/espago-1.2.js-demo

In the script there should be used “Public Key”, the same as in the Espago JS used to create normal credit card script.

<script src='https://js.espago.com/espago-1.2.js' type='text/javascript'></script>

<form action='cv_token.html' id='espago_new_cvv_form' method='POST'>
  <input id='espago_new_verification_value' type='text' value='712'>
  <span id='espago_new_verification_value_error'></span>
  <input type='submit' value='Create CVV token'>
</form>
var espago = new Espago({public_key: 'PfcMBQnqWjNF2ihkv9xs', custom: true, live: false})

$("#espago_new_cvv_form").submit(function(event){
  event.preventDefault()

  if (espago.validate_new_cvc()){
    $("#espago_new_verification_value_error").text("")
  } else {
    $("#espago_new_verification_value_error").text("Błędne dane!")
  }
  espago.create_new_cvv()
})

payment Espago Terminals

link What is Espago Terminals

xxx

link xxx

xxx

link Integracja

xx

link Działanie Espago Terminals

xxx

link Parametry obciążenia

xxx

link Back requests params

xxx

link Status płatności

xxx

link Recuring payments on terminal

xxx

web Espago.js

link The functioning of Espago.js

NOTE: The use of Espago JS described here is an accepted, but older solution than Espago iFrame. For new integrations, we strongly suggest using the iFrame solution that gives more opportunities and is constantly being developed.

In order to facilitate the integration process, we’ve prepared a script which generates a created token and returns its value in the ‘card_token’ parameter.
The URL where you can find this script: https://js.espago.com/espago-1.2.js

If the payment form will be located on your website (directly, not through an Iframe) the use of this script (https://js.espago.com/espago-1.2.js) is mandatory. The script has to be downloaded directly form the Espago server.

The availability of the js.espago.com script (SLA) is the same as the Espage gateway’s, therefore there is no need to copy the script to your server. On the download page you can download the latest example of the form using JS script with jQuery.

The sample form uses the JQuery library, which is not required for Espago.js to work correctly. It is possible to implement Espago Payment Form in pure JavaScript.

When using the script https://js.espago.com/espago-1.2.js, form fields with card data (card number, expiration date, the owner) must not have the “name” parameter. The Espago script needs just ‘id’. To obtain this data, you can make a request to get token information or (the easiest way) to read them from the response from Espago gateway during creation of a customer profile (query /api/clients) or payments (query /api/charges).

1. Filling in the form

The client fills in the form with their data and calls the token creation action by clicking on a designated button

<script src='https://js.espago.com/espago-1.2.js' type='text/javascript'></script>
<form action='/charge' id='espago_form' method='POST'>
  <input id='espago_card_number' type='text'>
  <input id='espago_first_name' type='text'>
  <input id='espago_last_name' type='text'>
  <input id='espago_month' type='text'>
  <input id='espago_year' type='text'>
  <input id='espago_verification_value' type='text'>
  <input type='submit' value='Pay'>
</form>

2. Receiving

The ‘create_token()’ function is the main action which communicates with our Gateway. The merchant is identified based upon a previously specified public key and any sent card data are bound with a token. By default the espago.create_token() function calls a submit action.

var espago = new Espago({public_key: 'PfcMBQnqWjNF2ihkv9xs', custom: true, live: false})

$("#espago_form").submit(function(event){
  event.preventDefault()
  if (!espago.validate_card_number()){
    alert("Błędne dane!")
  }

  if (!espago.validate_first_name()){
    alert("Błędne dane!")
  }

  if (!espago.validate_last_name()){
    alert("Błędne dane!")
  }

  if (!espago.validate_card_date()){
    alert("Błędne dane!")
  }

  if (!espago.validate_card_cvc()){
    alert("Błędne dane!")
  }

  espago.create_token()
})

3. Calling the payment

Calling a normal payment with a token - read more about payments

link Espago constructor parameters

The form will function properly only if the action is called on a previously defined espago object. Any methods responsible for communication and validation of sent data must be called on this object. The created obejct has to contain the merchant’s public key. You can see an example of this implementation below:

var espago = new Espago({public_key: 'klucz_publiczny:'});

Parametry

Parameter Required Default values Description
public_key done Merchant’s public key
live true If value of this parameter is true, then requests from espago.js library are sent to production environment.
In the case of ‘false’ value of this parameter, requests are sent to test environment.
form #espago_form Name of the form
card_number #espago_card_number ID of the field with client’s card number
first_name #espago_first_name ID of the field with the customer’s name
last_name #espago_last_name ID of the field with the customer’s surname
month #espago_month ID of the field with the month of card expiration date
year #espago_year ID of the field with the year of card expiration date
cvc #espago_verification_value ID of the field with Card Verification number
custom false The ‘true’ value enables the option of defining custom success and error parameters.
success function(data) {} A callback function. Actions within will be executed only in case of a postive response.
error function(data) {} A callback function. Action within will be executed when errors occur.
submit true Form confirmation and submitting.

link Token creation

The main action of the script which communicates with the gateway. The merchant is identified by a previously specified public key and any sent credit card data are bound with a token.

espago.create_token()

By default the espago.create_token() executes the submit action. It is possible to disable it by appending a few additional parameters which can be seen below (disabling the submit action and the actions after an error occurs respectively):

espago.create_token({
  submit: false,
  success: (data) => { 
    alert("success")
  },
  error: (data) => { 
    alert("error");
  }
})

link Form fields

Default field ID Field type Description
espago_card_number text Client’s card number
espago_first_name text Client’s name
espago_last_name text Client’s surname
espago_month text The month of card expiration date
espago_year text The year of card expiration date
espago_verification_value text Verification code

All available validation functions are presented below. In the sample code of every function we introduced data subjected to validation. In the case of their absence, the default value is adequate form field value.

validate_card_number()

This method validates card number. If card number is typed with additional non-numeric characters, these characters will be ignored.

espago.validate_card_number('4242424242424242') //true
espago.validate_card_number('42 42 42 42 42 42 42 42') //true
espago.validate_card_number('42 42 42') //false
espago.validate_card_number() //the default value of this method is form field 'espago_card_number' value

validate_first_name()

This method validates card owner’s first name.

espago.validate_first_name('Jan') //true
espago.validate_first_name('') //false
espago.validate_first_name() //default value of this method is form field 'espago_first_name' value

validate_last_name()

This method validates card owner last name.

espago.validate_last_name('Kowalski') //true
espago.validate_last_name('') //false
espago.validate_last_name() //default value of this method is form field 'espago_last_name' value

validate_card_date()

This method validates card expiration date.

espago.validate_card_date('02', '2017') //true
espago.validate_card_date(02, 2017) //true
espago.validate_card_date(2, 17) //false
espago.validate_card_date() //default values of this method are form field  'espago_month' and 'espago_year' values

validate_card_cvc()

This method validates card cvc code.

espago.validate_card_cvc('123') //true
espago.validate_card_cvc('12') //false
espago.validate_card_cvc('xyx') //false
espago.validate_card_cvc() //default value of this method is form field 'espago_verification_value' value

compare_arrows Compatibility

link Constraints

The purpose of the API is to not limit in any way the technology used by merchant’s services, in which payments are to be integrated, as well as devices from which customers will make payments. Nevertheless, there are some requirements during communication with Espago gateway, and it results in some limitations of compatibility with older technologies:

Espago gateway requires connections using TLSv1.1 or TLSv1.2 with strong ssl ciphers. This situation is present since 2015 on our test gateway https://sandbox.espago.com. If your app works fine in the test environment, it will also work in the production environment (and connect with the production gateway)


Some olders systems, libraries or browsers doesn’t support this connections, and need to by upgraded - This requirement applies to connections to API, 3D-Secure redirections and access to WWW panel.

List of software that supports TLS 1.2 and TLSv1.1

System/ application/ library The minimum compatible version Additional notes
Windows 7 and later In Windows XP and Vista customer need to use alternative web browser (ie. Chrome, Firefox, Opera)
Windows Server 2008 R2 and later Windows 2008 R2 requires enabling TLSv1.2 in systems registry and enabling additional ssl ciphers
Android 4.4.4 and later Android API level 20. Partial support available also in 4.2
OpenSSL 1.0.1 and later Note: OpenSSL 0.9.8 (all subversion) does not support TLSv1.2
Apache 2.2.23 and later
Java 8 and later Note: Java 6 and Java 7 does not support TLSv1.2
.NET Framework 4.5.1 and later enabling in preferences may be needed, and it requires Windows that supports TLSv1.2

List of protocols and ssl ciphers allowing secure connection to the Espago gateway

It is recommended to configure the application to permit connections using the safest available protocols and ciphers, and to have the opportunity to connect with several sets of codes (ie. not forcing one specific one cipher).

Protocol Ciphers
TLSv1.2
TLSv1.1
ECDHE-ECDSA-AES128-GCM-SHA256
ECDHE-ECDSA-AES256-GCM-SHA384
ECDHE-RSA-AES256-GCM-SHA384
ECDHE-RSA-AES128-GCM-SHA256
kEDH+AESGCM
ECDHE-ECDSA-AES256-SHA384
ECDHE-ECDSA-AES256-SHA
ECDHE-ECDSA-AES128-SHA256
ECDHE-ECDSA-AES128-SHA
ECDHE-RSA-AES256-SHA384
ECDHE-RSA-AES256-SHA
ECDHE-RSA-AES128-SHA256
ECDHE-RSA-AES128-SHA
DHE-RSA-AES256-SHA256
DHE-DSS-AES256-SHA
DHE-RSA-AES256-SHA
DHE-RSA-AES128-SHA256
DHE-RSA-AES128-SHA
DHE-DSS-AES128-SHA256
DHE-RSA-AES128-GCM-SHA256
DHE-DSS-AES128-GCM-SHA256
AES256-GCM-SHA384
AES256-SHA

Testing connections using TLSv1.2 and TLSv1.1

If your app connects with https://sandbox.espago.com API, this is not needed.

If your app can’t establish a stable SSL/TLS connection with the Espago gateway, you could use the special https://oldssl-sandbox.espago.com gateway, which serve’s the purpose of helping with finding SSL/TLS connection issues.oldssl-sandbox.espago.com is built according to old requirements (accepts TLSv1.0), it enables you to test payments without meeting current SSL requirements. This address should only be used to test connections in case of utter inability to connect with our API through sandbox.espago.com. If your app connects with oldssl-sandbox, but not with sandbox, your software does not support TLSv1.2 and needs to be updated/changed.

sandbox.espago.com meets the same SSL/TLS requirements as the production gateway (if not even harsher). If your app connects with https://sandbox.espago.com it will connect with the production environment as well. In case of any doubts, please contact the Espago Support Team. We can determine which protocols your app relies on (and uses for connections with Espago). To do this pass on your source IP and app ID (ms_xxxxxxxx).

link The payment form does not work in IE9 and older versions

For correct payment form functioning, you need Internet Explorer in version 10 or newer, or any other web browser (Google Chrome, Mozilla Firefox, Opera, Safari, etc). The payment form does not work with Internet Explorer in version IE9 and older. In some configurations there are also problems with token creation in Microsoft Edge ( due to limitation of CORS support in this browser).

The indicated IE browser incompatibility applies to any version of IE in Windows XP, so it is recommended for Windows XP users to make payments using any other browser. The indicated incompatibility is important for example for a program written in .NET on Windows XP, using the built-in system of IE or imitating it in an version earlier than or equal to IE9.

Explanation: https://js.espago.com/espago-1.2.js script that must be implemented in the payment form uses XMLHttpRequest addressed to a domain other than the seller (request to the Espago gateway forming a token), this is a Cross-Origin Resource Sharing, in short CORS. Older versions of IE do not allow such requests.

Welcome to the Espago docs!

We use cookies to enhance your experience. By continuing to visit this site you agree to our use of cookies. Enjoy Espago docs!

Espago Team