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:~~
- ~~Coinify PHP SDK~~
- ~~Coinify Python SDK~~
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 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:
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
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 |
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:
- Payment to refund must not be older than 14 days
- Requested refund must be in the same currency as you were credited for the payment
- 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 payment
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:
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
.