Using the ETN Instant Payment API

Our Instant Payment API allows users to register themselves as a vendor and receive instant API notification, optionally via a webhook. It is currently in FULLY FUNCTIONAL BETA on the live system - with a limit of 500 euros maximum value in ETN per checkout.

Getting API access
Log in to your https://my.electroneum.com dashboard and click on VENDOR SETTINGS in the menu. Click ENABLE BETA ACCESS to get started! There’s no delay, you’ll have instant access.

This allows you to accept ETN as payment through online e-commerce or retail ePOS (electronic point-of-sale) with assurance that a payment has been made.

An instant notification will be created on your account, accessible via the mobile app, allowing you to receive confirmation that a payment is on its way.

Using HTTP RESTful features, our API can additionally send a signed webhook instantly when a payment is made to you. You authenticate this by confirming the signature of the webhook. Alternatively, our API can respond to a request on the status of a payment.

Support is available via our community forum at https://community.electroneum.com; you will need to log in to your electroneum.com account to see the discussion thread.

All PHP example code snippets in this guide are compatible with PHP version 7.1 and above. It may work in lower versions.

Create Account

Having created your user account, register for access to our vendor program.

Those successful will receive email notification when it has been enabled.

Complete Vendor Account

Before you can use the Vendor API, you must complete your legal entity details and add your first vendor outlet. Each outlet is a place (a website or a retail shop) where you will accept ETN as payment.

When creating your outlet, enter a friendly brand name as the Outlet Name & upload a logo; this is shown to customers to identify you at checkout and in their transaction history. Use it to differentiate between shops in different towns or between a shop and a website.

Once you have added your first outlet, you will have access to your API keys and have the option to add your webhook URL (if you want to receive a signed webhook). The webhook URL must use valid HTTPS and is where we will send the instant payment notification & details.

It is important that you keep the API Secret secure. Never share it. Never send it. If you feel this is compromised, generate new API keys from your user vendor area of your user account and update your webhook listener accordingly.

Vendor Payment

Accepting payments as a vendor is a three-step process:

  1. Generate the payment string.
  2. Allow the customer to use the payment string.
  3. Check for confirmation that payment has been made.

There is a maximum spend limit on all transactions of €500.00. The vendor API will reject any transaction over this amount.

Step 1: Generate Payment String

The payment string is made up of the following parameters:

{vendor-address}/{payment-id}/{amount}

These parameters must conform as follows:

Parameter Description Format Example
vendor-address Identifier for your outlet; starting " etn-it- " followed by the Outlet Id from your user vendor page. string(20) etn-it-0 abc123def456
payment-id Unique (to you) identifier for the transaction. hexadecimal(10) 7ce25b4dc0
amount The amount to be charged in ETN, converted from your local currency, correct to two decimal places with no thousandth separator. decimal 1234.56

These example values would generate the string:

etn-it-0abc123def456/7ce25b4dc0/1234.56

More Information

Vendor Address

This is made of etn-it- followed by your 13 digit Outlet Id and can be found on your user vendor page or when editing an outlet.

Payment Id

We recommend this is generated from cryptographically secure pseudo-random bytes but this can be part-filled with a transaction reference from your existing vendor system.

This can be done with PHP as follows:

$paymentId = bin2hex(random_bytes(5));

Amount

We provide exchange rates for all major currencies at https://supply.electroneum.com/app-value-v2.json:

