Here's a quick overview of how the payment gateway works:
- When a customer indicates they want to check out and pay with 0xBTC, the web shop will send a POST to a 0xbtcpay component to tell it to watch for a payment of a certain amount. That endpoint has an IP whitelist -- only the web shop should be allowed to create payments.
- The response will contain, among other things, an id for that payment.
- The web shop, or Javascript running in the browser, will then periodically ask a 0xbtcpay component about the status of the payment.
- The statuses will most likely start out as not having seen anything on the blockchain, and then indicate that the payment has been seen, and then finally indicate that payment is complete.
Suppose that the customer has indicated they want to check out and pay with 0xBTC. The web shop will send a POST that looks like this:
{
"jsonrpc": "2.0",
"id": 111,
"method": "start_payment",
"params": {
"amount": "222.333",
"data": {"order_id": "444"},
"postback_url": "https://xxx.yyy/payment_complete"
}
}
id
is an integer used to identify the JSON-RPC request. The same id will be sent back in the response.amount
is the total price in 0xBTC.data
is optional. It could be used to contain metadata like the order id generated by the web shop software.postback_url
is optional. If present, 0xbtcpay will post to this URL when payment is complete.
To send this kind of request via curl, you could do something like this:
curl -X POST -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0", "id":111, "method":"start_payment", "params":{"amount":"222.333"}}' http://127.0.0.1:8888/
The response will be something like this:
{"jsonrpc":"2.0","result":{"id":"0c3fa5c9e5394cc9","amount":"222.333","address":"0xfb7d7aec8f66dac147496fde098d834f488963c3"},"id":111}
id
is 111, the same as in the request.result
is a dictionary containingid
the id of this payment.amount
the number of 0xBTC.address
the address to which the customer should send payment.
At this point, 0xbtcpay is watching for payment to be sent.
Now that the payment has been added, something, either code in your web shop software, or Javascript running in the browser, needs to poll for the status of this payment, perhaps every second or two. It will perform a GET to a 0xbtcpay component that is not IP restricted (it is reachable by any internet client). In this example, suppose it's accessible on https://xxx.yyy:8888/.
To get the payment status, send a GET like this:
curl https://xxx.yyy:8888/0c3fa5c9e5394cc9/status.json
Or, from Javascript, something like this:
function poll() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var data = JSON.parse(this.responseText);
if (data.paid_at == null && data.seen_at == null) {
message.innerText = `Please send ${data.amount} 0xBTC to ${data.address}.`;
} else {
if (data.seen_at != null) {
message.innerText = "Payment detected! Please wait...";
}
if (data.paid_at != null) {
clearInterval(timerId);
message.innerText = "Payment complete!";
}
}
}
};
xhr.open("GET", `https://xxx.yyy:8888/${payment_id}/status.json`, true);
xhr.send();
}
poll();
var timerId = setInterval(poll, 1000);
The response from /*/status.json
will look something like this:
{"address":"0xfb7d7aec8f66dac147496fde098d834f488963c3","amount":"222.333","seen_at":null,"paid_at":null,"tx_hash":null}
address
is the address to which the customer should send payment.amount
is the total amount of 0xBTC the customer should send.seen_at
will initially be null. It will be set to a UNIX timestamp when the first sign of the payment has been seen on the blockchain. When you see nonnullseen_at
, you can display a message to indicate progress to the customer, but it does NOT mean that payment is complete.paid_at
will initially be null. It will be set to a UNIX timestamp once payment has definitely been made. When this is nonnull, payment is complete.tx_hash
will be set to the tx hash of the payment in case you want to provide an Etherscan link or do further recordkeeping.