NAV
php python

Deprecated Documentation

To ensure uninterrupted access to our services, please refer to the Coinify’s new Payment API documentation available at here.

Introduction

Welcome to the Coinify API. You can use our API to interact with the Coinify systems.

All responses from the API are in JSON format, and all POST and PUT requests must use JSON to pass values to the API functions.

The production API is available at the URL https://api.coinify.com.

Environments

Aside from the production environment, we also have a sandbox environment for testing, which uses Bitcoin test network. In sandbox, you can get the experience of the whole payment service flow only by transacting with testnet bitcoin funds (BTCt). In order to set up a testnet wallet and receive some BTCt, check out this article.

Production

API Base URL:: https://api.coinify.com
Create account:: https://merchant.coinify.com/signup/now

Sandbox

API Base URL:: https://api.sandbox.coinify.com
Create account:: https://merchant.sandbox.coinify.com/signup/now

Versioning

https://api.coinify.com/v3

All API calls currently use the above URL

All API requests must include an API version number as the first part of the path like this: https://api.coinify.com/v<version>

As of this moment, there is only one version: 3, and all consumers of the API should use version 3, like the URL on the right.

~~# SDK’s~~ (Deprecated. Please do not use the SDKs)

~~Coinify provides SDKs for accessing our API for various programming languages.~~

~~At the moment, we provide SDKs for the following languages:~~

Authentication

To authorize, use the following code. Make sure to replace coinifyapikey and coinifyapisecret with your API key and API secret, respectively.

<?php
// Provide your API key and secret
$apikey = "coinifyapikey";
$apisecret = "coinifyapisecret";

/*
 * Using the Coinify PHP SDK
 */
$api = new CoinifyAPI( $apikey, $apisecret );

// ===============================================================

/*
 * Using cURL
 */
// Generate a nonce
$mt = explode(' ', microtime());
$nonce = $mt[1] . substr($mt[0], 2, 6);

// Concatenate the nonce and the API key
$message = $nonce . $apikey;
// Compute the signature and convert it to lowercase
$signature = strtolower( hash_hmac('sha256', $message, $apisecret, false ) );

// Construct the HTTP Authorization header.
$auth_header = "Authorization: Coinify apikey=\"$apikey\", nonce=\"$nonce\", signature=\"$signature\"";

// We assume that you are using PHP cURL to perform the API calls,
// but you can use any other HTTP client library
// that supports setting custom request headers.
$ch = curl_init('https://api.coinify.com/v3/invoices');
curl_setopt($ch, CURLOPT_HTTPHEADER, array($auth_header));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
?>
# Provide your API key and secret
apikey = "coinifyapikey"
apisecret = "coinifyapisecret"

"""
Using the Coinify Python SDK
"""
from coinify_api import CoinifyAPI

api = CoinifyAPI( apikey, apisecret )

# ================================================================

"""
Using the requests module 
"""
import requests, time

# Generate nonce, based on the current Unix timestamp
nonce = str( int( time.time() * 1000000 ) )

# Concatenate nonce and API key
message = nonce + self.api_key

# Compute signature
signature = hmac.new(self.api_secret, msg=message, digestmod=hashlib.sha256).hexdigest()

# Construct the header
auth_header = 'Coinify apikey="%s", nonce="%s", signature="%s"' % ( self.api_key, nonce, signature )

# Ready the HTTP headers
headers = {
    'Authorization': auth_header,
    'Content-Type': 'application/json'
}

# Call the List payments API
url = 'https://api.coinify.com/v3/payments'

response = requests.request( 'GET', url, headers=headers ).json()

In order to access our API, you need an API key and an API secret. You can create API keys and secrets by clicking here.

All requests to our API must contain the following three values:

These values must be provided in a HTTP Authorization header as follows:

Authorization: Coinify apikey="<api_key>", nonce="<nonce>", signature="<signature>

The signature is a HMAC-SHA256 hash of the concatenation of the nonce with your API key, using your API secret as the HMAC key. The hash must be in lowercase hexadecimal format, like the following example: b9926f02caed3c9c08224cd079a162b771c80b0ff49a69d0579cb806d5475ff3.

All following code examples assume that you send a Authentication header with your request as shown to the right.

Response format

Our API always responds with an HTTP 200 status code with the content in JSON format, and the response is either a success type or an error type. You can use the success variable to check which one it is: If success is true, the request succeeded. If success is false, the request failed.

All timestamps used in requests and responses are in ISO 8601 format.

Success format

{
  "success": true,
  "data": {}
}

The value of the data field contains the result of the API call

Whenever a request succeeds, the API returns a JSON object with two values - success and data. The data value contains the result of the request, and the value is either a JSON object (for a single result), or a JSON array (for multiple results).

In a successful request, success is always true.

Error format

The API returns the following object if you don’t provide a valid Authentication header.

{
  "success": false,
  "error": {
    "code": "api_key_required",
    "message": "Please provide a valid API key for this operation.",
    "url": "https://merchant.coinify.com/merchant/api"
  }
}

The url field is optional and does not appear in all error requests.

Whenever a request fails, the API returns a JSON object with two values - success and error. The error object always contains two fields - code, which contains a machine-readable error code, and message, which carries a human-readable error message - and optionally a third field - url, which contains a error-specific URL.

In a failed request, success is always false.

API Rate Limit

The API Rate Limit is set to 100 requests pr minute.

The following headers are added to the API response, even if the API Rate Limit is exceeded:

Header Type Description
X-RateLimit-Limit Integer Requests limit pr minute
X-RateLimit-Remaining Integer The number of requests left for the time window
X-RateLimit-Reset Integer The remaining window before the rate limit resets in seconds

If the API Rate Limit is exceeded, the API will return an error with code rate_limit_exceeded as shown to the right.

{
  "success": false,
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded. Limit is 100 requests pr. minute. Rate limit will be reset in XX seconds"
  }
}

Rates

Get the current exchange rates for all supported currencies. Returned rates will define the exchange rate for the number of fiat currency units equivalent to one BTC.

This end-point is public and no API key/secret is needed.

buy is the rate for buying bitcoin from Coinify as a Merchant.

sell is the rate for selling bitcoin to Coinify as a Merchant. This is also the rate used for payments.

Get all rates

This endpoint retrieves the rates for all currencies, sorted alphabetically.

<?php
/*
 * Using the Coinify PHP SDK
 */
$api = new CoinifyAPI();
$result = $api->ratesGet();

// ===============================================================

/*
 * Using cURL
 */
$ch = curl_init('https://api.coinify.com/v3/rates');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = json_decode( curl_exec($ch) );
curl_close($ch);
?>
"""
Using the Coinify Python SDK
"""
from coinify_api import CoinifyAPI

api = CoinifyAPI()
response = api.rates_get()

# ================================================================

"""
Using the requests module 
"""
import requests

headers = {
            'Content-Type': 'application/json'
}

url = 'https://api.coinify.com/v3/rates'
response = requests.request( 'GET', url, headers=headers ).json()

The above API call returns JSON structured like this:

{
  "success": true,
  "data": {
    "AED": {
      "name": "United Arab Emirates Dirham",
      "buy": 1316.8847,
      "sell": 1316.8479
    },
    "AFN": {
      "name": "Afghanistan Afghani",
      "buy": 23532.5964,
      "sell": 23531.9400
    },
    "ALL": {
      "name": "Albanian Lek",
      "buy": 46183.0427,
      "sell": 46181.7545
    },
    "(etc)": "(...)"
  }
}

HTTP Request

GET https://api.coinify.com/v3/rates

Get rates for specific currency

This endpoint retrieves the rates for a specified currency.

<?php
/*
 * Using the Coinify PHP SDK
 */
$api = new CoinifyAPI();
$result = $api->ratesGet($currency);

// ===============================================================

/*
 * Using cURL
 */
$ch = curl_init('https://api.coinify.com/v3/rates/<currency>');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = json_decode( curl_exec($ch) );
curl_close($ch);
?>
"""
Using the Coinify Python SDK
"""
from coinify_api import CoinifyAPI