Currency JSON Key
Argentina Peso ARS price_ars
Australia Dollar AUD price_aud
Bangladesh Taka BDT price_bdt
Brazil Real BRL price_brl
Bitcoin BTC price_btc
Canada Dollar CAD price_cad
DR Congo Franc CDF price_cdf
Switzerland Franc CHF price_chf
Chile Peso CLP price_clp
China Yuan Renminibi CNY price_cny
Colombian Peso COP price_cop
Czech Republic Koruna CZK price_czk
Denmark Krone DKK price_dkk
Egypt Pound EGP price_egp
Euro EUR price_eur
United Kingdom Pound GBP price_gbp
Ghana Cedi GHS price_ghs
Hong Kong Dollar HKD price_hkd
Hungary Forint HUF price_huf
Indonesia Rupiah IDR price_idr
Israel Rupee ILS price_ils
India Rupee INR price_inr
Japan Yen JPY price_jpy
Cambodian Riel KHR price_khr
Korea Won KRW price_krw
Mexico Peso MXN price_mxn
Malaysia Ringgit MYR price_myr
Nigeria Naira NGN price_ngn
Norway Krone NOK price_nok
New Zealand Dollar NZD price_nzd
Phillipines Peso PHP price_php
Pakistan Rupee PKR price_pkr
Poland Zloty PLN price_pln
Romania Leu RON price_ron
Russia Ruble RUB price_rub
Sweden Krona SEK price_sek
Singapore Dollar SGD price_sgd
Thailand Baht THB price_thb
Turkey Lire TRY price_try
Taiwan New Dollar TWD price_twd
Ukraine Hryvnia UAH price_uah
United States Dollar USD price_usd
Venezuela Bolívar Soberano VES price_ves
Vietnam đồng VND price_vnd
South Africa Rand ZAR price_zar

Requesting against this JSON with your local currency and the amount in that currency, you can calculate the amount in ETN. A PHP example may look like:

// Set the request.
$currency = "GBP";
$amount = 9.95;

// Get the JSON conversion data.
if (!$json = file_get_contents('https://supply.electroneum.com/app-value-v2.json')) {
    die("Could not load currency exchange JSON");
}

// Check the JSON is valid.
$arr = json_decode($json, true);
if (json_last_error() !== JSON_ERROR_NONE) {
    die("Could not load valid currency exchange JSON");
}

// Get the conversion rate.
if (!$rate = $arr['price_' . $currency]) {
    die("Currency exchange rate not found");
}

// Check the rate is valid or more than zero.
if (floatval($rate) <= 0) {
    die("Currency conversion rate not valid");
}

// Calculate the amount of ETN.
$etn = number_format(floatval($amount) / $rate, 2, '.', '');

As per our terms and conditions, you must not add any fee to this number and must be a clean calculation based on our exchange rates.

Step 2: Customer Payment

The customer will need to access the payment string to send you their payment.

ePOS

If using an ePOS (traditional retail point-of-sale), you can simply display the payment string as a QR code for the customer to scan using the Electroneum app on their mobile device. You can do this dynamically or via a third party like Google Charts QR Code.

Online

If you are selling via a website, we recommend using our Vendor Payment Widget from https://github.com/electroneum/vendor-payment-widget.

This accepts your payment string and displays it as both a QR code (for the customer to scan) and as a clickable link (for the customer to pay via our website).

Simply add a div to your checkout HTML page containing your payment string in the data-etn-vendor attribute and, optionally, a two-digit language string (defaulting to English):

<script src="widget.js"></script>
<div data-etn-vendor="{paymentString}" data-etn-lang="{language}"></div>

For example:

<script src="widget.js"></script>
<div data-etn-vendor="etn-it-0abc123def456/7ce25b4dc0/1234.56" data-etn-lang="en"></div>

Step 3: Payment Confirmation

There are three alternate methods to confirm that a payment has been made.

Option 1: Webhook

We will send a webhook notification to the webhook URL to your user vendor settings (if provided) when a payment has been made.

The user-agent sending the webhook will indicate the API version, the URL to the integration guide for the API and will always start Electroneum/. For example:

