BitKassa API documentatie (v0.42)

(Also available in Dutch / Ook beschikbaar in het Nederlands)

1. Processing payments - summary

  1. Call the BitKassa API to initiate a payment. We return a URL to our payment page, as well as a Bitcoin address and amount.
  2. Either redirect your customer to our payment page, or host your own payment page using the specified Bitcoin address and amount.
  3. If you're using our payment page, we will return your customer back to your website after the payment, including details on the result.
  4. Besides, we also call an optional callback URL, through which we notify you of any payment status changes.

2. Tech specs

Upon signing up for your BitKassa account, you'll receive a merchant ID and a secret API key (both alphanumeric strings).

For every API function you need to call this URL:

with two POST or GET parameters:

  p = base64-encoded json data
  a = authentication hash

Where a = sha256(secret key + json data + unixtime) + unixtime

The json data should always contain an element action to identify which API function you're calling, and a merchant_id containing your merchant ID. Other parameters (required or optional) depend on the action, see below. Unixtime is the current unix timestamp as integer. The + means string concatenation (i.e. just append as strings).


3. Starting a payment

To start a payment, call the API with the following json data: (* = required)
action *stringThe API function you want to use, in this case "start_payment"start_payment
merchant_id *stringYour merchant IDjoesbakery
currency *stringThe currency of the amount to be paid (can be EUR or BTC)EUR
amount *integerThe amount to be paid in cents or satoshis1295
descriptionstringDescription for the customer of the product or service to be paidChocolate Pie XL
return_urlstringThe URL where we'll redirect your customer after the payment (if you use our payment page)
update_urlstringA callback URL that we'll call to notify you of any payment status changes (see below)
meta_infostringA reference string, such as an ID in your database, that we'll send along with status updatesA947183352

The API call returns a json result, if successful this will contain:
payment_idstringOur ID for this paymentdhqe4cnj7f
payment_urlstringThe URL where you can redirect your customer to (if you want to use our payment page)
addressstringThe Bitcoin address where the customer is supposed to send his payment1BK9imjqeziWixvD64XfYNye5rKi2HcN7P
amountintegerThe amount in satoshis to be paid410000
bitcoin_urlstringThe Bitcoin payment URL which you can show (as link and/or QR) for the customer to pay from his wallet (if you're hosting your own payment page)bitcoin:1BK9imjqeziWixvD64XfYNye5rKi2HcN7P?amount=0.0041
expireintegerUnix timestamp when the payment expires (typically 15 minutes after start)1548037400
successbooleanConfirmation that the API call was processed successfullytrue
And otherwise:
errorstringReason why the payment could not be initiatedMissing amount
successbooleanIndication that the API call was not processed correctlyfalse

For example, you send:
 "action":       "start_payment",
 "merchant_id":  "shoemakerpete",
 "currency":     "EUR",
 "amount":       2250

And our API returns:
 "payment_id":    "r6fhp22x5c",
 "payment_url":   "",
 "address":       "1291C5pi4TPvjH5un89U4amTB8DhCHiTp3",
 "amount":        720000,
 "bitcoin_url":   "bitcoin:1BK9imjqeziWixvD64XfYNye5rKi2HcN7P?amount=0.0072",
 "expire":        1548037400,
 "success":       true

4. Processing a payment's result

If you specified a update_url when starting the payment, we'll call it whenever the status of a payment changes. We'll do this just like our own API calls with two POST parameters p and a, with p being a base64-encoded json object and a being an authentication hash (defined in the same way as above, to ensure the callback is actually coming from us).

If you specified a return_url when starting the payment, we'll redirect your customer there from our payment page after the payment is finished or cancelled. We also include the same two parameters here, containing the result of the payment.

The json data (the p parameter) with a callback or redirect contains:
payment_idstringThe ID of the payment for which we're sending a status update or returning the customerdhqe4cnj7f
payment_statusstringThe payment status (see below)pending
meta_infostringYour own reference string, if you specified it when starting the paymentA947183352

For example, upon calling your update_url and/or redirecting the customer to return_url, we send:
 "payment_id":      "r6fhp22x5c",
 "payment_status":  "paid"

Make sure to verify the authentication hash (the a parameter), otherwise someone could try and modify their own payment status into 'paid'. See also the PHP example 'Wrapper function to process the POST parameters' at the bottom.

5. Payment status

The status of a payment can be one of the following:
openThe payment just started and is still open, no transaction has been done yet
cancelledThe customer cancelled the payment
expiredThe payment expired (no transaction was done within the required time)
pendingA payment is incoming, it isn't confirmed by the Bitcoin network yet, but you could inform your customer that his payment is being processed and his order will be handled as soon as the transaction gets confirmed by the Bitcoin network
paidThe payment is confirmed by the Bitcoin network, you can now send the product or deliver the service

A payment always starts as open, and changes to cancelled if the customer cancels, or expired if the customer waits too long and doesn't do anything (or closes his browser), or pending as soon as the customer sends a Bitcoin payment. After pending the status will automatically change to paid as soon as it's confirmed by the Bitcoin network. In extreme cases where a payment does not get confirmed and is unlikely to get confirmed within a foreseeable time, the status will change to expired. Once a payment becomes either paid, cancelled, or expired, it never changes anymore.

Please note - we only guarantee to pay out the money when the status becomes paid, i.e. after confirmation from the Bitcoin network. Whether or not this happens and how long it will take is dependent on how busy the Bitcoin-network is and how much fee your customer included in his transaction. It varies from a few minutes to a couple of weeks, it's also possible the transaction may never get confirmed. We recommend as soon as a payment is pending, to inform the customer "thanks for your payment, your order will be processed as soon as your transaction gets confirmed by the Bitcoin network", and actually ship the product or deliver the service as soon as the status changes to paid.

6. Retrieving the payment status

Besides the status info we're sending to you through return_url and update_url, you can also get the status for a payment yourself, through an API call with the following JSON data: (* = required)
action *stringThe API function you want to use, in this case "get_payment_status"get_payment_status
merchant_id *stringYour merchant IDjoesbakery
payment_id *stringThe ID of the paymentdhqe4cnj7f

The result you're getting contains:
payment_statusstringThe status of the payment (see above)paid
successbooleanConfirmation that the API call was processed successfullytrue
Or if an error occurred:
errorstringReason why the payment status could not be retrievedInvalid payment_id
successbooleanIndication that the API call was not processed correctlyfalse

For example, you send:
 "action":       "get_payment_status",
 "merchant_id":  "joesbakery",
 "payment_id":   "r6fhp22x5c"

Our API returns:
 "payment_status":  "paid",
 "success":         true

Note that retrieving the payment status yourself is not necessary, the status we're passing through the update_url and/or return_url (of which you'll typically specify one or both in practice) is sufficient to completely process a payment.