api = CoinifyAPI()
response = api.rates_get(currency)

# ================================================================

"""
Using the requests module 
"""
import requests

headers = {
            'Content-Type': 'application/json'
}

url = 'https://api.coinify.com/v3/rates/<currency>'
response = requests.request( 'GET', url, headers=headers ).json()

The above API call returns JSON structured like this:

{
  "success": true,
  "data": {
      "name": "United States Dollar",
      "buy": 359.0400,
      "sell": 357.0900
    }
}

HTTP Request

GET https://api.coinify.com/v3/rates/<currency>

Get all altcoin rates

This endpoint retrieves the rates for all supported altcoins in default base BTC. See the Input currencies section for supported altcoins.

<?php
/*
 * Using the Coinify PHP SDK
 */
$api = new CoinifyAPI();
$result = $api->altratesGet();

// ===============================================================

/*
 * Using cURL
 */
$ch = curl_init('https://api.coinify.com/v3/altrates');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = json_decode( curl_exec($ch) );
curl_close($ch);
?>
"""
Using the Coinify Python SDK
"""
from coinify_api import CoinifyAPI

api = CoinifyAPI()
response = api.altrates_get()

# ================================================================

"""
Using the requests module 
"""
import requests

headers = {
            'Content-Type': 'application/json'
}

url = 'https://api.coinify.com/v3/altrates'
response = requests.request( 'GET', url, headers=headers ).json()

The above API call returns JSON structured like this:

{
  "success": true,
  "data": {
    "LTC": {
        "name": "Litecoin",  // Name of the altcoin
        "rate":121.55487804, // This means that 1 BTC is worth ~121 LTC
        "baseCurrency": "BTC",
        "limits": {
            "minimum": 0.00251036, // Litecoin supported for payments
            "maximum": 1.25518439 // between 0.00251036 and 1.25518439 BTC
        }
     },
     "XRP": {
        "name":"Ripple",
        "rate":54200.65252854,
        "baseCurrency": "BTC",
        "limits": {
            "minimum": 0.0025101,
            "maximum": 1.25505308
        }
     },
     "(etc)": "(...)"
  }
}

HTTP Request

GET https://api.coinify.com/v3/altrates

Query parameters

Name Type Default Description
baseCurrency String 'BTC' Currency to use as base for rates and limits

Get rates for specific altcoin

This endpoint retrieves the rates for a specified altcoin.

<?php
/*
 * Using the Coinify PHP SDK
 */
$api = new CoinifyAPI();
$result = $api->altratesGet($altcoin);

// ===============================================================

/*
 * Using cURL
 */
$ch = curl_init('https://api.coinify.com/v3/altrates/<altcoin>');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = json_decode( curl_exec($ch) );
curl_close($ch);
?>
"""
Using the Coinify Python SDK
"""
from coinify_api import CoinifyAPI

api = CoinifyAPI()
response = api.altrates_get(altcoin)

# ================================================================

"""
Using the requests module 
"""
import requests

headers = {
            'Content-Type': 'application/json'
}

url = 'https://api.coinify.com/v3/altrates/<altcoin>'
response = requests.request( 'GET', url, headers=headers ).json()

The above API call returns JSON structured like this:

{
  "success": true,
  "data": {
      "name": "Litecoin",   // Name of the altcoin
      "rate": 121.55487804, // This means that 1 BTC is worth ~121 LTC    
      "baseCurrency": "BTC",
      "limits": {
          "minimum": 0.00251036, // Litecoin supported for payments
          "maximum": 1.25518439 // between 0.00251036 and 1.25518439 BTC
      }
  }
}

HTTP Request

GET https://api.coinify.com/v3/altrates/<altcoin>

Query parameters

Name Type Default Description
baseCurrency String 'BTC' Currency to use as base for rates and limits

Account

Through this API you can execute operations or get data regarding your merchant account.

Check account balance

This endpoint returns the Bitcoin and fiat currency balances that you have on your merchant account.

btc contains the balance amount of your BTC account on our platform.

fiat contains the balance amount of your default fiat currency account on our platform.

fiat_currency is the 3-character currency code of the currency of your default account.

<?php
/*
 * Using the Coinify PHP SDK
 */
$api = new CoinifyAPI( $apikey, $apisecret );
$result = $api->balanceGet();

// ===============================================================

/*
 * Using cURL
 */
$ch = curl_init('https://api.coinify.com/v3/balance');
curl_setopt($ch, CURLOPT_HTTPHEADER, array($auth_header));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = json_decode( curl_exec($ch) );
curl_close($ch);
?>
"""
Using the Coinify Python SDK
"""
from coinify_api import CoinifyAPI

api = CoinifyAPI( apikey, apisecret )
response = api.balance_get()

# ================================================================

"""
Using the requests module 
"""
import requests

headers = {
            'Authorization': auth_header,
            'Content-Type': 'application/json'
}

url = 'https://api.coinify.com/v3/balance'
response = requests.request( 'GET', url, headers=headers ).json()

The above API call returns JSON structured like this:

{
  "success": true,
  "data": {
    "btc": 0.35783465,
    "fiat": 347.24,
    "fiat_currency": "EUR"
  }
}

HTTP Request

GET https://api.coinify.com/v3/balance

Payments

The payment is the cornerstone of the Coinify API. We use payments to create payment requests from customers.

Please use a moment to familiarize yourself with the payment object below before heading to the code samples.

Payment object

Payment sample object

{
  "id": 12345,
  "uuid": "0155d80d-a535-4b10-ab91-0d61f6969ccd",
  "create_time": "2016-01-26T12:09:01Z",
  "expire_time": "2016-01-26T12:24:01Z",
  "state": "new",
  "type": "normal",
  "bitcoin": {
    "amount": 0.00282,
    "address": "14KRwZqXrRxi1mag9B52r5fyn37AiWRPYi",
    "amount_paid": 0,
    "amount_due": 0.00282,
    "payment_uri": "bitcoin:14KRwZqXrRxi1mag9B52r5fyn37AiWRPYi?amount=0.00282&r=https://merchant.coinify.com/payment/abc/def"
  },
  "native": {
    "amount": 1,
    "currency": "EUR"
  },
  "transfer": {
    "amount": 1,
    "currency": "EUR"
  },
  "description": "Sample payment",
  "custom": {
    "sample_data": "value"
  },
  "payment_url": "https://merchant.coinify.com/payment/abc/def",
  "inputs": [{ // Requests on paying with different currencies than BTC
    "currency": "DOGE",
    "amount": 3893.33333333,
    "address": "DAfNsbdWnXnEZwTAZdNWeUZLNqnfFLs5D5",
    "return_address": "D95Kj5JJiWXH4kjTqHXovF5taxcLWoPNGG",
    "payment_uri": "dogecoin:D95Kj5JJiWXH4kjTqHXovF5taxcLWoPNGG&amount=3893.33333333",
    "verified": false,
    "timestamp": "2016-01-26T12:09:01Z"
  }],
  "callback_url": "https://myshop.com/callbacks/coinify",
  "callback_email": null,
  "return_url": "https://myshop.com/order_paid/xyz",
  "cancel_url": "https://myshop.com/order_cancelled/xyz",
  "payments": [], // Bitcoin transactions to this payment
  "original_invoice_id": 12345, // optional
  "sub_invoice_ids": [54321, 98765] // optional
}

To the right you can see a sample payment object, and the table below summarizes the individual fields of the object.

Note that all payments will contain the bitcoin object with the bitcoin details for the payment, regardless of whether or not another input currency is requested to pay with.

Payment object parameters

