B++ Logo

Multi-Part Payments (MPP)

Multi-Part Payments allow splitting a single payment across multiple routes. This enables larger payments and improves success rates by utilizing multiple channels. Instead of sending one large payment through a single route, MPP splits the payment into multiple smaller parts that can take different routes.

Example

Single Payment (fails):
Alice → Bob → Carol → Dave
Amount: 500,000 sats
Problem: Carol's channel only has 200,000 sats capacity

MPP Payment (succeeds):
Route 1: Alice → Bob → Carol → Dave (200,000 sats)
Route 2: Alice → Eve → Dave (200,000 sats)
Route 3: Alice → Fred → George → Dave (100,000 sats)
Total: 500,000 sats

Why Use MPP?

Benefits

  1. Larger Payments: Can send amounts larger than any single channel
  2. Higher Success Rate: Multiple routes increase chance of success
  3. Better Liquidity Utilization: Use multiple channels simultaneously
  4. Fault Tolerance: If one route fails, others can still succeed

Use Cases

  • Large Payments: Payments larger than channel capacity
  • Unbalanced Channels: When direct channels are one-sided
  • Network Congestion: When single routes are unreliable
  • Optimization: Split to minimize fees or maximize speed

How MPP Works

Payment Splitting

  1. Determine Split: Divide payment into multiple parts
  2. Find Routes: Find routes for each part
  3. Send Simultaneously: Send all parts at once
  4. Wait for All: Wait for all parts to complete
  5. Verify Completion: Ensure all parts succeeded

Equal Splitting

Simplest approach: divide payment equally among routes:

Payment: 120,000 sats
Routes: 3

Split: 120,000 / 3 = 40,000 sats per route

Optimal Splitting

More advanced: split based on:

  • Channel capacities
  • Fee optimization
  • Success probability
  • Route quality

TLV Encoding for MPP

MPP payments include special TLV (Type-Length-Value) fields in the final hop of each route.

Payment Data TLV

Type: 8
Length: 40 bytes

Value (40 bytes):
  32 bytes: payment_secret (payment_address)
  8 bytes: total_msat (total payment amount)

Example

Payment Secret: b3c3965128b05c96d76348158f8f3a1b92e2847172f9adebb400a9e83e62f066
Total Amount: 120,000 msat

TLV Encoding:
Type: 0000000000000008 (8)
Length: 0000000000000028 (40)
Value: b3c3965128b05c96d76348158f8f3a1b92e2847172f9adebb400a9e83e62f0660000000000000078

Where to Include

  • Last hop of each path: Include in final hop's TLV
  • Same values: All paths use same payment_secret and total_msat
  • Other hops: NULL TLV for non-final hops

MPP Implementation

Step 1: Simple Route

For single-path payments, no MPP TLV is needed:

Route: Alice → Bob → Carol → Dave
Amount: 100,000 sats
TLV: NULL (no MPP field)

Step 2: Multi-Path Payment

For multi-path payments, include TLV in last hop of each path:

Path 1: Alice → Bob → Carol → Dave
  Last hop (Carol → Dave): Include MPP TLV
  
Path 2: Alice → Eve → Dave
  Last hop (Eve → Dave): Include MPP TLV
  
Path 3: Alice → Fred → George → Dave
  Last hop (George → Dave): Include MPP TLV

TLV Structure

The TLV uses simplified encoding (not full BOLT specification):

Type [uint64]: 8
Length [uint64]: 40

Values [40 bytes]:
  32 bytes: payment_secret (hex)
  8 bytes: total_msat (uint64, big-endian)

Payment Secret

The payment secret (also called payment_address) is:

  • 32 bytes: Random value generated by recipient
  • Same for all parts: All MPP parts use the same secret
  • Verification: Recipient verifies all parts use same secret
  • Security: Prevents payment mixing attacks

Total Amount

The total_msat field specifies:

  • Total payment: Sum of all MPP parts
  • Verification: Recipient verifies sum matches invoice
  • Same for all parts: All parts include the same total
  • 8 bytes: uint64 in big-endian format

Example: 3-Path MPP

Invoice Details

Invoice Amount: 120,000 sats
Payment Secret: b3c3965128b05c96d76348158f8f3a1b92e2847172f9adebb400a9e83e62f066

Route Calculation

Path 0: Alice → Bob → Carol → Dave
  Amount per path: 40,000 sats
  Fees: Calculate for each hop
  
Path 1: Alice → Eve → Dave
  Amount per path: 40,000 sats
  Fees: Calculate for each hop
  
Path 2: Alice → Fred → George → Dave
  Amount per path: 40,000 sats
  Fees: Calculate for each hop

TLV for Each Path

All three paths include the same TLV in their final hop:

TLV: 00000000000000080000000000000028b3c3965128b05c96d76348158f8f3a1b92e2847172f9adebb400a9e83e62f0660000000000000078

Verification

Recipient Verification

The recipient verifies:

  1. All parts received: All MPP parts arrived
  2. Same secret: All parts use same payment_secret
  3. Correct total: Sum of parts equals total_msat
  4. Valid preimage: All parts have valid preimages

Sender Verification

The sender verifies:

  1. All parts sent: All parts were sent
  2. All succeeded: All parts completed successfully
  3. Correct amounts: Sum equals invoice amount
  4. Preimages match: All preimages are the same

Best Practices

For Senders

  1. Equal Splitting: Start with equal splits
  2. Route Quality: Use best available routes
  3. Monitor Progress: Track all parts
  4. Handle Failures: Retry failed parts if needed

For Recipients

  1. Wait for All: Don't settle until all parts arrive
  2. Verify Totals: Ensure sum matches invoice
  3. Check Secrets: Verify all parts use same secret
  4. Timeout Handling: Handle partial payments

Common Issues

Partial Payment Received

Problem: Only some MPP parts succeed

Solution:

  • Wait for timeout
  • Request remaining parts
  • Or cancel and retry

TLV Encoding Errors

Problem: TLV not encoded correctly

Solution:

  • Verify type is 8
  • Check length is 40
  • Ensure correct byte order
  • Validate hex encoding

Amount Mismatch

Problem: Sum of parts doesn't match total

Solution:

  • Verify calculation
  • Check fee inclusion
  • Ensure correct splitting

Summary

Multi-Part Payments enable:

  • Larger payments: Split across multiple routes
  • Better success rates: Multiple paths increase reliability
  • Liquidity utilization: Use multiple channels
  • TLV encoding: Payment data in final hops
  • Verification: Recipient verifies all parts

MPP is essential for handling large payments and improving Lightning Network usability.