How to start accepting crypto payments in your online store?

accept crypto bitcoin usdt on website

Accept cryptocurrency on your website in 5 minutes with Mitilena Payprocessing company for accepting cryptocurrencies on the site

1. Register in our system, registration is instant, no confirmation is required.
2. Connect your store via API or WordPress Woocommerce plugin.
3. Start accepting payment for your goods in cryptocurrency!
4. Withdraw cryptocurrency to any of your wallets without any restrictions.


Our features for accepting cryptocurrencies:
  • Quick registration
  • Connect in 5 minutes at any time, seven days a week
  • USDT support on three blockchains (ERC20 Ethereum, TRC20 Tron, BEP20 Binance Smart Chain)
  • Ready plugin for WooCommerce (WordPress)
  • The first 90 days commission is 0%, then 0.8%

We currently support the following cryptocurrencies: USDT, VMT, APFC.
We can add the cryptocurrency you need upon request.

A little more detailed:

  1. When a user chooses to pay with cryptocurrencies in the shopping cart, he is redirected to the page of our system for paying in cryptocurrencies.
  2. The price formation process is as follows: the cost of the whole order is converted into USD, and then into cryptocurrency. The rate is calculated by the official Central Bank of your country, without commission.
  3. Payments in USDT cryptocurrency are very fast, about 3 seconds. After payment, the user’s payment page signals to him that the payment was successful. You, as the owner of an online store, receive an email that the payment was successful.
  4. From our system, you can withdraw cryptocurrency to any other address at any time. We advise you to withdraw to your cold wallet in our wallet.


How are payments tracked?

Payments are tracked according to our unique system, by adding unique numbers to each payment, which do not directly affect the price, but allow you to identify the payment, and more importantly, allow you to save on collecting all payments later on 1 wallet.

How do I save with your payment tracking system?

Usually, when paying on the Internet through cryptocurrency, the client always receives a new address for payment. Each invoice has a new payment address. That is, if you have 1000 orders per day, 1000 addresses will be generated for you and 1000 addresses will receive payment. In order to collect all payments later in one wallet, you will need to pay 1000 times the commission, even if you put many addresses in one transaction, it will be very expensive. In short, 1000 transactions = 1000 fees (for example, one dollar per transaction). This greatly increases the cost of this payment method. With us, because of the unique technology and therefore the differing amounts per one millionth of a dollar, we collect 1000 payments to one address and only then change it. It turns out savings on commissions by 1000 times.

What other benefits?

We have the fastest system on USDT, the payment takes a few seconds, for the first few blocks and the status is Success. Due to the use of stablecoins, there is less volatility on the exchange rate, which allows you to use the cryptocurrency as a regular payment instrument with minimal risks, but with very good anonymity, even if you do not need it.

How then to withdraw the collected cryptocurrency?

Choose any address from your hot wallet, pay a commission of 1 USDT and send.

Do I need to verify the store or company to get started?

Not needed at the moment. In the future, some jurisdictions around the world may need it.

If the payment fails, will it be possible to manually resend the payment link?

Yes, you can send a payment link through any messenger (or by mail). When paying a specific amount to a specific wallet, regardless of where the payer got this information and even through which third-party wallet he paid for it, the order will automatically receive the paid status.

Does your system send a separate email to the customer about the payment?

At the moment there is no email sending. We do not store your clients’ emails. But plans to send a letter, but again, we will not store customer emails.

Does your platform store any information?

Stores your email without further explanation, as well as anonymized history of anonymized transactions without being tied to the address of your online store. We do not even store the address of your online store.

Are there any trackers tracking information on your end?

From our side there is no tracker, marketing cookies and so on. AdGuard AdBlocker shows proud 0 and we are proud of it.

Does your platform share customer information?

No, and we don’t plan to.

What fiat currencies does your plugin support?

Approximately 147 world currencies, i.e. Almost all. Attention, the USDT rate is not always exactly 1 dollar. Sometimes it is 0.999 or 1.001. Indirectly, this also applies to other currencies, first your currency is taken, for example, the Norwegian krone, it is converted to US dollars at the rate of the National Bank of Norway, and then USD is converted to USDT at the average rate of the tracker (coingecko or coinmarketcap).

Can I add my own cryptocurrency to your system?

At the moment, if your cryptocurrency is on the Tron blockchain and under the TRC20 protocol (03.09.2023, also added the ability to ERC20 Ethereum and BEP20 Binance Smart Chain tokens), there are the following possibilities:

  1. Within only your store or chain of stores (up to 10-15), we can add your cryptocurrency for 1990 USDT, payment link, after payment, write us an email at, specify the exact store addresses, information about your token and we will give these stores additionally your coin via API. Your users will be able to pay you with your own cryptocurrency. We can set the rate, both hard and from open sources (coinmarketcap, coingecko).
  2. If you want to add your coins to our entire network, you need to own at least 1% of our shares.