Name Type Description
id Integer Numeric ID of the payment
uuid String Alternate UUID of the payment
create_time ISO 8601 time The time when the payment was created
expire_time ISO 8601 time The time when the payment will expire/expired.
state String The payment’s state. See section on Payment state
type String The payment type. See section on Payment type
bitcoin Object The bitcoin details for this specific payment.
bitcoin.amount Float The total bitcoin amount of this payment
bitcoin.address String The bitcoin address to receive the payment
bitcoin.amount_paid Float How much has been paid to this payment
bitcoin.amount_due Float How much is yet to be paid for this payment
bitcoin.payment_uri String Payment URI for wallets, supporting BIP21 and BIP70. It is available only if state of the payment is new.
native.amount Float The amount used to create the payment and calculate the bitcoin amount. Denominated in native.currency
native.currency String The currency denominating native.amount
transfer.amount Float The amount that we will transfer to you once the payment has been paid. Denominated in transfer.currency
transfer.currency String The currency denominated transfer.amount
description String Your custom text for this payment
custom Object Your custom data for this payment
payment_url String The URL to redirect customers to when they want to pay
inputs List List of requests to pay with other input currencies. See section on Inputs.
callback_url String A URL that Coinify calls when the payment has been paid
callback_email String An email address to send a mail to when the payment has been paid
return_url String We redirect your customer to this URL to when the payment has been paid
cancel_url String We redirect your customer to this URL if they fail to pay the payment in time
payments List All payments received to this payment. See section on Payments
original_invoice_id
(optional)
Integer The ID of the original payment for the certain sub-payment. Field is named original_invoice_id for historical reasons.
sub_invoice_ids
(optional)
Array The IDs of the sub-payments for the certain original payment. Field is named sub_invoice_ids for historical reasons.

Note: The payment object may contain additional fields under certain circumstances. See References to original and sub-payments for more information.

Payment state

The state field of the payment object has the following possible values:

State Description
new Awaiting payment from the customer
paid The payment has been paid, but the payments are not yet verified
complete The payment has been paid, and payments are verified
expired The payment has expired

Payment type

The type field of the payment object has the following possible values:

State Description
normal Normal payment
underpaid The payment received too little payment within the time limit and the payment amounts were adjusted to match the actual paid amount. The actually paid amount is visible in the payment’s JSON object sent out via callbacks.
extra This payment was created as a sub-payment because the original payment received too much payment or received a payment too late. In these cases an additional callback is sent with the ID of the original payment request in the original_invoice_id parameter.

Payments

The payments field of the payment object is a list of bitcoin payments made to this payment. Each payment has the following five properties:

Name Type Description
time ISO 8601 time The time the payment was received
amount Float The amount (in bitcoin) paid
txid String The id of the blockchain transaction in which this bitcoin payment was made
confirmations Integer The number of confirmations on this payment
expired Boolean Whether or not the payment has expired when this bitcoin payment was made

Inputs

In addition to paying a payment with bitcoins, we also support paying with different input currencies. See section on Input currencies for more information.

The inputs field of the payment object is a list of requests to pay the payment with different input currencies. Such requests can be made upon payment creation, or after creation.

Each request has the following properties:

Name Type Description
currency String The input currency that the payment has been requested to be paid in.
amount Float The amount of the above input currency to be paid by the customer.
address Float The address (belonging to the input.currency) that the above amount should be paid to.
return_address String The address (belonging to the input.currency) that the money should be returned to in case of an error.
payment_uri String (URI) Wallet-compatible URI for this input currency request
verified Boolean Whether or not payment with this input currency has taken place and been verified.
destination_tag String (Optional) Tag for the input currency, see information regarding tags below.
timestamp ISO 8601 time The time when the input request was made

References to original and sub-payments

When we receive a payment to an expired or already paid payment, or we receive more than enough bitcoins to pay a payment, we create so-called sub-payments for the payment amount (or the excess amount for overpayments). These payments are linked to their original payments, and you can determine that link through the payment object:

For sub-payments, an additional key, original_invoice_id is added to the payment object, which contains the ID of the original payment. For original payments with sub-payments, a key sub_invoice_ids is added, which contains a list of IDs of sub-payments linked to the payment.

Note that although the keys are named original_invoice_id and sub_invoice_ids, they refer to payments, and are only named invoices to maintain backwards compatibility.

You can choose to receive callbacks on sub-payments or not in your Merchant IPN settings.

List all payments

<?php
/*
 * Using the Coinify PHP SDK
 */
$api = new CoinifyAPI( $apikey, $apisecret );
$result = $api->invoicesList();

// ===============================================================

/*
 * Using cURL
 */
$ch = curl_init('https://api.coinify.com/v3/payments');
curl_setopt($ch, CURLOPT_HTTPHEADER, array($auth_header));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = json_decode( curl_exec($ch) );
curl_close($ch);
?>
"""
Using the Coinify Python SDK
"""
from coinify_api import CoinifyAPI

api = CoinifyAPI( apikey, apisecret )
response = api.invoices_list()

# ================================================================

"""
Using the requests module 
"""
import requests

headers = {
            'Authorization': auth_header,
            'Content-Type': 'application/json'
}

url = 'https://api.coinify.com/v3/invoices'

response = requests.request( 'GET', url, headers=headers ).json()

The above API call returns JSON structured like this:

{
  "success": true,
  "data": [
    {
      "id": 12345,
      "uuid": "0155d80d-a535-4b10-ab91-0d61f6969ccd",
      "create_time": "2016-01-26T12:09:01Z",
      "expire_time": "2016-01-26T12:24:01Z",
      "state": "new",
      "type": "normal",
      "bitcoin": {
        "amount": 0.00282,
        "address": "14KRwZqXrRxi1mag9B52r5fyn37AiWRPYi",
        "amount_paid": 0,
        "amount_due": 0.00282,
        "payment_uri": "bitcoin:14KRwZqXrRxi1mag9B52r5fyn37AiWRPYi?amount=0.00282&r=https://merchant.coinify.com/payment/abc/def"

      },
      "native": {
        "amount": 1,
        "currency": "EUR"
      },
      "transfer": {
        "amount": 1,
        "currency": "EUR"
      },
      "description": "Sample payment",
      "custom": {
        "sample_data": "value"
      },
      "payment_url": "https://merchant.coinify.com/payment/abc/def",
      "inputs": [], // Requests on paying with different currencies than BTC
      "callback_url": "https://myshop.com/callbacks/coinify",
      "callback_email": null,
      "return_url": "https://myshop.com/order_paid/xyz",
      "cancel_url": "https://myshop.com/order_cancelled/xyz",
      "payments": [], // Bitcoin transactions to this payment
      "original_invoice_id": 12345, // optional
      "sub_invoice_ids": [54321, 98765] // optional
    }
  ]
}

This endpoint retrieves all your payments, sorted by newest first.

HTTP Request

GET https://api.coinify.com/v3/payments

Query parameters

Name Type Default Description
limit Integer 100 Maximum number of payments to retrieve. Maximum is 200.
offset Integer 0 How many payments to skip.
include_expired Boolean false If set to true, expired payments are included in the result. Default is not to include expired payments.

Get a specific payment

<?php
$payment_id = 12345;

/*
 * Using the Coinify PHP SDK
 */
$api = new CoinifyAPI( $apikey, $apisecret );
$result = $api->invoiceGet($payment_id);

// ===============================================================

/*
 * Using cURL
 */
$url = 'https://api.coinify.com/v3/payments/' . $payment_id;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array($auth_header));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = json_decode( curl_exec($ch) );
curl_close($ch);
?>
payment_id = 12345

"""
Using the Coinify Python SDK
"""
from coinify_api import CoinifyAPI

api = CoinifyAPI( apikey, apisecret )
response = api.invoice_get( payment_id )

# ================================================================

"""
Using the requests module 
"""
import requests

headers = {
            'Authorization': auth_header,
            'Content-Type': 'application/json'
}

url = 'https://api.coinify.com/v3/payments/%d' % ( payment_id, )

response = requests.request( 'GET', url, headers=headers ).json()

The above API call returns a payment JSON object structured like this:

{
  "success": true,
  "data": {
    "id": 12345,
    "uuid": "0155d80d-a535-4b10-ab91-0d61f6969ccd",
    "create_time": "2016-01-26T12:09:01Z",
    "expire_time": "2016-01-26T12:24:01Z",
    "state": "new",
    "type": "normal",
    "bitcoin": {
      "amount": 0.00282,
      "address": "14KRwZqXrRxi1mag9B52r5fyn37AiWRPYi",
      "amount_paid": 0,
      "amount_due": 0.00282,
      "payment_uri": "bitcoin:14KRwZqXrRxi1mag9B52r5fyn37AiWRPYi?amount=0.00282&r=https://merchant.coinify.com/payment/abc/def"
    },
    "native": {
      "amount": 1,
      "currency": "EUR"
    },
    "transfer": {
      "amount": 1,
      "currency": "EUR"
    },
    "description": "Sample payment",
    "custom": {
      "sample_data": "value"
    },
    "payment_url": "https://merchant.coinify.com/payment/abc/def",
    "inputs": [],
    "callback_url": "https://myshop.com/callbacks/coinify",
    "callback_email": null,
    "return_url": "https://myshop.com/order_paid/xyz",
    "cancel_url": "https://myshop.com/order_cancelled/xyz",
    "payments": []
  }
}

This endpoint retrieves a specific payment.

HTTP Request

GET https://api.coinify.com/v3/payments/<ID>

URL parameters

Name Type Description
ID Integer The ID of the payment to retrieve

Create a payment

<?php
$amount = 32.00;
$currency = 'USD';
$plugin_name = 'My PHP shop';
$plugin_version = '1.2';
$description = 'Sample payment';
$custom = array('sample_data' => 'value');

/*
 * Using the Coinify PHP SDK
 */
$api = new CoinifyAPI( $apikey, $apisecret );
$result = $api->invoiceCreate( $amount, $currency, $plugin_name,
    $plugin_version, $description, $custom );

// ===============================================================

/*
 * Using cURL
 */
$params = array(
  'amount' => $amount,
  'currency' => $currency,
  'plugin_name' => $plugin_name,
  'plugin_version' => $plugin_version,
  'description' => $description,
  'custom' => $custom
);

$url = 'https://api.coinify.com/v3/payments';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array($auth_header));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$result = json_decode( curl_exec($ch) );
curl_close($ch);
?>
amount = 32.00
currency = 'USD'
plugin_name = 'My Python website'
plugin_version = '1.0'
description = 'Sample payment'
custom = { 'sample_data': 'value' }

"""
Using the Coinify Python SDK
"""
from coinify_api import CoinifyAPI

api = CoinifyAPI( apikey, apisecret )
response = api.invoice_create( amount, currency, plugin_name, plugin_version,
    description=description, custom=custom )

# ================================================================

"""
Using the requests module 
"""
import requests

headers = {
            'Authorization': auth_header,
            'Content-Type': 'application/json'
}

params = {
    'amount': amount,
    'currency': currency,
    'plugin_name': plugin_name,
    'plugin_version', plugin_version,
    'description': description,
    'custom': custom
}

url = 'https://api.coinify.com/v3/payments'

response = requests.request( 'POST', url, headers=headers, json=params ).json()

The above API call returns a payment object like this:

{
  "success": true,
  "data": {
    "id": 12345,
    "uuid": "0155d80d-a535-4b10-ab91-0d61f6969ccd",
    "create_time": "2016-01-26T12:09:01Z",
    "expire_time": "2016-01-26T12:24:01Z",
    "state": "new",
    "type": "normal",
    "bitcoin": {
      "amount": 0.00282,
      "address": "14KRwZqXrRxi1mag9B52r5fyn37AiWRPYi",
      "amount_paid": 0,
      "amount_due": 0.00282,
      "payment_uri": "bitcoin:14KRwZqXrRxi1mag9B52r5fyn37AiWRPYi?amount=0.00282&r=https://merchant.coinify.com/payment/abc/def"
    },
    "native": {
      "amount": 1,
      "currency": "EUR"
    },
    "transfer": {
      "amount": 1,
      "currency": "EUR"
    },
    "description": "Sample payment",
    "custom": {
      "sample_data": "value"
    },
    "payment_url": "https://merchant.coinify.com/payment/abc/def",
    "inputs": [],
    "callback_url": "https://myshop.com/callbacks/coinify",
    "callback_email": null,
    "return_url": "https://myshop.com/order_paid/xyz",
    "cancel_url": "https://myshop.com/order_cancelled/xyz",
    "payments": []
  }
}

This endpoint creates a new payment.

If the creation is successful, you will receive a response object identical to the response from Get a specific payment.

HTTP Request

POST https://api.coinify.com/v3/payments

Required JSON parameters

Name Type Description
amount Float Fiat price of the payment
currency String 3 letter ISO 4217 currency code denominating amount.
plugin_name String The name of the plugin used to call this API
plugin_version String The version of the above plugin

Optional JSON parameters

Name Type Default Description
customer_id String empty string Your own identifier for the customer of the payment.
description String empty string Your custom text for this payment.
custom Object empty object Your custom data for this payment. This can be any JSON primitive - even nested arrays and objects!
callback_url String IPN callback* A URL that Coinify calls when the payment state changes.
callback_email String IPN callback* An email address to send a mail to when the payment state changes
return_url String Redirect URLs We redirect your customer to this URL to when the payment has been paid
cancel_url String Redirect URLs We redirect your customer to this URL if they fail to pay the payment in time
input_currency String "BTC" Input currency that the payment should be paid in. See supported input currencies for retrieving a list of supported currencies.
input_return_address String null The address (belonging to the input_currency) that the money should be returned to in case of an error. Mandatory if input_currency is not "BTC" - otherwise unused.
input_return_address_tag String null Tag for input_return_address (e.g. Destination tag for XRP).

* If neither callback_url nor callback_email is provided, these values default to your IPN callback URL or email.

Update a payment

<?php
$payment_id = 12345;
$new_description = 'Sample payment with changed description';
$new_custom = array( 'my_order_id' => 1337,
                     'sample_data' = 'value' );

/*
 * Using the Coinify PHP SDK
 */
$api = new CoinifyAPI( $apikey, $apisecret );
$result = $api->invoiceUpdate($payment_id,
    $new_description, $new_custom );

// ===============================================================

/*
 * Using cURL
 */
$params = array(
  'description' => $new_description,
  'custom' => $new_custom
);

$url = "https://api.coinify.com/v3/payments/" . $payment_id;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array($auth_header));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$result = json_decode( curl_exec($ch) );
curl_close($ch);
?>
payment_id = 12345
new_description = 'Sample payment with changed description'
new_custom = {'my_order_id': 1337, 'sample_data': 'value'}

"""
Using the Coinify Python SDK
"""
from coinify_api import CoinifyAPI

api = CoinifyAPI( apikey, apisecret )
response = api.invoice_update( payment_id, 
    description=new_description, 
    custom=new_custom )

# ================================================================

"""
Using the requests module 
"""
import requests

headers = {
            'Authorization': auth_header,
            'Content-Type': 'application/json'
}

params = {
    'description': new_description, 
    'custom': new_custom
}

url = 'https://api.coinify.com/v3/payments/%d' % ( payment_id, )

response = requests.request( 'PUT', url, headers=headers, json=params ).json()

The above API call returns a payment object like this:

{
  "success": true,
  "data": {
    "id": 12345,
    "uuid": "0155d80d-a535-4b10-ab91-0d61f6969ccd",
    "create_time": "2016-01-26T12:09:01Z",
    "expire_time": "2016-01-26T12:24:01Z",
    "state": "new",
    "type": "normal",
    "bitcoin": {
      "amount": 0.00282,
      "address": "14KRwZqXrRxi1mag9B52r5fyn37AiWRPYi",
      "amount_paid": 0,
      "amount_due": 0.00282,
      "payment_uri": "bitcoin:14KRwZqXrRxi1mag9B52r5fyn37AiWRPYi?amount=0.00282&r=https://merchant.coinify.com/payment/abc/def"
    },
    "native": {
      "amount": 1,
      "currency": "EUR"
    },
    "transfer": {
      "amount": 1,
      "currency": "EUR"
    },
    "description": "Sample payment with changed description",
    "custom": {
      "my_order_id": 1337,
      "sample_data": "value"
    },
    "payment_url": "https://merchant.coinify.com/payment/abc/def",
    "inputs": [],
    "callback_url": "https://myshop.com/callbacks/coinify",
    "callback_email": null,
    "return_url": "https://myshop.com/order_paid/xyz",
    "cancel_url": "https://myshop.com/order_cancelled/xyz",
    "payments": []
  }
}

