NAV Navbar

Overview

Authentication

auth = Base64.urlsafe_encode64 "#{api_key}:#{api_secret}"
headers = {
  'Authorization' => "Basic #{auth}",
  'Content-Type' => 'application/json',
  'Accept' => 'application/json'
}

To connect to our Payment API, you will need to construct and send HTTP Basic Authentication headers with each request. Our endpoint requires data to be sent in JSON format, make sure the Content-Type in your header is set to application/json.

Response Status Codes

Status Description
200 Payment found
201 Payment created
401 Unauthorized - check that the API key and secret have been set properly in the request Authorization header
404 Record not found
422 Unprocessable entity - check that all required request fields have been entered correctly
500 Internal server error
503 Service unavailable - service is undergoing maintenance

Errors

Example Responses

{
  "title": "Unauthorized",
  "code": "1001",
  "details": "Your user has not been authorized to access this endpoint"
}
{
  "title": "Invalid currency type",
  "code": "2004",
  "details": "The currency type submitted is invalid",
  "source": [{ "crypto_iso": "Invalid" }]
}

Errors will be returned in the following format

Field Type Description
title string Short message identifying the error
code string 4-digit error code
details string Text message describing the error
error string Optional, includes more specific error details
source array Optional, present when validation fails, an array of objects with the key corresponding to the invalid field and value the reason

Sandbox Mode

To make development easier we provide merchants with sandbox API keys and live API keys. Using the sandbox API keys merchants can simulate creating and processing transactions without making any blockchain transactions. Transactions created in sandbox mode can also be viewed in the Merchant Gateway by clicking "Transactions" > "Sandbox Transactions".

By default all sandbox transactions will be set to paid but you can also use certain amounts to test other situations as detailed below.

Amount Description
100 Overpaid
200 Underpaid

Hosted Payments

Setup Hosted Payments Plugin

Before setting up a hosted payment page, you must create a new hosted payment plugin from the Merchant Gateway. On the dashboard sidebar select Hosted Payments and then click the blue circle plus icon.

You will be prompted for some information and a hosted payment page will be created. It is important to provide accurate information regarding your Domain, Payment Received URL, and Webhook URL as each of these are important in the submission process.

Domain The base URL of the website submitting requests to the NetCents API
Payment received URL The URL of the custom page that a user will be redirected to upon successfully submitting a crypto deposit.
Webhook URL The server will return a response to this URL when the deposit has been confirmed. Note: This URL must be able to accept POST requests and cannot be protected by any form of authorization.

Create Widget Payment

To create a Widget Payment make a POST request to the below endpoint, the response will include a token that you should use to redirect your customer to https://merchant.net-cents.com/widget/payment?data=<token>.

For details on the authentication scheme please see Authentication.

Example Request

require 'rest-client'
require 'json'

headers = {
  'Authorization' => 'Basic ZnJlZDpmcmVk',
  'Content-Type' => 'application/json',
  'Accept' => 'application/json'
}

params = {
  external_id: "123",
  hosted_payment_id: 100,
  amount: "5.45",
  email: "[email protected]",
  first_name: "John",
  last_name: "Smith",
}

result = RestClient.post 'https://api.net-cents.com/merchant/v2/widget_payments',
  params: params, headers: headers

p JSON.parse(result)

POST https://api.net-cents.com/merchant/v2/widget_payments

Request Parameters