7. PHP examples

Wrapper function to call the BitKassa API:
function CallBitKassaApi( $action, $params )
	$merchantId = 'joesbakery';
	$secretApiKey = 'abcde12345';

	// insert action and merchant_id (required for every API call) into the params array
	$params['action'] = $action;
	$params['merchant_id'] = $merchantId;

	// create json and authentication
	$jsonData = json_encode($params);
	$t = time();
	$a = hash('sha256',$secretApiKey.$jsonData.$t).$t; // authentication hash
	$p = base64_encode($jsonData);

	// call API url (also possible with cURL etc)
	$jsonResult = file_get_contents("$p&a=$a");

	// abort on error, or return result as associative array
	if (!$jsonResult) die('Could not connect');
	$result = json_decode($jsonResult,true);
	if (!$result['success']) die('Error: '.$result['error']);
	return $result;
Start a payment:
$params = array(
	// required:
	'currency' => 'EUR',
	'amount'   => 1295,

	// optional:
	'description' => 'Chocolate Pie XL',
	'return_url'  => '',
	'update_url'  => '',
	'meta_info'   => '123456789', // could be an order or customer ID within your own database, for your own reference

$result = CallBitKassaApi('start_payment',$params);

// redirect customer to payment page
header('Location: '.$result['payment_url']);
Retrieve payment status:
$params = array( 'payment_id' => 'abcdefghijk' );
$result = CallBitKassaApi('get_payment_status',$params);

print('The status of your payment is: '.$result['payment_status']);
Wrapper function to process the POST parameters we include with a callback or redirect:
function GetBitKassaParams()
	$mySecretApiKey = 'abcde12345';
	$p = $_POST['p'];
	$a = $_POST['a'];
	$jsonData = base64_decode($p);

	// verify authentication hash to be sure this request actually came from us,
	// and not someone trying to forge their payment status into 'paid'
	$t = substr($a,64);
	$verify = hash('sha256',$mySecretApiKey.$jsonData.$t).$t;
	if ($a!=$verify) die('Authentication error');

	return json_decode($jsonData,true);
Callback script you could use as update_url:
$params = GetBitKassaParams();

$paymentId = $params['payment_id'];
$status = $params['payment_status'];
$myRef = $params['meta_info'];

if ($status=='paid')
	// (...send product...)
Return page you could use as return_url, where we redirect the customer after the payment:
$params = GetBitKassaParams();

$paymentId = $params['payment_id'];
$status = $params['payment_status'];
$myRef = $params['meta_info'];

if ($status=='pending' || $status=='paid')
	print('Thanks for your payment, we will process your order as soon as your transaction gets confirmed by the Bitcoin network!');
else if ($status=='expired') print('No payment received :(');
else if ($status=='cancelled') print('You cancelled the payment :(');

Questions? Please let us know!