After a payment has been created, you have the option to update some of the fields in that payment.

HTTP Request

PUT https://api.coinify.com/v3/payments/<ID>

URL parameters

Name Type Description
ID Integer The ID of the payment to retrieve

JSON parameters

Supply any of the below parameters to change their current value.

Name Type Description
description String Your custom text for this payment.
custom Object Your custom data for this payment. This can be any JSON primitive - even nested arrays and objects!

Pay with another input currency

<?php
$payment_id = 12345;
$input_currency = 'DOGE';
$input_return_address = 'D95Kj5JJiWXH4kjTqHXovF5taxcLWoPNGG';

/*
 * Using the Coinify PHP SDK
 */
$api = new CoinifyAPI( $apikey, $apisecret );
$result = $api->invoiceRequestInputCurrency($payment_id,
    $input_currency, $input_return_address );

// ===============================================================

/*
 * Using cURL
 */
$params = array(
  'currency' => $input_currency,
  'return_address' => $input_return_address
);

$url = "https://api.coinify.com/v3/payments/" . $payment_id . "/inputs";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array($auth_header));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$result = json_decode( curl_exec($ch) );
curl_close($ch);
?>
payment_id = 12345
input_currency = 'DOGE'
input_return_address = 'D95Kj5JJiWXH4kjTqHXovF5taxcLWoPNGG'

"""
Using the Coinify Python SDK
"""
from coinify_api import CoinifyAPI

api = CoinifyAPI( apikey, apisecret )
response = api.invoice_request_input_currency( payment_id, 
    input_currency, input_return_address )

# ================================================================

"""
Using the requests module 
"""
import requests

headers = {
            'Authorization': auth_header,
            'Content-Type': 'application/json'
}

params = {
    'currency': input_currency, 
    'return_address': input_return_address
}

url = 'https://api.coinify.com/v3/payments/%d/inputs' % ( payment_id, )

response = requests.request( 'POST', url, headers=headers, json=params ).json()

The above API call returns a payment object like this (Notice the inputs sub-object):

{
  "success": true,
  "data": {
    "id": 12345,
    "uuid": "0155d80d-a535-4b10-ab91-0d61f6969ccd",
    "create_time": "2015-01-01T12:00:00Z",
    "expire_time": "2015-01-01T12:15:00Z",
    "state": "complete",
    "type": "normal",
    "bitcoin": {
        "amount": 0.14951537,
        "address": "176WSTb4ZMtSKjSampleBitcoinAddress",
    },
    "native": {
        "amount": "32.00",
        "currency": "USD"
    },
    "transfer": {
        "amount": "213.20",
        "currency": "DKK"
    },
    "description": "Sample payment with changed description",
    "custom": {
      "my_order_id": 1337,
      "sample_data": "value"
    },
    "payment_url": "https://merchant.coinify.com/payment/abc/def",
    "inputs": [{ // Requests on paying with different currencies than BTC
      "currency": "DOGE",
      "amount": 3893.33333333,
      "address": "DAfNsbdWnXnEZwTAZdNWeUZLNqnfFLs5D5",
      "return_address": "D95Kj5JJiWXH4kjTqHXovF5taxcLWoPNGG",
      "payment_uri": "dogecoin:D95Kj5JJiWXH4kjTqHXovF5taxcLWoPNGG&amount=3893.33333333",
      "verified": false,
      "timestamp": "2016-01-26T12:09:01Z"
    }],
    "callback_url": "https://myshop.com/callbacks/coinify",
    "callback_email": null,
    "return_url": "https://myshop.com/order_paid/xyz",
    "cancel_url": "https://myshop.com/order_cancelled/xyz"
  }
}

After a payment has been created, you can request for the customer to pay with another input currency. This is essentially the same as providing input_currency and input_return_address when creating a payment.

HTTP Request

POST https://api.coinify.com/v3/payments/<ID>/inputs

URL parameters

Name Type Description
ID Integer The ID of the payment to retrieve

JSON parameters

Both of the below parameters must be supplied in order to create a new input currency request:

Name Type Description
currency String Input currency that the payment should be paid in. See supported input currencies for retrieving a list of supported currencies.
return_address String The address (belonging to the currency) that the money should be returned to in case of an error.
return_address_tag String (Optional) Tag for return_address (e.g. Destination tag for XRP).

Payment refunds

This section describes how to create a refund for a payment and list all refunds for a payment.

A refund basically means to send bitcoins back to the customer for a paid payment.

Refunds are subject to the following restrictions:

You can do multiple and partial refunds (i.e. for a payment that was credited 100 EUR, you can refund first 30 EUR, then 40 EUR), as long as the sum of all refunds do not exceed the credited amount of the payment.

Upon creating a refund, the refund amount is withdrawn from your credit account immediately.

When refunding to a customer, you must provide either the customer’s email address or the customer’s bitcoin address. If email address is provided, we will send an email to the customer, requesting them to provide us with a bitcoin address to send the refund to.

If refunding to an email address, and the customer doesn’t provide a bitcoin address within 7 days, the refund is cancelled, and the withdrawn amount is re-inserted into your credit account.

Refund object

Payment refund sample object

{
  "id": 44445555,
  "uuid": "d307823c-a916-472f-ba84-33add7db59ee",
  "invoice_id": 12345,
  "create_time": "2016-09-21T11:12:01Z",
  "state": "complete",
  "amount": 100,
  "currency": "EUR",
  "btc_address": "176WSTb4ZMtSKjSampleBitcoinAddress",
  "email_address": "customer@coinify.com",
  "btc_amount": 0.18580,
  "btc_txid": "d3b0a573ed2f8f77b01b44b868c8a69e46e8ce75b8618f06f5801fa408c0b881"
}
Name Type Description
id Integer The numeric ID of the refund
uuid String Alternate UUID of the refund
invoice_id Integer The ID of the payment that this refund refers to. Field is named invoice_id for historical reasons.
create_time ISO 8601 time The time when the refund was created
state String The refund state. See section on Refund state
amount Float The amount of the refund. Denominated in currency
currency String Currency denominating amount
btc_address
(optional)
String Customer’s bitcoin address to refund to. If refund to email address and customer has not yet provided their bitcoin address, this field is absent.
email_address
(optional)
String Customer’s email address to refund to. If refund was created with a btc_address, this field is absent.
btc_amount
(optional)
Float Amount of BTC that this refund sent to the customer’s btc_address. This field is absent in awaiting_btc_address and expired states.
btc_txid
(optional)
String ID of bitcoin transaction that sent the bitcoins to the customer. This field is only present in the complete state.

Refund state

The state field of the refund object has the following possible values:

State Description
awaiting_verification Refund is awaiting verification from the merchant (you), either by 2-factor or by verification email. Note: Refunds created through the API are automatically verified. This state only occurs for refunds created in the merchant dashboard.
awaiting_btc_address We have sent an email to the customer’s email address, and is awaiting the customer to respond to the email and provide us with a bitcoin address.
queued The refund is queued in our system to be sent out (no further action required).
complete The refund has been sent to the customer
expired The refund has expired

List refunds for payment

<?php
$payment_id = 12345;

/*
 * Using the Coinify PHP SDK
 */
$api = new CoinifyAPI( $apikey, $apisecret );
$result = $api->invoiceRefundsList($payment_id);

// ===============================================================

/*
 * Using cURL
 */