Field Type Required Description
amount string Yes The amount owing on the invoice, in your default merchant currency (ie. USD). The amount will be converted in to the endpoint cryptocurrency (Bitcoin, Ethereum, Litecoin etc.) using the current market value. Characters allowed: 0-9 . Must be a decimal number. Eg. 150.00
external_id string Yes ID or Order number or any reference to your transaction
hosted_payment_id integer Yes Hosted payment plugin ID
callback_url string No URL to redirect customer to after a payment is made, defaults to value of Payment Received URL configured on plugin
webhook_url string No URL to receive webhooks after a payment is made, defaults to value configured on plugin
cancel_url string No URL the customer is redirected to upon cancelling, defaults to value configured on plugin
first_name string Yes The customer's first name. Characters allowed: a-z A-Z . ' and -
last_name string Yes The customer's last name. Characters allowed: a-z A-Z . ' and -
email string Yes The customer's email address. Characters allowed: 0-9 a-z A-Z . ! # \$ % & ' * + - / = ? ^ _ ` and {"
address string No The customer's billing address. Characters allowed: 0-9 a-z A-Z / . ' and -
city string No The customer's billing city. Characters allowed: a-z A-Z
province string No The customer's state or province . Characters allowed: a-z A-Z
country string No The ISO-3166 2 character country code of the customer
phone string No The customer's phone number. Characters allowed: 0-9
invoice_number string No Invoice number to reference payment, must be unique, will be generated if omitted
crypto_currency_iso string No Provide a cryptocurrency ISO to skip currency selection screen
confirmations_required integer No Number of confirmations required, see confirmations required

Response Schema

Example Response

{
  "status": 200,
  "id": 12038,
  "token": "832d5fb2773cb3edc99447bb71d6630851230b24095a3b356339dae2f2c1f86c18b4e7e572183ec1342b"
}
Name Type Description
status integer 200
id integer Unique ID for Widget Payment
token string This is the token that should be included in the URL the customer is redirected to

Payment Received Redirect

The customer will be redirected to the URL provided in two scenarios:

If the param callback_url was submitted to create the Widget Payment the customer will be redirected to that URL. Otherwise we will use the value configured in the Merchant Gateway appended with the external_id as a query param. For example: https://example.com?external_id=<external_id>

Payment Confirmation

To update your system when a payment is processed you will need to configure an endpoint to receive webhooks. Please see the Webhooks section for details.

V2 Upgrade Guide

Upgrading your Hosted Payments integration from V1 to V2 should be reasonably straightforward, however there are a few key differences.

Payments

There is a number of important considerations for processing cryptocurrency payments. Please read the below sections carefully before integrating the payment API.

Display Crypto Address and Amount Due

When displaying payment information to the customer, there are a few important pieces of information to display. The amount due must be displayed for the customer to the correct decimal precision so that they send the correct amount.

Also, the payment address must be displayed, for XRP payments a destination tag is also provided that the customer must use to identify the payment. Optionally, you may also choose to encode the amount due and the address and display it as a QR code. This allows users to scan the QR code using a mobile wallet app and send a payment more conveniently. Several open source libraries exist to generate QR codes in different environments and it should be relatively straightforward to include one on your payment page.

If you choose to include a QR code, be aware that there are generally accepted URI schemes for encoding the QR code for each currency. To be sure you are using the correct URI scheme for a currency, it is worthwhile to do a web search to get the exact specifications of each URI encoding standard. At the time of writing the URI encoding scheme for displaying Bitcoin, Litecoin, and Bitcoin Cash addresses is:

<currency name>:<address>[?amount=<amount>][?label=<label>][?message=<message>]

For example:

bitcoin:13pvQHKVfBokNRZsQvynSPTkxRgcH4RPa4?amount=0.01

The URI scheme for Ethereum is:

ethereum:<address>[?value=<value>][?gas=<suggestedGas>][?data=<bytecode>]

For example:

ethereum:0xe3d428d312a385261d5239a5de85603d8cd67f8a?value=0.2

Expiring Payments and Time Limits

Most blockchain payments are found on the blockchain within a minute or less of being sent from a cryptocurrency wallet. With that in mind, customers must send a payment within five minutes of the address being displayed. We recommend that your web application incorporate a timer and force the user to reload their page after five minutes. If they have sent their payment within five minutes, but it has not been found in that time, their payment will still be processed once it is found. If, however, they have not sent a payment within five minutes, they should reload the page and generate a new payment address.

Updating a Payment

In order to monitor the status of a payment merchants can either set up an endpoint to receive webhooks or intermittently poll the Query a Payment endpoint, see Webhooks or Query a Payment for details.

If you choose to use polling we recommend that your app make making API calls every 5 seconds until the payment has been found. Once it is found, you may display an invoice to your customers.

After the payment has been found, you should continue to monitor the transaction until it is confirmed, but you may make API calls less frequently. We recommend every minute or more after it has been found.

Handling the Result

As soon as a payment has been found on the blockchain, you will see the ‘amount_received’ in the JSON response body. You may compare this value to the ‘amount_due’ to see if the right amount has been sent. If the amount received is different than the amount due, its status will show as ‘underpaid’ or ‘overpaid’ once the transaction has been confirmed on the blockchain.

Transactions with these statuses will not be included in regular payouts until some action has been taken by you or someone in your organization. To acknowledge that action has been taken, you must log into your merchant account and manually mark overpaid or underpaid transactions as ‘completed’. Once transactions have been marked completed, they will then be included in your next payout.

It is up to your organization how to handle overpaid or underpaid transactions. Some (but not all) of the options available are:

Create a Payment

Example Request

require 'rest-client'
require 'json'

headers = {
  'Authorization' => 'Basic ZnJlZDpmcmVk',
  'Content-Type' => 'application/json',
  'Accept' => 'application/json'
}
params = {
  payment: {
    email: "[email protected]",
    first_name: "John",
    last_name: "Smith",
    phone: "6045551234",
    address: "123 West Pender St",
    city: "Vancouver",
    state: "BC",
    zip: "V6E2S1",
    country: "CA",
    currency_iso: "CAD",
    amount: "150.00",
    invoice_number: "INV_001",
    ip: "127.0.0.1",
    crypto_iso: "BTC",
    confirmations_required: "6",
    webhook_url: "https://api.example.com/webhook"
  }
}

result = RestClient.post 'https://api.net-cents.com/merchant/v2/payments',
  params: params, headers: headers

p JSON.parse(result)

POST https://api.net-cents.com/merchant/v2/payments

Request Parameters

Field Type Required Description
amount string Yes The amount owing on the invoice, in your default merchant currency (ie. USD). The amount will be converted in to the endpoint cryptocurrency (Bitcoin, Ethereum, Litecoin etc.) using the current market value.Characters allowed: 0-9 .Must be a decimal number. Eg. 150.00
external_id string Yes ID or Order number or any reference to your transaction
currency_iso string Yes The merchant currency ISO code. (USD, CAD, or EUR)
crypto_iso string Yes The cryptocurrency ISO code
confirmations_required string Yes Number of confirmations required. See confirmations required for more details
ip string Yes The customer's IP address IPv4 or IPv6 addresses. Characters allowed: 0-9 . and :
invoice_number string Yes Characters allowed: a-z A-Z 0-9 . Must be unique
first_name string Yes The customer's first name. Characters allowed: a-z A-Z . ' and -
last_name string Yes The customer's last name. Characters allowed: a-z A-Z . ' and -
email string Yes The customer's email address. Characters allowed: 0-9 a-z A-Z . ! # \$ % & ' * + - / = ? ^ _ ` and {
phone string No The customer's phone number. Characters allowed: 0-9
address string No The customer's billing address. Characters allowed: 0-9 a-z A-Z / . ' and -
city string No The customer's billing city. Characters allowed: a-z A-Z
state string No The customer's state or province. Characters allowed: a-z A-Z
zip string No The customer's postal/zip code. Characters allowed: a-z A-Z 0-9 / ' # and -"
country string No The ISO-3166 2 character country code of the customer
webhook_url string No URL of endpoint on merchant’s platform that will receive webhook POST response on payment confirmation.

Response Schema

Example Response - New Payment

{
  "id": 1,
  "amount": "150.00",
  "txid": "",
  "invoice_number": "INV_001",
  "amount_due": "0.01394475",
  "amount_received": "0",
  "exchange_rate": "6404.17",
  "exchange_rate_currency": "USD",
  "status": {
    "blockchain_status": "Pending",
    "transaction_status": null
  },
  "crypto_address_info": {
    "iso": "BTC",
    "address": "mmFdxH6cCVDK9DE7LbhrZjUyJCEkqz3Mqn",
    "cash_address": "mmFdxH6cCVDK9DE7LbhrZjUyJCEkqz3Mqn",
    "start_timestamp": 1510958854,
    "expires_timestamp": 1510959754
  },
  "url": "https://api.net-cents.com/merchant/v2/payments/1?crypto_iso=BTC"
}

Example Response - Paid Payment (Awaiting Confirmations)

{
  "id": 1,
  "amount": "150.00",
  "txid": "8ba1a12f4c459e0dc628dbcd86b372ffff4b043c943282f8b13d0f798cffaff7",
  "invoice_number": "INV_001",
  "amount_due": "0.01394475",
  "amount_received": "0.01394475",
  "exchange_rate": "6404.17",
  "exchange_rate_currency": "USD",
  "status": {
    "blockchain_status": "Paid",
    "transaction_status": "pending_confirmation"
  },
  "crypto_address_info": {
    "iso": "BTC",
    "address": "mmFdxH6cCVDK9DE7LbhrZjUyJCEkqz3Mqn",
    "cash_address": "mmFdxH6cCVDK9DE7LbhrZjUyJCEkqz3Mqn",
    "start_timestamp": 1510958854,
    "expires_timestamp": 1510959754
  },
  "url": "https://api.net-cents.com/merchant/v2/payments/1?crypto_iso=BTC"
}

Example Response - Confirmed Payment

{
  "id": 1,
  "amount": "150.00",
  "txid": "8ba1a12f4c459e0dc628dbcd86b372ffff4b043c943282f8b13d0f798cffaff7",
  "invoice_number": "INV_001",
  "amount_due": "0.01394475",
  "amount_received": "0.01394475",
  "exchange_rate": "6404.17",
  "exchange_rate_currency": "USD",
  "status": {
    "blockchain_status": "Confirmed",
    "transaction_status": "paid"
  },
  "crypto_address_info": {
    "iso": "BTC",
    "address": "mmFdxH6cCVDK9DE7LbhrZjUyJCEkqz3Mqn",
    "cash_address": "mmFdxH6cCVDK9DE7LbhrZjUyJCEkqz3Mqn",
    "start_timestamp": 1510958854,
    "expires_timestamp": 1510959754
  },
  "url": "https://api.net-cents.com/merchant/v2/payments/1?crypto_iso=BTC"
}

A successful request will respond with a new payment object and HTTP status code 201 (created): It will include the amount in the merchant currency ("amount") and the converted cryptocurrency amount will be shown as amount_due.

Field Description
id The id used to look up the payment
amount The invoice amount in the merchant's default currency
txid The Bitcoin blockchain transaction id, this will be blank unless a transaction is found on the blockchain
invoice_number The number for the invoice being paid
amount_due Converted crypto currency amount due
amount_received Amount sent by the users to the provided address
exchange_rate The market price of the transaction cryptocurrency used to covert fiat into cryptocurrency.
exchange_rate_currency Base currency for quoting the cryptocurrency price
status.blockchain_status Blockchain status. See Statuses for possible values
status.transaction_status Transaction status. See Statuses for possible values
crypto_address_info.iso Cryptocurrency ISO
crypto_address_info.cash_address Bitcoin Cash cash address. (Only displayed for Bitcoin Cash)
crypto_address_info.xaddress XRP X-address. (Only displayed for XRP)
crypto_address_info.destination_tag XRP destination tag. (Only displayed for XRP)
crypto_address_info.address The address to be provided to the customer for payment.
crypto_address_info.start_timestamp A UNIX timestamp marking the start time from which the address will accept payment for this invoice
crypto_address_info.expires_timestamp A UNIX timestamp marking the end time until which the address will accept payment for this invoice
url The URL used to look up the payment's details

Query a Payment

Example Request

require 'rest-client'
require 'json'

headers = {
  'Authorization' => 'Basic ZnJlZDpmcmVk',
  'Content-Type' => 'application/json',
  'Accept' => 'application/json'
}

result = RestClient.get 'https://api.net-cents.com/merchant/v2/payments/12810',
  params: {
    crypto_iso: 'BTC'
  },
  headers: headers

p JSON.parse(result)

GET https://api.net-cents.com/merchant/v2/payments/:payment_id?crypto_iso=<crypto_iso>

Query a Payment uses the same response schema as Create a Payment

Request Parameters

Name In Type Required Description
payment_id path string Yes ID number for the payment on the Merchant Gateway
crypto_iso query string Yes ISO4217 of the currency payment was made in

Transactions

Query All Transactions

Example Request

require 'rest-client'
require 'json'

headers = {
  'Authorization' => 'Basic ZnJlZDpmcmVk',
  'Content-Type' => 'application/json',
  'Accept' => 'application/json'
}

result = RestClient.get 'https://api.net-cents.com/merchant/v2/transactions',
  params: { limit: 50, currency_iso: 'BTC' },
  headers: headers

p JSON.parse(result)

GET https://api.net-cents.com/merchant/v2/transactions

Request Parameters

Field Type Required Parameters
limit integer No Number of transactions displayed, default 100, max 500
offset integer No Offset from last transaction. (Transactions are sorted in descending order based on time created)
currency_iso string No ISO of currency transaction paid in
status string No Transaction status. See Statuses for possible values
external_id string No External ID provided when creating a payment via the API
transaction_id string No Blockchain transaction ID
invoice_number string No Invoice number of the transaction

Response Schema

Example Response

{
  "transactions": [
    {
      "created_at": "2019-04-23T18:20:21.000Z",
      "id": 605,
      "amount_due": "0.16174936",
      "amount_in_fiat": "646.99744",
      "amount_received": "0.16174936",
      "status": "pending_confirmation",
      "external_id": null,
      "invoice_number": "6d06d511079bc4be082b9d162c20163c",
      "device_id": null,
      "txid": "cd98a3bb73422f4e4857a10c475511df",
      "exchange_rate": "4000.0",
      "is_sandbox": false,
      "fees": "0.003218812264",
      "description": "Bitcoin Payment John Smith email: [email protected]",
      "payout_id": 102,
      "currency": "BTC"
    }
  ]
}
Field Type Parameters
created_at string ISO 8601 UTC DateTime created
id integer Unique ID for transaction
amount_due string Amount due in cryptocurrency
amount_in_fiat string Amount due in fiat
amount_received string Amount received in cryptocurrency
status string Transaction status. See Statuses for possible values
external_id string Unique reference for the payment in merchant’s system.
invoice_number string Invoice number of transaction
device_id string Device id (if payment made via POS terminal)
txid string Blockchain transaction hash (txid)
settlement_method string "instant" or "manual"
exchange_rate string Exchange rate in merchant’s fiat currency (USD, CAD,or EUR)
is_sandbox boolean Is transaction a sandbox transaction.
fees string Transaction fees (In merchant’s fiat currency for "Instant Settlement" transactions and transaction cryptocurrency if "Manual Settlement")
description string Description of transaction. Can contain transaction type and user information (if provided).
payout_id integer ID of payout which includes current transaction (if transaction has been paid out)
currency string ISO 4217 of transaction currency.

Query a Transaction

Example Request

require 'rest-client'
require 'json'

headers = {
  'Authorization' => 'Basic ZnJlZDpmcmVk',
  'Content-Type' => 'application/json',
  'Accept' => 'application/json'
}

result = RestClient.get 'https://api.net-cents.com/merchant/v2/transactions/605',
  headers: headers

p JSON.parse(result)

GET https://api.net-cents.com/merchant/v2/transactions/:id

Request Parameters

Field Type Required Parameters
id integer Yes ID

Response Schema

Example Response

{
  "created_at": "2019-04-23T18:20:21.000Z",
  "id": 605,
  "amount_due": "0.16174936",
  "amount_in_fiat": "646.99744",
  "amount_received": "0.16174936",
  "status": "pending_confirmation",
  "external_id": null,
  "invoice_number": "6d06d511079bc4be082b9d162c20163c",
  "device_id": null,
  "txid": "cd98a3bb73422f4e4857a10c475511df",
  "exchange_rate": "4000.0",
  "is_sandbox": false,
  "fees": "0.003218812264",
  "description": "Bitcoin Payment John Smith email: [email protected]",
  "payout_id": 102,
  "currency": "BTC"
}

Query a Transaction uses the same response schema as Query All Transcations.

Invoices

Create an Invoice

The API can be used to create and query invoices, an invoice includes a URL that a recipient can visit directly in order to make a payment. Merchants can decide whether to have NetCents email the recipient directly or handle this themselves.

POST https://api.net-cents.com/merchant/v2/invoices

Example Request - new recipient

require 'rest-client'
require 'json'

headers = {
  'Authorization' => 'Basic ZnJlZDpmcmVk',
  'Content-Type' => 'application/json',
  'Accept' => 'application/json'
}

params = {
  invoice: {
    currency_iso: "CAD",
    amount: "150.00",
    email: "[email protected]",
    first_name: "John",
    last_name: "Smith",
    phone: "6045551234",
    address: "123 West Pender St",
    city: "Vancouver",
    state: "BC",
    zip: "V6E2S1",
    country: "CA",
    invoice_number: "INV_001",
    send_customer_email: true
  },
  save_recipient: true
}

result = RestClient.post 'https://api.net-cents.com/merchant/v2/invoices',
  params: params, headers: headers

p JSON.parse(result)

Example Request - existing recipient

require 'rest-client'
require 'json'

headers = {
  'Authorization' => 'Basic ZnJlZDpmcmVk',
  'Content-Type' => 'application/json',
  'Accept' => 'application/json'
}

params = {
  invoice: {
    currency_iso: "CAD",
    amount: "150.00",
    invoice_recipient_id: 8177,
    send_customer_email: true
  }
}

result = RestClient.post 'https://api.net-cents.com/merchant/v2/invoices',
  params: params, headers: headers

p JSON.parse(result)

Request Parameters

Field Type Required Description
amount string Yes The amount owing on the invoice, in your default merchant currency (ie. USD). The amount will be converted in to the endpoint cryptocurrency (Bitcoin, Ethereum, Litecoin etc.) using the current market value. Characters allowed: 0-9 . Must be a decimal number. Eg. 150.00
currency_iso string Yes The merchant currency ISO code. Must match account currency (USD, CAD, or EUR)
email string Yes* The recipient's email address. Required unless invoice_recipient_id is provided. Characters allowed: 0-9 a-z A-Z . ! # \$ % & ' * + - / = ? ^ _ ` and {"
company_name string Yes* The recipient's company name. Characters allowed: a-z A-Z . ' and -
first_name string Yes* The recipient's first name. Characters allowed: a-z A-Z . ' and -
last_name string Yes* The recipient's last name. Characters allowed: a-z A-Z . ' and -
phone string No The recipient's phone number. Characters allowed: 0-9
address string No The recipient's billing address. Characters allowed: 0-9 a-z A-Z / . ' and -
city string No The recipient's billing city. Characters allowed: a-z A-Z
state string No The recipient's state or province . Characters allowed: a-z A-Z
zip string No The recipient's postal/zip code. Characters allowed: a-z A-Z 0-9 / ' # and -
country string No The ISO-3166 2 character country code of the recipient
invoice_number string No Characters allowed: a-z A-Z 0-9 . Must be unique, will be generated if omitted
due_at string No Date payment is due, displayed for recipient and used for optional reminders. All invoices expire 90 days after due_at. Value should be a ISO 8601 UTC DateTime. Default: current time.
description string No Description of invoice to be displayed to recipient
invoice_recipient_id integer No ID of existing invoice recipient
send_reminders boolean No Optionally send recipient reminders 5 days before due_at and 2 days after. If invoice is due within one week only one reminder will be sent.
send_customer_email boolean No Specify whether to send the recipient an email with a link to the invoice. Default: false.
save_recipient boolean No Save recipient details as an Invoice Recipient for future use. Default: false.

Response Schema

Example Response

{
  "id": 14,
  "amount": 10.0,
  "invoice_number": "INV_14a076fba218b2e58c2625d767b996e5",
  "created_at": "2020-04-29T19:21:42.000Z",
  "expires_at": "2020-07-28T19:21:42.000Z",
  "due_at": "2020-04-29T19:21:42.000Z",
  "invoice_recipient_id": 8177,
  "url": "https://merchant.net-cents.com/widget/payment/?data=e06f10996f181d1b63d73ad90d5b634aeb7f4513b921171340bb3d4b42202095c63077c2bb6f68057691",
  "email": "[email protected]",
  "status": "sent",
  "delivery_status": "sent",
  "transaction": {
    "created_at": "2019-10-30T12:44:52.000-07:00",
    "id": 100011,
    "amount_due": "10.0",
    "amount_in_fiat": "10.0",
    "amount_received": null,
    "status": "invoice_sent",
    "external_id": null,
    "invoice_number": "INV_14a076fba218b2e58c2625d767b996e5",
    "device_id": null,
    "exchange_rate": "1.0",
    "is_sandbox": true,
    "fees": "0.249",
    "settlement_method": "manual",
    "description": "User: first_name last_name [email protected]",
    "currency": "USD",
    "txid": null
  }
}

Requests to both create and query an invoice will return the same response containing details of the invoice and associated transaction. See the above Transactions section for details of fields included in the transaction response.

Field Type Description
id integer The ID of the invoice, can be used to lookup the invoice
created_at string ISO 8601 UTC DateTime invoice was created
expires_at string ISO 8601 UTC DateTime invoice expires
due_at string ISO 8601 UTC DateTime invoice is due
invoice_recipient_id integer ID of invoice recipient
amount string Amount due in fiat
invoice_number string Invoice number as specified or generated
url string The URL to be given to the recipient to pay the invoice
email string The recipients email address
status string Invoice status. See Statuses for possible values
delivery_status string Invoice delivery status. See Statuses for possible values
transaction object See response details in Transactions section above

Query an Invoice

GET https://api.net-cents.com/merchant/v2/invoices/:id

Query an Invoice uses the same response schema as Create an Invoice.

Upload CSV Invoices

The CSV upload feature can be used to create invoices in bulk.

Field Type Description
invoice_number string Invoice number as specified
email string The recipients email address
amount string Amount due in fiat. Do not use comma seperators.
include_netcents_fee string true or false
company_name string Company Name of invoice recipient. If not provided, must provide first_name and last_name fields.
first_name string First name of invoice recipient
last_name string Last Name of invoice recipient

Invoice Recipients

Query all Invoice Recipients

GET https://api.net-cents.com/merchant/v2/invoice_recipients

Response Schema

Example Response

{
  "invoice_recipients": [
    {
      "id": 8177,
      "first_name": "John",
      "last_name": "Smith",
      "address": "123 West Pender St",
      "city": "Vancouver",
      "phone": "6045551234",
      "province_or_state": "BC",
      "country": "CA",
      "email": "[email protected]",
      "company_name": null,
      "zip": "V6E2S1",
      "created_at": "2020-04-29T18:44:21.000Z",
      "updated_at": "2020-04-29T18:44:21.000Z"
    }
  ]
}
Field Type Description
id integer The ID of the invoice recipient, can be used to create an invoice
first_name string The recipient's first name. Characters allowed: a-z A-Z . ' and -
last_name string The recipient's last name. Characters allowed: a-z A-Z . ' and -
address string The recipient's billing address. Characters allowed: 0-9 a-z A-Z / . ' and -
city string The recipient's billing city. Characters allowed: a-z A-Z
phone string The recipient's phone number. Characters allowed: 0-9
province_or_state string The recipient's state or province . Characters allowed: a-z A-Z
country string The ISO-3166 2 character country code of the recipient
email string The recipient's email address. Characters allowed: 0-9 a-z A-Z . ! # \$ % & ' * + - / = ? ^ _ ` and {"
company_name string The recipient's company name. Characters allowed: a-z A-Z . ' and -
zip string The recipient's postal/zip code. Characters allowed: a-z A-Z 0-9 / ' # and -
created_at string ISO 8601 UTC DateTime invoice recipient was created
updated_at string ISO 8601 UTC DateTime invoice recipient was last updated

Query an Invoice Recipient

GET https://api.net-cents.com/merchant/v2/invoice_recipients/:id

Query an Invoice Recipient uses the same response schema as Query all Invoice Recipients.

Create an Invoice Recipient

POST https://api.net-cents.com/merchant/v2/invoice_recipients

Example Request

require 'rest-client'
require 'json'

headers = {
  'Authorization' => 'Basic ZnJlZDpmcmVk',
  'Content-Type' => 'application/json',
  'Accept' => 'application/json'
}

params = {
  invoice_recipient: {
    email: "[email protected]",
    first_name: "John",
    last_name: "Smith",
    phone: "6045551234",
    address: "123 West Pender St",
    city: "Vancouver",
    state: "BC",
    zip: "V6E2S1",
    country: "CA",
  }
}

result = RestClient.post 'https://api.net-cents.com/merchant/v2/invoice_recipients',
  params: params, headers: headers

p JSON.parse(result)

Request Parameters

Field Type Required Description
email string Yes The recipient's email address. Characters allowed: 0-9 a-z A-Z . ! # \$ % & ' * + - / = ? ^ _ ` and {"
company_name string Yes* The recipient's company name. Characters allowed: a-z A-Z . ' and -
first_name string Yes* The recipient's first name. Characters allowed: a-z A-Z . ' and -
last_name string Yes* The recipient's last name. Characters allowed: a-z A-Z . ' and -
phone string No The recipient's phone number. Characters allowed: 0-9
address string No The recipient's billing address. Characters allowed: 0-9 a-z A-Z / . ' and -
city string No The recipient's billing city. Characters allowed: a-z A-Z
province_or_state string No The recipient's state or province . Characters allowed: a-z A-Z
zip string No The recipient's postal/zip code. Characters allowed: a-z A-Z 0-9 / ' # and -
country string No The ISO-3166 2 character country code of the recipient

Create an Invoice Recipient uses the same response schema as Query all Invoice Recipients.

Update an Invoice Recipient

PATCH https://api.net-cents.com/merchant/v2/invoice_recipients/:id

Invoice recipients can be updated using any of the parameters in Create an Invoice Recipients.

Update an Invoice Recipient uses the same response schema as Query all Invoice Recipients.

Delete an Invoice Recipient

DELETE https://api.net-cents.com/merchant/v2/invoice_recipients/:id

Delete an Invoice Recipient will return HTTP status 204 no content on success.

Refunds

Use of the refund feature requires having refunds enabled. If you wish to use this feature please contact [email protected]

Create a Refund

Example Request

require 'rest-client'
require 'json'

headers = {
  'Authorization' => 'Basic ZnJlZDpmcmVk',
  'Content-Type' => 'application/json',
  'Accept' => 'application/json'
}
params = {
  email: "[email protected]",
  amount_to_refund_fiat: "100",
  send_email: true
}

result = RestClient.post 'https://api.net-cents.com/merchant/v2/transactions/8915/refunds',
  params: params, headers: headers

p JSON.parse(result)

POST https://api.net-cents.com/merchant/v2/transactions/:transaction_id/refunds

Creating a refund using the API requires enabling the Refund Create permission for the API key in use. To do this log in to the Merchant Gateway and select Account, then API Keys.

Request Parameters

Field Type Required Description
email string Yes The customer's email address to receive link to receive refund. Characters allowed: 0-9 a-z A-Z . ! # \$ % & ' * + - / = ? ^ _ ` and {
amount_to_refund_fiat string Yes* Required for instant settlement transactions. Amount in transaction fiat currency to refund to customer, will be converted into crypto at time of processing
amount_to_refund string Yes* Required for manual settlement transactions. Amount in transaction cryptocurrency to refund to customer
expires_in integer No Number of hours to allow customer to accept refund. Defaults to 24, must be between 12 and 336 (14 days)
send_email boolean No Specify whether to send the customer an email with a link to process the refund. Default: false.
webhook_url string No The URL where a webhook will be sent when your refund is processed. (Notes: Must use https. No webhook will be returned if this field is left blank)

Response Schema

Example Response - Pending

{
  "id": 891,
  "amount_to_refund": null,
  "amount_to_refund_fiat": "100.0",
  "email": "[email protected]",
  "expires_at": "2020-01-09T19:51:56.000Z",
  "status": "pending",
  "txid": null,
  "transaction_fees": "0.0",
  "created_at": "2020-01-08T19:51:56.000Z",
  "url": "https://merchant.net-cents.com/refund_confirmation/YmtlkjxhFOSSbVupmLCyXbG1iHM8z2jqsS6b9XGjRqc"
}

Example Response - Complete

{
  "id": 891,
  "amount_to_refund": "0.013850416",
  "amount_to_refund_fiat": "100.0",
  "email": "[email protected]",
  "expires_at": "2020-01-09T19:51:56.000Z",
  "status": "refunded",
  "txid": "8cc4a9baa9314c1234952396b60d22ec5feebcea866e38742bd345115555ddf1",
  "transaction_fees": "3.61",
  "created_at": "2020-01-08T19:51:56.000Z",
  "url": "https://merchant.net-cents.com/refund_confirmation/YmtlkjxhFOSSbVupmLCyXbG1iHM8z2jqsS6b9XGjRqc",
  "webhook_url": "https://www.example.com/refund/webhook"
}
Field Description
id The id used to look up the refund
amount_to_refund Amount in transaction cryptocurrency to be refunded to customer
amount_to_refund_fiat Amount in transaction fiat currency to refund to customer, will be converted into crypto at time of processing
email The customer's email address
expires_at ISO 8601 UTC DateTime refund expires
status One of pending, cancelled, refunded, email_opened, problem
txid Cryptocurrency transaction ID of refund to customer
transaction_fees Blockchain fee for processing refund transaction, in fiat currency for instant settlements or cryptocurrency for manual settlements
created_at ISO 8601 UTC DateTime created
url URL to be sent to customer for them to process refund
webhook_url URL where webhook is to be delivered

Query a Refund

GET https://api.net-cents.com/merchant/v2/refunds/:refund_id

Query a Refund uses the same response schema as Create a Refund.

Query a Transactions Refunds

Example Response

{
  "refunds": [
    {
      "id": 891,
      "amount_to_refund": null,
      "amount_to_refund_fiat": "100.0",
      "email": "[email protected]",
      "expires_at": "2020-01-09T19:51:56.000Z",
      "status": "pending",
      "txid": null,
      "transaction_fees": "0.0",
      "created_at": "2020-01-08T19:51:56.000Z",
      "url": "https://merchant.net-cents.com/refund_confirmation/YmtlkjxhFOSSbVupmLCyXbG1iHM8z2jqsS6b9XGjRqc"
    }
  ]
}

GET https://api.net-cents.com/merchant/v2/transactions/:transaction_id/refunds

Query a Transactions Refunds uses the same response schema as Create a Refund for the refund details.

Currencies

Query All Currencies

Example Response

{
  "currencies": [
    {
      "iso": "BTC",
      "name": "Bitcoin",
      "online": true,
      "precision": 8,
      "price_precision": 2,
      "confirmations_required": 6
    },
    {
      "iso": "ETH",
      "name": "Ethereum",
      "online": true,
      "precision": 8,
      "price_precision": 2,
      "confirmations_required": 30
    },
    {
      "iso": "LTC",
      "name": "Litecoin",
      "online": true,
      "precision": 8,
      "price_precision": 2,
      "confirmations_required": 6
    },
    {
      "iso": "BCH",
      "name": "BitcoinCash",
      "online": true,
      "precision": 8,
      "price_precision": 2,
      "confirmations_required": 6
    },
    {
      "iso": "XRP",
      "name": "XRP",
      "online": true,
      "precision": 8,
      "price_precision": 5,
      "confirmations_required": 0
    }
  ]
}

GET https://api.net-cents.com/merchant/v2/currencies

This endpoint returns a list of all currencies that are enabled for payments in the Merchant Gateway.

Response Schema

Field Type Description
iso string Cryptocurrency symbol
name string Name of currency
online boolean False when service is under maintenance
precision integer Number of decimal places used for amounts
price_precision integer Number of decimal places used for prices and exchange rates
confirmations_required integer Default number of confirmations required

Payouts

Query All Payouts

Example Response

{
  "payouts": [
    {
      "id": 1,
      "payment_made_at": "2019-04-16T22:09:02.000Z",
      "status": "processing",
      "settled_amount": "45433.66"
    },
    {
      "id": 2,
      "payment_made_at": "2019-05-16T22:10:03.000Z",
      "status": "processing",
      "settled_amount": "23598.54"
    },
    {
      "id": 3,
      "payment_made_at": "2019-05-16T22:05:01.000Z",
      "status": "processing",
      "settled_amount": "50156.86"
    }
  ]
}

GET https://api.net-cents.com/merchant/v2/payouts

Response Schema

Field Type Description
id number The payout identification number
payment_made_at string The payout date.
status string Payout status. See Statuses for possible values
settled_amount string The settled amount of the payout.

Query a Payout

GET https://api.net-cents.com/merchant/v2/payouts/:id

Example Response - Query a Payout

{
  "id": 1,
  "payment_made_at": null,
  "monthly_fee": "0.0",
  "status": "processing",
  "payout_info": null,
  "settled_amount": "45433.66",
  "settlement_method": "instant",
  "refund_total": "0.0",
  "previous_reserve_amount": "0.0",
  "txid": null,
  "created_at": "2019-04-16T22:09:04.000Z",
  "transaction_total": "46356.16",
  "transaction_total_fiat": "46356.16",
  "transaction_fees": "922.49"
}

Response Schema

Field Type Description
id number payout identification number
payment_made_at string payout date
monthly_fee string payout monthly fee.
status string Payout status. See Statuses for possible values
payout_info string information regarding payout.
settled_amount string settled amount of the payout.
settlement_method string settlement method (instant or manual).
refund_total string total amount of refunds processed in payout.
previous_reserve_amount string previous reserve amount in payout
txid string transaction id
created_at string creation date of payout.
transaction_total string total payout amount
transaction_total_fiat string total payout amount in fiat
transaction_fees string transaction fees amount

Transactions for Payout

Example Response - Payout Transactions

{
  "transactions": [
    {
      "created_at": "2019-04-08T20:34:36.000Z",
      "id": 4,
      "amount_due": "0.63175015",
      "amount_in_fiat": "2527.0006",
      "amount_in_fiat_received": "2527.0006",
      "amount_received": "0.63175015",
      "status": "completed",
      "external_id": null,
      "invoice_number": "fff334b440eee2104b6e029a40e3a4b6",
      "source": null,
      "device_id": null,
      "transaction_id": "531c843e14b9eb9f65ce90188c42048f",
      "exchange_rate": "4000.0",
      "fees": "50.28731194",
      "settlement_method": "instant",
      "description": null
    }
  ]
}

For a list of transactions included in a payout, make a request to the following endpoint.

GET https://api.net-cents.com/merchant/v2/payouts/:id/transactions

Response Schema

Field Description
transactions list of Transactions

Pending Payouts

Example Response - Pending Payouts

{
  "pending_payouts": {
    "instant_settlement": {
      "transaction_total": "382068.87",
      "fees": "7603.17",
      "total_pending_payout": "374465.7"
    },
    "manual_settlement": [
      {
        "currency_iso": "LTC",
        "transaction_total": "19.45",
        "fees": "0.23",
        "total_pending_payout": "19.22"
      }
    ]
  }
}

To get an up-to-date tally of your transaction volume and an estimate of your next payout total for each currency that you accept, make a request to the following endpoint.

GET https://api.net-cents.com/merchant/v2/payouts/pending

Response Schema

Field Type Description
transaction_total string transaction total of pending payout
fees string pending payouts fee
total_pending_payout string total amount of pending payout
currency_iso string the cryptocurrency iso of pending manual settlement

Pending Transactions (Instant)

Example Response - Pending Transactions (Instant)

{
  "transactions": [
    {
      "created_at": "2019-04-08T20:34:36.000Z",
      "id": 4,
      "amount_due": "0.63175015",
      "amount_in_fiat": "2527.0006",
      "amount_in_fiat_received": "2527.0006",
      "amount_received": "0.63175015",
      "status": "completed",
      "external_id": null,
      "invoice_number": "fff334b440eee2104b6e029a40e3a4b6",
      "source": null,
      "device_id": null,
      "transaction_id": "531c843e14b9eb9f65ce90188c42048f",
      "exchange_rate": "4000.0",
      "fees": "50.28731194",
      "settlement_method": "instant",
      "description": null
    }
  ]
}

To get an up-to-date list of transactions that will be included in your next payouts, make a request to the following endpoint.

GET https://api.net-cents.com/merchant/v2/payouts/pending/transactions

Response Schema

Field Description
transactions list of Transactions

Pending Transactions (Manual)

Example Response - Pending Transactions (Manual)

{
  "transactions": [
    {
      "created_at": "2019-04-08T20:34:36.000Z",
      "id": 4,
      "amount_due": "0.63175015",
      "amount_in_fiat": "2527.0006",
      "amount_in_fiat_received": "2527.0006",
      "amount_received": "0.63175015",
      "status": "completed",
      "external_id": null,
      "invoice_number": "fff334b440eee2104b6e029a40e3a4b6",
      "source": null,
      "device_id": null,
      "transaction_id": "531c843e14b9eb9f65ce90188c42048f",
      "exchange_rate": "4000.0",
      "fees": "50.28731194",
      "settlement_method": "manual",
      "description": null
    }
  ]
}

If you are accepting payments and receiving payouts in cryptocurrency, you can view transactions pending payout via the following endpoint.

GET https://api.net-cents.com/merchant/v2/payouts/pending/transactions/manual/:currency_iso

Response Schema

Field Description
transactions list of Transactions

Webhooks

General

The NetCents platform sends webhooks when the status of a payment changes. To receive webhooks set up your platform to receive an HTTP POST request. Webhooks will be sent to the URL submitted to Create a Payment or Create Widget Payment or as configured in the Merchant Gateway for Hosted Payments, this URL must use HTTPS.

The first webhook will be sent when a payment is found on the blockchain. The second webhook will be sent when a payment is confirmed on the blockchain. Note that only one webhook will be sent when a payment is paid by a NetCents user as payments are confirmed instantly.

When the payment is found or confirmed, a POST request will be returned with a body structure as per the example.

Example Payload

{
  "signature": "t=18273718273,s1=JDF89Mmch8sdhf89h8hdhf",
  "data": "IntzdGF0dXM6IDIwMCwgIi8iYmFqc2RkamlzamRpYXNkYXNkc2RmZ2RzZmd9Ig=="
}
Field Parameters
signature Timestamp & Signature you will use to verify this is coming from us
data Contains an encoded JSON string. See Example Decoded Payload and Decoded Payload Schema below for details

PLEASE NOTE:

Your signing signature that is found on the hosted page should be stored securely on your backend to be used when verifying the webhook data received.

Verifying Data

Verifying Data

  require "base64"
  require "openssl"

  # isolate timestamp(t) and signature(s1)
  signature_pair = params[:signature].split(',')
  timestamp = signature_pair[0].split('=')[1]
  signature = signature_pair[1].split('=')[1]
  hashable_payload_string = timestamp + '.' + params[:data]

  # SECURELY_STORED_SIGNING_SIGNATURE should be retrieved from a secured backend source (Environment variables, Database etc...)
  signature_hash = OpenSSL::HMAC.hexdigest('sha256', SECURELY_STORED_SIGNING_SIGNATURE, hashable_payload_string)

  raise 'Invalid signature' unless signature_hash == signature

  # Check timestamp (Recommended)
  timestamp_tolerance = 300
  raise 'Invalid timestamp' unless Time.now.to_i - timestamp.to_i <= 300

  decoded = Base64.decode64(params[:data])
  payload = JSON.parse(decoded)

Once you have received a webhook response, there are a few steps that need to be taken to ensure that the data sent is not from a third party. First, you will need to isolate the timestamp(t) and signature(s1). Extract both by splitting the string on the comma (“,”). Then, split each string on the “=”. Refer to the code sample for implementation.

Then, create a HMAC with SHA256 encryption with the key being your securely stored signing signature and hashable_payload_string as the message.

The signature_hash and signature we created can be checked for equality. If they are equal, we have verified that the signature has not been tampered with.

The final step is to decode the data. The data string is a Base64 encoded JSON object. See the decoded example for what the data will look like.

Recommended:

To mitigate against replay attacks (an attack where an attacker intercepts and resends valid data in order to cause a certain action eg. double crediting an account) you can create a timestamp tolerance and find the difference between current time and the payloads timestamp. Your webhook endpoint should also prevent against duplicate actions happening if receiving the same webhook twice.

Decoded Payment Webhook Payload

Example Decoded Payload

{
  "external_id": "5438015",
  "amount_due": "0.02038624",
  "amount_received": "0.02038624",
  "exchange_rate": "9810.54",
  "exchange_rate_currency": "CAD",
  "invoice_number": "INV_001",
  "transaction_currency": "BTC",
  "transaction_status": "pending_confirmation",
  "payment_id": 19340,
  "transaction_id": 23425,
  "txid": "6810410d9928af31f9b0c86fb3e3a8a1baaa60f7793c546a0d32961e457014a3",
  "blockchain_transactions": [
    {
      "id": 2300,
      "status": "paid",
      "amount_received": "0.02038624",
      "find_time": "2020-07-24T10:54:36.000-07:00",
      "txid": "6810410d9928af31f9b0c86fb3e3a8a1baaa60f7793c546a0d32961e457014a3"
    }
  ]
}
Field Type Parameters
external_id string Unique reference number to identify the payment in a merchant’s database
amount_due string Amount due in cryptocurrency.
amount_received string Amount received in cryptocurrency
exchange_rate string Exchange rate for transaction’s cryptocurrency in fiat currency.
exchange_rate_currency string ISO 4217 of base exchange rate currency (‘USD’, ‘CAD’ or ‘EUR’)
invoice_number string Unique invoice number to reference the payment.
transaction_currency string ISO 4217 of cryptocurrency used for payment.
transaction_status string Transaction status. See Statuses for possible values
payment_id integer ID number for the payment on the Merchant Gateway.
transaction_id integer ID of the transaction on the Merchant Gateway.
txid string Transaction ID on blockchain (same as blockchain transaction txid)
blockchain_transactions array Array of blockchain transactions
id integer blockchain transaction id
status string Blockchain payment status
amount_received string Amount received from blockchain transactions
txid string txid of blockchain transactions
find_time string DateTime string when the blockchain transaction was found

Decoded Refund Webhook Payload

{
  "id": "502",
  "amount_to_refund": "0.005988",
  "amount_to_refund_fiat": "50.0",
  "email": "[email protected]",
  "expires_at": "2020-01-25T22:00:49.000Z",
  "status": "refunded",
  "txid": "6810410d9928af31f9b0c86fb3e3a8a1baaa60f7793c546a0d32961e457014a3",
  "transaction_fees": "4.17365",
  "created_at": "2020-01-24T22:00:49.000Z",
  "currency_iso": "BTC",
  "sandbox_mode": false
}
Field Description
id The id used to look up the refund
amount_to_refund Amount in transaction cryptocurrency to be refunded to customer
amount_to_refund_fiat Amount in transaction fiat currency to refund to customer, will be converted into crypto at time of processing
email The customer's email address
expires_at ISO 8601 UTC DateTime refund expires
status One of pending, cancelled, refunded, email_opened, problem
txid Cryptocurrency transaction ID of refund to customer
transaction_fees Blockchain fee for processing refund transaction, in fiat currency for instant settlements or cryptocurrency for manual settlements
created_at ISO 8601 UTC DateTime created
currency_iso ISO 4217 of the currency sent as refund
sandbox_mode Boolean representing whether a transaction was created in sandbox mode

General

Confirmations Required

The threshold for considering a payment confirmed is up to each individual merchant. The minimum required confirmations on the NetCents platform is 1. This means that once a payment has been found on the blockchain, its status will be set to ‘paid’ as soon as it receives one blockchain confirmation. If you choose a higher threshold, the transaction status will not be updated from pending_confirmation to paid until the threshold has been met.

While you need at least one confirmation for a transaction to be confirmed, we recommend a greater number. The number that is considered safe depends on the cryptocurrency used and the amount being transacted. As a general rule, larger transactions should have a higher confirmation threshold than smaller ones. You may lower your required confirmations below the accepted threshold if you are processing smaller transactions or if you have additional assurance that a customer can be trusted. Be aware that confirming transactions early is AT YOUR OWN RISK and NetCents will not be held responsible in the event of a malicious or double spent transaction.

For most uses, the following settings would pose a low risk:

Currency Confirmations
Bitcoin 3
Ethereum 24
Litecoin 12
Bitcoin Cash 3
Horizen 12
Verge 100
Tron 3

Statuses

Transaction status

Status Description
null Transaction not yet created, payment has not been found on blockchain
invoice_sent Payment has not been found on blockchain, only for invoices
pending_confirmation Payment has been found but is waiting for confirmation
paid Payment confirmed, amount received equal to amount due
overpaid Payment confirmed, amount received is greater than amount due
underpaid Payment confirmed, amount received is less than amount due
completed Payment was previously overpaid or underpaid but has been marked completed
cancelled Payment was found but never confirmed

Blockchain status

Status Description
Pending Payment has not been found on blockchain
Paid Payment has been found but is waiting for confirmation
Confirmed Payment has reached required number of confirmations
Expired Payment has expired

Payout status

Status Description
processing Payment is being processed
completed Payment has been made
settlement_pending Payout has been generated but payment has not yet been processed
settlement_error There was an error processing payment (for manual payouts)

Invoice status

Status Description
unpaid Invoice has been created and not yet paid
cancelled Invoice has been marked as cancelled
expired Invoice has passed expires_at date
pending_confirmation Payment has been found but is waiting for confirmation
paid Payment confirmed, amount received equal to amount due
overpaid Payment confirmed, amount received is greater than amount due
underpaid Payment confirmed, amount received is less than amount due
completed Payment was previously overpaid or underpaid but has been marked completed
cancelled Payment was found but never confirmed

Invoice delivery status

Status Description
null Email pending if send_customer_email true
sent Email was sent
viewed Recipient has viewed payment by clicking link in email
opened Recipient has viewed email
error Unknown delivery error
bounced Email was undeliverable, email address may be invalid
delivered Email was delivered to recipient
spam Email was marked as spam