Requesting payment
Now that our wallet is loaded and synced with the network, we can read the BIP 70 URI provided by the merchant in order to make the payment. You can write a few lines of code to directly parse the bitcoin payment URL and register your app as the bitcoin URI (:bitcoin) handler. But to keep it simple, we will manually copy the payment link provided by Node.js earlier and assign it to a local variable (I've omitted irrelevant parameters):
String url ="bitcoin:mhc5YipxN6GhRRXtgakRBjrNUCbz6ypg66?r=http://bip70.com:3000/request?amount=888888";
The important part in the URL is the r parameter, which represents the merchant server, so edit it to set your server's IP or domain name.
Prior to requesting payment details from merchant's server details, we can add a sanity check to evaluate whether the address has sufficient bitcoins:
if (Float.parseFloat(String.valueOf(kit.wallet().getBalance())) == 0.0) {
System.out.println("Please send some testnet Bitcoins to your address "+kit.wallet().currentReceiveAddress());
} else {
sendPaymentRequest(url, kit);
}
Then we define sendPaymentRequest() as follows:
private static void sendPaymentRequest(String location, WalletAppKit k) {
try {
if (location.startsWith("bitcoin")) {
BitcoinURI paymentRequestURI = new BitcoinURI(location);
ListenableFuture<PaymentSession> future =
PaymentSession.createFromBitcoinUri(paymentRequestURI,true);
PaymentSession session = future.get();
if (session.isExpired()) {
log.warn("request expired!");
} else { //payment requests persist only for a certain duration.
send(session, k);
System.exit(1);
}
} else {
log.info("Try to open the payment request as a file");
}
} catch (Exception e) {
System.err.println( e.getMessage());
}
}
This method is comprised of two steps: parsing the bitcoin URI in order to request payment details from the specified URL, and running another function, send(), which proceeds with the payment.
The createFromBitcoinUri method initializes a PaymentSession using the payment URI. If this function is called with a second parameter set to true, the system trust store will be used to verify the signature provided by the payment request and a CertPathValidatorException exception is thrown in the failure case. The future.get() method parses the payment request, which is returned as a protocol buffer.
Once the payment session is established, we call the send() method to proceed with the payment. Note that you'll have to handle a few different exceptions, but I've set here a global try/catch for all expected exceptions to make the code cleaner for the reader.