PeerPay

Guide for integrating and using the PeerPay Client to manage real-time micropayments. The PeerPay Client enables you to send and receive payment requests, coordinate transactions seamlessly, and integrate with existing messaging and payment systems. This guide covers initialization, transaction flows, error handling, and best practices to ensure a secure and efficient payment experience.

Read as Markdown

Version boundary: examples checked against the published @bsv/message-box-client 2.6.1 API and SDK 4.0.0, October 26, 2026. Use maintained Node.js 22 or 24. Pin package versions while reproducing a guide, and review wallet permissions and any messaging/payment charges.

Overview

The PeerPay Client extends the functionality of the MessageBox Client to enable peer-to-peer Bitcoin payments via MessageBox. It supports generating secure payment tokens, sending payments (via HTTP or live WebSocket), and handling incoming payment notifications. This guide covers all key features and usage scenarios for integrating PeerPay into your application.


Initialization and Configuration

PeerPay Client is instantiated by providing a WalletClient along with optional configuration settings. Configure messageBoxHost with your own MessageBox Server when you deploy. Logging is off by default, but you can enable it by setting enableLogging: true—which is useful during development and debugging.

1import { WalletClient } from '@bsv/sdk'
2import { PeerPayClient } from '@bsv/message-box-client'
3
4const walletClient = new WalletClient('auto')
5const peerPayClient = new PeerPayClient({
6  walletClient,
7  messageBoxHost: 'https://your-messagebox.example',
8  enableLogging: true
9})
Copied!

Generating a Payment Token

The createPaymentToken() method is responsible for generating a secure payment token. It works by:

  • Creating unique derivation nonces.

  • Deriving the recipient’s public key.

  • Constructing a P2PKH locking script.

  • Creating a payment action with the specified amount.

Example usage:

1const paymentToken = await peerPayClient.createPaymentToken({
2  recipient: '<recipient_identity_key>',
3  amount: 1000
4})
Copied!

If token creation fails (for example, due to an invalid recipient key or amount), an error is thrown.


Sending a Payment

PeerPay offers two methods to send payments:

Sending a Payment via HTTP The sendPayment() method generates a payment token and sends it via an HTTP POST request (inherited from MessageBox Client):

1await peerPayClient.sendPayment({
2  recipient: '<recipient_identity_key>',
3  amount: 1000
4})
Copied!

Sending a Live Payment For real-time transactions, use sendLivePayment(). This method sends the payment token over WebSockets for instantaneous delivery. If the live transmission fails or times out, it automatically falls back to HTTP:

1await peerPayClient.sendLivePayment({
2  recipient: '<recipient_identity_key>',
3  amount: 1000
4})
Copied!

Listening for Incoming Payments

To handle incoming payments in real time, the listenForLivePayments() method listens on the standard payment message box. It converts incoming messages into structured IncomingPayment objects and then triggers a callback:

1await peerPayClient.listenForLivePayments({
2  onPayment: (payment) => {
3    console.log('Received payment:', payment)
4  }
5})
Copied!

This makes it easy to integrate live payment notifications into your user interface.


Accepting a Payment

Once a payment is received, you can process it using the acceptPayment() method. This method internalizes the transaction using your wallet client and acknowledges the payment:

1const result = await peerPayClient.acceptPayment(incomingPayment)
2console.log('Payment accepted:', result)
Copied!

Rejecting a Payment

If a payment is not desired, you can reject it using rejectPayment(). This method may create a real refund transaction or acknowledge a payment below its refund threshold. In 2.6.1, a payment must be at least 2,000 satoshis for the refund branch; it deducts 1,000 satoshis from the payment amount. This is a library policy, not a universal miner fee. Review the wallet action before approving. Refund processing is not an exactly-once journal: reconcile an uncertain original refund before calling reject again. Do not promise that rejecting always returns the full amount:

1await peerPayClient.rejectPayment(incomingPayment)
Copied!

Listing Incoming Payments

To retrieve a list of pending payments from the standard payment message box, use listIncomingPayments(). This returns an array of IncomingPayment objects for further processing:

1const pendingPayments = await peerPayClient.listIncomingPayments()
2console.log('Pending payments:', pendingPayments)
Copied!

Summary

The PeerPay Client streamlines peer-to-peer Bitcoin micropayments by:

  • Generating secure payment tokens.

  • Supporting real-time (WebSocket) and fallback HTTP payment transmission.

  • Handling incoming payments with robust processing methods.

  • Allowing you to accept or reject payments with integrated logging and error handling.

By following this guide, developers can effectively integrate PeerPay Client into their applications for a seamless payment experience.


Was this page helpful?