The rest of the blockchains are on the way, if you send us an email with your blockchain and how we implement it, we will let you know.

Our payment system is focused on everyday smooth use, so we prefer stablecoins. However, we plan to accept Bitcoin and other more volatile currencies in the near future.

If you want to clarify something, write to our technical support. Attention, tech. support works only for Premium users, becoming a premium user, you will get the opportunity to download the application for signing transactions offline and other advantages. Cost from $2 per month. Also try our super secure offline private key generation system to be sure that the private key of your wallet belongs only to you. Well, and our wallet, where you can use your cryptocurrency without sending your private key anywhere, but keeping it on your computer or flash drive.


API connection instructions for developers

  1. You need to get an API key in our system in the “Settings” section. Registration takes approximately 5 seconds. Initial review and confirmation of your store is not necessary. You can start accepting cryptocurrency immediately and withdraw it immediately.
  2. When the order is placed in your online store and the total cost of the order is ready on your part, you create a JSON object, which you send to our server with a POST request.
  3. We register your possible payment request, in response we send you our internal order number and a payment link.
  4. You redirect the user to this payment page, he pays, he is automatically redirected back to your site.
  5. We contact your site with a hidden request and tell you that the order is paid (this is done through the so-called webhook). You put the order in your database as paid (automatically) and then the process is standard for you, like any other paid order.

If your online store is powered by WordPress (WooCommerce), then you don’t need to program anything, we have a ready-made plugin for accepting cryptocurrency, follow the link for instructions and the plugin itself


API description:

Step 2, creating a JSON object (JavaScript example).

Possible values for the blockchain field, take the value from the quotes (for example: tether-trc20):

'tether-erc20' (ERC20 Ethereum USDT, contract: 0xdac17f958d2ee523a2206206994597c13d831ec7)

'tether-bep20' (BEP20 Binance smart chain USDT, contract: 0x55d398326f99059ff775485246999027b3197955)

'tether-trc20' (TRC20 Tron USDT, contract: TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t)

'mitilena-own' (Vanishing Mitilena, VMT token)
'apfcoin' (ERC20 Ethereum APFC, contract: 0x8eD955a2b7d2C3a17a9d05dACa95E01818f8C11e)


let createPaymentObj =
        userSecret: 'your_API_key', // required
        userPaymentId: 'your_payment_id_usually_order_id', // required
        blockchain: 'tether-trc20', // required 
        fiatCode: '3x_ISO_code_of_your_fiat_currency_for example_EUR', // required
        customerEmail: 'customer_mail', // required

        fiatAmount: 'digit_amount_in_fiat_currency_for_example_100', // number, required
        userProductId: 'your_product_id_if_any', // not required
        language: 'two_digit_ISO_language_code', // default en, not required [available: en, cz, ru, tr, my, hr, si, ar, swa] - the rest will be an error
        // redirectUrl_yours: 'thank_you_page or success_page',
        redirectUrl_yours: 'url_on_your_site_where_to_send_user_after_successful_payment', // not required, but very desirable
        webHookPostUrl_yours: 'url_on_your_site_where_the_hidden_POST_request_will_go_on_successful_payment,' // required

In the headers of the request, you also need to insert your API key: ‘mitilena-signature’: ‘your_api_key’
It looks something like this:

