Displaying Invoices

Because cryptocurrency payments are push transactions, rather than using the traditional authorize and capture process (pull) as does a credit card, you must accommodate this in your checkout flow.

While a traditional checkout flow would collect credit card info and then present a “finalize order” page and subsequently charge the card, with cryptocurrencies no details need to be collected prior to confirmation. A click on “confirm order” should present a modal or blocking payment screen which will provide a BitPay invoice for payment, then proceed to confirmation once the payment is received.

Redirect to BitPay

The simplest integration is to simply redirect your customer to the BitPay site to complete payment, then return them to your site for order confirmation. In this case, you need only redirect your customer to the url returned in the JSON response from the /invoices endpoint.

The BitPay invoice uses responsive design to ensure that the user gets optimal presentation regardless of device form factor.

Be sure that you have also set the redirectURL when generating the invoice, which will ensure that the user gets redirected to the appropriate confirmation page following payment.

You should always validate that the invoice was paid by re-querying the BitPay API, or by manually validating that it appears in your account ledger, before completing the transaction.

Modal Invoice

BitPay allows you display the invoice within a modal on your web page, so the shopper never has to leave your site during the checkout process.

  1. To use the modal invoice, add bitpay.min.js to your web page:

    <script src="https://bitpay.com/bitpay.min.js"></script>
    
  2. When you create an invoice with a POST request to BitPay, BitPay returns the id of the invoice as part of the request response.

  3. To display the newly created invoice within a modal, pass the invoice id into the showInvoice method provided by bitpay.min.js:

    bitpay.showInvoice(id);
    
  4. The modal invoice will automatically update when payments have been received. In addition to the server IPN sent to your notificationURL, the modal will send a message to the parent window that the status has changed.

Additional methods provided by bitpay.min.js include:

  • onModalWillEnter: Allows you to specify a function to be called right before the modal opens.
  • onModalWillLeave: Allows you to specify a function to be called when the user closes the modal.
  • enableTestMode: Allows you to display invoices created via the test environment.
bitpay.onModalWillEnter(function() {  
  console.log('modal is opening');  
});

bitpay.onModalWillLeave(function() {  
  console.log('modal is closing');  
});

bitpay.enableTestMode();

It is highly recommended that you include the email of the buyer as part of the buyer{} object when creating the invoice via the BitPay API. The email parameter in the buyer{} object will be used by BitPay to contact the buyer in the case of an underpayment or overpayment in order to administer a refund. If you do not provide any buyer{} object, BitPay will prompt the user for an email address when the modal opens.

Post to Parent Window

When an invoice is presented using the modal you have an option to receive invoice status updates in the parent window. This option is useful for updating the parent window presentation or redirecting the parent window to another URL after the invoice has been paid.

When the modal invoice receives a status update from the BitPay server the new status is posted from the modal to the parent window via the Window.postMessage method and passing {status: string} where status can be any of the Invoice States according to the descriptions provided.

Your implementation should take into consideration the browser support for this method. See CanIUse for a list of browsers supporting Window.postMessage.

Following is an HTML code example illustrating a simple interaction between a modal invoice and its parent document.

<html>
  <head>
    <title>Parent</title>
  </head>
  <body>
    <script language="javascript">
      var is_paid = false
      window.addEventListener("message", function (event) {
        payment_status = event.data.status;
        if (payment_status == "paid") {
          is_paid = true
          //take action PAID
          return;
        }
      }, false);
      //show the order info
      bitpay.onModalWillLeave(function () {
        if (is_paid == false) {
          //take action, NOT PAID
          } //endif
      });
      //show the modal
      if(env == 'test'){
        bitpay.enableTestMode()
      }
      bitpay.showInvoice(<invoice id goes here>)
    </script>
  </body>
</html>