$url = "https://api.coinify.com/v3/payments/" . $payment_id . "/refunds";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array($auth_header));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = json_decode( curl_exec($ch) );
curl_close($ch);
?>
payment_id = 12345

"""
Using the Coinify Python SDK
"""
from coinify_api import CoinifyAPI

api = CoinifyAPI( apikey, apisecret )
response = api.invoice_refunds_list(payment_id)

# ================================================================

"""
Using the requests module 
"""
import requests

headers = {
            'Authorization': auth_header,
            'Content-Type': 'application/json'
}

url = 'https://api.coinify.com/v3/payments/%d/refunds' % ( payment_id, )

response = requests.request( 'GET', url, headers=headers ).json()

The above API call returns a (possibly empty) list of refund objects like this:

{
  "success": true,
  "data": [
    {
      "id": 44445555,
      "uuid": "d307823c-a916-472f-ba84-33add7db59ee",
      "invoice_id": 12345,
      "create_time": "2016-09-21T11:12:01Z",
      "state": "complete",
      "amount": 100,
      "currency": "EUR",
      "btc_address": "176WSTb4ZMtSKjSampleBitcoinAddress",
      "email_address": "customer@coinify.com",
      "btc_amount": 0.18580,
      "btc_txid": "d3b0a573ed2f8f77b01b44b868c8a69e46e8ce75b8618f06f5801fa408c0b881"
    }
  ]
}

List all refunds to a specific payment

HTTP Request

GET https://api.coinify.com/v3/payments/<ID>/refunds

URL parameters

Name Type Description
ID Integer The ID of the payment to list refunds for

Create refund

<?php
$payment_id = 12345;
// Refund 100 EUR
$refund_amount = 100;
$refund_currency = 'EUR';
// Refund to email address
$email_address = 'customer@coinify.com';

/*
 * Using the Coinify PHP SDK
 */
$api = new CoinifyAPI( $apikey, $apisecret );
$result = $api->invoiceRefundCreate($payment_id, 
    $refund_amount, $refund_currency, $email_address );

// ===============================================================

/*
 * Using cURL
 */

$url = "https://api.coinify.com/v3/payments/" . $payment_id . "/refunds";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array($auth_header));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$result = json_decode( curl_exec($ch) );
curl_close($ch);
?>
payment_id = 12345
# Refund 100 EUR
refund_amount = 100
refund_currency = 'EUR'
# Refund to email address
email_address = 'customer@coinify.com'

"""
Using the Coinify Python SDK
"""
from coinify_api import CoinifyAPI

api = CoinifyAPI( apikey, apisecret )
response = api.invoice_refund_create( payment_id, 
     amount=refund_amount, currency=refund_currency,
     email_address=email_address )

# ================================================================

"""
Using the requests module 
"""
import requests

headers = {
            'Authorization': auth_header,
            'Content-Type': 'application/json'
}

params = {
    'description': new_description, 
    'custom': new_custom
}

url = 'https://api.coinify.com/v3/payments/%d/refunds' % ( payment_id, )

response = requests.request( 'POST', url, headers=headers, json=params ).json()

The above API call returns an refund object like this:

{
  "success": true,
  "data": {
    "id": 44445555,
    "uuid": "d307823c-a916-472f-ba84-33add7db59ee",
    "invoice_id": 12345,
    "create_time": "2016-09-21T11:12:01Z",
    "state": "awaiting_btc_address",
    "amount": 100,
    "currency": "EUR",
    "email_address": "customer@coinify.com"
    // Fields btc_address and btc_amount are currently absent from this refund
  }
}

This endpoint allows you to refund a payment to a customer.

HTTP Request

POST https://api.coinify.com/v3/payments/<ID>/refunds

URL parameters

Name Type Description
ID Integer The ID of the payment to refund

Required JSON parameters

Name Type Description
amount Float Amount of currency to refund
currency String 3 letter ISO 4217 currency code denominating amount. This must be the currency that the payment was credited in.
email_address String Email address of customer to refund to
btc_address String Bitcoin (BTC) address of customer to refund to

Optional JSON parameters

Name Type Default Description
use_payment_protocol_refund_address Boolean true If true and customer supplied a refund bitcoin address during payment (through the BIP70 payment protocol), use that refund address and ignore email_address and btc_address parameters. If false, always use provided email_address or btc_address.

Buy Orders

This API allows our preapproved merchants to buy bitcoins from their fiat account balance. In order to test a buy order in sandbox you need a testnet Bitcoin address. Have a look at our article if you need help on setting this up.

Instant order

When creating buy orders, you have the choice between whether the order should be instant or not.

If you create a non-instant order, our API will return to you a quote so you can decide whether or not you want to accept the order at the rate promised. You will then have to perform another API call instructing us to actually execute the order for you.

If you create an instant order, you will automatically accept the given rate and we will execute the order immediately.

Buy order object

Buy order sample object

{
  "id": 12345,
  "uuid": "5a0c1a16-d46c-4d20-b919-9cec171791bd",
  "create_time": "2015-01-01T12:00:00Z",
  "expire_time": "2015-01-01T12:01:00Z",
  "state": "complete",
  "fiat_currency": "USD",
  "fiat_amount": 1000,
  "btc_rate": 231.58,
  "btc_amount": 4.31819481,
  "btc_address": "176WSTb4ZMtSKjSampleBitcoinAddress",
  "btc_txid": "bd59acf87db5a7859fd6a95ad69569b5d6bf9dbfa65f6dfa35f2afdbfbcfad1f",
  "failure_reason": null,
  "callback_url": "https://myshop.com/callbacks/coinify",
  "callback_email": null,
  "custom": {
    "sample_data": "value"
  }
}

To the right you can see a sample buy order object. The table below summarizes the individual fields of the object.

Buy order object parameters

Name Type Description
id Integer Numeric ID of the buy order
uuid String Alternate UUID of the buy order
create_time ISO 8601 time The time when the buy order was created
expire_time ISO 8601 time The time when the buy order will expire if not confirmed
state String The state of the buy order. See section on Buy order state
fiat_currency String The 3 letter ISO 4217 currency code denominating fiat_amount
fiat_amount Float The amount of fiat_currency that you will buy bitcoins for.
btc_rate Float The BTC/fiat_currency rate of the buy order.
btc_amount Float The amount of bitcoins that the buy order will result in.
btc_address String The bitcoin address to send the bitcoins to.
btc_txid String If state is complete, this field will contain the ID of the bitcoin transaction sending the bitcoins to btc_address. Otherwise, this field will be null.
failure_reason String If state is failed, this field will contain a reason for the failure. See Failure reasons for possible values. Otherwise, this field will be null.
callback_url String A URL that Coinify calls when the state of the buy order changes
callback_email String An email address to send a mail to when the state of the buy order changes
custom Object Your custom data for this buy order

Buy order state

The state field of the buy order object has the following possible values:

State Description
waiting Quote given - awaiting merchant confirmation (Only non-instant orders)
queued Order confirmed by merchant - awaiting transfer
complete Bitcoins have been sent to provided address
failed Order failed. The failure_reason field will contain a reason for the failure.
cancelled Order cancelled (When a non-instant order expires)

The buy order moves between the different states as shown in the following chart:

Possibles states of a buy order

Failure reasons

When the state field is failed, the buy order object will contain an additional field failure_reason, which can have the following values:

Failure reason Description
insufficient_funds There wasn’t enough money in your account to complete the order.
internal_error An internal error happened. Create a support ticket for Merchant Support with the buy order ID to resolve the issue.

List all buy orders

<?php
/*
 * Using the Coinify PHP SDK
 */
$api = new CoinifyAPI( $apikey, $apisecret );
$result = $api->buyOrdersList();

// ===============================================================

/*
 * Using cURL
 */
$ch = curl_init('https://api.coinify.com/v3/buys');
curl_setopt($ch, CURLOPT_HTTPHEADER, array($auth_header));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = json_decode( curl_exec($ch) );
curl_close($ch);
?>
"""
Using the Coinify Python SDK
"""
from coinify_api import CoinifyAPI

