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 blockchain Testnet.
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
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
andcoinifyapisecret
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 invoices API
url = 'https://api.coinify.com/v3/invoices'
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:
apikey
: Your API keynonce
: A regular integer, that must be increasing with every request you make. For example, if you use 1 as the nonce in your first request, you must use 2 (or a higher number) in your second request. You can use Unix timestamps for this purpose.signature
: Your signature authenticating this request.
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
Invoices
The invoice is the cornerstone of the Coinify API. We use invoices to create payment requests from customers.
Please use a moment to familiarize yourself with the invoice object below before heading to the code samples.
Invoice object
Invoice sample object
{
"id": 12345,
"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/invoice/abc/def"
},
"native": {
"amount": 1,
"currency": "EUR"
},
"transfer": {
"amount": 1,
"currency": "EUR"
},
"description": "Sample invoice",
"custom": {
"sample_data": "value"
},
"payment_url": "https://merchant.coinify.com/invoice/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 invoice
"original_invoice_id": 12345, // optional
"sub_invoice_ids": [54321, 98765] // optional
}
To the right you can see a sample invoice object, and the table below summarizes the individual fields of the object.
Note that all invoices will contain the bitcoin
object with the bitcoin details for the invoice,
regardless of whether or not another input currency is requested to pay with.
Invoice object parameters
Name | Type | Description |
---|---|---|
id |
Integer | The ID of the invoice |
create_time |
ISO 8601 time | The time when the invoice was created |
expire_time |
ISO 8601 time | The time when the invoice will expire/expired. |
state |
String | The invoice’s state. See section on Invoice state |
type |
String | The invoice type. See section on Invoice type |
bitcoin |
Object | The bitcoin details for this specific payment. |
bitcoin.amount |
Float | The total bitcoin amount of this invoice |
bitcoin.address |
String | The bitcoin address to receive the payment |
bitcoin.amount_paid |
Float | How much has been paid to this invoice |
bitcoin.amount_due |
Float | How much is yet to be paid for this invoice |
bitcoin.payment_uri |
String | Payment URI for wallets, supporting BIP21 and BIP70. It is available only if state of the invoice is new . |
native.amount |
Float | The amount used to create the invoice 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 invoice has been paid. Denominated in transfer.currency |
transfer.currency |
String | The currency denominated transfer.amount |
description |
String | Your custom text for this invoice |
custom |
Object | Your custom data for this invoice |
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 invoice has been paid |
callback_email |
String | An email address to send a mail to when the invoice has been paid |
return_url |
String | We redirect your customer to this URL to when the invoice has been paid |
cancel_url |
String | We redirect your customer to this URL if they fail to pay the invoice in time |
payments |
List | All payments received to this invoice. See section on Payments |
original_invoice_id (optional) |
Integer | The ID of the original invoice for the certain sub-invoice |
sub_invoice_ids (optional) |
Array | The IDs of the sub-invoices for the certain original invoice |
Note: The invoice object may contain additional fields under certain circumstances. See References to original and sub-invoices for more information.
Invoice state
The state
field of the invoice object has the following possible values:
State | Description |
---|---|
new |
Awaiting payment from the customer |
paid |
The invoice has been paid, but the payments are not yet verified |
complete |
The invoice has been paid, and payments are verified |
expired |
The invoice has expired |
Invoice type
The type
field of the invoice object has the following possible values:
State | Description |
---|---|
normal |
Normal invoice |
underpaid |
The invoice received too little payment within the time limit and the payment amounts were adjusted to match the actual paid amount |
extra |
This invoice was created as a sub-invoice because the original invoice received too much payment or received a payment too late. |
Payments
The payments
field of the invoice object is a list of bitcoin payments made to this invoice. 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 payment was made |
confirmations |
Integer | The number of confirmations on this payment |
expired |
Boolean | Whether or not the invoice has expired when this payment was made |
Inputs
In addition to paying an invoice with bitcoins, we also support paying with different input currencies. See section on Input currencies for more information.
The inputs
field of the invoice object is a list of requests to pay the invoice with different input currencies.
Such requests can be made upon invoice creation, or after creation.
Each request has the following properties:
Name | Type | Description |
---|---|---|
currency |
String | The input currency that the invoice 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-invoices
When we receive a payment to an expired or already paid invoice, or we receive more than enough bitcoins to pay a invoice, we create so-called sub-invoices for the payment amount (or the excess amount for overpayments). These invoices are linked to their original invoices, and you can determine that link through the invoice object:
For sub-invoices, an additional key, original_invoice_id
is added to the invoice object, which
contains the ID of the original payment.
For original invoices with sub-invoices, a key sub_invoice_ids
is added, which contains a
list of IDs of sub-payments linked to the payment.
You can choose to receive callbacks on sub-invoices or not in your Merchant IPN settings.
List all invoices
<?php
/*
* Using the Coinify PHP SDK
*/
$api = new CoinifyAPI( $apikey, $apisecret );
$result = $api->invoicesList();
// ===============================================================
/*
* Using cURL
*/
$ch = curl_init('https://api.coinify.com/v3/invoices');
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,
"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/invoice/abc/def"
},
"native": {
"amount": 1,
"currency": "EUR"
},
"transfer": {
"amount": 1,
"currency": "EUR"
},
"description": "Sample invoice",
"custom": {
"sample_data": "value"
},
"payment_url": "https://merchant.coinify.com/invoice/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 invoice
"original_invoice_id": 12345, // optional
"sub_invoice_ids": [54321, 98765] // optional
}
]
}
This endpoint retrieves all your invoices, sorted by newest first.
HTTP Request
GET https://api.coinify.com/v3/invoices
Query parameters
Name | Type | Default | Description |
---|---|---|---|
limit |
Integer | 100 | Maximum number of invoices to retrieve. Maximum is 200. |
offset |
Integer | 0 | How many invoices to skip. |
include_expired |
Boolean | false | If set to true, expired invoices are included in the result. Default is not to include expired invoices. |
Get a specific invoice
<?php
$invoice_id = 12345;
/*
* Using the Coinify PHP SDK
*/
$api = new CoinifyAPI( $apikey, $apisecret );
$result = $api->invoiceGet($invoice_id);
// ===============================================================
/*
* Using cURL
*/
$url = 'https://api.coinify.com/v3/invoices/' . $invoice_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);
?>
invoice_id = 12345
"""
Using the Coinify Python SDK
"""
from coinify_api import CoinifyAPI
api = CoinifyAPI( apikey, apisecret )
response = api.invoice_get( invoice_id )
# ================================================================
"""
Using the requests module
"""
import requests
headers = {
'Authorization': auth_header,
'Content-Type': 'application/json'
}
url = 'https://api.coinify.com/v3/invoices/%d' % ( invoice_id, )
response = requests.request( 'GET', url, headers=headers ).json()
The above API call returns an invoice JSON object structured like this:
{
"success": true,
"data": {
"id": 12345,
"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/invoice/abc/def"
},
"native": {
"amount": 1,
"currency": "EUR"
},
"transfer": {
"amount": 1,
"currency": "EUR"
},
"description": "Sample invoice",
"custom": {
"sample_data": "value"
},
"payment_url": "https://merchant.coinify.com/invoice/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 invoice.
HTTP Request
GET https://api.coinify.com/v3/invoices/<ID>
URL parameters
Name | Type | Description |
---|---|---|
ID |
Integer | The ID of the invoice to retrieve |
Create an invoice
<?php
$amount = 32.00;
$currency = 'USD';
$plugin_name = 'My PHP shop';
$plugin_version = '1.2';
$description = 'Sample invoice';
$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/invoices';
$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 invoice'
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/invoices'
response = requests.request( 'POST', url, headers=headers, json=params ).json()
The above API call returns an invoice object like this:
{
"success": true,
"data": {
"id": 12345,
"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/invoice/abc/def"
},
"native": {
"amount": 1,
"currency": "EUR"
},
"transfer": {
"amount": 1,
"currency": "EUR"
},
"description": "Sample invoice",
"custom": {
"sample_data": "value"
},
"payment_url": "https://merchant.coinify.com/invoice/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 invoice.
If the creation is successful, you will receive a response object identical to the response from Get a specific invoice.
HTTP Request
POST https://api.coinify.com/v3/invoices
Required JSON parameters
Name | Type | Description |
---|---|---|
amount |
Float | Fiat price of the invoice |
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 |
---|---|---|---|
description |
String | empty string | Your custom text for this invoice. |
custom |
Object | empty object | Your custom data for this invoice. This can be any JSON primitive - even nested arrays and objects! |
callback_url |
String | IPN callback* | A URL that Coinify calls when the invoice state changes. |
callback_email |
String | IPN callback* | An email address to send a mail to when the invoice state changes |
return_url |
String | Redirect URLs | We redirect your customer to this URL to when the invoice has been paid |
cancel_url |
String | Redirect URLs | We redirect your customer to this URL if they fail to pay the invoice in time |
input_currency |
String | "BTC" |
Input currency that the invoice 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 an invoice
<?php
$invoice_id = 12345;
$new_description = 'Sample invoice 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($invoice_id,
$new_description, $new_custom );
// ===============================================================
/*
* Using cURL
*/
$params = array(
'description' => $new_description,
'custom' => $new_custom
);
$url = "https://api.coinify.com/v3/invoices/" . $invoice_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);
?>
invoice_id = 12345
new_description = 'Sample invoice 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( invoice_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/invoices/%d' % ( invoice_id, )
response = requests.request( 'PUT', url, headers=headers, json=params ).json()
The above API call returns an invoice object like this:
{
"success": true,
"data": {
"id": 12345,
"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/invoice/abc/def"
},
"native": {
"amount": 1,
"currency": "EUR"
},
"transfer": {
"amount": 1,
"currency": "EUR"
},
"description": "Sample invoice with changed description",
"custom": {
"my_order_id": 1337,
"sample_data": "value"
},
"payment_url": "https://merchant.coinify.com/invoice/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 an invoice has been created, you have the option to update some of the fields in that invoice.
HTTP Request
PUT https://api.coinify.com/v3/invoices/<ID>
URL parameters
Name | Type | Description |
---|---|---|
ID |
Integer | The ID of the invoice 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 invoice. |
custom |
Object | Your custom data for this invoice. This can be any JSON primitive - even nested arrays and objects! |
Pay with another input currency
<?php
$invoice_id = 12345;
$input_currency = 'DOGE';
$input_return_address = 'D95Kj5JJiWXH4kjTqHXovF5taxcLWoPNGG';
/*
* Using the Coinify PHP SDK
*/
$api = new CoinifyAPI( $apikey, $apisecret );
$result = $api->invoiceRequestInputCurrency($invoice_id,
$input_currency, $input_return_address );
// ===============================================================
/*
* Using cURL
*/
$params = array(
'currency' => $input_currency,
'return_address' => $input_return_address
);
$url = "https://api.coinify.com/v3/invoices/" . $invoice_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);
?>
invoice_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( invoice_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/invoices/%d/inputs' % ( invoice_id, )
response = requests.request( 'POST', url, headers=headers, json=params ).json()
The above API call returns an invoice object like this (Notice the
inputs
sub-object):
{
"success": true,
"data": {
"id": 12345,
"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 invoice with changed description",
"custom": {
"my_order_id": 1337,
"sample_data": "value"
},
"payment_url": "https://merchant.coinify.com/invoice/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 an invoice 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 an invoice.
HTTP Request
POST https://api.coinify.com/v3/invoices/<ID>/inputs
URL parameters
Name | Type | Description |
---|---|---|
ID |
Integer | The ID of the invoice 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 invoice 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). |
Invoice refunds
This section describes how to create a refund for an invoice and list all refunds for an invoice.
A refund basically means to send bitcoins back to the customer for a paid invoice.
Refunds are subject to the following restrictions:
- Invoice to refund must not be older than 14 days
- Requested refund must be in the same currency as you were credited for the invoice
- You must have sufficient balance in your credit account to pay for the refund
- Requested refund must not be larger than the amount that was credited your account for the invoice
You can do multiple and partial refunds (i.e. for an invoice 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 invoice.
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
Invoice refund sample object
{
"id": 44445555,
"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 ID of the refund |
invoice_id |
Integer | The ID of the invoice that this refund refers to |
create_time |
ISO 8601 time | The time when the invoice was created |
state |
String | The refund state. See section on Refund state |
amount |
Float | The 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 invoice 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 invoice
<?php
$invoice_id = 12345;
/*
* Using the Coinify PHP SDK
*/
$api = new CoinifyAPI( $apikey, $apisecret );
$result = $api->invoiceRefundsList($invoice_id);
// ===============================================================
/*
* Using cURL
*/
$url = "https://api.coinify.com/v3/invoices/" . $invoice_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);
?>
invoice_id = 12345
"""
Using the Coinify Python SDK
"""
from coinify_api import CoinifyAPI
api = CoinifyAPI( apikey, apisecret )
response = api.invoice_refunds_list(invoice_id)
# ================================================================
"""
Using the requests module
"""
import requests
headers = {
'Authorization': auth_header,
'Content-Type': 'application/json'
}
url = 'https://api.coinify.com/v3/invoices/%d/refunds' % ( invoice_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,
"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 invoice
HTTP Request
GET https://api.coinify.com/v3/invoices/<ID>/refunds
URL parameters
Name | Type | Description |
---|---|---|
ID |
Integer | The ID of the invoice to list refunds for |
Create refund
<?php
$invoice_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($invoice_id,
$refund_amount, $refund_currency, $email_address );
// ===============================================================
/*
* Using cURL
*/
$url = "https://api.coinify.com/v3/invoices/" . $invoice_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);
?>
invoice_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( invoice_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/invoices/%d/refunds' % ( invoice_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,
"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 an invoice to a customer.
HTTP Request
POST https://api.coinify.com/v3/invoices/<ID>/refunds
URL parameters
Name | Type | Description |
---|---|---|
ID |
Integer | The ID of the invoice 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 invoice 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.
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,
"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 | The ID 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:
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,
"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,
"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,
"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,
"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 invoice creation, or after an invoice has been created.
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 invoice or as currency when requesting to pay an existing invoice 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. |
POS
This section lists endpoints intended for use in Point-of-Sales terminals.
Generate API key
<?php
$email = 'example@coinify.com';
$password = 'hunter2';
$mfa_token = '123456';
$params = array(
'email' => $email,
'password' => $password,
'mfa_token' => $mfa_token // Required if 2FA enabled
);
$url = 'https://api.coinify.com/v3/pos-generate-api-key';
$ch = curl_init($url);
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);
?>
email = 'example@coinify.com'
password = 'hunter2'
mfa_token = '123456'
import requests
headers = {
'Content-Type': 'application/json'
}
params = {
'email': email,
'password': password,
'mfa_token': mfa_token # Required if 2FA enabled
}
url = 'https://api.coinify.com/v3/pos-generate-api-key'
response = requests.request( 'POST', url, headers=headers, json=params ).json()
The above API call returns an object like this:
{
"success": true,
"data": {
"api_key": "GQBbql5X3YKptE+p2GOAZC45xYgUUg1VNfQYLSih19PoajmjNnvIo7QYupPGcnCW",
"api_secret": "4mXuNVwpomlFrrxMicJ+AAJv419gVM8ELjdr+FHeI48jnWy2rzuXEENvT3k/ZUyf"
}
}
Manually entering long and complex API keys and secrets on a terminal is time-consuming and error-prone. In certain situations it can be more user-friendly to enter email/password credentials, which can then be used to generate an API key.
This endpoint does just that. If the email/password combination is correct, an API key and secret will be generated and returned. If the user account has 2-factor authentication enabled, a 2FA token is also required.
The API key will have permissions to
Read invoices and
Create new invoices.
It is not possible to get any other permissions with this endpoint.
HTTP Request
POST https://api.coinify.com/v3/pos-generate-api-key
Required JSON parameters
Name | Type | Description |
---|---|---|
email |
String | Email address |
password |
String | Password |
Optional JSON parameters
Name | Type | Description |
---|---|---|
mfa_token |
String | 2FA token if user has 2-factor authentication enabled |
Response object parameters
The response object contains an API key and API secret:
Name | Type | Description |
---|---|---|
api_key |
String | Key |
api_secret |
String | Secret |
Callbacks
Whenever something changes – such as the state of an invoice, for example when a customer has paid an invoice – you usually want to know about it as soon as possible.
To avoid you having to constantly poll our API for changes to your invoice, 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 an invoice object has changed |
Invoice object |
invoice_manual_resend |
Manual resend of invoice callback from dashboard | Invoice 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
.