Client side
As for the backend, we'll use bitcore in the client side, therefore we need to install the frontend component. For that, create a bower.json file in the views/ folder with the following content:
{
"dependencies": {
"bitcore-lib": "^0.15.0",
"bitcore-payment-protocol": "1.2.2"
}
}
Then run the following command (inside the views/ folder):
bower install
Next, we need to install a QR code library in the views/ directory:
git clone https://github.com/davidshimjs/qrcodejs
Then create two files – index.html and main.js – in the views/ directory. In the first of these files, paste the following code:
<html>
<head>
<script src="bower_components/bitcore-lib/bitcore-lib.js"></script>
<script src="bower_components/bitcore-payment-protocol/bitcore-payment-protocol.min.js"> </script>
<script src="qrcodejs/qrcode.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<div class="main_div">
<form id="myForm">
<img src="watch.jpg" width="200px" class="item">
<br>
<h1>MVMT WATCH</h1>
<strong>Item Details:</strong> WATER RESISTANT
<br>
<strong>Price :</strong> 0.888888 BC.
<input type="hidden" id="amount" value=888888>
<br>
<br>
<input
type="submit"
value="Pay with BTC"
id="submit"
onclick="event.preventDefault();ProcessingPayment()" />
</form>
</div>
<script src="./main.js"></script>
</body>
</html>
This code builds a demo web page with a single product (a watch) and a payment button. On the other hand, in main.js, we define the frontend functions to interact with the payment server.
First, we define the ProcessingPayment() function, which initiates an Ajax call to request the payment URI:
function ProcessingPayment() {
var amount_ = $('#amount').val();
$.ajax({
method: 'POST',
url: '/ProcessingPayment',
data: JSON.stringify({'amount' : amount_}),
contentType: 'application/json',
processData: false,
success: function(data) {
pay(data);
}
});
}
The server will answer back with a payment link, which will be displayed as a URL and QR code using the method pay():
function pay(pay_url) {
document.write("<body><div class='pay_div'><h1>Quick Checkout</h1><div class='result' id='result' name='result'> <div class='overview'> Payment URL : <a href=" +pay_url+ ">"+ pay_url +"</a> </div><br> <div id='qrcode'></div> <input type='hidden' id='amount' value='888888'> <br> <input type='button' value='Transaction Details' onclick='check_details()' id='check' class='check'><div class='details'></div></div><script src='./main.js'></script> <link rel='stylesheet' type='text/css' href='style.css' /></body>");
var qrcode = new QRCode(document.getElementById("qrcode"), {
text: pay_url.toString(),
width: 128,
height: 128,
colorDark : "#000000",
colorLight : "#ffffff",
correctLevel : QRCode.CorrectLevel.H
});
}
We then define a check_details() method to request from the server the payment details when the customer presses the Transaction Details button:
function check_details() {
var amount_ = $('#amount').val();
$.ajax({
method: 'GET',
url: '/request?amount='+amount_+'&browser=1',
datatype:'binary',
processData: false,
success: function(data) {
get_payment_details(data);
}
});
}
In the last step, once the payment request details are received, they will be unpacked and displayed using the following get_payment_details method:
function get_payment_details(rawbody) {
try {
var body = PaymentProtocol.PaymentRequest.decode(rawbody);
var request = (new PaymentProtocol()).makePaymentRequest(body);
var version = request.get('payment_details_version');
var pki_type = request.get('pki_type');
var pki_data = request.get('pki_data');
var serializedDetails = request.get('serialized_payment_details');
var signature = request.get('signature');
var verified = request.verify();
verified=(verified) ? "Valid" : verified;
var decodedDetails = PaymentProtocol.PaymentDetails.decode(serializedDetails);
var details = new PaymentProtocol().makePaymentDetails(decodedDetails);
var network = details.get('network');
var outputs = details.get('outputs');
var time = details.get('time');
var expires = details.get('expires');
var memo = details.get('memo');
var payment_url = details.get('payment_url');
var merchant_data = details.get('merchant_data');
$('.details').append('<h2>Invoice :</h2><ul><li> Network : '+network+'</li><li>Transaction Timestamp : '+time+'</li><li>Expiration Date: '+expires+'</li><li>Merchant data : '+merchant_data+'</li><li> Merchant Signature verification: '+verified+'</li><li>Memo: '+memo+'</li><li> Total : 0.0088888</li>');
} catch (e) {
console.log(('Could not parse payment protocol: ' + e));
}
}
The details displayed are very important, especially the validation of the merchant identity status using request.verify(), which validates the payment request signature against the merchant's identity.
Great! Now the application is ready to be tested. Let's check it out.