api = CoinifyAPI( apikey, apisecret )
response = api.buy_orders_list()

# ================================================================

"""
Using the requests module 
"""
import requests

headers = {
            'Authorization': auth_header,
            'Content-Type': 'application/json'
}

url = 'https://api.coinify.com/v3/buys'

response = requests.request( 'GET', url, headers=headers ).json()

The above API call returns JSON structured like this:

{
  "success": true,
  "data": 
  [
    {
      "id": 12345,
      "uuid": "5a0c1a16-d46c-4d20-b919-9cec171791bd",
      "create_time": "2015-01-01T12:00:00Z",
      "expire_time": "2015-01-01T12:01:00Z",
      "state": "complete",
      "fiat_currency": "USD",
      "fiat_amount": 1000,
      "btc_rate": 231.58,
      "btc_amount": 4.31819481,
      "btc_address": "176WSTb4ZMtSKjSampleBitcoinAddress",
      "btc_txid": "bd59acf87db5a7859fd6a95ad69569b5d6bf9dbfa65f6dfa35f2afdbfbcfad1f",
      "failure_reason": null,
      "callback_url": "https://myshop.com/callbacks/coinify",
      "callback_email": null,
      "custom": {
        "sample_data": "value"
      }
    }
  ]
}

This endpoint retrieves all your buy orders, sorted by newest first.

HTTP Request

GET https://api.coinify.com/v3/buys

Query parameters

Name Type Default Description
limit Integer 100 Maximum number of buy orders to retrieve. Maximum is 200.
offset Integer 0 How many buy orders to skip.
include_cancelled Boolean false If set to true, cancelled buy orders are included in the result. Default is not to include cancelled buy orders.

Get a specific buy order

<?php
$buy_order_id = 12345;

/*
 * Using the Coinify PHP SDK
 */
$api = new CoinifyAPI( $apikey, $apisecret );
$result = $api->buyOrderGet($buy_order_id);

// ===============================================================

/*
 * Using cURL
 */
$url = 'https://api.coinify.com/v3/buys/' . $buy_order_id;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array($auth_header));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = json_decode( curl_exec($ch) );
curl_close($ch);
?>
buy_order_id = 12345

"""
Using the Coinify Python SDK
"""
from coinify_api import CoinifyAPI

api = CoinifyAPI( apikey, apisecret )
response = api.buy_order_get( buy_order_id )

# ================================================================

"""
Using the requests module 
"""
import requests

headers = {
            'Authorization': auth_header,
            'Content-Type': 'application/json'
}

url = 'https://api.coinify.com/v3/buys/%d' % ( buy_order_id, )

response = requests.request( 'GET', url, headers=headers ).json()

The above API call returns JSON structured like this:

{
  "success": true,
  "data": {
    "id": 12345,
    "uuid": "5a0c1a16-d46c-4d20-b919-9cec171791bd",
    "create_time": "2015-01-01T12:00:00Z",
    "expire_time": "2015-01-01T12:01:00Z",
    "state": "complete",
    "fiat_currency": "USD",
    "fiat_amount": 1000,
    "btc_rate": 231.58,
    "btc_amount": 4.31819481,
    "btc_address": "176WSTb4ZMtSKjSampleBitcoinAddress",
    "btc_txid": "bd59acf87db5a7859fd6a95ad69569b5d6bf9dbfa65f6dfa35f2afdbfbcfad1f",
    "failure_reason": null,
    "callback_url": "https://myshop.com/callbacks/coinify",
    "callback_email": null,
    "custom": {
      "sample_data": "value"
    }
  }
}

This endpoint retrieves a specific buy order.

HTTP Request

GET https://api.coinify.com/v3/buys/<ID>

URL parameters

Name Type Description
ID Integer The ID of the buy order to retrieve

Create a buy order

<?php

$amount = 32.00;
$currency = 'USD';
$btc_address = '176WSTb4ZMtSKjSampleBitcoinAddress';
$instant_order = true;
$callback_url = 'https://myshop.com/callbacks/coinify';
$callback_email = 'callback@example.com';
$custom = ['sample_data' => 'value'];

/*
 * Using the Coinify PHP SDK
 */
$api = new CoinifyAPI( $apikey, $apisecret );
$result = $api->buyOrderCreate( $amount, $currency, $btc_address,
    $instant_order, $callback_url, $callback_email, $custom );

// ===============================================================

/*
 * Using cURL
 */
$params = array(
  'amount' => $amount,
  'currency' => $currency,
  'btc_address' => $btc_address,
  'instant_order' => $instant_order,
  'callback_url' => $callback_url,
  'callback_email' => $callback_email,
  'custom' => $custom
);

$url = 'https://api.coinify.com/v3/buys';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array($auth_header));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$result = json_decode( curl_exec($ch) );
curl_close($ch);
?>
amount = 32.00
currency = 'USD'
btc_address = '176WSTb4ZMtSKjSampleBitcoinAddress'
instant_order = true
callback_url = 'https://myshop.com/callbacks/coinify'
callback_email = 'callback@example.com'
custom = {'sample_data': 'value'}

"""
Using the Coinify Python SDK
"""
from coinify_api import CoinifyAPI

api = CoinifyAPI( apikey, apisecret )
response = api.buy_order_create( amount, currency, btc_address,
    instant_order, callback_url, callback_email, custom )

# ================================================================

"""
Using the requests module 
"""
import requests

headers = {
            'Authorization': auth_header,
            'Content-Type': 'application/json'
}

params = {
    'amount': amount,
    'currency': currency,
    'btc_address': btc_address,
    'instant_order': instant_order,
    'callback_url': callback_url,
    'callback_email': callback_email,
    'custom': custom
}

url = 'https://api.coinify.com/v3/buys'

response = requests.request( 'POST', url, headers=headers, json=params ).json()

The above API call returns an buy order object like this:

{
  "success": true,
  "data": {
    "id": 12345,
    "uuid": "5a0c1a16-d46c-4d20-b919-9cec171791bd",
    "create_time": "2015-01-01T12:00:00Z",
    "expire_time": "2015-01-01T12:01:00Z",
    "state": "queued",
    "fiat_currency": "USD",
    "fiat_amount": 1000,
    "btc_rate": 231.58,
    "btc_amount": 4.31819481,
    "btc_address": "176WSTb4ZMtSKjSampleBitcoinAddress",
    "btc_txid": null,
    "failure_reason": null,
    "callback_url": "https://myshop.com/callbacks/coinify",
    "callback_email": null,
    "custom": {
      "sample_data": "value"
    }
  }
}

This endpoint creates a new buy order.

If the creation is successful, you will receive a response object identical to the response from Get a specific buy order.

HTTP Request

POST https://api.coinify.com/v3/buys

Required JSON parameters

Name Type Description
amount Float Amount that you want to buy BTC for - denominated in currency. If currency is BTC, then this is amount of bitcoins to buy.
currency String 3 letter ISO 4217 currency code denominating amount. Must be either BTC or your merchant account currency.
btc_address String The bitcoin address to send the bitcoins to.

Optional JSON parameters

Name Type Default Description
instant_order Boolean true Should this be an instant order or not? See Instant order.
callback_url String IPN callback* A URL that Coinify calls when the buy order state changes.
callback_email String IPN callback* An email address to send a mail to when the buy order state changes
custom Object empty object Your custom data for this buy order. This can be any JSON primitive - even nested arrays and objects!

* If neither callback_url nor callback_email is provided, these values default to your IPN callback URL or email.

Confirm a non-instant buy order

<?php
$buy_order_id = 12345;

/*
 * Using the Coinify PHP SDK
 */
$api = new CoinifyAPI( $apikey, $apisecret );
$result = $api->buyOrderConfirm($buy_order_id);

// ===============================================================

/*
 * Using cURL
 */
