Create an invoice

invoice scheme

1. Create your website and get the “SECRET_KEY”. Instruction can be found here.

2. Send the “GET” request to create an invoice

 

Endpoint:

https://plisio.net/api/v1/invoices/new

cURL request example:

curl --location --request GET https://plisio.net/api/v1/invoices/new
  ?source_currency=USD
  &source_amount=2
  &order_number=1
  &currency=BTC
  &[email protected]
  &order_name=btc1
  &callback_url=http://test.com/callback
  &api_key=SECRET_KEY

List of all supported request fields:

FieldDescription
currencyone of the cryptocurrencies supported by Plisio (ID column from supported cryptocurrencies). Optional parameter. If the parameter is not set, one of the active cryptocurrencies from the API settings is selected automatically when creating an invoice.
order_name *merchant internal order name
order_number *merchant internal order number. Must be an unique number in your store for each new store`s order!!!
amountany cryptocurrency float value.
If a fiat currency is to be converted, skip this field and use the source_currency and source_amount fields instead
source_currencyone of the 167 fiat currencies
source_amountany float value
allowed_psys_cidscomma-separated list of cryptocurrencies that are allowed for a payment. Also, you will be able to select one of them. Example: 'BTC,ETH,TZEC';. To display one currency, need allow_psys_cids to match the currency parameter
descriptionmerchant invoice description
callback_urlmerchant full URL to get invoice updates. The POST request will be sent to this URL. If this parameter isn’t set, a callback will be sent to the URL that can be set under profile in API settings, in the 'Status URL' field;. When adding json=true to the url, the response will come in the form of JSON
success_callback_url merchant full URL to get succeed invoice. When adding json=true to the url, the response will come in the form of JSON
fail_callback_url merchant full URL to get failed invoice. When adding json=true to the url, the response will come in the form of JSON
emailBefore paying an invoice, your client will be asked to enter an email to which a notification will be sent. If you want to skip this step for your clients, fill in this field beforehand (with any information acceptable).
languageen_US (supports English only)
pluginPlisio’s internal field to determine integration plugin
versionPlisio’s internal field to determine integration plugin version
redirect_to_invoiceInstead of JSON response user will be redirected to the Plisio's invoice page (is not working for a white-label shop)
api_key“Secret key” value from your API » Api settings page
expire_minInterval in minutes when invoice will be expired

* - required

 

3. The response is a model that can fill differently depending on whether you have While Label or not. In the first case, only two fields are returned: txn_id is a Plisio’s intertnal ID and invoice_url is an invoice URL. And in the second case, extra fields are added to them:

 

Success response example:

 {
    "status": "success",
    "data": {
      "txn_id": "5ee0e502283675293c450d0e",
      "invoice_url": "https://plisio.net/invoice/5ee0e502283675293c450d0e"
    }
  }

White-label success response example:

 {
    "status": "success",
    "data": {
      "txn_id": "5f3268bcb7a85576c50d6307",
      "invoice_url": "https://plisio.net/invoice/5f3268bcb7a85576c50d6307"
      "amount": "0.00017305"
      "pending_amount": "0.00017305"
      "wallet_hash": "2Mvt2KbPfF7SFsVrPe7wqbcWKiJx6DmXKQM"
      "psys_cid": "BTC"
      "currency": "BTC"
      "status": "new"
      "source_currency": "USD"
      "source_rate": "0.00008525"
      "expire_utc": 1597175132
      "expected_confirmations": "1"
      "qr_code": "data:image/png;base64..."
      "verify_hash": "13e34f5f9efeb5394d7ab5f432df5cc856cc38a4"
      "invoice_commission": "0.00005550"
      "invoice_sum": "0.00364490"
      "invoice_total_sum": "0.00370040"
    }
  }

HTTP response status code: 200

 

Success response:

FieldDescription
statussuccess
data.txn_idPlisio’s intertnal ID
data.invoice_urlInvoice URL

White-label additional data:

FieldDescription
amountInvoice amount in the selected cryptocurrency
pending_amountThe remaining amount to be paid in the selected cryptocurrency
wallet_hashInvoice hash
psys_cidCryptocurrencies ID (supported cryptocurrencies)
currencyCryptocurrencies code (supported cryptocurrencies)
source_currencyFiat currency
source_rateExchange rate from the “psys_cid” to the “source_currency” at the moment of transfer
expected_confirmationsHow many confirmations expected to mark invoice completed
qr_codeQR code image in base64 format
verify_hashHash to verify the “POST” data signed with your SHOP_API_KEY (PHP code example)
invoice_commissionPlisio commission
invoice_sumShop pays commission:
invoice amount - invoice_commission,
client pays commission: invoice amount
invoice_total_sumshop pays commission:
invoice amount,
client pays commission: invoice_commission + invoice_sum

Error response example:

 {
    "status": "error",
    "data": {
      "name": "Bad Request",
      "message": "Missing required attribute: {\"name\":\"order_number\"}",
      "code": 103
    }
  }

HTTP response status code: 400, 401, 422, 500

 

Error response:

FieldDescription
statuserror
data.nameerror name
data.messageerror explanation
data.codeerror code

4. Expect invoice updates if the “callback_url” was entered in the invoice request. Status=completed

 

Callback:

POST http://test.com/callback

FieldDescription
txn_idPlisio transaction ID
ipn_typeinvoice
merchantmerchant site name
merchant_idmerchant site ID
amountreceived amount in the selected cryptocurrency
currencyselected cryptocurrency
order_numbermerchant internal order number
order_namemerchant internal order name
confirmationsblock confirmations number
statusnew - initial invoice status
pending - some amount received and waiting for confirmations
pending internal - moving invoice money to user wallet has been initiated
expired - look for the “source_amount” field to verify payment. The full amount may not have been paid.
completed - paid in full
mismatch - overpaid
error - some error has occurred
cancelled - no payment received within 10 hours
source_currency“source_currency” if stated
source_amountamount in the “source_currency” if stated
source_rate“source_currency” cryptocurrency exchange rate
commentPlisio’s comments
verify_hashHash to verify the “POST” data signed with your SECRET_KEY
Code example
invoice_commissionPlisio commission
invoice_sumshop pays commission: invoice amount - invoice_commission
client pays commission: invoice amount
invoice_total_sumshop pays commission: invoice amount
client pays commission: invoice_commission + invoice_sum

White-label additional data:

FieldDescription
psys_cidCryptocurrencies ID (supported cryptocurrencies)
pending_amountInvoice amount in the selected cryptocurrency
qr_codeQR code image in base64 format
tx_urlsArray of transaction URLs

Callback data PHP verification example:

function verifyCallbackData () {
  if (!isset($_POST['verify_hash'])) {
    return false;
  }
  $post = $_POST;
  $verifyHash = $post['verify_hash'];
  unset($post['verify_hash']);
  ksort($post);
  $postString = serialize($post);
  $checkKey = hash_hmac('sha1', $postString, 'SECRET_KEY');
  if ($checkKey != $verifyHash) {
    return false;
  }
  return true;
}

Example getting callback data in Node:

Works if the url is callback_url, success_callback_url , fail_callback_url has the value json=true. Example: https://Localhost.loc/success?json=true .


const http = require("http");
const crypto = require('crypto');
const secretKey = 'SECRET_KEY';

const host = '127.0.0.1';
const port = 8000;

const vallidateRequest = function (data) {
  if (typeof data === 'object' && data.verify_hash && secretKey) {    
    const ordered = {...data};
    delete ordered.verify_hash;    
    const string = JSON.stringify(ordered);
    const hmac = crypto.createHmac('sha1', secretKey);
    hmac.update(string);
    const hash = hmac.digest('hex');
    return hash === data.verify_hash;
  }
  return false;
}

const requestListener = function (req, res) {
  let chunks = '';
  req.on('data', chunk => chunks += chunk);
  req.on('end', () => {
    let data;
    try {
      data = JSON.parse(chunks);
      res.setHeader("Content-Type", "application/json");
    } catch (e){
      // console.error(e);
      data = false;
    }

    if (data && vallidateRequest(data)) {
      res.writeHead(200);
      res.end('This is a correct JSON callback');
    } else {
      res.writeHead(422);
      res.end('Incorrect data 1');
    }
  })
};

const server = http.createServer(requestListener);
server.listen(port, host, () => {
  console.log(`Server is running on http://${host}:${port}`);
});