Electroneum/0.1.0 (+https://electroneum.com/instant-payments)

You may want to prevent this user-agent from being falsely filtered by firewalls or you may want to filter incoming webhooks by user-agent.

The webhook will be signed (to confirm that it has come from us and has not been altered after being created) and will contain a payload with details of the payment.

This is our suggested method. It is the most secure and is the fastest confirmation of payment that we provide.

Signature

We sign the webhook so that you know it came from us and can be trusted.

The signature is sent in the ETN-SIGNATURE HTTP header with the webhook and is calculated using the SHA256 hash of the JSON payload using your API Secret.

Example code using PHP may look like:

// Your API Secret from your user vendor settings
$api_secret = 'sec_live_zxyxwvutsrqponmlkjihgfedcba0987654321zxyxwvutsrqponmlkj';

// The payload and signature from the webhook
$payload_json = @file_get_contents('php://input');
$payload_arr = json_decode($payload_json, true);
$signature = $_SERVER['HTTP_ETN_SIGNATURE'];

if ($signature !== hash_hmac('sha256', $payload_json, $api_secret)) {
    // Invalid webhook signature
    http_response_code(401);
} elseif (strtotime($payload_arr['timestamp']) < strtotime('-5 minutes')) {
    // Expired webhook
    http_response_code(400);
} else {
    // Valid webhook signature
    http_response_code(200);

    // Process the transaction ...
}

If you receive a valid webhook signature, you are safe to trust the payload.

We advise you to check against duplicate webhooks by making your event processing idempotent; log a payment as processed so that if you get a duplicate webhook payment id you can immediately ignore it.

Payload

The webhook payload is sent with a HTTP POST request and the body contains the following JSON:

Parameter Description Format Example
event The type of payment; either “payment” or “refund”. string payment
payment_id The payment id provided by you, to identify the transaction. If the event is refund, the payment_id refers to the original transaction the refund is made against. string(10) 7ce25b4dc0
amount The amount of ETN paid by the customer, to two decimal places. decimal 1234.56
key Your vendor API Key. string(32) key_live_1234567890abcdefghijklm
timestamp The datetime of the payment in ISO 8601 format. string 2018-06-11T11:02:31+01:00
customer The customer’s email addresses associated with their ETN account. string customer@example.com
ref Our reference for the payment. string(13) 1234567890abc

WARNING: You should confirm that the API Key matches your credentials, that the timestamp is recent (we recommend no more than 5 minutes old), that the payment_id hasn’t already been processed by your system and that the amount is the value you expected to be paid.

To prevent replay attacks, whereby an attacker will capture and resend a payload, you should verify the timestamp is recent, within a threshold of your choosing. We recommend a period less than 5 minutes is valid for the customer to complete the transaction and to allow for inaccurate clock synchronisations.

Response Code

You must return a valid HTTP response code when receiving a webhook. To prevent our webhook timing out, you should return a HTTP response as soon as possible.

A success must return a 2XX code, for example 200. This will let us know that you have received is successfully. Any error should return a 4XX code, for example 401.

Failed Webhooks / Retries

Any response to our webhook that is not a successful code (not a 2XX) will alert us that we should retry said webhook. Webhooks are retried every hour for three days, after which they will not be retried.

Generate Test Webhook

You can generate a valid payload and signature to test against your webhook listener from your user vendor account.

Please note that the payload generated by the test webhook is formatted for ease of reading when displayed in the browser. You may want to decode & encode to ensure this is formatted before validating a signature; see our Vendor PHP library on how this can be handled.

Using a REST client like Insomnia REST Client will allow you to test against a number of requests. We do not push the payload & signature to your webhook URL for this test.

Option 2: Electroneum App Notification

A notification will appear in the mobile app for your vendor user account when an instant payment has been made to you.

WARNING: You should confirm the amount paid is correct.

Option 3: API Poll

You can send the payment id to our API for us to confirm if it has been received.

We do not recommend this method due to its frequency restrictions but it exists should you not be able to open your network or ePOS systems to receive a webhook.

Post your outlet id and payment id, signed with your API Secret, to our API and we’ll return whether the request if payment has been made and, if so, how much has been paid.

Signing your request with your API Secret means only you can request the status of your payments.

Payload

Post a JSON with the following parameters in this order:

Parameter Description Format Example
payment_id The payment id of the transaction you want to check. string(10) 7ce25b4dc0
vendor_address Your vendor address, made of “etn-it” and your outlet id. string(20) etn-it-0abc123def456

Signature

Sign the payload by SHA-256 hashing the JSON using your API Secret.

If using PHP, this may look like:

// Your API Secret from your user vendor settings
$api_secret = 'sec_live_zxyxwvutsrqponmlkjihgfedcba0987654321zxyxwvutsrqponmlkj';

// The payload to be sent.
$payload = [
    'payment_id' => '7ce25b4dc0',
    'vendor_address' => 'etn-it-0abc123def456'
];

// Generate the signature
$signature = hash_hmac('sha256', json_encode($payload), $api_secret);

HTTP POST

You can then HTTP POST the JSON to https://poll.electroneum.com/vendor/check-payment including the signature in the header ETN-SIGNATURE.

If using PHP, this may look like:

// Post the request.
$ch = curl_init('https://poll.electroneum.com/vendor/check-payment');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'ETN-SIGNATURE: ' . $signature
]);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);

