Introduction
Welcome to HAYVN Pay API Documentation.
Endpoints:
- Console URL: https://console.hayvnpay.com.
- API URL: https://api.hayvnpay.com.
SDK or API?
HAYVN Pay can be integrated into your website in either of two ways:
SDK
This is browser / Javscript based.
It's ideal for a front end focused developer to easily use HAYVN Pay.REST API
This is for server side integration with HAYVN Pay.
General Usage
Terminology
Term | Meaning |
---|---|
Payment | The core entity of HAYVN Pay. A request for crypto from a merchant to a customer, which ultimately is converted to fiat. |
Account Merchant | Has customers who make deposits into their account e.g. an FX trader |
Purchase Merchant | Has customers who buy goods and services e.g. an online store, or bricks and mortar store with Point of Sale terminal |
Tolerance | Boundary for when crypto received is deemed to match required amount. Only used by purchase merchants. Expressed as a percentage of payment value. e.g. I'll accept 0.25% below value as good enough. & anything 5% above is an overpayment. |
Profiles | Parts of a merchant's settings. Controls how markups are applied and optionally specifies tolerances. |
A typical payment lifecycle
Let's look at a simple crypto payment with HAYVN Pay.
This example uses the API, but the general flow applies equally to the SDK.
Suppose you are a merchant "Acme Corporation" with an online store, accepting payment in crypto.
- Your customer decides to buy an item for $100
- Your website gets the available crypto currencies + amounts to meet $100, shows to customer
- Customer chooses a currency and is shown a QR code to send crypto to
- Customer sends crypto from his wallet to that address
- HAYVN Pay notifies your website of the payment's progress
- Once complete, HAYVN Pay converts the crypto to fiat in your account & payment is
Complete
- You can now take that $100 as a payout.
Crypto payment issues
Paying with crypto has considerations not found in traditional payment schemes.
Market price volatility
The market price can change in between quoting a crypto amount and the customer transferring the crypto.
As a merchant you can deal with this in different ways. This guide will talk through your options.Crypto must be transferred separately by the customer Paying with crypto is unlike paying with a credit card; rather, its similar to accepting payment using Direct Deposit. In both cases once agreement is reached between the merchant and customer on a price, the customer must transfer the money to an address using a separate mechanism (e.g. their online banking website for Direct Deposit, or crypto wallet for HAYVN Pay). Only once the deposit is confirmed is the payment complete.
Crypto can take some time to be confirmed on the blockchain
This is also similar to a Direct Deposit. It can take minutes, depending on the currency and blockchain network.
This guide will talk through how you as a merchant can manage these considerations.
Market price movements
How you deal with price movements will depend on your type of business.
Market price movements for an account merchant
If you're an account merchant, accepting crypto to make deposits into a fiat account, you'll typically accept fiat at the current market price, regardless of whether this means an under or overpayment of the stated deposit amount.
To illustrate, suppose your customer decided to deposit $100 when bitcoin was at $1000/BTC.
He is told to transfer 0.1 BTC.
However by the time the transfer has occurred, the price has dropped to $978/BTC.
The payment will still be deemed Complete
, even though only $97.80 has been credited to the account.
The customer will be informed of the final fiat value.
Market price movements for a purchase merchant
Price movements are a bigger problem if you're a purchase merchant.
An item being purchased has a given fiat value, regardless of any crypto pricing.
You rely on the customer sending enough crypto to cover that fiat value, for the payment to be considered Complete
.
However, the customer should be insulated against minor price movements.
Minor price movements
To mitigate against minor changes, you may nominate tolerances on a HAYVN Pay profile.
Tolerances define a range of crypto that you will accept. If the market moves only within this range and the customer transfers the correct amount, the payment will be considered Complete
.
For example, -1% / +5% means "Accept crypto 1% less than the payment value but more than 5% above the payment value is an overpayment".
You receive only $99.50, but it’s within tolerance so is close enough. The payment is Complete
.
Adverse price drop
What if the market has dropped beyond the lower tolerance?
You cannot accept a fiat value well below the item price - instead, the customer is obliged to transfer further crypto.
After 0.1 BTC is initially sent, the payment is Incomplete
.
If a further 0.002041 BTC is sent and the price doesn't change adversely, the payment will become Complete
.
Your account is credited with fiat using the current market price.
Large price rise
What if the market price has risen sharply?
If the value now exceeds the upper tolerance, HAYVN Pay will alert your website that the payment is now Overpaid
.
How you deal with this is a commercial decision. The crypto is effectively held in escrow, waiting for your direction.
You may either:
- Refund the excess crypto back to the customer
- Refund all crypto back to the customer
- Manually convert all crypto to fiat, keeping the windfall
or - A mix of refunding crypto + converting to fiat
See the merchant console user guide for how to refund + convert to fiat manually.
Incorrect crypto transfers
Unlike conventional payment means (EFTPOS, credit card payments), we are reliant on the customer making the crypto transfer separately to the merchant's website.
This introduces some unique problems.
HAYVN Pay will send callbacks to your merchant website with as much information as possible to inform the customer of any problems.
Sometimes you will be able to use the merchant console to resolve a problem. Other times the payment support team must be contacted. See Contact link on the merchant console.
Incomplete crypto
We cannot control how much crypto a customer sends. If an insufficient amount is sent to cover a purchase price (whether deliberately or accidentally), HAYVN Pay will re-calculate how much is outstanding. The customer is then informed of the remaining amount.
Once enough has been sent, the payment is Complete
.
Wrong currency
A customer may choose one crypto currency, but accidentally send another.
Most of the time, HAYVN Pay is unable to detect these incorrect currencies. If not, the payment will simply never become Complete
. The customer will not be informed of his payment progressing as HAYVN Pay cannot “see” the wrong currency. You may be able to resolve this dilemma with our support team’s help.
If HAYVN Pay is able to detect the incorrect currency transaction, it will notify of the mismatch. You may refund the incorrect currency. The customer is then free to transfer the correct crypto.
Reused destination address
Nothing prevents a customer from accidentally (or intentionally) sending crypto to an address that has already been used for a past payment.
You can configure how HAYVN Pay handles address reuse in your merchant profile.
If you are an account merchant, turning Reuse Address
on is advised:
If more payments are made to the address of already Complete
payment, a new payment entry is created in the merchant console for each and the
fiat deposited into your account. No errors are raised.
However if you are a purchase merchant you would normally have Reuse Address
left off:
Once an earlier purchase payment is Complete
, sending more crypto to the same address will mark the earlier purchase
as Address Reused
, an error state. It will then be up you as merchant to deal with the matter.
You could refund the new crypto to the customer.
Alternatively if the customer has made a second purchase, the second payment could manually be marked Complete
and the new crypto converted to fiat.
Timeouts
Like all internet based services, HAYVN Pay is at the mercy of network outages. If HAYVN Pay cannot process a payment due to an outage, it will inform your website with a callback.
If the customer has already sent crypto, the support team should be consulted to resolve the matter.
Available currencies
- Bitcoin
- Ethereum
Tether
USD
AED
AUD
SDK
Follow these steps to offer crypto payments using HAYVN Pay SDK:
- Include HAYVN Pay SDK javascript:
<script type="text/javascript"
src="https://static.hayvnpay.com/static/js/sdk.js"></script>
- Add button with
hayvnpay-button
class name and use following data attributes:data-product
Specify product name.data-amount
Specify payment amount (fiat).data-currency
Currently, HAYVN Pay only supports USD, AED and AUD; other fiat currencies are coming soon.data-passthrough
optional
Provide any of your own data that will be returned with callbacks.
Can be JSON string.data-show-payment-url
optional
Show additional public payment URL that can be shared or copied further.
<button class="hayvnpay-button"
data-product="Blue Suede Shoes"
data-amount="100"
data-currency="USD"
data-passthrough="Order 12345"
data-show-payment-url="true">
Click to buy
</button>
Initialize SDK using your Account ID and Profile ID parameters and callbacks (if needed).
The Account ID and Profile ID can be found in the HAYVN Pay Console.
The callbacks are fired as the payment proceeds through its lifecycle.
HayvnPaySDK.setup({
account: '<YOUR_ACCOUNT_ID>',
profile: '<YOUR_PROFILE_ID>',
apiEndpoint: 'https://console.hayvnpay.com/',
// Callbacks
// onOpen: onNewPayment,
// onUpdate: onPaymentUpdate,
// onSuccess: onPaymentSuccess,
// onIncomplete: onPaymentIncomplete,
// onCancel: onPaymentCancel
})
// Callback example:
// function onPaymentOpen(data, code) {
// console.log(code, data)
// }
Important Note! Never fully rely on JavaScript / client-side data provided in onSuccess
, onUpdate
and onIncomplete
events as it can easily be manipulated. When it comes to transactions data processing you should fully trust only server to server callbacks.
- Handle callbacks from HAYVN Pay. Following event callbacks are available:
onOpen
, onUpdate
, onIncomplete
, onSuccess
, onCancel
.
- When finished, close and destroy modal window
HayvnPay.destroy()
Live SDK example
Try clicking this button:
API Authentication
To sign requests, you can use following code:
import time
import base64
import hashlib
import hmac
import json
import requests
API_URL = 'https://api.hayvnpay.com'
API_KEY = 'my_api_key'
API_SECRET = 'my_api_secret'
def encode_hmac(key, msg, digestmod=hashlib.sha256):
return hmac.new(key.encode(), msg=msg, digestmod=digestmod).hexdigest()
def hayvn_api_request(endpoint: str, payload: dict = None, method: str = 'GET'):
nonce = str(int(time.time() * 1000))
request_path = '/v1/%s/' % endpoint
if payload:
payload = json.dumps(payload)
# Create signature data object. Keep order of keys as specified:
signature_data = {'path': request_path,
'nonce': nonce,
'payload': payload or ''}
# Convert signature data to json + base64 format and create signature using your API_SECRET
signature_data = json.dumps(signature_data, separators=(',', ':')).encode()
b64 = base64.b64encode(signature_data)
signature = encode_hmac(API_SECRET, b64)
# Add your API key, nonce and signature to following headers
request_headers = {
'X-HAYVNPAY-KEY': API_KEY,
'X-HAYVNPAY-NONCE': nonce,
'X-HAYVNPAY-SIGNATURE': signature,
}
# Make request using payload JSON string as request body
response = requests.request(method, API_URL + request_path,
data=payload, headers=request_headers)
return response.json()
profiles = hayvn_api_request('profiles')
print(json.dumps(profiles, indent=2))
const axios = require('axios');
const Base64 = require('js-base64').Base64;
const crypto = require('crypto');
const API_URL = 'https://api.hayvnpay.com';
const API_KEY = 'my_api_key';
const API_SECRET = 'my_api_secret';
function encode_hmac(key, msg) {
return crypto.createHmac('sha256', key).update(msg).digest('hex');
}
function hayvn_api_request(endpoint, payload = null, method = 'GET') {
const request_path = '/v1/' + endpoint + '/'
const nonce = (new Date).getTime().toString()
payload = typeof (payload) === 'object' && Object.keys(payload).length ?
JSON.stringify(payload) : ''
// Create signature data object. Keep order of keys as specified:
var signature_data = {
path: request_path,
nonce: nonce,
payload: payload,
}
// Convert signature data to json + base64 format and create signature using your API_SECRET
signature_data = JSON.stringify(signature_data)
const b64 = Base64.encode(signature_data)
const signature = encode_hmac(API_SECRET, b64)
// Add your API key, nonce and signature to following headers
let request_headers = {
'X-HAYVNPAY-KEY': API_KEY,
'X-HAYVNPAY-NONCE': nonce,
'X-HAYVNPAY-SIGNATURE': signature,
}
return axios({
method: method,
url: API_URL + request_path,
data: payload,
headers: request_headers,
})
}
hayvn_api_request('profiles').then(function (response) {
console.log(response)
}).catch(function (error) {
console.log(error)
});
<?php
function hayvnpay_api_request($endpoint, $payload = [], $method = 'GET'){
$API_URL = 'https://api.hayvnpay.com';
$API_KEY = 'your_api_key';
$API_SECRET = 'your_secret';
$request_path = '/v1/' . $endpoint . '/';
$nonce = (string)round(microtime(true) * 1000);
$payload = $payload ? json_encode($payload) : '';
// Create signature data object. Keep order of keys as specified:
$signature_data = array(
'path' => $request_path,
'nonce' => $nonce,
'payload' => $payload,
);
// Convert signature data to json + base64 format and create signature using your API_SECRET
$signature_data = json_encode($signature_data, JSON_UNESCAPED_SLASHES);
$b64 = base64_encode($signature_data);
$signature = hash_hmac('sha256', $b64, $API_SECRET);
// Add your API key, nonce and signature to following headers
$request_headers = [
'X-HAYVNPAY-KEY: ' . $API_KEY,
'X-HAYVNPAY-NONCE: ' . $nonce,
'X-HAYVNPAY-SIGNATURE: ' . $signature,
];
$result = file_get_contents($API_URL . $request_path, null, stream_context_create(array(
'http' => array(
'method' => $method,
'header' => implode("\r\n", $request_headers),
'ignore_errors' => true,
'content' => $payload)
)
));
return $result;
}
$response = hayvnpay_api_request('profiles');
var_dump($response);
You can obtain API Keys by logging in and creating a key in Settings > API Keys. This will give you both an "API Key" that will serve as your user name, and an "API Secret" that you will use to sign messages.
All requests must contain a nonce, a number that will never be repeated and must increase between requests. This is to prevent an attacker who has captured a previous request from simply replaying that request. We recommend using a timestamp at millisecond or higher precision.
PAYLOAD
The payload for the POST requests must be a JSON string and must be put in the request body. You'll find more detailed Signature generation code in the examples. The following three headers are required to make requests to HAYVN API.
Header | Value |
---|---|
X-HAYVNPAY-KEY | Your HAYVN API Key |
X-HAYVNPAY-NONCE | Nonce |
X-HAYVNPAY-SIGNATURE | hex(HMAC_SHA256(base64(signature_data), key=api_secret)) |
Payments
Payments are time-sensitive payment requests addressed to specific buyers or payers. Payment has a unique receiving address and fixed price, typically denominated in fiat currency. It also has a BTC equivalent price, calculated by HAYVN Pay, with an expiration time of about 15 minutes.
List Payments
payments = hayvn_api_request('payments')
hayvn_api_request('payments').then(function(response) {
console.log(response);
}).catch(function(error) {
console.log(error);
});
$response = hayvnpay_api_request('payments');
var_dump($response);
The above command returns JSON structured like this:
{
"pagination": {
"num_pages": 1,
"count": 12,
"page": 1,
"next_page": null,
"previous_page": null,
"per_page": 25
},
"result": [
{
"id": "e4f78557-7fb4-42da-89b2-6874d235c70d",
"created_at": "2022-01-17T22:15:05.859322+00:00",
"confirmed_at": "2022-01-18T14:50:05+00:00",
"completed_at": null,
"profile_id": "deb23315-1eae-46fe-929f-6f3067292493",
"payment_currency": "BTC",
"payment_amount": "0.00094700",
"requested_currency": "USD",
"requested_amount": "9.47000000",
"address": "tb1qcq9ne8jjgnss4xyt2cdn37g674ngmfy07yum2g",
"addresses": {
"BTC": "tb1qcq9ne8jjgnss4xyt2cdn37g674ngmfy07yum2g"
},
"status": "confirmed",
"paid_amount": {
"crypto": {
"currency": "BTC",
"amount": "0.00094700"
},
"fiat": {
"currency": "USD",
"amount": "9.47000000"
}
},
"conversion_fee": "0.04000000",
"notes": null,
"passthrough": "{\"order_id\":1642457702}",
"transactions": [
{
"id": "2ceeeec5-acbf-4fed-98f3-99c364532322",
"txid": "c5020b9615eaff5586f595655a22e8d61cf64161172811406d9c3801bd1e7b90",
"amount": {
"crypto": {
"currency": "BTC",
"amount": "0.00094700"
},
"fiat": {
"currency": "USD",
"amount": "9.47000000"
}
},
"currency": "BTC",
"created_at": "2022-01-17T22:16:03.399328+00:00",
"confirmed_at": null,
"url": "https://blockstream.info/testnet/tx/c5020b9615eaff5586f595655a22e8d61cf64161172811406d9c3801bd1e7b90"
}
]
}
]
}
This endpoint retrieves all payments. Endpoint uses pagination and returns 25
payments per page. Payments are sorted
by creation time in descending order.
HTTP Request
GET https://api.hayvnpay.com/v1/payments/
Query Parameters
Parameter | Default | Description |
---|---|---|
p |
None | Page number. |
txid |
None | Filter payments by txid |
address |
None | Filter payments by receiving address |
status |
None | Filter by status. Available values specified in Payment Statuses. |
Get Payment
payment = hayvn_api_request('payments/0baa1b12-1d05-4ca1-b0fd-4c391e9d3b9f')
hayvn_api_request('payments/0baa1b12-1d05-4ca1-b0fd-4c391e9d3b9f').then(function(response) {
console.log(response);
}).catch(function(error) {
console.log(error);
});
$response = hayvnpay_api_request('payments/0baa1b12-1d05-4ca1-b0fd-4c391e9d3b9f');
var_dump($response);
The above command returns JSON structured like this:
{
"result": {
"id": "e4f78557-7fb4-42da-89b2-6874d235c70d",
"created_at": "2022-01-17T22:15:05.859322+00:00",
"confirmed_at": "2022-01-18T14:50:05+00:00",
"completed_at": null,
"profile_id": "deb23315-1eae-46fe-929f-6f3067292493",
"payment_currency": "BTC",
"payment_amount": "0.00094700",
"requested_currency": "USD",
"requested_amount": "9.47000000",
"address": "tb1qcq9ne8jjgnss4xyt2cdn37g674ngmfy07yum2g",
"addresses": {
"BTC": "tb1qcq9ne8jjgnss4xyt2cdn37g674ngmfy07yum2g"
},
"status": "confirmed",
"paid_amount": {
"crypto": {
"currency": "BTC",
"amount": "0.00094700"
},
"fiat": {
"currency": "USD",
"amount": "9.47000000"
}
},
"conversion_fee": "0.04000000",
"notes": null,
"passthrough": "{\"order_id\":1642457702}",
"transactions": [
{
"id": "2ceeeec5-acbf-4fed-98f3-99c364532322",
"txid": "c5020b9615eaff5586f595655a22e8d61cf64161172811406d9c3801bd1e7b90",
"amount": {
"crypto": {
"currency": "BTC",
"amount": "0.00094700"
},
"fiat": {
"currency": "USD",
"amount": "9.47000000"
}
},
"currency": "BTC",
"created_at": "2022-01-17T22:16:03.399328+00:00",
"confirmed_at": null,
"url": "https://blockstream.info/testnet/tx/c5020b9615eaff5586f595655a22e8d61cf64161172811406d9c3801bd1e7b90"
}
]
}
}
This endpoint retrieves a specific payment.
HTTP Request
GET https://api.hayvnpay.com/v1/payments/<ID>/
URL Parameters
Parameter | Description |
---|---|
ID | The ID of the payment to retrieve. |
Create Payment
import json
payload = {
"requested_currency": "USD",
"requested_amount": "10",
"payment_currency": "BTC",
"profile_uuid": "deb23315-1eae-46fe-929f-6f3067292493",
"passthrough": json.dumps({"order_id": 1642457702}),
"notes": "this is demo"
}
payment = hayvn_api_request('payments', payload, 'POST')
print(json.dumps(payments, indent=2))
var payload = {
"requested_currency": "USD",
"requested_amount": "10",
"payment_currency": "BTC",
"profile_uuid": "deb23315-1eae-46fe-929f-6f3067292493",
"passthrough": JSON.stringify({"order_id": 1642457702}),
"notes": "this is demo"
}
hayvn_api_request('payments', payload, 'POST').then(function(response) {
console.log(response);
}).catch(function(error) {
console.log(error);
});
$payload = array(
'requested_currency' => 'USD',
'requested_amount' => '10',
'payment_currency' => 'BTC',
'profile_uuid' => 'deb23315-1eae-46fe-929f-6f3067292493',
'passthrough' => json_encode(array('order_id' => 1642457702)),
'notes' => 'this is demo',
);
$response = hayvnpay_api_request('payments/0baa1b12-1d05-4ca1-b0fd-4c391e9d3b9f');
var_dump($response);
JSON response for Create Payment endpoint:
{
"result": {
"id": "e4f78557-7fb4-42da-89b2-6874d235c70d",
"created_at": "2022-01-17T22:15:05.859322+00:00",
"confirmed_at": "2022-01-18T14:50:05+00:00",
"completed_at": null,
"profile_id": "deb23315-1eae-46fe-929f-6f3067292493",
"payment_currency": "BTC",
"payment_amount": "0.00094700",
"requested_currency": "USD",
"requested_amount": "9.47000000",
"address": "tb1qcq9ne8jjgnss4xyt2cdn37g674ngmfy07yum2g",
"addresses": {
"BTC": "tb1qcq9ne8jjgnss4xyt2cdn37g674ngmfy07yum2g"
},
"status": "confirmed",
"paid_amount": {
"crypto": {
"currency": "BTC",
"amount": "0"
},
"fiat": {
"currency": "USD",
"amount": "0"
}
},
"conversion_fee": "0",
"notes": null,
"passthrough": "{\"order_id\":1642457702}",
"transactions": []
}
}
This endpoint creates an payment. Response is identical to Get Payment endpoint response.
HTTP Request
POST https://api.hayvnpay.com/v1/payments/
Payload Parameters
Parameter | Description | Required |
---|---|---|
profile_uuid |
Profile ID to use for settings, callback and wallet address generation. | Yes |
requested_currency |
Currency for the specified payment amount. Available values: USD, AED, AUD | Yes |
requested_amount |
Quoted decimal payment amount. | Yes |
payment_currency |
Currency for the specified payment amount. Available values: BTC, ETH, USDT. | Yes |
passthrough |
String. Meta-data you wish to store with the payment. Will be sent alongside all callbacks associated with the payment. | No |
notes |
Can be product or service name or any other notes. Visible in dashboard and in public payment link. | No |
Payment Statuses
Status | Description |
---|---|
new |
A new payment has been created and a deposit address has been generated for the client to send their Crypto. |
pending |
Transactions are found and are awaiting confirmations. |
converting |
The Crypto amount received is within the accepted threshold and the conversion of the Crypto to FIAT has been initiated. |
canceled_ |
The payment has been manually set to canceled by the user. |
completed |
Payment conversion has finished and payment is now complete. |
complete_ |
The payment has been manually set to complete by the user. |
incomplete |
A Crypto deposit was made by the client, but the received amount is below the accepted threshold. |
overpay |
A Crypto deposit was made by the client, but the received amount is above the accepted threshold. |
address_reuse |
A Crypto deposit has been made to a wallet address that was used on a previously completed payment. It will require manual handling. This will only occur on profiles that do not allow address re-use. |
conversion_failed |
Conversion from crypto to fiat has failed. Requires manual handling. |
Payment Callbacks
Callbacks provide same exact response format as in Get Payment
API endpoint in result
field plus three extra
fields specified in Callbacks Documentation.
You can view history of callbacks (if any) in HAYVN Pay in Payment detail view.
Payment Callback Statuses
Status | Description |
---|---|
payment_pending |
Payment matches requested amount, has zero confirmations on blockchain (BTC only). |
payment_converting |
Payment is received and it matches requested amount, conversion process from crypto into fiat has started. |
payment_complete |
Conversion has finished and payment is now complete. |
payment_incomplete |
Payment amount doesn't match profile "Allowed Difference" range. Requires manual handling. |
payment_address_reuse |
Already previously complete payment address receives a new transaction and "Address Reuse" parameter for related profile is not enabled. Requires manual handling. |
payment_conversion_failed |
Conversion from crypto to fiat has failed. Requires manual handling. |
Payouts
Payouts are Fiat currency withdrawals or payments to External Bank Account.
List Payouts
payouts = hayvn_api_request('payouts')
hayvn_api_request('payouts').then(function (response) {
console.log(response);
}).catch(function (error) {
console.log(error);
});
This endpoint retrieves all payouts. Endpoint uses pagination and returns 25
payouts per page. Payouts are sorted by
creation time in descending order.
HTTP Request
GET https://api.hayvn.com/v1/payouts/
Query Parameters
Parameter | Default | Description |
---|---|---|
p | None | Page number. |
Get Payout
payout = hayvn_api_request('payouts/42dbee1d-8659-44c3-aab2-6e414c5825a5')
hayvn_api_request('payouts/42dbee1d-8659-44c3-aab2-6e414c5825a5').then(function (response) {
console.log(response);
}).catch(function (error) {
console.log(error);
});
This endpoint retrieves a specific payout.
HTTP Request
GET https://api.hayvn.com/v1/payouts/<ID>/
URL Parameters
Parameter | Description |
---|---|
ID | The ID of the payout to retrieve. |
Create Payout
import json
payload = {
"amount": "35.00000000",
"currency": "USD",
"notes": "Payout notes",
}
payout = hayvn_api_request('payouts', payload, 'POST')
print(json.dumps(payout, indent=2))
var payload = {
"amount": "35.00000000",
"currency": "USD",
"notes": "Payout notes",
}
hayvn_api_request('payouts', payload, 'POST').then(function (response) {
console.log(response);
}).catch(function (error) {
console.log(error);
});
JSON response for Create Payout endpoint:
{
"result": [
{
"id": "205eac49-963d-46b0-bac0-b41af5615c65",
"remote_uuid": "8afd0ade-fbcd-49ed-be2e-0c4011bf12d8",
"reference": "CHZ68OY0R3",
"created_at": "2022-01-07T14:04:44+00:00",
"from_wallet_uuid": "7c2c7e53-307d-40e1-90b9-275c583934b9",
"to_wallet_uuid": "b00f8b70-36ac-4f84-9d79-62e88e939767",
"amount": "35.00000000",
"currency": "USD",
"status": "pending",
"notes": null
}
]
}
This endpoint creates a payout. Response is identical to Get Payout endpoint response.
HTTP Request
POST https://api.hayvn.com/v1/payouts/
Payload Parameters
Parameter | Description | Required |
---|---|---|
currency | Currency for the specified payout amount. Available values: USD, AED, AUD | Yes |
amount | Quoted decimal payout amount. | Yes |
notes | Optional notes on Payout | No |
Payout Statuses
Status | Description |
---|---|
pending | Payout is created and not settled. |
completed | Payout is settled. |
Withdrawals
Withdrawals are Fiat currency withdrawals to External Digital Wallet.
List Withdrawals
withdrawals = hayvn_api_request('withdrawals')
hayvn_api_request('withdrawals').then(function (response) {
console.log(response);
}).catch(function (error) {
console.log(error);
});
This endpoint retrieves all withdrawals. Endpoint uses pagination and returns 25
withdrawals per page. Withdrawals are sorted by
creation time in descending order.
HTTP Request
GET https://api.hayvn.com/v1/withdrawals/
Query Parameters
Parameter | Default | Description |
---|---|---|
p | None | Page number. |
Get Withdrawal
withdrawal = hayvn_api_request('withdrawal/42dbee1d-8659-44c3-aab2-6e414c5825a5')
hayvn_api_request('withdrawal/42dbee1d-8659-44c3-aab2-6e414c5825a5').then(function (response) {
console.log(response);
}).catch(function (error) {
console.log(error);
});
This endpoint retrieves a specific withdrawal.
HTTP Request
GET https://api.hayvn.com/v1/withdrawal/<ID>/
URL Parameters
Parameter | Description |
---|---|
ID | The ID of the withdrawal to retrieve. |
Create Withdrawal
import json
payload = {
"fiat_currency": "USD",
"fiat_amount": "500",
"address": "2NCmwGXjgs822C1jXHJrUNda3DJu45YJ2jr",
"currency": "BTC",
"network": "BTC",
"notes": "some notes",
}
withdrawal = hayvn_api_request('withdrawal', payload, 'POST')
print(json.dumps(withdrawal, indent=2))
var payload = {
"fiat_currency": "USD",
"fiat_amount": "500",
"address": "2NCmwGXjgs822C1jXHJrUNda3DJu45YJ2jr",
"currency": "BTC",
"network": "BTC",
"notes": "some notes",
}
hayvn_api_request('withdrawal', payload, 'POST').then(function (response) {
console.log(response);
}).catch(function (error) {
console.log(error);
});
JSON response for Create Withdrawal endpoint:
{
"result": [
{
"id": "205eac49-963d-46b0-bac0-b41af5615c65",
"remote_uuid": "8afd0ade-fbcd-49ed-be2e-0c4011bf12d8",
"reference": "CHZ68OY0R3",
"created_at": "2022-01-07T14:04:44+00:00",
"profile_id": "deb23315-1eae-46fe-929f-6f3067292493",
"address": "2NCmwGXjgs822C1jXHJrUNda3DJu45YJ2jr",
"txid": null,
"from_wallet_uuid": "7c2c7e53-307d-40e1-90b9-275c583934b9",
"to_wallet_uuid": "b00f8b70-36ac-4f84-9d79-62e88e939767",
"fiat_amount": "35.00000000",
"fiat_currency": "USD",
"currency": "BTC",
"network": "BTC",
"status": "pending",
"notes": "some notes"
}
]
}
This endpoint creates a withdrawal. Response is identical to Get Withdrawal endpoint response.
HTTP Request
POST https://api.hayvn.com/v1/withdrawals/
Payload Parameters
Parameter | Description | Required |
---|---|---|
fiat_currency |
Currency for the specified withdrawal amount. Available values: USD , EUR , GBP |
Yes |
fiat_amount |
Quited decimal withdrawal amount. | Yes |
profile_id |
Profile ID for settings and callbacks. | No |
address |
Address of the recipient. | Yes |
currency |
Recipient address currency. BTC , ETH , USDT . |
Yes |
network |
Recipient address network. BTC , ETH , BSC , TRX |
Yes |
notes |
Optional notes on Withdrawal | No |
Withdrawal Statuses
Status | Description |
---|---|
draft |
Withdrawal is created and not settled. |
converting |
Converting fiat currency into desired cryptocurrency. |
pending |
Waiting for withdrawal to be settled. |
complete |
Withdrawal has been settled. |
requires_confirmation |
Withdrawal made through API requires confirmation in Console app. |
failed |
Withdrawal process failed. |
Withdrawal Callbacks
Callbacks provide same exact response format as in Get Withdrawal
API endpoint in result
field plus three extra
fields specified in Callbacks Documentation.
Withdrawal Callback Statuses
Status | Description | |
---|---|---|
withdrawal_pending |
Waiting for withdrawal to be settled. | |
withdrawal_converting |
Converting fiat currency into desired cryptocurrency. | |
withdrawal_complete |
Withdrawal has been settled. | |
withdrawal_requires_confirmation |
Withdrawal made through API requires confirmation in Console app. | |
withdrawal_failed |
Withdrawal process failed. |
Callbacks
Callbacks are POST
(as JSON
encoded request body) requests made by HAYVN Pay to URL endpoint specified in Profile that was used for related payment creation.
Callback expects HTTP 200
OK success status response code. For any other status code or timeout it will try to reach endpoint again with exponential time increase between retries. If after 72 hours
endpoint will be still unreachable callback sender will stop trying.
You can view history of callbacks in HAYVN App under every instance that have callbacks.
Callbacks Verification
import hashlib
import hmac
import json
# You will find your callback token under Settings
CALLBACK_TOKEN = 'your_callback_token'
# You can reuse same method used in API auth signature generation
def encode_hmac(key, msg, digestmod=hashlib.sha256):
return hmac.new(key.encode(), msg=msg, digestmod=digestmod).hexdigest()
# Decode request json body
payload = json.loads(request.body)
# Get signature and callback_id fields from provided data
signature = payload['signature']
callback_id = payload['callback_id']
# Compare signatures
is_valid = signature == encode_hmac(CALLBACK_TOKEN, callback_id.encode())
assert is_valid, 'Failed to verify HAYVN Callback signature.'
# Debug callback data
print(json.dumps(payload, indent=2))
const Base64 = require('js-base64').Base64;
const crypto = require('crypto');
// You will find your callback token under Settings
const CALLBACK_TOKEN = 'your_callback_token';
// You can reuse same method used in API auth signature generation
function encode_hmac(key, msg) {
return crypto.createHmac('sha256', key).update(msg).digest('hex');
}
// Decode request json body
var payload = JSON.parse(request.body);
// Get signature and callback_id fields from provided data
const signature = payload['signature'];
const callback_id = payload['callback_id'];
// Compare signatures
const is_valid = signature === encode_hmac(CALLBACK_TOKEN, callback_id);
if(!is_valid) {
throw new Error('Failed to verify HAYVN Callback signature.');
}
// Debug callback data
console.log(payload);
To verify callback and make sure it really comes from HAYVN Pay you must use Callback Token which you can find in HAYVN App under Settings > API Keys.
Always verify if signature provided in callback POST data matches the one you generate on your own by signing callback_id
value with callback_token
using following hashing algorithm:
signature = hex(HMAC_SHA256(<callback_id>, key=<callback_token>))
Callbacks Response
All callbacks have these fields in common:
Key | Meaning |
---|---|
callback_id | Unique callback ID. If callback fails to reach endpoint, it will retry with the same ID. |
callback_status | Callback status identifying specific event. |
signature | HAYVN Signature for verification. |
For event specific response documentation see Callback section under specific endpoint.
Errors
Error payload
Example of error response:
{
"result": "error",
"reason": "ObjectNotFound",
"message": "Object by specified ID not found"
}
In the event of an error, a non-200 error code will be returned, and the response body will be a json object with three fields:
result
– which will always be "error".reason
– which will be one of the string constants.message
– a human-readable string with additional error information.
HTTP error codes
Error Code | Meaning |
---|---|
400 | Bad Request – Your request is invalid. |
401 | Unauthorized – Your API key or signature is wrong. |
403 | Forbidden – Not enough permissions. |
404 | Not Found – The specified page could not be found. |
405 | Method Not Allowed – You tried to access endpoint with an invalid method. |
500 | Internal Server Error – We had a problem with our server. |
503 | Service Unavailable – We're temporarily offline for maintenance. |