# PeerPay

Canonical: https://docs.projectbabbage.com/docs/guides/messagebox/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.

**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.

```ts
import { WalletClient } from '@bsv/sdk'
import { PeerPayClient } from '@bsv/message-box-client'

const walletClient = new WalletClient('auto')
const peerPayClient = new PeerPayClient({
  walletClient,
  messageBoxHost: 'https://your-messagebox.example',
  enableLogging: true
})
```

________________________________________

### 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:

```ts
const paymentToken = await peerPayClient.createPaymentToken({
  recipient: '<recipient_identity_key>',
  amount: 1000
})
```

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):

```ts
await peerPayClient.sendPayment({
  recipient: '<recipient_identity_key>',
  amount: 1000
})
```

**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:

```ts
await peerPayClient.sendLivePayment({
  recipient: '<recipient_identity_key>',
  amount: 1000
})
```

________________________________________

### 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:

```ts
await peerPayClient.listenForLivePayments({
  onPayment: (payment) => {
    console.log('Received payment:', payment)
  }
})
```

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:

```ts
const result = await peerPayClient.acceptPayment(incomingPayment)
console.log('Payment accepted:', result)
```
________________________________________

### 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:

```ts
await peerPayClient.rejectPayment(incomingPayment)
```

________________________________________

### 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:

```ts
const pendingPayments = await peerPayClient.listIncomingPayments()
console.log('Pending payments:', pendingPayments)
```
________________________________________

### 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.

________________________________________