$url = 'https://api.coinify.com/v3/buys/' . $buy_order_id . '/actions/confirm';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array($auth_header));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$result = json_decode( curl_exec($ch) );
curl_close($ch);
?>
buy_order_id = 12345

"""
Using the Coinify Python SDK
"""
from coinify_api import CoinifyAPI

api = CoinifyAPI( apikey, apisecret )
response = api.buy_order_confirm( buy_order_id )

# ================================================================

"""
Using the requests module 
"""
import requests

headers = {
            'Authorization': auth_header,
            'Content-Type': 'application/json'
}

url = 'https://api.coinify.com/v3/buys/%d/actions/confirm' % ( buy_order_id, )

response = requests.request( 'PUT', url, headers=headers, json=params ).json()

The above API call returns an buy order object like this:

{
  "success": true,
  "data": {
    "id": 12345,
    "uuid": "5a0c1a16-d46c-4d20-b919-9cec171791bd",
    "create_time": "2015-01-01T12:00:00Z",
    "expire_time": "2015-01-01T12:01:00Z",
    "state": "queued",
    "fiat_currency": "USD",
    "fiat_amount": 1000,
    "btc_rate": 231.58,
    "btc_amount": 4.31819481,
    "btc_address": "176WSTb4ZMtSKjSampleBitcoinAddress",
    "btc_txid": null,
    "failure_reason": null,
    "callback_url": "https://myshop.com/callbacks/coinify",
    "callback_email": null,
    "custom": {
      "sample_data": "value"
    }
  }
}

When you create a non-instant buy order, you have 1 minute to confirm it. This endpoint confirms a newly created buy order. Note that the state of the buy order has to be waiting for this call to work. If it is in any other state, the call will fail.

If the confirmation is successful, you will receive a response object identical to the response from Get a specific buy order, where the state is either queued or complete.

HTTP Request

PUT https://api.coinify.com/v3/buys/<ID>/actions/confirm

URL parameters

Name Type Description
ID Integer The ID of the buy order to confirm

Input currencies

Apart from receiving payments in Bitcoin (BTC), we also support a range of other input currencies such as Litecoin (LTC), Ether (ETH), and Dogecoin (DOGE).

You can request for the customer to pay with another input currency during payment creation, or after a payment has been created. However, this does not disable the end-user to choose another cryptocurrency to pay with from the available list of currencies. It only sets your input currency as the default one.

We constantly monitor the state of our input currencies, enabling or disabling them as we see fit, and provide a means to query for currently supported input currencies:

Supported input currencies

<?php
/*
 * Using the Coinify PHP SDK
 */
$api = new CoinifyAPI( $apikey, $apisecret );
$result = $api->inputCurrenciesList();

// ===============================================================

/*
 * Using cURL
 */
$url = 'https://api.coinify.com/v3/input-currencies';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$result = json_decode( curl_exec($ch) );
curl_close($ch);
?>
"""
Using the Coinify Python SDK
"""
from coinify_api import CoinifyAPI

api = CoinifyAPI( apikey, apisecret )
response = api.input_currencies_list()

# ================================================================

"""
Using the requests module 
"""
import requests

headers = {
            'Content-Type': 'application/json'
}

url = 'https://api.coinify.com/v3/input-currencies'

response = requests.request( 'GET', url, headers=headers ).json()

The above API call returns an object like this:

{
  "success": true,
  "data": [
    { // One object for each supported input currency
      "currency": "ETH",
      "name": "Ethereum"
    },
    {
      "currency": "LTC",
      "name": "Litecoin"
    },
    {
      "currency": "XEM",
      "name": "NEM",
      "tag_name": "Message"
    },
    {
      "currency": "XRP",
      "name": "Ripple",
      "tag_name": "Destination Tag"
    }
    // ... more supported currencies
  ]
}

Receive a list of supported input currencies

HTTP Request

GET https://api.coinify.com/v3/input-currencies

Response object parameters

The response object contains a list of currency objects. The below table describes the fields of the objects:

Name Type Description
currency String Currency code. Use this as input_currency when creating a new payment or as currency when requesting to pay an existing payment with another input currency.
name String The name of the input currency.
tag_name String (Optional) If the input currency requires a tag (see Inputs), this field contains the human-readable name of the tag parameter.

Callbacks

Whenever something changes – such as the state of a payment, for example when a customer has paid a payment – you usually want to know about it as soon as possible.

To avoid you having to constantly poll our API for changes to your payment, we support sending callbacks whenever the state changes, either through a HTTP call to your webservice, or by email.

The callback data informs you of what changed, as well as the new complete state of the object.

Callback data

{
  "event": "invoice_state_change",
  "time": "2015-01-01T13:14:15Z",
  "data": {
    "id": 12345,
    "create_time": "2015-01-01T12:00:00Z",
    "state": "complete",

    "(etc)": "(...)"
  }
}

The data contained in a callback is encoded as a JSON object, and it is the same, whether you choose to receive callbacks by HTTP calls or by email. It looks like the JSON object you see on the right:

Name Type Description
event String The reason for the callback. The event dictates the data type of the data parameter.
time ISO 8601 time The time that this callback was initiated
data Object The object, dependent on the event parameter as described in the table below.

Possible events

Event Description data parameter
invoice_state_change The state variable of a payment object has changed Payment object
invoice_manual_resend Manual resend of payment callback from dashboard Payment object
buy_order_state_change The state variable of a buy order object has changed Buy order object

Responding to HTTP callbacks

<?php
header('HTTP/1.1 200 OK');

// Don't output anything back to the client performing the HTTP callback
?>

When performing a HTTP callback, we will always use the POST method. When you receive a HTTP callback, always reply with a HTTP 200 OK status code and an empty body, regardless of the result of validating the callback.

Validating callbacks

<?php
$ipnsecret = "<my_ipn_secret>";

// Get the raw HTTP POST body (JSON object encoded as a string)
// Note: Substitute getBody() with a function call to retrieve the raw HTTP body.
// In "plain" PHP this can be done with file_get_contents('php://input')
$body = getBody();

// Get the signature from the HTTP or email headers
$signature = getHeader("X-Coinify-Callback-Signature");

/*
 * Using the Coinify PHP SDK
 */
$callback = new CoinifyCallback( $ipnsecret );

return $callback->validateCallback( $body, $signature );

// ===============================================================

/*
 * Without the Coinify PHP SDK
 */
// Calculate the signature using the callback data and your IPN secret
$expected_signature = strtolower( hash_hmac('sha256', $body, $ipnsecret, false) );

// Check that the signatures match
return $signature === $expected_signature );
?>
ipnsecret = '<my_ipn_secret>'

# Get the raw HTTP POST body (JSON object encoded as a string)
body = get_body()

# Get the signature from the HTTP or email headers
signature = get_header("X-Coinify-Callback-Signature")

"""
Using the Coinify Python SDK
"""
from coinify_callback import CoinifyCallback

callback = CoinifyCallback( ipnsecret )
return callback.validate_callback( body, signature )

# ================================================================

"""
Using raw Python hmac and hashlib modules
"""
import hashlib, hmac

expected_signature = hmac.new(self.ipn_secret, msg=callback_raw, digestmod=hashlib.sha256).hexdigest()
return signature == expected_signature

Remember to replace <my_ipn_secret> with your actual IPN secret in the code above.

To ensure that the callback actually originated from Coinify, and that the callback data has not been modified in transit, you must validate the callback data as shown in this section.

First, you need to obtain your IPN secret, which you can generate here: https://merchant.coinify.com/merchant/ipn. The callbacks coming from Coinify are signed with the IPN secret, similar to how you authenticate against our API with your API secret.

Second, you must extract the signature from the HTTP headers, if using HTTP callbacks, or from the email headers if using email callbacks.

Then, you must check that the provided signature matches the HMAC-SHA256 hash of the raw callback data (which is a JSON object encoded as a string), using your IPN secret as the HMAC key. The signature will always be in lowercase hexadecimal format, like the following example: b9926f02caed3c9c08224cd079a162b771c80b0ff49a69d0579cb806d5475ff3.