Introduction home
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.
<!-- iFrame Configuration -->
<script
async=""
data-id="EspagoFrameScript"
data-key="VrYVaA1CjmRooKh63YYv"
data-live="false"
data-button="Pay"
src="https://js.espago.com/iframe.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
andstate
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 signing 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 40 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
link Changes and requirements resulting from PSD2
The Espago gateway provides the functions and mechanisms necessary to process payments in compliance with the PSD2 directive. From the perspective of merchants using card payments, the new requirements primarily include two elements:
1. Every online payment initiated by the customer utilizes strong customer authentication (SCA) provided by 3-D Secure;
2. Every subscription or card-on-file registration begins with an SCA payment, and subsequent payments are appropriately marked.
Failure to implement SCA will result in increased payment rejections for cards issued by European banks. It is the responsibility of the merchants to verify and adapt their integration to meet the new requirements.
- If you are currently using APIv3 with 3D Secure enabled for one-time payments, no changes are required.
- If you already process recurring payments using the “cof=storing” flag (feature added in August 2019), you most likely do not need to make any changes.
- If your application uses APIv3 without utilizing 3D Secure, this security feature must be enabled and used for all one-time payments and recurring payments.
- If you are still using the old APIv2, a migration to APIv3 is necessary.
- If you initiate recurring payments by creating a client profile with a separate request and double authorization, you need to modify the customer registration process to incorporate SCA.
PSD2-Related Change Checklist
To ensure compliance with PSD2 requirements regarding card acceptance, please perform the following checks:
Question | Scope | Response: YES List of potential changes |
Response: NO List of potential changes |
---|---|---|---|
1. Is your integration based on Espago API v3? | Applies to all clients. To verify if your integration uses API v3, check if you’re applying the appropriate request headers. | Yes - proceed to check if requirements from subsequent points are fulfilled; | No - you need to integrate with API v3: migrate from API v2; |
2. Are all cardholder-initiated payments (CIT) using strong customer authentication (SCA)? | Applies to all services. Strong customer authentication is provided through the 3-D Secure mechanism offered by Espago. | Yes - requirement fulfilled; | No - changes are required: - If API requests include the “skip_3ds” parameter for exemptions, it should be removed. If strong authentication is not possible due to the nature of the payment, utilize the moto mechanism (use the “moto” parameter in the API request). |
3. Are recurring, card-on-file, and merchant-initiated payments (MIT) preceded by strong customer authentication at the initiation stage? | Applies to services utilizing mechanisms such as: - Espago Subscriptions - Recurring, card-on-file, and other payments based on the card on file (COF) mechanism. |
Yes - requirement fulfilled; | No - you need to adjust the payment process to comply with the requirements described in the Multiple Payments or Espago Subscriptions section, depending on the mechanism used. Significant change - Client Profile (which can be used for subsequent charges) is created during the initiating payment with the cof=storing parameter, utilizing SCA. There is no need to create it with a separate client profile request. |
4. Was the client profile previously created based on the card token, before the first payment? | Applies to payments made using a saved client profile (including Espago Subscriptions). | Yes - changes are required to align with the requirements described in the Recurring Payments or Espago Subscriptions section. Although it is still possible to create a client profile without invoking SCA payment, in such cases, the first payment using that profile must utilize SCA or be marked as MOTO (it cannot be a recurring payment with the cof=recurring parameter). |
No - if a client profile created using the cof=storing payment is utilized, the requirement is fulfilled. |
5. Have you previously used the automatic card authorization mechanism (option selected in the secure.espago.com panel) when creating a client card token? | Applies to payments made using a saved client profile (including Espago Subscriptions). | Yes - you need to discontinue this option. We have introduced a different mechanism that allows you to determine whether a profile can be used for payments: If a client profile was created based on an SCA payment, it includes the sca_payment parameter, indicating a successfully authenticated payment. This serves as the basis for using the client profile for recurring and multiple charges. If the parameter is absent, the profile is not suitable for charges other than cardholder-initiated (with SCA) or MOTO payments. |
No - requirement fulfilled; |
6. Did the initial payment with 3DS or authorization return immediately upon saving the client card? | Applies primarily to merchants with recurring payments starting from a free trial period. | Yes - you need to modify the integration so that the initial SCA/3DS payment is not immediately reversed. Reversing the payment will be interpreted by the bank as revoking the customer’s consent for subsequent charges. To save the client card without charging it, use the cof=storing payment with an amount of 0 currency units. |
No - no changes are necessary; |
Integration assignment
link Integration process
linkIntegration with the test environment
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
linkIntegration with the production environment
In order to switch over to the production environment you have to alter the connection parameters - 5 of them need to be changed:
- Gateway address
- App ID
- API password
- Public key
- 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:
- Navigate to this page:
- Click on the ‘Edit’ button to access the site editing panel
- 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
- 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 |
---|---|---|---|---|---|
4012000000020006 | Visa | PLN | 3DSv2.1.0 Challenge |
No | Yes For one time payment and cof=storing |
4916978838794412 | Visa | PLN | 3DSv2.1.0 Frictionless: OK |
No | Yes |
4556914091330789 | Visa | PLN | 3DSv2.1.0 Frictionless: Reject |
No | Yes |
5432670000041258 | Mastercard | PLN | Mastercard SecureCode | No | Yes |
4242424242424242 | Visa | PLN | Yes | No | Yes |
4012001037141112 | Visa | PLN | Verified by Visa | No | No Since 2022-10 3DSv1 is disabled |
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 |
4916978838794412 | Visa | PLN | 3DSv2.1.0 [Frictionless OK] |
No | Recommended |
4556914091330789 | Visa | PLN | 3DSv2.1.0 [Frictionless Reject] |
No | Recommended |
4012000000020006 | Visa | PLN | 3DSv2.1.0 [Challenge] |
o | Yes, when testing cof=storing |
4012001038443335 | Visa | PLN | 3DSv2.1.0 Frictionless: OK |
No | No |
6771798021000008 | Maestro | PLN | 3DSv2.2.0 Frictionless: OK |
No | No |
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. |
Rejection code control
Card 4012001038443335 allows Merchant to control rejection codes through transaction amount.
The rejection code takes the value of the transaction amount after the decimal point, for example:
Decimal value | Rejection code |
---|---|
n.04 | 04 |
n.51 | 51 |
n.43 | 43 |
n.65 | 65 |
Where n is a natural number.
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send('api/test', method: :post)
puts response.body
$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."
},
. . .
]
}
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. Every requirement and configuration about SSL/TLS is first implemented 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.3 | TLS_AES_128_GCM_SHA256 TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 |
TLSv1.2 | ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-CHACHA20-POLY1305 ECDHE-RSA-CHACHA20-POLY1305 |
Secure web page exit_to_app
link Payment initialization
There are two ways to initiate a payment using the secure payment page:
1. HTML form request - by sending from the user’s browser a form containing payment data and a checksum to the / secure_web_page
address;
2. Registering the payment in API - registering the payment through sending a POST request to the Espago API endpoint: / api / secure_web_page_register
. After registering the payment, it is necessary to redirect the user to the URL address received in response - in the redirect_url
parameter.
link Payment initialized using the HTML form
1. Submitting the form
By clicking on the submit button, the client sends a HTML form with hidden fields containing the payment details, 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
The client fillings the card data form and the payment with 3-D Secure strong authentication is proceeded. When the authorization is completed, a back request is sent to the merchant service with the authorization details.
3. Redirecting to the merchant
Depending upon the payment status, the client gets redirected to one of the two URLs (for the positive or negative authorization result). The merchant service should display the payment status and if the payment is rejected - also a recejt reason..
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: demo.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 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 | done | E-mail of the client, required for 3D Secure authentication. A confirmation email will be sent to this address. | |
skip_email |
Boolean (false/true, default: false). | Disables email notifications - even if you send a request charge with a customer profile with an email 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: “|” | |
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" />
<div class="button">
<button name="button" type="submit">Buy now!</button>
</div>
</form>
link Payment initialization through API request
To initiate a payment using a Secure Web Page, send a request to the API using the POST method, and then redirect the customer to the URL received in the response - in the redirect_url
parameter.
The API initialized secure web page payment process:
In this endpoint the same parameters as in API “charge” method are used.
Request params
Ścieżka:/api/secure_web_page_register
Metoda:POST
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=199' \
-d 'currency=PLN' \
-d 'description=Payment_123' \
-d 'kind=sale' \
require 'net/http'
require 'uri'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send(
'api/secure_web_page_register',
method: :post,
body: {
amount: 199,
currency: 'PLN',
description: 'Opis transakcji',
kind: 'sale',
service_client_id: 'xxxxxx',
client_description: 'xxxxx'
}
)
puts response.body
$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=199¤cy=PLN&description=Payment_123&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": "Payment_123",
"amount": "199",
"currency": "PLN",
"state": "new",
"created_at": 1550224439,
"transaction_id": "tn_CLN2HhetI",
"redirect_url": "https://sandbox.espago.com/secure_web_page/tn_CLN2HhetI"
}
iFrame open_in_browser
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 integration can be found on this test site demo.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.3.js"></script>
<script
async=""
data-id="EspagoFrameScript"
data-key="VrYVaA1CjmRooKh63YYv"
data-live="false"
data-button="Pay"
src="https://js.espago.com/iframe.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_8a1kqN20X6JYeuD-Y" \ # token
-d "description=Espago docs"
require 'net/http'
require 'uri'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send(
'api/charges',
method: :post,
body: {
amount: 10,
currency: 'PLN',
card: 'cc_8a1kqN20X6JYeuD-Y',
description: 'Espago docs'
}
)
puts response.body
$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¤cy=pln&card=cc_8a1kqN20X6JYeuD-Y&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);
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, ua. | |
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’. |
|
data-styler | esp | String, Optional form styling. If a special version of the iframe has been prepared for the Merchant, after including the iframe parameter, it will be displayed in the ordered graphic design. The styling option is only available after prior arrangement with Espago. |
One-time payment attach_money
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] [deprecated] |
Parameter is deprecated, you should use cof=storing instead. Adding parameter “recurring=true” enforces classification of transaction in bank as recurring transaction. This results in not checking the 3D-Secure. |
complete | [optional] | Adding parameter “complete=false” enforces making only reservation of payment. See details in separate chapter. |
moto | [optional] | Adding parameter “moto=true” enforces classification of transaction as MOTO (Mail Order/Telephone Order), for example when hotel owner recieved card number for charge from booking service. This results in the omission of 3D-Secure. Before using please contact the Espago Tech Team, using MOTO need to be playced in agreement betwen Merchant and Acquirer. |
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 |
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. |
Client’s E-mail address | Client’s E-mail address required for 3D Secure authentication. Additionally a notification about the charge’s result will be sent to this address unless the skip_email parameter is present. 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, or (when used with client profile) updating referenced sca_payment in client profile), 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), unscheduled (transaction requested by Merchant, for example customer billing for the service). Details in COF section. |
recurring_expiry | [optional] | This parameter will be used if cof has the value of storing . The date on which the recurring payment expires (no more charges will be carried out) Accepted Format: YYYYMMDD . If cof=storing and this parameter is not set, then by default card expiry date is used. NOTICE: during 3-D Secure flow, on Bank site this parameter can be displayed. |
recurring_freq | [optional] | This parameter will be used if cof has the value of storing . Indicates the minimum number of days between recurring charges. Integer value. If cof=storing and this parameter is not set, then by default recurring_freq=1 is used. NOTICE: during 3-D Secure flow, on Bank site this parameter can be displayed. |
authentication_ind | [optional] | Type of later transactions, described in part 3-D Secure. |
challenge_ind | [optional] | Enforcing SCA, described in part 3-D Secure. |
payment_referenced | [optional] | The reference to a initial payment other than the one saved in the client’s profile. Takes the value of the payment ID. The parameter can only be used with cof = recurring orcof = unscheduled . By default, for recurring payments, the payment saved in the client’s profile is used (visible as sca_payment in the client’s profile), saved during the payment with the parametercof = storing |
link Charge example
{
"amount": 10,
"currency": "pln",
"card": "cc_772ahSzjmMnOt4eIk",
"description": "Espago docs"
}
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send(
'api/charges',
method: :post,
body: {
amount: 10,
currency: 'pln',
card: 'cc_8a1kqN20X6JYeuD-Y',
description: 'Espago docs'
}
)
puts response.body
$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¤cy=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
linkWhat is 3D Secure?
3D Secure is a transaction authorisation method used in the web. It redirects users to their bank’s site (or show iFrame) for additional authorisation (through SMS, submitting some credentials or confirmation on mobile phone application).
The use of 3-D Secure transfers from the Seller to the Customer’s Bank possible liability for fraud.
Proper handling of cards with 3D Secure is necessary for correct transaction flow.
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.
Until 2019, 3-D Secure v1.0.2 was the standard, currently EMV 3-D Secure v2.2.0 is being introduced. From the customer’s point of view, the difference is small, but for the Merchant, there are:
- Many available parameters that could better adjust the 3DS authentication to a given type of transaction or business through paremeterauthentication_ind
andchallenge_ind
.
- Authorization on amount “0” EUR/USD/etc, usefull for storing card data with authentication without charging customer.
- In payment with thecof = storing
flag, SCA is always enforced (i.e. customer redirection and his conscious authorization of the transaction). In one-off payments, the Bank may, based on the data of the browser and / or mobile device, decide to authorize and redirect the customer to the store immediately without customer’s action (the so-called frictionless flow, e.g. for amounts below EUR 50, at a seller with whom customer has already made purchases, etc.).
For standard payments (one-time, recurring), Espago sets the appropriate parameters for 3-D Secure v2 authentication. In specific situations the Seller has the option to trigger a payment with additional 3DS indications.
Parameter used in charge request | Description | Notes and values |
---|---|---|
authentication_ind | type of transactions for which authentication applies Default: “01” for single payment “02” for payments with cof=storing “04” for non-payment authorization ( cof=storing and amount=0 ). |
Need to be 2 digits. Possible values: ‘01’: ‘Payment transaction’ ‘02’: ‘Recurring transaction’ ‘03’: ‘Instalment transaction’ ‘04’: ‘Add card’ [usefull when used with unscheduled payments (ex. payments after renting a bike), should be used in initial transaction( cof=storing )‘05’: ‘Maintain card’ ‘06’: ‘Cardholder verification as part of EMV token ID&V’ |
challenge_ind | Forcing mode for Strong Customer Authentication (SCA) Default: “01” for single payment “04” fored allways for payments with cof=storing (no possibility to change challenge_ind during storing) |
Need to be 2 digits. Possible values: ‘01’: ‘No preference’ ‘02’: ‘No challenge requested’ ‘03’: ‘Challenge requested (3DS Requestor preference)’ ‘04’: ‘Challenge requested (Mandate, for example due to PSD2)’ ‘05’: ‘No challenge requested (transactional risk analysis is already performed)’ ‘06’: ‘No challenge requested (Data share only)’ ‘07’: ‘No challenge requested (strong consumer authentication performed)’ ‘08’: ‘No challenge requested (utilise whitelist exemption if no challenge required)’ ‘09’: ‘Challenge requested (whitelist prompt requested if challenge required)’ |
linkCardholder’s personal data required for Visa 3D Secure authentication
Starting from August 12, 2024, Visa will increase the amount of data required for 3D Secure authentication. From this date, for each 3D Secure transaction, the Merchant will be required to submit the cardholder’s email address.
Depending on the form of integration, the email address can be provided:
- as the value of the
email
parameter for transactions initiated via an API request to the /api/charges or /api/secure_web_page_register endpoints - as the value of the
email
parameter for transactions initiated via an HTML form - as the value of the
email
parameter in the Client’s Profile
link eDCC
linkWhat is 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.
linkeDCC - how does it work?
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send(
'api/charges',
method: :post,
body: {
amount: 49.99,
currency: 'pln',
client: 'cli_772uWYtgJXnL_F9I',
description: 'Opis transakcji'
}
)
puts response.body
$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¤cy=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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
payment_id = 'pay_8a1FKrxqzJG9sszX'
response = client.send(
"api/charges/#{payment_id}/dcc_decision",
method: :post,
body: {
decision: 'Y'
}
)
puts response.body
$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
link3D Secure and eDCC
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"
}
}
linkFetching conversion rates
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send "api/dcc/rates", method: :get
puts response.body
$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. |
tds2_challenge |
[State available only when using 3D-Secure v2]. Customer was redirected to 3-D Secure website or have displayed iFrame, waiting for commin back. |
tds_redirected |
[State available only when using 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. |
blik_redirected |
[State available only for BLIK payments]. Customer was redirected to the payment page to enter the BLIK code. |
transfer_redirected |
[State available only for BLIK transfers]. Customer was redirected to the payment page to make a transfer. |
link Possible rejection reasons
linkGeneral information - reject_reason parameter
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 | |
insert card |
soft decline | Strong Customer Authentication (SCA) required for this client profile | If the payment was made with client profile, it needs to be proceeded again with SCA - to do this, retry with cof=storing parameter in the API request. |
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 |
please retry |
System failure, please re-attempt. | Temporary acquirer or issuer system malfunction. | 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. |
linkDetails concerning “issuer_response_code” parameter
The current table (MySQL dump) with the issuer_response_code and descriptions can be found in the “Download” section.
Codes
issuer_response_code
, after witch you sholud not try to charge again due to possible fraud or the lack of chance of success:04, 07, 12, 14, 15, 41, 43, 46, 57, R0, R1, R3 B14, B15, B41, B43, B54
linkCategory 1: Issuer will never approve (Reattempt Not Allowed).
Decline response codes that indicate the account never existed or has been permanently blocked including lost or stolen account numbers. This category also includes decline codes that indicate the account is valid however the transaction is not permitted due to permanent product/regulatory restrictions or transaction error conditions that prevent approval.
Response code | Meaning | Proposed message |
---|---|---|
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! |
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 account number (no such number) | Payment rejected by the issuer - invalid account number. Please use a different card or contact the issuer for clarification. |
15 | No such issuer | Payment rejected - no such issuer. Please use a different card or contact the issuer for clarification. |
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! |
46 | Closed account | Please use a different card or contact the issuer for clarification. |
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. |
R0 | Stop Payment Order | Payment rejected by the issuer - Stop Payment Order. Please contact the issuer for clarification. |
R1 | Revocation of authorization order | Payment rejected by the issuer - Revocation of authorization order. Please contact the issuer for clarification. |
R3 | Revocation of all authorizations order | Payment rejected by the issuer - Revocation of all authorizations order. Please contact the issuer for clarification. |
linkCategory 2: Issuer cannot approve at this time (Reattempt Allowed)
Decline response codes that indicate the Issuer may approve, but cannot do so now, perhaps due to temporary decline condition such as credit risk, Issuer velocity controls or other account restrictions. This cluster covers temporary decline decisions made by the Issuer that may change over time, and for which the Issuer would welcome a future authorisation attempt. In some cases, cardholder action is required to remove the restriction before an approval can be obtained.
Response code | Meaning | Proposed message |
---|---|---|
03 | Invalid merchant or service provider | REJECTED - Authorization’s Error. Please contact your card issuer and try again later. |
19 | Re-enter transaction | Payment rejected by the issuer. Please use a different card or contact the issuer for clarification. |
51 | Insufficient funds | REJECTED - Insufficient funds. Please check funds on your account and try again later. |
59 | Suspected fraud | REJECTED – Please contact your card issuer to get more details and try again later. |
61 | Exceeds approval amount limit | REJECTED – Please check settings of your account and configurations of limits. Please contact your card issuer 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 | VIsa: Activity count limit exceeded | Visa: 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. |
86 | Cannot verify PIN | Payment rejected by the issuer - cannot verify PIN. Please try again or contact the issuer for clarification. |
91,92,94,98 | Please retry | REJECTED - Refused by Issuer because Issuer is temporarily inoperative. Try again later. |
93 | Transaction cannot be completed - violation of law | Please use a different card or contact the issuer for clarification. |
E4 | 3D-Secure failure in bank. | REJECTED - 3D-Secure failure in bank. |
linkCategory 3: Data quality (Revalidate data prior to reattempt)
Decline codes that indicate data quality issues where invalid payment or authentication data has been provided and the Issuer may approve if valid information is provided.
Response code | Meaning | Proposed message |
---|---|---|
54 | Expired card | REJECTED - Expired card. Please check your card or try another. |
55 | Incorrect PIN or PIN missing | Płatność odrzucona - niepoprawny lub brakujący PIN. |
65 | Mastercard: soft decline | Mastercard: Soft decline - an authentication required.(SCA) |
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! |
1A | Visa: soft decline | Visa: Soft decline - an authentication required.(SCA) |
linkCategory 4: Generic response codes (Reattempt allowed)
This category includes all other decline response codes, many of which are caused by technical problems and provide little to no value to Merchants in determining their reattempt strategy.
Response code | Meaning | Proposed message |
---|---|---|
01,02 | Voice authorisation required | REJECTED - Authorisation Error. Please contact your card issuer. |
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 | Invalid amount or currency conversion field overflow | Payment rejected by the issuer - invalid amount or currency conversion field overflow. Please use a different card or contact the issuer to check the ecommerce payment settings. |
30 | Invalid data format | REJECTED – Please contact your card issuer to get more details and try again later. |
E3 | Incorrect 3D-Secure verification | REJECTED - Incorrect 3D-Secure verification or another error. Please try again later. |
E5 | 3D-Secure error | REJECTED - Temporary 3D-Secure error. Please try again later. |
Additional category, containing response codes unrelated to rejections by card issuers. Contains codes related to payment aproval and rejections by Acquirer/Espago.
Response 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. |
85 | Successful approval/completion | Transaction approved, thank You! |
B04, B14, B15, B41, B43, B54 | Abort | The payment has been blocked by Espago, due to an inactive or stolen card. Please update the customer profile with a altered card. |
B46 | The payment has been blocked by Espago - closed account | Please use a different card or contact the issuer for clarification. |
B1A, B65 | Abort | The payment has been blocked by Espago, due to a missing SCA identificator - Strong Customer Authentication (SCA) required. |
E1 | Refusal limit exceeded | The payment has been blocked by Espago due to exceeding the limit of rejected retries and the risk of additional fees from the operator. Please use a different card or contact the Merchant. |
Q1 | Transaction blocked on acquirer level due to suspected fraud. The rejection code assigned by the acquirer is returned in the reject_reason parameter. | The payment has been blocked by acquirer due to suspected fraud. |
Q2 | An error occurred while communicating with the acquirer’s system. Additional error information may be returned in the reject_reason parameter. |
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": "description:invalid_length",
"message": "Description should be between 5 and 255 characters, was: 0",
"param": "description",
"type": "invalid_request_error"
}
]
}
Response when the token has already been used
{
"errors": [
{
"code": "card:token_not_found",
"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": "card:blank",
"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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send(
'api/charges',
method: :post,
body: {
card: 'cc_7724fuzWy0SYasoLV',
amount: 49.99,
currency: 'pln',
description: 'Opis transakcji',
complete: false
}
)
puts response.body
$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¤cy=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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
payment_id = 'pay_8a1Wx0ggKxvxxmv1'
response = client.send(
"api/charges/#{payment_id}/complete",
method: :post,
body: {
amount: 35
}
)
puts response.body
$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 a pending 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 12:00AM CEST). 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 a pending 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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
payment_id = 'pay_8a1Wx0ggKxvxxmv1'
response = client.send "api/charges/#{payment_id}", method: :delete
puts response.body
$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
linkDisplaying the data of a single charge
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
payment_id = 'pay_8a1Wx0ggKxvxxmv1'
response = client.send "api/charges/#{payment_id}", method: :get
puts response.body
$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,
"card": {
"company": "VI",
"last4": "4242",
"year": 2024,
"month": 9,
"first_name": "Adam",
"last_name": "Nowak",
"authorized": null,
"created_at": 1612977801
},
"issuer_response_code": "00",
"reversable": true,
"transaction_id": "tr_771EQhf18",
"reference_number": "Test_doc"
}
linkDisplaying groupes of charges
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
response = client.send(
'api/charges',
method: :get,
body: {
client: 'cli_772YYE_98HM1DmAD',
page: 1,
per: 5,
}
)
puts response.body
$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"
},
. . .
]
}
link HTTP Response Codes
Successfully processed API Requests receive a response with HTTP code 200 (OK).
Responses with codes 4xx and 5xx indicate errors in processing the API request and should not be interpreted as rejected transactions.
.
HTTP error codes:
HTTP 401
A response to incorrect authentication data in the API request.
Example
{
"error":"Invalid authentication credentials."
}
HTTP 422
It is a result of an integration error. It occurs when the data contained in the request is incorrect and cannot be processed. The error message indicates the data that prevents the processing of the request.
Example
{
"errors":[
{
"code":"currency:invalid_currency",
"message":"Currency is not a valid ISO 4217 currency",
"param":"currency",
"type":"invalid_request_error"
}
]
}
HTTP 500
Responses with code HTTP 500 indicate temporary technical issues Espago’s or Acquirer’s side.
Occurences of this error code should be reported to Espago’s Support.
Example
{
"error":"Something went wrong"
}
Charge attempts resulting in HTTP 500 status code or ending with a “failed” status should be treated as unsuccessful due to temporary technical issues and reattempted. In such cases, even if the charge is succesful despite the technical problems, it will be automatically reversed/refunded.
Recurring Payments autorenew
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 |
---|---|
|
|
This chapter describes payments handled by the Merchant. More on Espago subscriptions can be found: here.
link How recurring payments work
- The merchant initiates a payments with
cof=storing
, (which creates a new client profile with the credit card data) and optionalauthentication_ind
, and receives the client ID and confirmation of payment’s execution or a redirection URL (SCA: 3D-Secure). Amount of this initial transaction should be the same as later recurring amount, or (ex. in case of free trial): 0 amount. - 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).
- 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 SCA/3D-Secure. | Since 01.01.2021 each subscription or storing card for delayed/recurring payments need start with a payment with SCA. This first payment should be with the amount of later recurring payments or “0” - this is the authorization without charging customer. |
You should not reverse/refund payment with SCA/3D-Secure which initialised recurring payment. | If you need to do trial-free period, you should consider payment on “0” USD/EUR. Reversing first/SCA payment may be seen by Bank as resignation of customer, and may occur in rejection of subsequent recurring payments. |
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.
It would be inconvenient for both the Seller and the Customer to successfully add a card and make the first payment (with SCA) and after a month it turns out that no further payments with this card are possible.
To avoid such a situation, it is worth to do immediately after adding the card (payment with
cof = storing
and strong authentication 3D-Secure) preauthorization with the parametercof = recurring
. After successful preauthorization (state = preauthorized
), it can be withdrawn and the customer’s card is considered suitable for recurring payments.
It is also important to ensure that recurring/cyclic transactions (where is no longer used CVV/CVC code) were marked with the parameter cof=recurring
. Many banks/issuers will reject normal internet payment if there is no CVV/CVC ando 3D-Secure, but will accept recurring/cyclic payment. Since 1 January 2021 this behavior will apply to all European banks.
Step | Function | Description |
---|---|---|
1 | Initial payment with saving of customer profile | The Merchant triggers a payment with the parameter cof = storing , for the amount that will later be a recurring charge or or amount of 0 USD/EUR/etc. It is expected that the customer will have to pass 3D-Secure verification. ** PAYMENT SUCCESSFUL: ** card supports internet payments, you can go to step 2. This payment should not be deleted / refunded. After successful payment, the customer profile cli_xxxxxxxxxx remains for later use. ** PAYMENT FAILURE: ** the card does not support online payments, so another charge attempt will certainly not be successful ^ 1,3 |
2 | Creation of subscription First charge Second authorization or preauthorization |
Create a subscription (with automatical charge) or making of the first payment (if recurring is handled by the Merchant) or requesting another preauthorization 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 (issuer_response_code=51
) 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 (MIT) - standing instructions
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 (MIT) - 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;
Espago subscriptions poll
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:
- Access this subpage
- Click “Edit” to see the details
- Set up the back request URL (more on this under “Back request”)
- 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.
linkCreating a new plan
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
response = client.send(
'api/plans',
method: :post,
body: {
description: 'plan description',
period_unit: 'month',
period: 1,
amount: 50,
currency: 'pln'
}
)
puts response.code
puts response.body
$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¤cy=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
}
linkFetching plan data
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
plan_id = 'pl_8a1W3P6xTXOZ4epTp'
response = client.send "api/plans/#{plan_id}", method: :get
puts response.code
puts response.body
$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
}
linkDeleting plans
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
plan_id = 'pl_8a1FInbtEadoX0PER'
response = client.send "api/plans/#{plan_id}", method: :delete
puts response.code
puts response.body
$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);
Status: 204 NoContent
linkUpdating an existing plan
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 planNotice
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
plan_id = 'pl_8a1FInbtEadoX0PER'
response = client.send(
"api/plans/#{plan_id}",
method: :put,
body: {
description: 'updated plan description',
period_unit: 'month',
period: 1,
amount: 75,
currency: 'pln'
}
)
puts response.code
puts response.body
$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¤cy=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);
Status: 204 No Content
linkDisplaying a list of plans
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
response = client.send 'api/plans', method: :get
puts response.code
puts response.body
$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.
linkCreating a new subscription
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 |
channel | Payment channel | Optional - by default is set to the service payment channel Available values: elavon_cc , worldline_cc , polcard_cc . |
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
response = client.send(
'api/subscriptions',
method: :post,
body: {
client: 'cli_772YYE_98HM1DmAD',
plan: 'pl_8a1trIGa-EMTQN1VI'
}
)
puts response.code
puts response.body
$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.
linkCreating a subscription with a delayed start
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.
linkFetching subscription data
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
subscription_id = 'sub_8a1xsjIpXYYlKFzF'
response = client.send "api/subscriptions/#{subscription_id}", method: :get
puts response.code
puts response.body
$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
}
}
linkStopping a subscription
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
subscription_id = 'sub_8a1FXEDVNMINvTOS'
response = client.send "api/subscriptions/#{subscription_id}", method: :delete
puts response.code
puts response.body
$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);
status: 204 No Content
linkDisplaying a list of active subscriptions
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
response = client.send(
'api/subscriptions',
method: :get,
body: {
page: 1,
per: 5
}
)
puts response.code
puts response.body
$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,
}
}
]
}
linkDisplaying active subscriptions of a client
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
client_id = 'cli_772YYE_98HM1DmAD'
response = client.send(
"api/clients/#{client_id}/subscriptions",
method: :get,
body: {
page: 1,
per: 5
}
)
puts response.code
puts response.body
$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.
linkDisplaying all invoices of a client
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
client_id = 'cli_772YYE_98HM1DmAD'
response = client.send "api/clients/#{client_id}/invoices", method: :get
puts response.code
puts response.body
$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 |
linkManual payment for the invoice
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 invoiceNotice
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
invoice_id = 'in_7728vjvj-BdSK0B64'
response = client.send "api/invoices/#{invoice_id}/pay", method: :post
puts response.code
puts response.body
$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
.
linkDisplaying invoice data
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
invoice_id = 'in_7728vjvj-BdSK0B64'
response = client.send "api/invoices/#{invoice_id}", method: :get
puts response.code
puts response.body
$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
linkCreating a new invoice item
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
response = client.send(
"api/invoice_items",
method: :post,
body: {
currency: 'pln',
date: 1764363614,
amount: 100,
client: 'cli_772YYE_98HM1DmAD',
description: 'Opis transakcji'
}
)
puts response.code
puts response.body
$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
}
linkFetching information about the items in an invoice
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
invoice_id = 'in_7728vjvj-BdSK0B64'
response = client.send "api/invoices/#{invoice_id}/line_items", method: :get
puts response.code
puts response.body
$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
}
]
}
linkDeleting an existing invoice item
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
invoice_id = 'in_7728vjvj-BdSK0B63'
response = client.send "api/invoices/#{invoice_id}", method: :delete
puts response.code
puts response.body
$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);
204 "No content"
Back requests receipt
link Configuration
linkTypes of back requests
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.
linkConfiguration in the Merchant Panel
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.
linkConfiguration by an API Request
Using the following PUT request, you can edit the settings related to back requests:
- The URL where the request should be sent
- The username and password that you want to use to authenticate the request in your system
curl -i https://sandbox.espago.com/api/back_request_settings \
-X PUT \
-H 'Accept: application/vnd.espago.v3+json' \
-u your_app_id:your_api_app_password \
-d "url=https://example.espago.com/" \
-d "login=MyLogin" \
-d "password=MyPassword"
{}
{
"url": ["is invalid or not responding"]
}
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 |
object | 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. | |
tds_status_reason |
Code which siginfies the reason behind the status of the 3D-Secure 2 authorization. More detailed descriptions of these codes can be found in the Downloads section as 3D-Secure status codes . |
|
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/object | 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. |
liability_shift |
Available only for the worldline_cc payment channel |
Boolean. The liability_shift=true parameter indicates the liability shift to the card issuer in the case of fraud-related chargebacks. |
trace_id |
Available only for the worldline_cc payment channel |
ID of an SCA transaction, which serves as evidence of its completion. This ID is sent to the bank as part of the authorization data for MIT payments (payments without cardholder’s involvement). |
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:
- 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.
- 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.
- 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.
- Through the use of the token received from Espago (or from the client), the Merchant’s service can carry out a payment.
{
"subject": "card",
"id": "cc_7762MqOeLF1iVw7fD",
"created_at": 1571170086,
"used": false,
"card": {
"company": "VI",
"last4": "4242",
"year": 2020,
"month": 2,
"first_name": "Jan",
"last_name": "Kowalski",
"authorized": null,
"description": "Client_1234567890",
"created_at": 1571170086
},
"description": "Client_1234567890"
}
Refunds undo
link Refund of a settled Charge
In current chapter described is only the refund of a settled charge. If you want to reverse a 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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
payment_id = 'pay_315gfsdf234'
response = client.send(
"api/charges/#{payment_id}/refund",
method: :post,
body: {
amount: 100
}
)
puts response.code
puts response.body
$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"
}
link Refund without a previous ecommerce payment
The following chapter describes refunds without prior ecommerce payment. If you want to learn about refunds of existing payments, go here.
A refund without a prior ecommerce transaction occurs by sending a POST request to the address
https://sandbox.espago.com/api/refunds
.
The preferred method of refund is to refer to a previous transaction. Refunds without an ecommerce transaction may be applicable in situations where the original transaction was made on a physical payment terminal and the Espago gateway does not have its data.
Request body
Parameter | Description | Required |
---|---|---|
amount |
Amount to be refunded | Required |
currency |
Three-letter currency code in the ISO 4217 standard. | Required |
description |
The description of the refund (5 to 255 characters). | Required |
channel |
The channel that will be used to process the refund. Supported values: elavon_cc , elavon_eisop |
Required |
custom_order_id |
An identifier that will appear in the settlement file. | Optional |
eisop_token |
An eisop_token object that contains the data of the EISOP token that will be used to process the refund. |
Conditional |
card |
ID of an existing card token in Espago, with which the refund will be processed. Mandatory if client or eisop_token is not provided. |
Conditional |
client |
ID of an existing client profile in Espago, with which the refund will be processed. Mandatory if card or eisop_token is not provided. |
Conditional |
The eisop_token
object
Parameter | Description | Required |
---|---|---|
token |
EISOP token number | Required |
card_year |
Expiration year of the customer’s card in the numerical format YYYY. | Required |
card_month |
Expiration month of the customer’s card in the numerical format MM | Required |
Important response parameters
Parameter | Description | Notes |
---|---|---|
id |
The identifier of the refund. | |
state |
The state of the refund | After a successful refund, the value should be "refunded" or "refund_executed" . Other values include "refund_rejected" and "failed" |
refunded_amount |
The refunded amount. | |
issuer_response_code |
Rejection code | Code indicating the reason for rejecting the refund attempt. |
Example request
curl -i https://sandbox.espago.com/api/refunds \
-X POST \
-H 'Content-Type: application/json' \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d '{ "amount": 10, "currency": "PLN", "channel": "elavon_eisop", "description": "docs test refund", "eisop_token": { "token": "BEYOVBGIVPBX0006", "card_year": "2025", "card_month": "12" } }'
require 'net/http'
require 'uri'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
payment_id = 'pay_315gfsdf234'
response = client.send(
"api/charges/#{payment_id}/refund",
method: :post,
body: {
amount: 10,
currency: "PLN",
description: "docs test refund",
eisop_token: {
token: "BEYOVBGIVPBX0006",
card_year: "2025",
card_month: "12"
}
}
)
puts response.code
puts response.body
{
"id": "pay_COy6zH9fLj1d7K",
"channel": "elavon_eisop",
"refunded_amount": "10.0",
"currency": "GBP",
"state": "refunded",
"created_at": 1381823580,
"eisop_token": {
"token": "xxx",
"token_type": "xxx",
"last4": "xxxx",
"year": "YYYY",
"month": "MM",
"company": "CC"
},
"issuer_response_code": "XX",
"transaction_id": "xxx"
}
Client Profile accessibility_new
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 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 |
Issuer response code | If authorized=false, then this parameter will contain the rejection code (issuer_response_code) |
created_at |
(number) | Time in unix format |
sca_payment |
object | Array of information about initial transaction which starts recurring (first or lattest payment with cof=storing on this client profile). This payment details will be sent to Bank in as reference in recurring payments. Example: "sca_payment": { "id": "pay_aaaaaaaaaaaa", "amount": "19.00", "updated_at": 1605775020, "client": "cli_xxxxxxxxxxxxxxx" } |
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
response = client.send(
"api/clients",
method: :post,
body: {
description: 'Jan Kowalski',
card: 'token_id'
}
)
puts response.code
puts response.body
$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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
response = client.send(
"api/tokens",
method: :post,
body: {
card: {
first_name: "Jan",
last_name: "Kowalski",
month: "02",
number: "4242424242424242",
verification_value: "123",
year: "2030"
}
}
)
puts response.code
puts response.body
// 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 the token details
You can get the following details of the tokenized payment card:
- issuer country code
- bank name (but only Polish banks)
- currency code
- card type
In order to turn on this feature, please contact the Espago support.
In some cases, checking the card details takes over 1 s.
To check the tokenized card details send a
POST
request tohttps://sandbox.espago.com/api/tokens/(:id)/check_type
(:id) - id of the card 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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
token_id = 'cc_8a1IcKzD4NzD7httF'
response = client.send "api/tokens/#{token_id}/check_type", method: :post
puts response.code
puts response.body
$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":2026,
"month":2,
"first_name":"John",
"last_name":"Smith",
"authorized":true,
"card_type":"D",
"country":"HKG",
"currency":"HKD",
"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-letter country code defined in ISO 3166-1 alpha-3. U - no info |
currency |
Card currency | 3-letter country code defined in ISO 4217. U - no info |
bank |
Bank’s name | Bank’s name U - no info |
link Profile editing
linkCustomer profile deletion
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 \
-H 'Accept: application/vnd.espago.v3+json' \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD
require 'net/http'
require 'uri'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
client_id = 'cli_8a1IcKzD4NzD7httF'
response = client.send "api/clients/#{client_id}", method: :delete
puts response.code
puts response.body
$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');
$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);
We send a response of: Status 204: no content
linkUpdating an existing customer
Update an exisitng customer by sending a PUT request to
https://sandbox.espago.com/api/clients/(:id)
where (:id)
is the Id of the client that you want to udpate (example path: /api/clients/cli_xxxxxxx)
Send the same parameters as when creating a customer profile, at least one needs to be different:
* email [optional]
* description [optional]
* card=token_id
when card is updated
WARNING
Just like in customer profile creation, submitting a card’s token id is the required method (created before sending an update request) If (in case of a Merchant with PCI certification) any of the card’s details are updated, you need to send a complete set of the card’s data (Even if only a single parameter is changed).
After updating card data there is no way to get back to revert this process. If you want to make it possible to submit a new card, only if it functions properly and deleting the old one thereafter, you may 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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
client_id = 'cli_772YYE_98HM1DmAD'
response = client.send(
"api/clients/#{client_id}",
method: :put,
body: {
description: 'Jan Kowalski',
email: 'client@example.com',
card: {
first_name: 'Jan',
last_name: 'Kowalski',
number: 4242424242424242,
verification_value: 123,
year: 2025,
month: 02
}
}
)
puts response.code
puts response.body
$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
}
link Fetching profiles
linkDisplaying existing customers’ data
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
client_id = 'cli_772YYE_98HM1DmAD'
response = client.send "api/clients/#{client_id}", method: :get
puts response.code
puts response.body
$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,
"created_at":1561126879
},
"deleted":false",
"sca_payment": {
"payment_id": "pay_772bLKUDa1sdfsd",
"amount": "0.00",
"channel": "elavon",
"updated_at": 1561126879,
"client_id": "cli_772q8GcejiQfRl4z"
}
}
linkDisplaying a group of customers
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
response = client.send(
"api/clients",
method: :get,
body: {
page: 1,
per: 5
}
)
puts response.code
puts response.body
$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, is not expired and that the bank account has funds.
- If authentication fails, it means that it is almost certain that the next payments will also fail (except for a rejection due to a temporary lack of funds or reached transaction limit of the day).
In Espago’s web panel you can set automatic authorisation on client profile creation. 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 transaction fails. 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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
client_id = 'cli_772YYE_98HM1DmAD'
response = client.send "api/clients/#{client_id}/authorize", method: :post
puts response.code
puts response.body
$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. |
client[email] |
check (unless the email parameter is provided) |
Client Profile’s e-mail address | Client’s E-mail address required for 3D Secure authentication. Additionally a notification about the charge’s result will be sent to this address. |
email |
check (unless the client[email] parameter is provided) |
Client’s E-mail address | Client’s E-mail address required for 3D Secure authentication. Additionally a notification about the charge’s result will be sent to this address unless the skip_email parameter is present. 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 |
Disables email notifications - even if you send a request charge with a customer profile with an email address. Boolean (false/true, default: false). | Allows to disable the notification sent by Espago in the form of an email - even if a Client Profile with a saved email address was used for the payment or the email parameter was passed in the charge request. Note: if the notification sent by Espago is disabled, the obligation to send a notification to the customer lies with the Merchant. | |
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
response = client.send(
"api/clients/card_page",
method: :post,
body: {
client: {
description: "Jan Kowalski id:321",
email: "test@example.com"
},
check: "recurring",
store: "recurring",
title: "Card for future subscription for the radio ABC"
}
)
puts response.code
puts response.body
$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 client card information
You can get the following details of the payment card assigned to the client’s profile:
- issuer country code
- bank name (but only Polish banks)
- currency code
- card type
In order to turn on this feature, please contact the Espago support.
In some cases, checking the card details takes over 1 s.
To check the card details, send a
POST
request tohttps://sandbox.espago.com/api/clients/(:id)/check_type
(:id) - id of the requested client’s profile.
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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
client_id = 'cli_772YYE_98HM1DmAD'
response = client.send "api/clients/#{client_id}/check_type", method: :post
puts response.code
puts response.body
$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":2026,
"month":2,
"first_name":"John",
"last_name":"Smith",
"card_type":"D",
"country":"HKG",
"currency":"HKD",
"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-letter country code defined in ISO 3166-1 alpha-3. U - no info |
currency |
Card currency | 3-letter country code defined in ISO 4217. U - no info |
bank |
Bank’s name | Issuer bank name. U - no info |
Submitting CVV Numbers vpn_key
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.3.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.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'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD'
response = client.send(
"api/charges",
method: :post,
body: {
amount: 10,
currency: 'pln',
client: 'cli_772YYE_98HM1DmAD',
description: 'Espago docs',
cvv: 'cv_772oAPNIwkEZlEIPo'
}
)
puts response.code
puts response.body
$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¤cy=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.3. 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.3.js
Demo: https://github.com/espago/espago-1.3.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.3.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()
})
Espago Terminals payment
link What is Espago Terminals
Espago Terminals allows integration of physical payment terminals with a sales system accessible through browser. The integration involves sending payments to the terminal via API request and the sales system receiving information about the status of the transaction. It also allows for executing a refund initialized by sales system.
Standard integration can be extended with functionality that allows the transaction ID received from the terminal to be linked with the client in the merchant’s system, and based on that, the client card can be re-charged without its physical presence (as long as the merchant’s terms and conditions allow for it).
The usage of the Espago Terminals is consistent with Espago API (used in e-commerce, e-invoicing and recurring services), since after payment is made on the terminal and Espago Terminals obtains client profile, all future proceedings are being made in the same way on Espago gateway based on that profile.
For implementation purposes Espago prepared simulation of a physical terminal, due to this feature integration partner does not need access to actual test physical terminal as well as test payment cards.
link Application scope of Espago Terminals
Due to nature of payment terminals operations, Espago Terminals has several technical limitations:
1. The computer (later referred to as POS) from which payment will be sent must be directly connected to the same LAN network as the terminal.
2. POS must have one of the following operating system: Android (phone or tablet), or Windows.
3. POS must have a dedicated Espago Terminals application installed (Download).
4. Espago Terminals only work with certain acquirers. For more information, please contact sales@espago.com.
Espago Terminals application
Our application was created with transaction security purposes in mind, and without it our solution will not work properly. It is used for direct communication between our API and the payment terminal.
No additional software or special configuration is needed besides installing said application. The extension was created in such a way that it does work in background - with other app in focus and is booting up with OS.
The extension is available in the Download section. Link
link Integration
After getting access to the account from support staff, log in at https://terminals-beta.espago.com/users/sign_in. After that, it is recommended to change your password. This can be done in your account panel - it is located under the “account” tab in the bottom left corner.
In the next step, go to “Service” tab. There you will be able to find your test service.
In Espago Terminals, each user can have multiple services; service can have multiple terminals, but each service has its own separate API access, and they cannot share any information nor share any terminals each other.
After selection your service, click “Edit Service” button and set API access password - it must not be shared to any third party. Also, you should specify back_request_url
- parameter that specifies an address to which a back request will be sent with transaction information after it has been executed, as well as basic auth login and password used for authorizing back requests.
The final step is terminals configuration. To do this, from service view, you should select “View Terminal” on the terminal you want to configure. Choose name to your liking - convenient for integrator. Key parameters for basic configuration are LAN IP address and port on which terminal will listen. At the stage of integration into the test environment, these parameters are not relevant for making payments work properly.
After this configuration, you can start sending requests to Espago Terminals gateway according to the instructions in following sections. Espago also provides a tool to preview requests that are being sent to the gateway. These are located in Api Requests tab.
link Espago Terminals apps
linkInstallation and general information
In order to use the services we offer, it is necessary to install one of the dedicated applications for this purpose. They will serve as an intermediary in the communication of the payment terminal with our API. These applications are available for computers running Windows and Android phones. Application of our choice can be downloaded in the Download section. Link
The installer guides us through the entire installation process, which includes only two steps:
1. Choosing for whom to install the application (current user / all users)
2. Path under which the application will be installed
After installation, the application will be added to the system autostart, so that, when the computer is restarted, we do not have to start it manually. It also works completely in the background, so we will not see its window at startup. If we want to display the application’s window, expand tray (system tray) in the taskbar, then left-click on the white Espago Terminals icon. To avoid accidentally closing the application with the X button, its behavior has been changed, so that trying to close the application this way will only minimize it to the tray.
Right-clicking on the icon will display additional actions.
* Force reload - forces a restart of the application’s connection to the Espago cloud and payment terminal.
* Disable Virtual Terminal - disables / enables the capture of sent payments by the virtual terminal.
* Quit - forces a complete shutdown of the application.
linkConfiguration
Before the application is ready to work, we need to enter the settings panel by clicking on the gear located in the upper right corner of the window, and then enter the following information to the application:
* TID - ID of the terminal we want to connect.
* API login - login to API for your service.
* API password - password to API for your service.
The above data are needed to connect to the Espago cloud and the terminal. Without them, the application will not work properly!
We can access the above information in our service panel. Note that if we don’t have the API password set, it should be done by going to Service → Edit Service → Edit Passwords.
linkSandbox mode
Currently, this mode is only available on Windows applications.
It should only be used for development purposes, when trying to connect to our API.
For integration purposes, an option has been added that switches the application to Sandbox mode. This mode changes the environment with which the application and the terminal communicate. To enable said mode, set the switch described as “Run in sandbox mode ” in the application settings, so it turns yellow. In order to avoid confusion as to what mode the application is running in, a special message will appear in the main view of the application indicating that Sandbox mode is enabled.
You need to remember to check the data of the service and the terminal you are trying to communicate with, as these can vary from environment to environment.
Payment state in Sandbox mode
The payment state for any charge made in the Sandbox mode can be controlled with the decimal value of its amount.
The paymennt state will take the value:
-
success
if the amount’s decimal value is equal to 00 (e.g.10.00
) -
failed
if the amount’s decimal value is not equal to 00 (e.g.10.01
)
linkWindows
More multiple user accounts at one device
If your setup include more than one user account, you need to change Login settings for all users (Microsoft documentation) . To do this, you need to Settings, find position Sign-in options, and under Privacy ensure that “Use my sign-in info to automatically finish setting up my device and reopen my apps after an update or restart.” option is disabled. Without this Espago Terminals app will not be working properly.
link Espago Terminals in action
1. Request with data to perform the transaction
Sending a request to Espago Terminals API with terminal data and transaction information to terminals.espago.com/api/charges
.
{
"amount": 12.00,
"currency": "EUR",
"description": "Payment #5656",
"terminal": "1234567",
"kind": "mobile"
}
2. Response
After submitting the correct data, Espago Terminals will send payment on terminal, and respond with information about the created payment.
{
"payment_guid": "tp_4455rgT6Ve",
"state": "sent"
}
When the terminal is not connected or wrong params are provided, then the error message will be given.
3. Sending payment to the payment terminal
After successful API request the transaction will be sent immediately. At this moment client can pay on device, according to terminal payment instructions.
4. Response with transaction status
Once the transaction is completed, the status of transaction will be displayed on the terminal. Transaction information will be sent to the address provided as a back request.
{
"payment": {
"id": "tp_7d7z-noWFPW",
"description": "Payment #5656",
"state": "success",
"amount": "12.00",
"currency": "EUR"
}
}
link Charge parameters
A new payment on the terminal is made by sending a POST request to https://terminals.espago.com/api/charges. Just like in the standard Espago API, the request must be authorized using the
Authorization
header with the valueBasic app_id:password
.
The following parameters are available:
Parameter | Description | Mandatory | Comment |
---|---|---|---|
terminal |
TID | Yes | Tid of the terminal to which the payment is to be sent. |
description |
Transaction description | Yes | Must be 3 to 255 characters. It should be used to associate the payment with the customer of the service. |
amount |
Transaction amount | Yes | Positive decimal number, e.g. 123.45. |
currency |
Currency | Yes | A three-letter abbreviation according to the currency accepted by the terminal. |
kind |
Transaction type | Yes | Has to be "mobile" string, otherwise payment will not be sent on terminal |
fetch_client |
Customer object | No | A value of true will result in the passing of the customer object in the back request. |
In response, Espago Terminals will send a link to redirect the POS computer or, in the case of an invalid request, its reason.
link Back requests params
After the payment is completed, Espago Terminals sends information about its status.
Sample response:
{
"payment": {
"id": "tp_7d7z-noWFPW",
"description": "Order #55665",
"state": "success",
"amount": "12.99",
"currency": "PLN"
},
"client": {
"id": "cli_7d7Cm9pP61YyvOKZ",
"card": {
"full_name": "Myrna Cummings",
"company": "VI",
"last4": "0002",
"year": "2024",
"month": "12",
"country_code": "en"
}
}
}
Parameter | Description | Notes |
---|---|---|
payment |
Payment data | |
payment id |
Payment ID | As assigned by Espago Terminals |
payment description |
Description of the payment | Provided by the merchant at the time of payment creation |
payment state |
Payment status | A value other than success means failure |
payment amount |
Payment amount | |
payment currency |
Payment currency | |
client |
Client data | Returned only if fetch_client=true |
client id |
Id of client profile in Espago | |
client card |
Data of the card assigned to the profile | |
reject_reason |
Reason for rejecting payment | This parameter is only sent if the transaction fails |
link Payment rejected - reject_reason parameter
The reject_reason parameter contains a general infromation about payment rejection or refusal from the payment terminal. It is included in the response only when the payment status is failed. Returned together with payments via back requests and API request. It contains information about: name, message and description of the error. It is strictly informative to help locate a possible error.
{
"payment": {
...,
"state": "failed"
},
"reject_reason": {
"name": "declinedWrongPin",
"message": "Authorization declined - Wrong PIN",
"description": "Authorization failed, cardholder entered wrong PIN."
}
}
link Payment status
Espago Terminals logs all communication with the terminal and all necessary information about the payment, including its status. You can view this information in the panel at https://espago.terminals.com/manage, but in case of ambiguity, the information on the terminal screen is always the superior source of information.
Possible payment states on the terminal:
State | Description |
---|---|
new |
Payment created on Espago Terminals service, but the link assigned to it has not been used. |
sent |
Payment sent to the terminal, awaiting completion. |
success |
Payment completed, customer account was charged. |
failed |
Payment failed. |
link Recuring payments on terminal
Recuring payments based on the first transaction made on the terminal are very simple to implement, especially if the merchant already has integration with Espago’s standard payment gateway.
In order to get the transaction reference after the payment when it is created via a request on endpoint /api/charges
, the fetch_client
parameter should be added and given the value true
. Then, when the payment is successful in the back request, we will get the client object with the id
parameter.
{
"payment": { ... },
"client": {
"id": "cli_7d7Cm9pP61YyvOKZ",
"card": {
"full_name": "Myrna Cummings",
"company": "VI",
"last4": "0002",
"year": "2024",
"month": "12",
"country_code": "en"
}
}
}
After a successful payment, Espago Terminals creates a client profile for the standard Espago gateway. ID means the ID of the profile, which can be specified instead of the token (client: ...
) in the payment creation parameters and can be used in the same way as a regular client profile created by a regular request to the Espago gateway.
You can read more about the client profile in client profile.
link Fetching client profile after payment was made
It is possible to get a client after making a payment with a status of success
, even if the fetch_client
parameter has not been set to true
. This request can be especially useful for a payment that was made on the terminal, but for some reason the card data could not be extracted, and the client profile could not be created, although we would like to get it.
To do this, send a standard POST
request to endpoint /api/payment/fetch_client
with the parameter
Example request.
{
"payment": "tp_3452342"
}
Example response.
{
"client": {
"id": "cli_83cSYFUwtQQ4Nd72",
"card": {
"full_name": "Gayle Erdman",
"company": "VI",
"last4": "0002",
"year": "2025",
"month": "12",
"country_code": "en"
}
},
"status": "ok"
}
link Terminal status
It is possible to get terminal data and its current status from API.
To do this, send a standard POST
request to endpoint /api/terminal
with the terminal
parameter indicating the terminal’s TID.
The
connection
parameter indicates the status of the terminal’s connection to the cloud via the native application. If integrating via a browser extension, ignore this.
Example request.
{
"terminal": "238409245"
}
Example response.
{
"tid": "238409245",
"ip": "192.168.0.2",
"port": "7784",
"name": "reception-2",
"updated_at": "1628548083",
"connection": {
"connected": true,
"busy": false
}
}
link Getting transaction data
It is possible to pull the payment data and its current status through the API.
To do this, send a standard POST
request to endpoint /api/payment
with parameter payment
indicating the payment id (tp_....
).
Example request.
{
"payment": "tp_83cePB345fg"
}
Example response.
{
"guid": "tp_83cePNfN04b",
"description": "order #345323",
"state": "success",
"amount": "15.99",
"currency": "EUR"
}
~~~
link Refund payment executed on terminal
To execute refund on successfully charged payment, you need to send a POST request on https://terminals.espago.com/api/charges/(payment id)/refunds
, and provide amount in JSON body.
Note: For complete emulation in sandbox environment, odd number of decimal points will result as failed transaction.
Example request:
/api/charges/tp_456xyz/refunds
{
"amount": 5.99
}
Response:
{
"id": "tp_456xyz",
"refunded_amount": "5.99",
"state": "refunded"
}
Espago.js web
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.3.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.3.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.3.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.3.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 thesubmit
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
Google Pay™ payment
link Description
Google Pay allows buyers to make a fast and simple checkout without having to enter credit card data.
Card data is stored securely by Google.
There are two ways of implementing Google Pay support:
1. Using our Hosted Checkout solution – Espago Secure Web Page
2. Using Google Pay API on the Merchant’s domain and sending the received token to the Espago API with a POST
request to /api/charges
All Merchants must adhere to the Google Pay APIs Acceptable Use Policy and accept the terms defined in the Google Pay API Terms of Service.
link Hosted Checkout
Google Pay can be handled entirely by Espago if you redirect the cardholder to Espago Secure Web Page.
In order to enable this feature one should contact the Espago support team.
Test payments
In the Sandbox environment the decimal value of transaction can be used to define the Secure Webpage simulated payment scenario.
Decimal value | Payment scenario |
---|---|
n.00 | successful with cryptogram, no 3D Secure |
n.01 | successful PAN_ONLY, 3D Secure Challenge |
n.02 | successful PAN_ONLY, 3D Secure Frictionless |
n.10 | rejected with cryptogram |
n.11 | rejected PAN_ONLY, 3D Secure Challenge |
n.12 | rejected PAN_ONLY, 3D Secure Frictionless |
n.66 | incorrect gatewayMerchantId |
Where n is a natural number.
link Google Pay API integration
The integration itself is relatively simple:
1. Merchants integrates with the Google Pay API.
2. Buyer selects the Google Pay button on the Merchant’s website or mobile application.
3. Buyer finalizes the transaction and Google Pay returns the payment token to Merchant.
4. Merchant encodes the received token using base64 and sends it to the Espago API as a part of a POST
request to /api/charges
.
Google Pay API Web integration
In order to integrate your website with the Google Pay API, follow the instructions in the Google Pay API documentation for web applications, familiarize yourself with Google Pay web application brand guidelines and refer to Google Pay web application integration checklist.
Google Pay API Android integration
In order to integrate your Android application with the Google Pay API, follow the instructions in the Google Pay documentation for Android developers, familiarize yourself with GooglePay Android App Brand Guidelines and refer to Google Pay Android Integration Checklist.
Integration setup
In the code invoking the script, Merchant has to indicate the payment gateway and the Merchant ID. For the Espago gateway, the parameters take the following values:
gateway: 'espago',
gatewayMerchantId: '[merchant service app_id]'
For example:
const tokenizationSpecification = {
type: 'PAYMENT_GATEWAY',
parameters: {
'gateway': 'espago',
'gatewayMerchantId': 'ms_771eUTliRiZ'
}
};
Supported card networks
Amongst the card networks supported by Google Pay, Espago supports all Visa, Mastercard and JCB cards, which implies the following Google Pay API configuration:
const allowedCardNetworks = ["JCB", "MASTERCARD","VISA"];
link Transfer of encrypted payment data to Espago and a charge request
After recieving encrypted payment data from Google Pay, Merchant has to encode it using base64, then send them to the Espago gateway as the value of the googlepay
parameter.
A new charge is created after a POST request is sent to https://sandbox.espago.com/api/charges
The payment is initiated using the same parameters as in the case of charge parameters described in the chapter One-time payment. The exception is the new parameter googlepay
and the value of the channel
parameter, which must be equal to elavon_google_pay
.
Currently Google Pay is available only for Elavon integrations
For PAN_ONLY
payments, 3D Secure authentication is initiated automatically, similarly to card payments.
As a part of the API response, Merchant will receive a url address to redirect the customer (value of the redirect_url
parameter).
link Google Pay payload generator
There is a form that generates Google Pay payloads for use in the sandbox.espago.com environment.
link Charge example
{
"amount": 10,
"currency": "pln",
"channel": "elavon_google_pay",
"description": "Espago docs Google Pay",
"google_pay": "eyJwcm90b2NvbFZlcnNpb24iOiJFQ3YyIiwic2lnbmVkTWVzc2FnZSI6IntcImVuY3J5cHRlZE1lc3NhZ2VcIjpcInY4bmhGYVJVWmYveERJakhFcnAvOEc2WmdyK2xCcCt2N2cyL0MveXl4UmNhbGcwTElKUmF1NUljblVpYnZMMUh1UkdETTV2dVNYQUNxUG0yaSt3cFBBL0lrSzZvWko4WlNVdFFEcXc1K0RPY002a2ZJYy9jeUVtdmpXTWhVTkdDZkJ2dUF5RU0xeGk3dzU4MjNoVmhQemVUSk12K2YyYjZwQTAvZGZRZkpSWURjRVp1bjFWWGFFalRDdWFRcUVlV0x6RW81MDlBd25nOFJjYmFRelNzQXcwd0U4dUZsVDliRlY3cVc5N2svS3RuYTluYUdHR29UdmVaS3lKdDF4SmQ0NkhTRlkyNkN4WmxLRkppaGFLN2d4OW94RGVqVEE2VGtHL2tDd05keUZUQk4wSGY3ZEZUaUpEVkRiUklZOUtlalpkRXJwWnlQbHFES1luMWJSRytPSldWNGszWVhldmp6QWZoTmpzMWZyQ0dpTE5GeUtWa1RMRFl1enhOQWZobkQvZHpINVkyYkZUSnRqYmhOUFpNL3VmdmJMWjNTN1dKOVpuWFkxS2dyRlpNRFBzQkRjb3hjZE1nVmtMcVptQjVSNFZhUndDdm96M2JtcDhUd2tiVG5Vb2lndE5hQ29pclJ2TT1cIixcImVwaGVtZXJhbFB1YmxpY0tleVwiOlwiQk9IcXNPME55Z3NNQThFcHpyaGIyWTV5SjR0V3hjeU8wUmhJdTMyMmIvc1B0VE5uU3Q4RGlNUlVEZWx1WU5rbUZMcFJoeTg3blVPTTlNbk5KcVBhS3JzPVwiLFwidGFnXCI6XCJySU5Nay9DVjFjQUQzYVgwc2JOOSt2UEdjb1g4RGdzTHE0R0hld2NEMEw4PVwifSIsInNpZ25hdHVyZSI6Ik1FVUNJUUQ4ZkhSWG5kWFVjd2FpczltTW9Hd0QwSm90MlYvby9vOU41cG9JemRTS0V3SWdjdWw5RGhoSVppVGN3N2RrWisxUGtQbDlJZjBwNG1qamg5OVQvVXZZQ0NBPSIsImludGVybWVkaWF0ZVNpZ25pbmdLZXkiOnsic2lnbmVkS2V5Ijoie1wia2V5RXhwaXJhdGlvblwiOlwiMTc0MjgxMDMxNzAwMFwiLFwia2V5VmFsdWVcIjpcIk1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRWhtUzhlbWExdEFhQWtHWkVmMERKVllHM0d5T3FNenpxL2lZR3JLZHZGbWlOK2s2cGdOQWNoTzFXRlo1NUFtYzZwL1o4RU5CdlZ3MnRhai9EaDNDNGNnPT1cIn0iLCJzaWduYXR1cmVzIjpbIk1FUUNJQ012Vm9mUVpzVDFQSmZORHR4aHZwS1c4SHRWbFRKYXBwdkVFQjJMbURsdkFpQTBLZElCNVVjNmFsdTlXSmJpSHBGbWRyclFkaHZwZHV2YnlsN1JybGhSQXc9PSJdfX0="
}
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 "channel=elavon_google_pay"\
-d "description=Espago docs Google Pay"\
-d "google_pay=eyJwcm90b2NvbFZlcnNpb24iOiJFQ3YyIiwic2lnbmVkTWVzc2FnZSI6IntcImVuY3J5cHRlZE1lc3NhZ2VcIjpcInY4bmhGYVJVWmYveERJakhFcnAvOEc2WmdyK2xCcCt2N2cyL0MveXl4UmNhbGcwTElKUmF1NUljblVpYnZMMUh1UkdETTV2dVNYQUNxUG0yaSt3cFBBL0lrSzZvWko4WlNVdFFEcXc1K0RPY002a2ZJYy9jeUVtdmpXTWhVTkdDZkJ2dUF5RU0xeGk3dzU4MjNoVmhQemVUSk12K2YyYjZwQTAvZGZRZkpSWURjRVp1bjFWWGFFalRDdWFRcUVlV0x6RW81MDlBd25nOFJjYmFRelNzQXcwd0U4dUZsVDliRlY3cVc5N2svS3RuYTluYUdHR29UdmVaS3lKdDF4SmQ0NkhTRlkyNkN4WmxLRkppaGFLN2d4OW94RGVqVEE2VGtHL2tDd05keUZUQk4wSGY3ZEZUaUpEVkRiUklZOUtlalpkRXJwWnlQbHFES1luMWJSRytPSldWNGszWVhldmp6QWZoTmpzMWZyQ0dpTE5GeUtWa1RMRFl1enhOQWZobkQvZHpINVkyYkZUSnRqYmhOUFpNL3VmdmJMWjNTN1dKOVpuWFkxS2dyRlpNRFBzQkRjb3hjZE1nVmtMcVptQjVSNFZhUndDdm96M2JtcDhUd2tiVG5Vb2lndE5hQ29pclJ2TT1cIixcImVwaGVtZXJhbFB1YmxpY0tleVwiOlwiQk9IcXNPME55Z3NNQThFcHpyaGIyWTV5SjR0V3hjeU8wUmhJdTMyMmIvc1B0VE5uU3Q4RGlNUlVEZWx1WU5rbUZMcFJoeTg3blVPTTlNbk5KcVBhS3JzPVwiLFwidGFnXCI6XCJySU5Nay9DVjFjQUQzYVgwc2JOOSt2UEdjb1g4RGdzTHE0R0hld2NEMEw4PVwifSIsInNpZ25hdHVyZSI6Ik1FVUNJUUQ4ZkhSWG5kWFVjd2FpczltTW9Hd0QwSm90MlYvby9vOU41cG9JemRTS0V3SWdjdWw5RGhoSVppVGN3N2RrWisxUGtQbDlJZjBwNG1qamg5OVQvVXZZQ0NBPSIsImludGVybWVkaWF0ZVNpZ25pbmdLZXkiOnsic2lnbmVkS2V5Ijoie1wia2V5RXhwaXJhdGlvblwiOlwiMTc0MjgxMDMxNzAwMFwiLFwia2V5VmFsdWVcIjpcIk1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRWhtUzhlbWExdEFhQWtHWkVmMERKVllHM0d5T3FNenpxL2lZR3JLZHZGbWlOK2s2cGdOQWNoTzFXRlo1NUFtYzZwL1o4RU5CdlZ3MnRhai9EaDNDNGNnPT1cIn0iLCJzaWduYXR1cmVzIjpbIk1FUUNJQ012Vm9mUVpzVDFQSmZORHR4aHZwS1c4SHRWbFRKYXBwdkVFQjJMbURsdkFpQTBLZElCNVVjNmFsdTlXSmJpSHBGbWRyclFkaHZwZHV2YnlsN1JybGhSQXc9PSJdfX0="
require 'net/http'
require 'uri'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send(
'api/charges',
method: :post,
body: {
amount: 10,
currency: 'pln',
channel: 'elavon_google_pay',
description: 'Espago docs Google Pay',
google_pay: 'eyJwcm90b2NvbFZlcnNpb24iOiJFQ3YyIiwic2lnbmVkTWVzc2FnZSI6IntcImVuY3J5cHRlZE1lc3NhZ2VcIjpcInY4bmhGYVJVWmYveERJakhFcnAvOEc2WmdyK2xCcCt2N2cyL0MveXl4UmNhbGcwTElKUmF1NUljblVpYnZMMUh1UkdETTV2dVNYQUNxUG0yaSt3cFBBL0lrSzZvWko4WlNVdFFEcXc1K0RPY002a2ZJYy9jeUVtdmpXTWhVTkdDZkJ2dUF5RU0xeGk3dzU4MjNoVmhQemVUSk12K2YyYjZwQTAvZGZRZkpSWURjRVp1bjFWWGFFalRDdWFRcUVlV0x6RW81MDlBd25nOFJjYmFRelNzQXcwd0U4dUZsVDliRlY3cVc5N2svS3RuYTluYUdHR29UdmVaS3lKdDF4SmQ0NkhTRlkyNkN4WmxLRkppaGFLN2d4OW94RGVqVEE2VGtHL2tDd05keUZUQk4wSGY3ZEZUaUpEVkRiUklZOUtlalpkRXJwWnlQbHFES1luMWJSRytPSldWNGszWVhldmp6QWZoTmpzMWZyQ0dpTE5GeUtWa1RMRFl1enhOQWZobkQvZHpINVkyYkZUSnRqYmhOUFpNL3VmdmJMWjNTN1dKOVpuWFkxS2dyRlpNRFBzQkRjb3hjZE1nVmtMcVptQjVSNFZhUndDdm96M2JtcDhUd2tiVG5Vb2lndE5hQ29pclJ2TT1cIixcImVwaGVtZXJhbFB1YmxpY0tleVwiOlwiQk9IcXNPME55Z3NNQThFcHpyaGIyWTV5SjR0V3hjeU8wUmhJdTMyMmIvc1B0VE5uU3Q4RGlNUlVEZWx1WU5rbUZMcFJoeTg3blVPTTlNbk5KcVBhS3JzPVwiLFwidGFnXCI6XCJySU5Nay9DVjFjQUQzYVgwc2JOOSt2UEdjb1g4RGdzTHE0R0hld2NEMEw4PVwifSIsInNpZ25hdHVyZSI6Ik1FVUNJUUQ4ZkhSWG5kWFVjd2FpczltTW9Hd0QwSm90MlYvby9vOU41cG9JemRTS0V3SWdjdWw5RGhoSVppVGN3N2RrWisxUGtQbDlJZjBwNG1qamg5OVQvVXZZQ0NBPSIsImludGVybWVkaWF0ZVNpZ25pbmdLZXkiOnsic2lnbmVkS2V5Ijoie1wia2V5RXhwaXJhdGlvblwiOlwiMTc0MjgxMDMxNzAwMFwiLFwia2V5VmFsdWVcIjpcIk1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRWhtUzhlbWExdEFhQWtHWkVmMERKVllHM0d5T3FNenpxL2lZR3JLZHZGbWlOK2s2cGdOQWNoTzFXRlo1NUFtYzZwL1o4RU5CdlZ3MnRhai9EaDNDNGNnPT1cIn0iLCJzaWduYXR1cmVzIjpbIk1FUUNJQ012Vm9mUVpzVDFQSmZORHR4aHZwS1c4SHRWbFRKYXBwdkVFQjJMbURsdkFpQTBLZElCNVVjNmFsdTlXSmJpSHBGbWRyclFkaHZwZHV2YnlsN1JybGhSQXc9PSJdfX0='
}
)
puts response.body
{
"id": "pay_8ffCLdBYBSzMk6HJ",
"description": "Espago docs Google Pay",
"channel": "elavon_google_pay",
"amount": "10.00",
"currency": "pln",
"state": "executed",
"client": "cli_8ffe5FGyhZceHb6q",
"created_at": 1679651962,
"card": {
"company": "VI",
"last4": "0006",
"year": 2030,
"month": 1,
"created_at": 1679651962
},
"issuer_response_code": "00",
"reversable": true,
"transaction_id": "tr_8ffi3se3t"
}
More info about responses can be found here.
{
"id": "pay_8ffaeAEaCyzUY-D-",
"description": "Espago docs Google Pay",
"channel": "elavon_google_pay",
"amount": "10.00",
"currency": "pln",
"state": "new",
"client": "cli_8ffEpSsgrShInvKc",
"created_at": 1679651893,
"card": {
"company": "VI",
"last4": "0006",
"year": 2030,
"month": 1,
"created_at": 1679651893
},
"issuer_response_code": "",
"transaction_id": "tr_8fftqyPct",
"redirect_url": "https://sandbox.espago.com/secure_web_page/pay_8ffaeAEaCyzUY-D-"
}
BLIK phonelink_ring
link Introduction
BLIK is a Polish mobile payment platform that enables convenient and fast payments in both stationary and online stores using a 6-digit code. To use BLIK, your customers need a mobile application from a bank that supports BLIK payments.
BLIK payments are only available for the PLN currency
There are three ways to initiate a BLIK transaction:
1. Payment by sending a BLIK code to the Espago gateway.
2. Payment through the eblik.pl website.
3. BLIK one-click payment, after registering a BLIK one-click alias.
link BLIK charge by code
The seller must create a form within their application to obtain the BLIK number from the payer and then submit it to the Espago gateway via a POST request to the /api/charges
address.
After the request is sent, the payer is prompted to confirm the BLIK transaction in their banking application, and the payment enters the blik_decision
state.
The response with the final payment status is sent via a Back Request.
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 the
p24_blik
payment channel.
linkCharge parameters for p24_blik
payment channel.
For BLIK charge by code payments, it is necessary to send the parameter
p24_regulation_accepted
with a value oftrue.
Because in this case, the payer will be directly redirected to the bank.
Parameter | Description | Format | Mandatory |
---|---|---|---|
channel | The value p24_blik must be passed. |
String | Mandatory |
blik_code | The BLIK code (T6) generated in the payer’s banking application. | String (6 characters) | Mandatory if the alias_type parameter is not provided. |
alias_type | Provided when creating a one-click alias. Allowed values: one_click . |
String | Optional |
client | The Client Profile ID (the created BLIK alias will be assigned to the Client Profile). | String | Optional |
Email address of the payer. | String | Mandatory (unless the client parameter is provided with the Client ID that has an assigned email address). |
|
return_url | URL to which the client will be forwarded after the transaction processing | String | Optional, if parameter blik_code is provided. Mandatory for eblik.pl payments. |
locale | Transaction language | String, Language code in ISO 639-1 standard. Available values: bg, cs, de, en, es, fr, hr, hu, it, nl, pl, pt, se, sk. |
Optional |
p24_regulation_accepted | Acceptance of the Przelewy24 terms and conditions. Specifies whether the payer will be shown the consent after redirection to the P24 page. The default value is false - do show. |
Boolean | Optional |
When providing the value
true
, for the thep24_regulation_accepted
parameter - partner’s website must include the consent statement: “I hereby state that I have read the regulations and information obligation of Przelewy24”.
The words "regulations” and “information obligation” must contain links to the respective documents. The checkbox cannot be pre-selected.
linkCharge example
{
"channel": "p24_blik",
"blik_code": "777100",
"amount": 10,
"currency": "PLN",
"description": "Espago docs P24 BLIK",
"email": "example@example.com"
}
curl -i https://sandbox.espago.com/api/charges \
-H "Accept: application/vnd.espago.v3+json" \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "channel=p24_blik" \
-d "blik_code=777100" \
-d "amount=10" \
-d "currency=PLN" \
-d "description=Espago docs P24 BLIK" \
-d "email=example@example.com"
require 'net/http'
require 'uri'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param method_name [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send(
"api/charges",
method: :post,
body: {
channel: 'p24_blik',
blik_code: '777100',
amount: 10,
currency: 'PLN',
description: 'Espago docs P24 BLIK',
email: 'example@example.com'
}
)
puts response.body
$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, "channel=p24_blik&blik_code=7771000&amount=10¤cy=PLN&description=Espago docs P24 Blik&email=example@example.com");
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_901X97fmqW7-ZQqo",
"description":"Espago docs P24 Blik",
"channel":"p24_blik",
"amount":"10.00",
"currency":"PLN",
"state":"blik_decision",
"email":"example@example.com",
"created_at":1684166626,
"transaction_id":"p24_901E5Jsu2IlhzNE2"
}
link eblik.pl Payment
In case the blik_code
parameter is not provided, the payment status will be returned as new
along with a link to redirect the payer to the eblik
page where they can enter the BLIK code. This option is not available when creating a one_click
alias. After successful redirection, the payment status changes to blik_redirected
.
The final payment status response is sent through a Back Request.
linkCharge example
{
"channel": "p24_blik",
"amount": 10,
"currency": "PLN",
"description": "Espago docs P24 BLIK",
"return_url": "https://espago.com",
"email": "example@example.com"
}
curl -i https://sandbox.espago.com/api/charges \
-H "Accept: application/vnd.espago.v3+json" \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "channel=p24_blik" \
-d "amount=10" \
-d "currency=PLN" \
-d "description=Espago docs P24 BLIK" \
-d "return_url=https://espago.com" \
-d "email=example@example.com"
require 'net/http'
require 'uri'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param method_name [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send(
"api/charges",
method: :post,
body: {
channel: 'p24_blik',
amount: 10,
currency: 'PLN',
description: 'Espago docs P24 BLIK',
return_url: 'https://espago.com',
email: 'example@example.com'
}
)
puts response.body
$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, "channel=p24_blik&amount=10¤cy=PLN&description=Espago docs P24 Blik&return_url=https://espago.com&email=example@example.com");
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_901oh54m1sFgJfHj",
"description":"Espago docs P24 Blik",
"channel":"p24_blik",
"amount":"10.00",
"currency":"PLN",
"state":"new",
"email":"example@example.com",
"created_at": 1684166942,
"transaction_id": "p24_901GMO87ibiWf8KZ",
"redirect_url":"https://sandbox.espago.com/p24_eblik/pay_901oh54m1sFgJfHj"
}
link BLIK one-click
BLIK one-click payments allow for making purchases without the need to enter the BLIK code, only by confirming the payment in the mobile application.
linkOne-click alias registration
Registration of a BLIK one-click alias occurs after initiating a charge request for the p24_blik
channel, using the alias_type=one_click
parameter.
The alias registration request will be forwarded to the BLIK system, and the customer will receive an invitation in their banking application for payment without a BLIK code at the Merchant’s store.
If the customer’s decision is positive, the alias will be registered in the BLIK system, and the customer will not be asked for a BLIK code during future payments.
Depending on the use of the Client Profile in the API request, there are 3 scenarios for registering a one-click alias.
Client Profile | Result |
---|---|
No | One-time payment and creating a Client Profile with a one-click alias, if the customer approves. |
Yes (without active alias) | One-time payment and adding the alias to the Client Profile, if the customer approves. |
Yes (with active alias) | One-time payment and registering another bank application for the alias. |
linkCharge example with a one-click alias registration
{
"channel": "p24_blik",
"blik_code": "777101",
"amount": 21.04,
"currency": "PLN",
"description": "Espago docs P24 BLIK",
"email": "example@example.com",
"alias_type": "one_click"
}
curl -i https://sandbox.espago.com/api/charges \
-H "Accept: application/vnd.espago.v3+json" \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "channel=p24_blik" \
-d "blik_code=777101" \
-d "amount=21.04" \
-d "currency=PLN" \
-d "description=Espago docs P24 BLIK" \
-d "email=example@example.com"
-d "alias_type=one_click"
require 'net/http'
require 'uri'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param method_name [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send(
"api/charges",
method: :post,
body: {
channel: 'p24_blik',
blik_code: '777101',
amount: 21.04,
currency: 'PLN',
description: 'Espago docs P24 BLIK',
email: 'example@example.com',
alias_type: 'one_click'
}
)
puts response.body
$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, "channel=p24_blik&blik_code=777101&amount=21.04¤cy=PLN&description=Espago docs P24 Blik&email=example@example.com&alias_type=one_click");
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_901D3j3SglzRigHQ",
"description":"Espago docs P24 Blik",
"channel":"p24_blik",
"amount":"21.04",
"currency":"PLN",
"state":"blik_decision",
"email":"example@example.com",
"created_at":1684166626,
"transaction_id":"p24_901E5maO86lhzNE2",
"client":"cli_9015q7ioPP2EllAO"
}
linkOne-click alias charge
Starting a new charge for a one-click alias is done by sending a POST request to the address https://sandbox.espago.com/api/charges. One-click transactions must be processed through the p24_blik_alias
payment channel.
linkCharge parameters for the p24_blik_alias
channel
For BLIK one-click alias payments, it is necessary to send the parameter
p24_regulation_accepted
with a value oftrue.
Because in this case, the payer will be directly redirected to the bank.
Parameter | Description | Format | Mandatory |
---|---|---|---|
channel | The value should be p24_blik_alias |
String | Mandatory |
alias_type | Indicates which type of alias to use | String, allowed values: one_click |
Mandatory |
client | The ID of the client profile | String | Mandatory |
Email address of the payer. | String | Mandatory (unless the client parameter is provided with a client ID that has an associated email address) |
|
locale | Transaction language | String, Language code in ISO 639-1 standard. Available values: bg, cs, de, en, es, fr, hr, hu, it, nl, pl, pt, se, sk. |
Optional |
p24_regulation_accepted | Acceptance of the Przelewy24 terms and conditions. Specifies whether the payer will be shown the consent after redirection to the P24 page. The default value is false - do show. |
Boolean | Mandatory |
When providing the value
true
, for the thep24_regulation_accepted
parameter - partner’s website must include the consent statement: “I hereby state that I have read the regulations and information obligation of Przelewy24”.
The words "regulations” and “information obligation” must contain links to the respective documents. The checkbox cannot be pre-selected.
linkCharge example for BLIK one-click alias
{
"channel": "p24_blik_alias",
"alias_type": "one_click",
"amount": 10,
"currency": "PLN",
"description": "Espago docs P24 BLIK",
"client": "cli_8a2lAMfJiJRblhYR"
}
curl -i https://sandbox.espago.com/api/charges \
-H "Accept: application/vnd.espago.v3+json" \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "channel=p24_blik_alias" \
-d "alias_type=one_click" \
-d "amount=10" \
-d "currency=PLN" \
-d "description=Espago docs P24 BLIK" \
-d "client=cli_8a2lAMfJiJRblhYR"
require 'net/http'
require 'uri'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param method_name [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send(
"api/charges",
method: :post,
body: {
channel: 'p24_blik_alias',
alias_type: 'one_click',
amount: 10,
currency: 'PLN',
description: 'Espago docs P24 BLIK',
client: 'cli_8a2lAMfJiJRblhYR'
}
)
puts response.body
$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, "channel=p24_blik_alias&alias_type=one_click&amount=10¤cy=PLN&description=Espago docs P24 Blik&client=cli_8a2lAMfJiJRblhYR");
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_9011PZTylAm-JEsM",
"description":"Espago docs P24 Blik",
"channel":"p24_blik_alias",
"amount":"10.00",
"currency":"PLN",
"state":"blik_decision",
"email":"example@example.com",
"created_at":1684166626,
"transaction_id":"p24_901E1z-JffNa-F4098",
"client":"cli_8a2lAMfJiJRblhYR"
}
linkHandling multiple bank applications registered to a single one-click alias
A customer profile can have one active one-click alias registered. Multiple bank applications of the payer can be registered to a single one-click alias. After registering a second bank application, the Espago API will return a payment with the new
status and a list of available applications to choose from in response to the api/charges
request on the p24_blik_alias
channel (for a given customer profile):
"alternative_keys": [
{
"label": "TEST APP 032",
"alias": "617987"
},
{
"label": "TEST APP 028",
"alias": "617986"
}
]
To complete the payment, send a POST
request to the api/charges/(:id)/blik_app_decision
endpoint, sending the alias
parameter in the request body. For example:
POST /api/charges/pay_8a1UC6bjMbhsBbYH/blik_app_decision
{
"alias": "617987"
}
These aliases are variable and there is no need to save them for later use.
linkRequest example
{
"alias": "617987"
}
curl -i https://sandbox.espago.com/api/charges/pay_8a1UC6bjMbhsBbYH/blik_app_decision \
-H "Accept: application/vnd.espago.v3+json" \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "alias=617987"
require 'net/http'
require 'uri'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param method_name [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send(
"api/charges/pay_8a1UC6bjMbhsBbYH/blik_app_decision",
method: :post,
body: {
alias: '617987'
}
)
puts response.body
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://sandbox.espago.com/api/charges/pay_8a1UC6bjMbhsBbYH/blik_app_decision');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "alias=617987");
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_9011PZTylAm-JEsM",
"description":"Espago docs P24 Blik",
"channel":"p24_blik_alias",
"amount":"10.00",
"currency":"PLN",
"state":"blik_decision",
"email":"example@example.com",
"created_at":1684166626,
"transaction_id":"p24_901E1z-JffNa-F4098",
"client":"cli_8a2lAMfJiJRblhYR"
}
linkQuerying for the BLIK one-click alias assigned to a client profile
To see the assigned BLIK aliases for a client profile, you need to use the Client Profile data fetching method.
The BLIK one-click alias is visible as the p24_blik_alias_one_click
parameter.
Example of Client Profile’s data with a registered one-click alias.
{
"email": "example@example.com",
"id": "cli_8a2lAMfJiJRblhYR",
"created_at": 1665433136,
"description":"Client with a BLIK alias",
"card": {
"company":"VI",
"last4":"4242",
"year":2022,
"month":2,
"first_name":"Jan",
"last_name":"Kowalski",
"authorized":true,
"created_at":1561126879
},
"p24_blik_alias_one_click": {
"kind": "one_click",
"state": "registered",
"email": "example@example.com",
"expiration_date": 1728476779,
"value": "27c798a90f9fbbb546c5c5cda71bacb87c8ee5a644c2f9ab384c5336ad50"
},
"deleted": false
}
If the payer does not accept the registration of the one-click alias, an inactive alias (“state”: “unregistered”) will be assigned to their customer profile.
link Test payments
BLIK payments in the Sandbox environment are automatically confirmed. The response with the final payment status is sent via Back Request, just like in the production environment.
To correctly process BLIK payments, codes should be created according to the pattern 777xxx, where x represents any digit. BLIK codes are one-time-use, and should be changed for each subsequent test charge attempt.
linkError codes
The sandbox environment will return a specific error code when a BLIK transaction is made with the appropriate amount:
- 288.00 — ALIAS_DECLINED
- 192.00 — TAS_DECLINED
- 144.00 — USER_DECLINED
- 216.00 — SEC_DECLINED
- 264.00 — SYSTEM_ERROR
- 360.00 — GENERAL_ERROR
- 120.00 — INSUFFICIENT_FUNDS
- 312.00 — TIMEOUT
- 96.00 — LIMIT_EXCEEDED
- 336.00 — USER_TIMEOUT
- 168.00 — ISSUER_DECLINED
linkBLIK one-click
In the sandbox environment, the BLIK one-click alias can be confirmed (status REGISTERED
) by making a BLIK transaction for an amount with the “04” decimal value, e.g. 21.04 PLN.
Changing the status of the BLIK one-click alias to UNREGISTERED
requires making a BLIK transaction with a payment amount with the “33” decimal value, for example 37.33 PLN.
Fast Bank Transfer account_balance
link How to order a bank transfer
It is possible to make a payment via bank transfer using the “Przelewy24” platform. To initiate the transaction, you need to send a POST request to the /api/charges
path. In response, you will receive a redirect_url
parameter, which contains the URL to redirect the client to the “Przelewy24” payment page. After the redirection, the payment will enter the transfer_redirected
state. The final payment status will be sent asynchronously through a back request.
To initiate a new charge, send a POST request to the address https://sandbox.espago.com/api/charges. Bank transfer transactions must be made through the
p24_transfer
payment channel.
linkCharge example
{
"channel": "p24_transfer",
"amount": 10,
"currency": "PLN",
"description": "Espago docs P24 Transfer",
"email": "example@example.com",
"return_url": "https://espago.com",
"p24_regulation_accepted": true
}
curl -i https://sandbox.espago.com/api/charges \
-H "Accept: application/vnd.espago.v3+json" \
-u ms_771eUTliRiZ:SeCreT_P@ssw0rD \
-d "channel=p24_transfer" \
-d "amount=10" \
-d "currency=PLN" \
-d "description=Espago docs P24 Transfer" \
-d "email=example@example.com" \
-d "return_url=https://espago.com" \
-d "p24_regulation_accepted=true"
require 'net/http'
require 'uri'
require 'json'
class EspagoClient
# @param user [String]
# @param password [String]
def initialize(user:, password:)
@user = user
@password = password
end
# @param path [String]
# @param body [Hash, nil]
# @param method [Symbol]
# @return [Net::HTTPResponse]
def send(path, body: nil, method: :get)
uri = URI.join('https://sandbox.espago.com', path)
request = request_class(method).new(uri)
request.basic_auth(@user, @password)
request['Accept'] = 'application/vnd.espago.v3+json'
request['Content-Type'] = 'application/json'
request.body = body.to_json if body
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
end
private
# @param method_name [Symbol]
# @return [Class<Net::HTTPRequest>]
def request_class(method_name)
Net::HTTP.const_get(method_name.to_s.capitalize)
end
end
client = EspagoClient.new(user: 'ms_771eUTliRiZ', password: 'SeCreT_P@ssw0rD')
response = client.send(
"api/charges",
method: :post,
body: {
channel: 'p24_transfer',
amount: 10,
currency: 'PLN',
description: 'Espago docs P24 Transfer',
email: 'example@example.com',
return_url: 'https://espago.com',
p24_regulation_accepted: true
}
)
puts response.body
$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, "channel=p24_transfer&amount=10¤cy=PLN&description=Espago docs P24 Transfer&return_url=https://espago.com&email=example@example.com");
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_901oh54m1sFgJfHj",
"description":"Espago docs P24 Transfer",
"channel":"p24_transfer",
"amount":"10.00",
"currency":"PLN",
"state":"new",
"email":"example@example.com",
"created_at": 1684166942,
"transaction_id": "p24_902rCZV7MGssIo61",
"redirect_url":"https://sandbox.espago.com/payment_p24/pay_901oh54m1sFgJfHj"
}
linkCharge parameters for the p24_transfer
payment channel.
Parameter | Description | Format | Mandatory |
---|---|---|---|
channel | Value p24_transfer must be passed. |
String | Mandatory |
amount | Transaction amount | Decimal number, up to 2 decimal places. For example: 123.45. | Mandatory |
description | Transaction description | String, from 5 to 99 characters. | Mandatory |
Email address of the payer. | String | Mandatory (unless the client parameter is provided with a client ID that has an associated email address) |
|
return_url | URL to which the client will be forwarded after the transaction processing | String | Mandatory |
locale | Transaction language | String, Language code in ISO 639-1 standard. Available values: bg, cs, de, en, es, fr, hr, hu, it, nl, pl, pt, se, sk. |
Optional |
p24_regulation_accepted | Acceptance of the Przelewy24 terms and conditions. Specifies whether the payer will be shown the consent after redirection to the P24 page. The default value is false - do show. |
Boolean | Optional |
When providing the value
true
, for the thep24_regulation_accepted
parameter - partner’s website must include the consent statement: “I hereby state that I have read the regulations and information obligation of Przelewy24”.
The words "regulations” and “information obligation” must contain links to the respective documents. The checkbox cannot be pre-selected.
Apple Pay credit_card
link Hosted Checkout
Apple Pay can be handled entirely by Espago if you redirect the cardholder to Espago Secure Web Page.
In order to enable this feature one should contact the Espago support team.
Test payments
In the Sandbox environment the decimal value of transaction can be used to define the Secure Webpage simulated payment scenario.
Decimal value | Payment scenario |
---|---|
n.00 | successful |
n.10 | rejected |
n.20 | rejected ECI=7 |
Where n is a natural number.
link Apple Pay payload generator
There is a form that generates Apple Pay payloads for use in the sandbox.espago.com environment.
link ApplePay in an iFrame 3.0
The Apple Pay button can be located on the merchants page in two ways. The merchant can implement EspagoFrame on their website, which will display a Secure Web Page with multiple possible payment methods or only the Apple Pay button will be displayed on the merchant’s page. Thanks to this implementation, the merchants’s integration with Apple Pay is much easier.
Onboarding
In order to use Apple Pay in Iframe you have prepare your domain for registration in Apple Pay.
Domain verification file
For iframe integrations using iframe it is necessary to upload the Domain Verification File to your domain.
The file should be located under the path: /.well-known/apple-developer-merchantid-domain-association
.
If your domain is my_domain.com
the file should be available for download with a GET request to https://my_domain.com/.well-known/apple-developer-merchantid-domain-association
.
Domain verification files for sandbox and production can be found in the Download section.
Domain registration
When you are sure that the appropriate domain verification file is available for download under the required path on your domain you should contact the Espago support team. They will register your domain for use in Apple Pay.
link Implementation of Apple Pay in iFrame 3.0
Once the onboarding process is completed, merchant can implement EspagoFrame according to the Iframe 3.0 documentation. When a customer has an ApplePay wallet with a saved card and uses the Safari browser, an additional Apple Pay payment button will be displayed in EspagoFrame
After authorizing the payment using Apple Pay, the response from the iframe is the same as in the case of card payments (sayment status and its id will be returned).
Learn more about iFrame 3.0 implementation here.
link Apple Pay button implementation
To display only the ApplePay button on your website without having to display other payment methods inside the iframe, call EspagoFrame in a modified way.
1. HTML element for Apple Pay button location
In the website code, you need to prepare an element with the selected ID, which will be passed to the `open()` method in the further integration process. EspagoFrame will display an iframe there, which will contain the Apple Pay button only.<body>
.
.
.
<div id="apple-pay-button"></div>
.
.
.
</body>
2. Implement modified code from Iframe 3.0 documentation
You should add the code similarly to the iFrame 3.0 implementation, with the difference that instead of calling the `open()` method after pressing the “Pay” button, you should call it directly after the `init()` method with additional `kind parameters: “applePayButton”` and `element: <script src="https://js.espago.com/espago-frame.js"></script>
<script lang="text/javascript">
const onPaymentResult = function (result) {
console.log(`Payment ${result.payment_id} finished with state ${result.state}`);
};
const onError = function (errorMessage) {
console.log("Something went wrong: " + errorMessage);
};
const onClose = function () {
console.log("Modal closed.");
};
const espagoFrame = new EspagoFrame({
key: "merchantPublicKey123",
env: "sandbox",
payment: "pay_123123123",
token: "aa111a11-111-1aa1-aa11-a11aaa111111"
})
espagoFrame.init().then(() => {
espagoFrame.open({
kind: „applePayButton”,
element: „apple-pay-button”
onPaymentResult: onPaymentResult,
onError: onError,
onClose: onClose
});
});
</script>
3. Customer pays using Apple Pay
When the customer has an ApplePay wallet with at least one saved card and uses the Safari browser, an ApplePay button inside EspagoFrame will be displayed in the place where the element added in the first step is indicated in the page code. After clicking Apple Pay button and going through the payment authorization process, the response from the iframe is the same as in the case of card payments (the payment status and its id will be returned to callback method).4. Response - information for the customer
Merchant proceeds in the same way as in the case of integration with iFrame v3.0 without modifications - request to Espago for full payment details must be send in order to then properly handle the payment summary process on the website.