BRC-29

Overview

BRC-29 is the Simple Payments Protocol standard that defines a structured way for applications to request, negotiate, and deliver payments on the BSV blockchain. It provides standardized PaymentRequest and PaymentResponse formats with integrated SPV envelope support, enabling direct payment negotiations between wallets and applications without requiring third-party payment processors. The BSV TypeScript SDK includes full BRC-29 implementation for building compliant payment systems.

Purpose

  • Create standardized payment requests with clear payment terms

  • Generate payment responses with transaction and SPV proofs

  • Enable direct wallet-to-application payment negotiations

  • Provide proof of payment with merkle path verification

  • Support multiple payment destinations in a single request

  • Ensure payment authenticity through cryptographic verification

  • Enable offline payment verification through SPV

Basic Usage

Creating a Payment Request

import { PaymentRequest, P2PKH } from '@bsv/sdk';

// Create payment request
const paymentRequest: PaymentRequest = {
  network: 'mainnet',
  outputs: [
    {
      script: new P2PKH().lock('1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa').toHex(),
      satoshis: 10000,
      description: 'Digital content purchase'
    }
  ],
  creationTimestamp: Date.now(),
  expirationTimestamp: Date.now() + (3600 * 1000), // 1 hour
  memo: 'Payment for article #12345',
  merchantData: JSON.stringify({
    orderId: '12345',
    customerId: 'user_abc',
    items: ['article-xyz']
  })
};

console.log('Payment request created');
console.log('Amount:', paymentRequest.outputs[0].satoshis, 'satoshis');
console.log('Expires:', new Date(paymentRequest.expirationTimestamp));

Creating a Payment Response

Key Features

1. PaymentRequest Structure and Creation

PaymentRequest defines the terms and requirements for a payment:

2. PaymentResponse with SPV Envelopes

PaymentResponse includes the transaction and SPV proof in BEEF format:

3. Direct Payment Negotiation

BRC-29 enables direct payment negotiation between wallets and applications:

4. Reference Implementation Patterns

Complete reference patterns for common BRC-29 use cases:

API Reference

PaymentRequest Interface

Properties:

  • network - Target BSV network

  • outputs - Array of payment outputs required

  • creationTimestamp - When request was created (Unix timestamp ms)

  • expirationTimestamp - Optional expiration time (Unix timestamp ms)

  • memo - Optional human-readable note

  • merchantData - Optional data for merchant use (recommend JSON string)

  • paymentUrl - Optional URL where payment should be submitted

PaymentResponse Interface

Properties:

  • payment - BEEF envelope containing transaction and proofs (hex)

  • memo - Optional note from payer

  • paymentId - Transaction ID of payment transaction

Helper Functions

createPaymentRequest(params): PaymentRequest

Creates a standardized payment request.

Parameters:

  • params.network - Target network

  • params.outputs - Payment outputs

  • params.validForMinutes - Validity duration

  • params.memo - Payment description

  • params.merchantData - Additional data

verifyPaymentResponse(request, response, chainTracker): Promise<VerificationResult>

Verifies a payment response against its request.

Parameters:

  • request: PaymentRequest - Original payment request

  • response: PaymentResponse - Payment response to verify

  • chainTracker: ChainTracker - For SPV verification

Returns: Promise<VerificationResult>

  • valid: boolean - Whether payment is valid

  • errors: string[] - Array of validation errors

Common Patterns

Pattern 1: E-commerce Checkout Integration

Complete e-commerce checkout with BRC-29:

Pattern 2: Content Paywall with BRC-29

Implement content paywall using BRC-29:

Pattern 3: Peer-to-Peer Marketplace

P2P marketplace using BRC-29:

Security Considerations

  1. Expiration Validation: Always check expiration timestamps on payment requests. Reject expired requests to prevent replay attacks.

  2. Amount Verification: Verify exact payment amounts match the request. Reject partial or excessive payments.

  3. SPV Proof Validation: Always verify merkle proofs with a trusted chain tracker. Invalid proofs indicate fraudulent payments.

  4. Merchant Data Integrity: Don't trust merchantData from payment responses. Always validate against original request data stored server-side.

  5. Double-Spend Monitoring: Monitor for double-spend attempts on payment transactions. Wait for confirmations for high-value transactions.

  6. HTTPS Only: Always use HTTPS for paymentUrl endpoints to prevent man-in-the-middle attacks.

Performance Considerations

  1. Request Caching: Cache payment requests server-side to avoid regenerating identical requests.

  2. BEEF Size: For large transaction chains, BEEF envelopes can be substantial. Use compression for network transmission.

  3. Batch Processing: Process multiple payments in batches when possible to improve throughput.

  4. Async Verification: Perform SPV verification asynchronously to avoid blocking payment submission.

  5. Database Indexing: Index orders by paymentId (txid) for fast payment lookup.

  6. Expiration Cleanup: Periodically clean up expired payment requests to free resources.

  • Transaction - Create payment transactions

  • BEEF - Transaction envelope format

  • P2PKH - Standard payment script

  • SPV - Payment verification

  • ARC - Transaction broadcasting

Code Examples

See complete working examples in:

Best Practices

  1. Always set expiration timestamps for payment requests to limit replay window

  2. Verify all payment details against original request stored server-side

  3. Use BEEF format for payment responses to include SPV proofs

  4. Implement proper error handling for expired, invalid, or underpaid requests

  5. Store merchantData as JSON for easy parsing and extensibility

  6. Generate unique order IDs to prevent collisions and enable tracking

  7. Validate network field matches your expected network (mainnet vs testnet)

  8. Monitor payment confirmations for high-value transactions

  9. Provide clear descriptions for each output to inform users

  10. Implement callback URLs for asynchronous payment notifications

Troubleshooting

Issue: Payment verification fails with correct payment

Solution: Ensure output order matches request and verify script encoding.

Issue: Payment request expired before user could pay

Solution: Set reasonable expiration times and provide expiration warnings.

Issue: BEEF envelope too large for HTTP request

Solution: Use compression or split large transaction chains.

Issue: Cannot parse merchantData from old requests

Solution: Implement versioning in merchantData format.

Further Reading

Status

✅ Complete

Last updated