headers: {
     'Content-Type': 'application/json',
     accept: 'application/json',
     'mitilena-signature': 'your_key',

And send it as a POST request to the address:

If the creation of the invoice was successful, then the server response will be with the code 200 and the response will contain a JSON object, for example, something like this:
From this response you only need 2 fields, invoiceId and paymentPage. You must send (redirect) the user to the payment page to the Mitilena Pay website [paymentPage field]!

  usdtOverAmount: '1.580437',
  invoiceId: 'auto-e80099-ef456c-e0de42',
  invoiceVs: '0437',
  fiatAmount: '1.450',
  fiatCurrency: 'EUR',
  rateLocalCurrencyToNeededCrypto: '0.917',
  rateNeededCryptoToUSD: '0.99959700',
  isTrc20: 1,
isErc20: 0,
isBep20: 0, whenInit: '2023-08-22T11:30:05.000Z', contractAddress: 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t', customerEmail: '', productId: 85, expiresAt: '2023-09-05T11:30:05.000Z', blockchainHash: null, cryptoShortCode: 'USDT', cryptoValue: '1.580437', fiatValue: '1.450', receivedOnAddress: 'TRHpcBugcdEdD6BdW6k1Grtof6LBvRGWWJ', txId: 'auto-e80099-ef456c-e0de42', fiatShortCode: 'EUR', wasPaid: null, redirectUrl: '', paymentPage: '' }

If an error occurs, the server response will be with a 400 code and the response will contain a String, the error text.
The lifetime of such a link is 14 days. There are plans to make it possible to choose the lifetime of the link.

JavaScript examples (node.js version 16.8)
const https = require('https');
const url = require('url');

const data = JSON.stringify({
    userSecret: '',
    userPaymentId: 'userPaymentdId111',
    blockchain: 'tether-trc20',
    fiatCode: 'EUR',
    customerEmail: '',

    fiatAmount: 1.45,
    userProductId: 'new_someGoodsOk',
    language: 'en', // default en, not neccessary
    // redirectUrl_yours: '',
    redirectUrl_yours: '',
    webHookPostUrl_yours: ''

const myURL = url.parse('');

const options = {
    hostname: myURL.hostname,
    port: myURL.port,
    path: myURL.pathname,
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        accept: 'application/json',
        'mitilena-signature': '',

requestAsync(options, data)
    .then(dataFObj => {
        if (dataFObj.statusCode === 200) {
            let tokensObj = JSON.parse(dataFObj.dataRaw);
            console.log('success:', tokensObj)
        } else {
            console.log('error dataFObj', dataFObj);
            throw new Error('some errror in postToWebHook ' + dataFObj.dataRaw);
    .catch(e => {
        console.log('error request:', e)

function requestAsync(optionsArr, dataToPost = false) {
    return new Promise((resolve, reject) => {
        const req = https.request(optionsArr, (resp) => {
            // console.log(`statusCode: ${resp.statusCode}`);
            let dataF = '';
            // A chunk of data has been received.
            resp.on('data', (chunk) => {
                dataF += chunk;

            resp.on('end', () => {
                resolve({statusCode: resp.statusCode, dataRaw: dataF});
            }).on('error', (err) => {
                console.log('Error: ' + err);

        if (dataToPost) {


The url module in Node.js above version 16 seems to have changed the syntax, if anything, find information on this topic or enter the address and path manually.

Examples in PHP and WordPress:
Query using a WordPress function wp_remote_post(), check out the pure PHP function, it will look something like this:
$request_body = [
    'userSecret' => $this->mitilenaToken,
    'userPaymentId' => $order->id,    
  'blockchain' => 'tether-trc20', 'fiatCode' => $order->currency,    
  'customerEmail' => $order->get_billing_email(), 'fiatAmount' => $order->get_total(), 'userProductId' => $orderids, 'language' => 'en', // default en, not neccessary 'redirectUrl_yours' => $order->get_checkout_order_received_url(), 'webHookPostUrl_yours' => '' ]; $request_headers = [ 'content-type' => 'application/json', 'mitilena-signature' => $this->mitilenaToken, ]; $args = [ 'method' => 'POST', 'httpversion' => '1.0', 'timeout' => 90, 'headers' => $request_headers, 'body' => '' ]; $environment_url = ''; $result = wp_remote_post($environment_url, array( 'method' => 'POST', 'headers' => $request_headers, 'timeout' => 60, // added 'redirection' => 5, // added 'blocking' => true, // added 'httpversion' => '1.0', 'sslverify' => false, 'body' => json_encode($request_body)) ); $fullObj = json_decode($result['body']); if (isset($result['response']) && isset($result['response']['code']) && $result['response']['code'] != 200) { $mi__err_message = 'Unknown error'; if (isset($result['body'])) { $mi__err_message = 'Error: ' . $result['body']; } // error handling + exit exit; } if (!isset($fullObj->paymentPage)) { http_response_code(400); // Bad Request echo "Error: No payment page specified"; exit; } $paymentPage = $fullObj->paymentPage; if (strlen($paymentPage) < 5) { http_response_code(400); // Bad Request echo "Error: payment page is too short."; exit; } ?>


Step 5, creating a WebHook handler on the side of your site (server):

On the example of Node.js 16.8 version and Express.js 4 version (JavaScript)
const bodyParser = require('body-parser');
const Big = require('big.js')
let endpointSecret = 'copy of the api key value'

// an object called statusObj arrives'/mi_webhook/', bodyParser.json(), (request, response) => {

    try {
        let eventObj = request.body;
        const signature = request.headers['mitilena-signature'];

// compare the incoming secret key with your real one
        if (signature === endpointSecret) {
            if (!eventObj.statusObj) {
                return response.status(400).send('Error, no object.');

            let hookObj = eventObj.statusObj;

            if (
                typeof hookObj.mitilenaInvoiceId === 'undefined' ||
                typeof hookObj.yourPaymentId === 'undefined' ||
                typeof hookObj.yourProductName === 'undefined' ||
                typeof hookObj.yourProductId === 'undefined' ||
                typeof hookObj.secretKey === 'undefined' ||
                typeof hookObj.stableCoinAmount === 'undefined' ||
                typeof hookObj.stableCoinSymbol === 'undefined' ||
                typeof hookObj.stableCoinBlockchain === 'undefined' ||
                typeof hookObj.localCurrencyAmount === 'undefined' ||
                typeof hookObj.localCurrencyCode === 'undefined' ||
                typeof hookObj.wasPaid === 'undefined' ||
                typeof hookObj.blockchainHash === 'undefined'
            ) {
                return response.status(400).send('Error, incomplete object.');

            if (hookObj.wasPaid === true) {
                let centsAmount = Big(hookObj.localCurrencyAmount).times(Big(100)).round(0).toNumber();

// put the order in your database as paid and return the status code 200
// this is an example of our code, yours may look different
                    .completeUserPayment(hookObj.mitilenaInvoiceId, centsAmount)
                    .then((okString) => {
                        return response.status(200).send('all good Mitilena token');
                    .catch((e) => {
                        console.log('err in completeUserCardPayment', e.message);
                        return response.status(400).send('error, contact support');
            } else {
                return response.status(400).send('invoice was not paid');
        } else {
            return response.status(400).send('bad Mitilena token');
    } catch (e) {
        console.log('webhook err:', e.message);
        return response.status(400).send('bad request, error');
Using the PHP example:

Create a handler file and put it on your web server (site) so that it is accessible from the outside, i.e. if you write the full path to the file so that it opens, for example (this is an example, you can do it differently, through routing, etc.).

As mentioned above, specify this address in the object in which you create a payment link, i.e.
webHookPostUrl_yours: ‘’

File contents:

$mi__jsonData = file_get_contents('php://input');
if (!$mi__jsonData) {
    http_response_code(400); // Bad Request
    echo 'bad input data';
// Decode the JSON data into a PHP associative array
$mitilena_data = json_decode($mi__jsonData, true);

// Check if decoding was successful
if ($mitilena_data !== null && isset($mitilena_data['statusObj'])) {
    $mitilena_data = $mitilena_data['statusObj'];

    if (!isset($mitilena_data['secretKey'])) {
        http_response_code(400); // Bad Request
        echo "Error: Api key of Mitilena (Mitilena Token) is not specified. We can't verify if the request is genuine. Cancellation of a transaction.";
    $mitilenaToken = $mitilena_data['secretKey'];

    // compare your real API key with the one you received
    $realMitilenaToken = 'your_api_key'

    if ($mitilenaToken != $realMitilenaToken) {
        http_response_code(400); // Bad Request
        echo "Error: API token does not match. The website owner must specify the correct Api Mitilena token.";

    if (!isset($mitilena_data['yourPaymentId'])) {
        http_response_code(400); // Bad Request
        echo "Error: No payment id specified";
    $mi__paymentId = $mitilena_data['yourPaymentId'];

    if (strlen($mi__paymentId) < 1) {
        http_response_code(400); // Bad Request
        echo "Error: too short payment id.";
    function mi__pay_escapeString($var)
        $var = stripslashes($var);
        $var = htmlentities($var);
        $var = strip_tags($var);
        return $var;

    // yourPaymentId
    try {
        $mi__order = '';  // search your database for this order, mi__pay_escapeString($mi__paymentId)
    } catch (Throwable $e) {
        http_response_code(400); // Bad Request
        echo "Error: wrong payment id (order id). {yourPaymentId: \"\"}";

    if (!isset($mitilena_data['wasPaid'])) {
        http_response_code(400); // Bad Request
        echo "Error: No payment status specified";
    $mi__wasPaid = $mitilena_data['wasPaid'];

    if ($mi__wasPaid == true) {

        $blockchainHash = '';
        if (isset($mitilena_data['blockchainHash'])) {
            $blockchainHash = mi__pay_escapeString($mitilena_data['blockchainHash']);

        // set the order as paid in your database
        // reduce inventory if required
        // send the user an email if required

        echo 'success';
    } else {
        echo 'unpaid status received';
 } else {

    // JSON decoding failed
    http_response_code(400); // Bad Request
    echo "Invalid JSON data";


That’s all, if you have any questions, ask in the comments.

Don’t have a developer to implement this for you? Write to us at, we will make you a commercial proposal for the developer’s work on connecting crypto-payments.

Leave a Reply

Your email address will not be published. Required fields are marked *