// Decode the JSON result into an array.
$result = json_decode($result);

// Check the result.
if ($result['status'] === 1) {
    // Payment made.
    echo "Payment made for " . $result['amount'] . " ETN";
} elseif ($result['status'] == 0) {
    // Payment not made.
} else {
    // Invalid request (e.g. invalid signature).
}

The API will return a JSON array of:

Parameter Description Format Example
status The result of the request:
0 Payment not sent by customer
1 Payment sent by customer
int(1) 1
message An error message (only present if status=0) string Vendor address unknown
amount The amount paid (only present if status=1) decimal 123.45

To avoid being blocked by our API, please restrict your poll to no more than one request per second.

WARNING: You should confirm that the amount is the value you expected to be paid.

PHP API

We have provided a PHP library to help you integrate with our API as efficiently as possible https://github.com/electroneum/vendor-php.

This contains a README.md file with full details and demonstration integration code in the /example directory. Example usage may look like:

// Generate the URL for a QR image for Outlet Id 0abc123def456 and for 9.95 GBP.
$vendor = new \Electroneum\Vendor\Vendor($apiKey, $apiSecret);
$qr = $vendor->getQr(9.95, 'GBP', '0abc123def456');

// Verify a received webhook is valid.
$payload = @file_get_contents('php://input');
$signature = @$_SERVER['HTTP_ETN_SIGNATURE'];
$isValid = $vendor->verifySignature($payload, $signature);

// Check if a payment is sent.
$payload = [
    'payment_id' => '0abc123def456',
    'vendor_address' => 'etn-it-0abc123def456'
];
$result = $vendor->checkPaymentPoll(json_encode($payload));

Brand Assets

We have brand assets available at https://electroneum.com/brand-assets/ to show users that you accept ETN as payment.

Integration Complete

Once your integration is live, you should update the outlet in your vendor account to enable how users to can spend ETN. There are two options; one for websites and one for ePOS (retail stores).

Let us know when your integration is live, we’d love to share the news! You can share images & videos on Twitter, Facebook or on the community forum.

10 Likes

Hello, Please confirm that vendors do not need to apply for BETA if they’ve already done so at the first announcement on Facebook. Thanks so much!

2 Likes

Please correct this. ZAR is South African Rand, not Zimbabwe Dollar.

4 Likes

Hello, also remove the semi-colon : at the end of the link. It’s concatenated to the link and returns a 404 not found.

1 Like

Alot of the links to the vendor parts are not working. Will the content be added soon to view?

1 Like

Can anyone make a video showing how to do all of this? I’m more of a visual guy.

5 Likes

Try and add Nigeria Naira. Etn fan base is high in Nigeria

5 Likes

Thanks for the excellent write up. A lot of links such as the one below is still inactive. Just letting you know. Can’t wait for when it launches!

2 Likes

That’s correct, those who have already applied to be Beta do not need to apply again. You should receive an email shortly confirming when the URLs are live. Thanks!

2 Likes

Thanks for that, you are quite right. ZAR has been updated to the South Africa Rand.

2 Likes

Does anyone know how I can Implement this into my prestashop website. This is urgent as I have a already running business that accepts ETN. And many more ideas. However I’m not that great at making modules for prestashop that’s the problem. I can design and do little bits of code. Someone must be able to help me accept etn on my sites.

1 Like

Heyy, well my community account says I’m a beta tester! I applied to be a beta tester too but I’ve had no email and no instructions so literaly no idea what to do or how to use it :sweat_smile:

1 Like

Good work @Egg !
Just correct please Czech Republic Koruna instead of Czech Repucalic Koruna in the currency table.
Thank you!

2 Likes

Most certainly thinking of putting something like a video together! ; )

1 Like

Thank you for the thorough write-up! Can’t wait!! :grinning: :+1:

2 Likes

@Rothomson I haven’t received one yet. So far it seems as if the API is still inactive. My guess is that they’ll launch it this week.

2 Likes

Thanks mate! Didn’t realise that. I appreciate your reply.

1 Like

Thanks! The text has been updated to Czech Republic Koruna.

2 Likes

Hello. Don’t worry about the email on BETA testing it will be with you very soon!

3 Likes

IT IS NOW! : ) Thank you!! : )

1 Like