Introduction
The Busha Pay API provides a simple and powerful REST API to integrate Bitcoin, and Ethereum payments into your business or application. This API reference provides information on available endpoints and how to interact with them.
Authentication
Example authenticated request:
# With shell, you can just pass the correct header with each request
curl https://api.pay.busha.co/charges \
-H "X-BP-Api-Key: <Your API Key>"
Most requests to the Pay API must be authenticated with an API key. You can create an API key in your Settings page after creating a Busha Pay account.
Authenticated API requests should be made with a X-BP-Api-Key header. Your secret API key should be passed as the value.
If authentication fails, a JSON object with an error message will be returned as a response along with HTTP status 401.
Versioning
Example request:
# With shell, you can just pass the correct header with each request
curl https://api.pay.busha.co/charges \
-H "X-BP-Api-Key: <Your API Key>"
-H "X-BP-Version: 2019-06-30"
All API calls should include an X-BP-Version
header containing the API version with which you would like to make your request. API versions are of the form YYYY-MM-DD
, indicating the date on which that version was released; a new version will be released for every breaking change to the API. The latest API version is 22019-06-30
.
If no version is passed, or if an unknown or invalid version is given, the latest API version will be used and a warning will be included in the response. Be sure to include a valid version with every request in order to avoid unexpected breakage. Do not pass the current date as your version header.
Pagination
Example request:
# With shell, you can just pass the correct header with each request
curl https://api.pay.busha.co/charges?page=2&limit=20 \
-H "X-BP-Api-Key: <Your API Key>"
-H "X-BP-Version: 2019-06-30"
Example response:
{
"paginator": {
"order": "desc",
"page": 1,
"per_page": 20,
"offset": 0,
"total_entries_size": 6,
"current_entries_size": 6,
"total_pages": 1
},
"data": [
...
]
}
All GET endpoints which return an object list support cursor based pagination with pagination information inside a paginator object. This means that to get all objects, you need to paginate through the results by always using the page and limit parameter for the next call. Default limit is set to 20 but values up to 100 are permitted.
Arguments
Field | Description |
---|---|
order optional |
Order of the resources in the response. desc (default), asc |
limit optional |
Number of results per call. Accepted values: 0 - 100. Default 20 |
page |
Use this along with the limit to paginate through data consistently. Defaults to 1 |
Errors
Error response
Error response 400:
{
"error": {
"type" : "invalid_request",
"message": "Required parameter missing: name"
}
}
All error messages include a type
identifier and a human readable message
.
validation_error with status code 400 is returned when the validation of the resource fails on POST or PUT requests. Response contains errors field with a list of errors.
Warnings
Example warning
{
"warnings": [
"Missing X-BP-Version header; serving latest API version (2018-03-22)"
]
}
Responses can include a warnings parameter to notify the developer of best practices, implementation suggestions or deprecation warnings. While you don’t need show warnings to the user, they are usually something you need to act on.
Rate limiting
Rate limiting error (429)
{
"error": {
"type": "rate_limit_exceeded",
"message": "Rate limit exceeded"
}
}
The Busha PayAPI is rate limited to prevent abuse that would degrade our ability to maintain consistent API performance for all users. By default, every user is rate limited at 25 requests per minute on the charge creation endpoint and 200 requests per minute for all other endpoints. If your requests are being rate limited, HTTP response code 429
will be returned with an rate_limit_exceeded
error.
Charges
To request a cryptocurrency payment, you create a charge. You can create and view charges. Since cryptocurrency payments are push payments, a charge will expire after a waiting period (payment window) if no payment has been detected. Charges are identified by a unique code.
Charge Resource
Fields
Field | Type | Description |
---|---|---|
id |
string | Charge UUID |
description |
string | This can be anything the charge is for |
code |
string | Charge user-friendly primary key |
created_at |
timestamp | Charge creation time |
expires_at |
timestamp | Charge expiration time |
confirmed_at |
timestamp | Charge confirmation time |
timeline |
timestamp | Array of status update objects |
pricing |
hash | Charge price information object |
payments |
array | Array of charge payment objects |
addresses |
hash | Set of addresses associated with the charge |
Charge Timeline
Every charge
object has a timeline of status updates. Charge timeline is an array of objects of the following format:
Field | Type | Description |
---|---|---|
time |
timestamp | Time of the status update |
status |
string | One of the following statuses: NEW , PENDING , COMPLETED , EXPIRED , UNRESOLVED , RESOLVED , CANCELED |
context |
string, optional | For charges with UNRESOLVED status, additional context is provided. Context can be one of the following: UNDERPAID , OVERPAID , DELAYED , MULTIPLE , MANUAL , OTHER |
Pricing
All charges
have a fixed_price pricing type, therefore there will be a pricing object associated with it. Pricing object is composed of local price which is set by the merchant in their native fiat currency and corresponding prices in every cryptocurrency that the merchant has activated for their account
Field | Type | Description |
---|---|---|
local |
money | Price set by the merchant in local fiat currency |
bitcoin |
money | Price in BTC |
ethereum |
money | Price in ETH |
Addresses
For every active cryptocurrency for a charge addresses
object will contain an address that the buyer will be expected to pay to
Field | Type | Description |
---|---|---|
bitcoin |
string, optional | Bitcoin address |
ethereum |
string, optional | Ethereum address |
List Charges
Example request:
# With shell, you can just pass the correct header with each request
curl https://api.pay.busha.co/charges?page=2&limit=20 \
-H "X-BP-Api-Key: <Your API Key>"
-H "X-BP-Version: 2019-06-30"
Example response:
{
"data": [
{
"addresses": {
"bitcoin": "35EZAktBdnkzJ1dT2QfDT4Gqhxco3UALSx",
"ethereum": "0x019Ec4f8bE636cCc4692CC672918470a85787ECF"
},
"description": "1 Large Pizza",
"pricing": {
"bitcoin": {
"currency": "BTC",
"value": "0.00111982"
},
"ethereum": {
"currency": "ETH",
"value": "0.03952834"
},
"local": {
"currency": "NGN",
"value": "2000"
}
},
"payments": [],
"id": "ff5eb3dd-12eb-4c41-b513-8f92f2e31970",
"created_at": "2019-06-12T23:43:25.982566Z",
"code": "OyRO1y2tJk",
"hosted_url": "http://pay.busha.co/charges/OyRO1y2tJk",
"redirect_url": "https://example.com",
"cancel_url": "https://example.com",
"expires_at": "2019-06-13T00:13:25.982216Z",
"timeline": [
{
"time": "2019-06-12T23:43:25.985952Z",
"status": "NEW",
"context": null
}
],
"metadata": {
"customer_id": "id_1005",
"customer_name": "Jane Doe"
}
}
],
"paginator": {
"page": 1,
"per_page": 20,
"offset": 0,
"total_entries_size": 1,
"current_entries_size": 1,
"total_pages": 1
}
}
List all charges
HTTP Request
GET https://api.pay.busha.co/charges
Show a charge
Example request:
# With shell, you can just pass the correct header with each request
curl https://api.pay.busha.co/charges/jNaS7egtY1 \
-H "X-BP-Version: 2019-06-30"
Example response:
{
"data": {
"addresses": {
"bitcoin": "35EZAktBdnkzJ1dT2QfDT4Gqhxco3UALSx",
"ethereum": "0x019Ec4f8bE636cCc4692CC672918470a85787ECF"
},
"description": "1 Large Pizza",
"pricing": {
"bitcoin": {
"currency": "BTC",
"value": "0.00111982"
},
"ethereum": {
"currency": "ETH",
"value": "0.03952834"
},
"local": {
"currency": "NGN",
"value": "2000"
}
},
"payments": [],
"id": "ff5eb3dd-12eb-4c41-b513-8f92f2e31970",
"created_at": "2019-06-12T23:43:25.982566Z",
"code": "OyRO1y2tJk",
"hosted_url": "http://pay.busha.co/charges/OyRO1y2tJk",
"redirect_url": "https://example.com",
"cancel_url": "https://example.com",
"expires_at": "2019-06-13T00:13:25.982216Z",
"timeline": [
{
"time": "2019-06-12T23:43:25.985952Z",
"status": "NEW",
"context": null
}
],
"metadata": {
"customer_id": "id_1005",
"customer_name": "Jane Doe"
}
}
}
Retrieves the details of a charge that has been previously created. Supply the unique charge code that was returned when the charge was created. This information is also returned when a charge is first created
HTTP Request
GET https://api.pay.busha.co/charges/:charge_code|:charge_id
Create a charge
Example request:
curl https://api.pay.busha.co/charges \
-X POST \
-H 'Content-Type: application/json' \
-H "X-BP-Api-Key: <Your API Key>"
-H "X-BP-Version: 2019-06-30"
-d '{
"description": "1 Large Pizza",
"local_price": {
"amount": "2000",
"currency": "NGN"
},
"redirect_url": "https://example.com",
"cancel_url": "https://example.com",
"metadata": {
"customer_id": "id_1005",
"customer_name": "Jane Doe"
}
}'
Example response:
{
"data": {
"addresses": {
"bitcoin": "35EZAktBdnkzJ1dT2QfDT4Gqhxco3UALSx",
"ethereum": "0x019Ec4f8bE636cCc4692CC672918470a85787ECF"
},
"description": "1 Large Pizza",
"pricing": {
"bitcoin": {
"currency": "BTC",
"value": "0.00111982"
},
"ethereum": {
"currency": "ETH",
"value": "0.03952834"
},
"local": {
"currency": "NGN",
"value": "2000"
}
},
"payments": [],
"id": "ff5eb3dd-12eb-4c41-b513-8f92f2e31970",
"created_at": "2019-06-12T23:43:25.982566Z",
"code": "OyRO1y2tJk",
"hosted_url": "http://pay.busha.co/charges/OyRO1y2tJk",
"redirect_url": "https://example.com",
"cancel_url": "https://example.com",
"expires_at": "2019-06-13T00:13:25.982216Z",
"timeline": [
{
"time": "2019-06-12T23:43:25.985952Z",
"status": "NEW",
"context": null
}
],
"metadata": {
"customer_id": "id_1005",
"customer_name": "Jane Doe"
}
}
}
To get paid in cryptocurrency, you need to create a charge object and provide the user with a cryptocurrency address to which they must send cryptocurrency. Once a charge is created a customer must broadcast a payment to the blockchain before the charge expires.
HTTP Request
GET https://api.pay.busha.co/charges
Arguments
PARAMETER | TYPE | REQUIRED | DESCRIPTION |
---|---|---|---|
local_price |
money | Required | Price in local fiat currency |
redirect_url |
string | Optional | Redirect URL |
cancel_url |
string | Optional | Cancel URL |
metadata |
hash | Optional | Developer defined key value pairs |
Cancel a charge
Example request:
curl https://api.pay.busha.co/harges/ff5eb3dd-12eb-4c41-b513-8f92f2e31970/cancel \
-X POST \
-H "X-BP-Api-Key: <Your API Key>"
-H "X-BP-Version: 2019-06-30"
Example response:
{
"data": {
"addresses": {
"bitcoin": "35EZAktBdnkzJ1dT2QfDT4Gqhxco3UALSx",
"ethereum": "0x019Ec4f8bE636cCc4692CC672918470a85787ECF"
},
"description": "1 Large Pizza",
"pricing": {
"bitcoin": {
"currency": "BTC",
"value": "0.00111982"
},
"ethereum": {
"currency": "ETH",
"value": "0.03952834"
},
"local": {
"currency": "NGN",
"value": "2000"
}
},
"payments": [],
"id": "ff5eb3dd-12eb-4c41-b513-8f92f2e31970",
"created_at": "2019-06-12T23:43:25.982566Z",
"code": "OyRO1y2tJk",
"hosted_url": "http://pay.busha.co/charges/OyRO1y2tJk",
"redirect_url": "https://example.com",
"cancel_url": "https://example.com",
"expires_at": "2019-06-13T00:13:25.982216Z",
"timeline": [
{
"time": "2019-06-12T23:43:25.985952Z",
"status": "NEW",
"context": null
},
{
"time": "2019-06-12T23:46:04.088522Z",
"status": "CANCELED",
"context": null
}
],
"metadata": {
"customer_id": "id_1005",
"customer_name": "Jane Doe"
}
}
}
Cancels a charge that has been previously created. Supply the unique charge code that was returned when the charge was created.
Note: Only new charges can be successfully canceled. Once payment is detected, charge can no longer be canceled.
HTTP Request
POST https://api.pay.busha.co/charges/:charge_id/cancel
Resolve a charge
Example request:
curl https://api.pay.busha.co/harges/4cd7b2bb-bab2-4048-bc49-3234db959468/resolve \
-X POST \
-H "X-BP-Api-Key: <Your API Key>"
-H "X-BP-Version: 2019-06-30"
Resolve a charge that has been previously marked as unresolved. Supply the unique charge code that was returned when the charge was created.
Note: Only unresolved charges can be successfully resolved. For more on unresolved charges, check out at Charge timeline
HTTP Request
GET https://api.pay.busha.co/charges/:charge_id/resolve
Events
Events let you know when a charge is updated. When an event occurs we create a new event object. Retrieve individual events or a list of events. You can also subscribe to webhook notifications which send event objects directly to an endpoint on your server. Learn more about webhooks.
Example of an event resource:
{
"resource": "event",
"type": "charge:completed",
"api_version": "v1",
"created_at": "2019-06-17T20:09:16.334547+01:00",
"data": {
"addresses": {
"bitcoin": "32R3K4SjwY24c8TzT5mf2AMYUVxu24U6Ea",
"ethereum": "0xe81677c0DFD5d9501c71DDbc230F37B9bBE5CC61"
},
"description": "1 Large Pizza",
"pricing": {
"bitcoin": {
"currency": "BTC",
"value": "0.00128212",
"rate": "2786000"
},
"ethereum": {
"currency": "ETH",
"value": "0.07059761",
"rate": "50596.62"
},
"local": {
"currency": "NGN",
"value": "3572",
"rate": "1"
}
},
"payments": [
{
"created_at": "2019-06-17T20:08:25.73142Z",
"network": "bitcoin",
"transaction_id": "fe7b729d-16-5900s55906a0-80f9d103rr3403135",
"transaction_hash": "749f267f9238345s7044440b0b8e53de8623d09bd144760bf9a59",
"status": "COMPLETED",
"detected_at": "2019-06-17T00:36:58.750387Z",
"traded": false,
"value": {
"local": {
"amount": "3572",
"currency": "NGN"
},
"crypto": {
"amount": "0.00128212",
"currency": "BTC"
}
}
}
],
"id": "36326ab4-5315-4cc8-9973-5174c4046500",
"created_at": "2019-06-17T20:07:32.317368Z",
"code": "pv35ZuCyDd",
"hosted_url": "http://pay.busha.co/charges/pv35ZuCyDd",
"redirect_url": "https://example.com",
"cancel_url": "https://example.com",
"expires_at": "2019-06-17T20:37:32.317067Z",
"confirmed_at": "0001-01-01T00:00:00Z",
"timeline": [
{
"time": "2019-06-17T20:07:32.325297Z",
"status": "NEW",
"context": null
},
{
"time": "2019-06-17T20:08:25.761538Z",
"status": "PENDING",
"context": null
},
{
"time": "2019-06-17T20:09:13.32346Z",
"status": "COMPLETED",
"context": null
}
],
"metadata": {
"customer_id": "id_1005",
"customer_name": "Jane Doe"
}
}
}
Fields
FIELD | TYPE | DESCRIPTION |
---|---|---|
id |
string | Event UUID |
resource |
string | Resource name: "event" |
type |
string | Event type: charge:created , charge:confirmed , charge:failed , charge:delayed , charge:pending |
created_at |
timestamp | Event creation time |
api_version |
string | API version of the data payload |
data |
hash | Event payload: resource of the associated object (e.g. charge ) at the time of the event |
Webhooks
Webhooks make it easier to integrate with Busha Payby allowing you to subscribe to a set of charge events. You can subscribe to the events by going to your settings page and adding a new webhook subscription. When you create a new subscription, you can specify what events you would like to receive updates for. Below is the list of all available webhook events:
Example of a webhook payload:
{
"id": 1,
"event": {
"resource": "event",
"type": "charge:completed",
"api_version": "v1",
"created_at": "2019-06-17T20:09:16.334547+01:00",
"data": {
"addresses": {
"bitcoin": "32R3K4SjwY24c8TzT5mf2AMYUVxu24U6Ea",
"ethereum": "0xe81677c0DFD5d9501c71DDbc230F37B9bBE5CC61"
},
"description": "1 Large Pizza",
"pricing": {
"bitcoin": {
"currency": "BTC",
"value": "0.00128212",
"rate": "2786000"
},
"ethereum": {
"currency": "ETH",
"value": "0.07059761",
"rate": "50596.62"
},
"local": {
"currency": "NGN",
"value": "3572",
"rate": "1"
}
},
"payments": [
{
"created_at": "2019-06-17T20:08:25.73142Z",
"network": "bitcoin",
"transaction_id": "fe7b729d-16-5900s55906a0-80f9d103rr3403135",
"transaction_hash": "749f267f9238345s7044440b0b8e53de8623d09bd144760bf9a59",
"status": "COMPLETED",
"detected_at": "2019-06-17T00:36:58.750387Z",
"traded": false,
"value": {
"local": {
"amount": "3572",
"currency": "NGN"
},
"crypto": {
"amount": "0.00128212",
"currency": "BTC"
}
}
}
],
"id": "36326ab4-5315-4cc8-9973-5174c4046500",
"created_at": "2019-06-17T20:07:32.317368Z",
"code": "pv35ZuCyDd",
"hosted_url": "http://pay.busha.co/charges/pv35ZuCyDd",
"redirect_url": "https://example.com",
"cancel_url": "https://example.com",
"expires_at": "2019-06-17T20:37:32.317067Z",
"confirmed_at": "0001-01-01T00:00:00Z",
"timeline": [
{
"time": "2019-06-17T20:07:32.325297Z",
"status": "NEW",
"context": null
},
{
"time": "2019-06-17T20:08:25.761538Z",
"status": "PENDING",
"context": null
},
{
"time": "2019-06-17T20:09:13.32346Z",
"status": "COMPLETED",
"context": null
}
],
"metadata": {
"customer_id": "id_1005",
"customer_name": "Jane Doe"
}
}
}
}
Event types
Field | Description |
---|---|
charge:created |
New charge is created |
charge:confirmed |
Charge has been confirmed and the associated payment is completed |
charge:failed |
Charge failed to complete |
charge:delayed |
Charge received a payment after it had been expired |
charge:pending |
Charge has been detected but has not been confirmed yet |
charge:resolved |
Charge has been resolved |
Fields
FIELD | TYPE | DESCRIPTION |
---|---|---|
id |
number | Delivery attempt number |
scheduled_for |
timestamp | Delivery schedule time |
event |
hash | Corresponding event object |
Securing webhooks
Every Busha Paywebhook request includes an X-BP-Webhook-Signature header. This header contains the SHA256 HMAC signature of the raw request payload, computed using your webhook shared secret as the key. You can obtain your shared webhook secret from your settings page. Always make sure that you verify the webhook signature before acting on it inside your system.