Hybrid Payment Mode for DPP
A payment protocol with no actual payment method defined does nothing. This adds a flexible mode to the direct payment protocol, covering ordinary Bitcoin as well as other kinds of token.
Reference for an AI
Everything an assistant needs to answer questions about BRC-54 accurately, including what it depends on.
Summary
- Why
- Merchants need to accept payment in several different funding types or output combinations without forcing every wallet down one rigid path.
- What
- BRC-54 defines the Hybrid Payment Mode, a way for a Direct Payment Protocol payment request to list multiple alternative payment options, each made of one or more required outputs, so a wallet can pick whichever option it can fulfill.
- How
- A payment host lists several named options, each option a set of transactions with required outputs that must all be satisfied together, the wallet picks one option by its ID, builds the matching transactions, and returns them along with the chosen optionId in the Payment message, which the host acknowledges with…
What this lets you do
- Offer multiple alternative ways to pay for the same invoice
- Bundle several required outputs into one all-or-nothing payment option
- Mix native BSV outputs with token outputs like STAS or custom token types
- Attach transaction policies such as fees, SPV requirements, or lock time
- Let a wallet report back which option and transactions it used
Written by claude-sonnet-5 from the specification text. Where the two differ, the original is correct.
The specification
Abstract
The core DPP (Direct Payment Protocol) has been defined by BRC-27, but it is non-functional without at least one mode to facilitate payments. We extend the core DPP by introducing the Hybrid Payment Mode. This flexible and open-ended payment mode facilitates payments with BSV as well as various token types, such as loyalty points and stable coins. The Hybrid Payment Mode allows a payment host to stipulate payment from a set of funding types created with AND and OR connections, enabling a wallet to choose the most suitable option based on user resources.
Motivation
The motivation behind the Hybrid Payment Mode is to provide a flexible and versatile payment mode within the Direct Payment Protocol. This mode aims to accommodate various payment scenarios and combinations by enabling payment hosts to define multiple payment options with different funding types. The Hybrid Payment Mode can address the growing demand for handling diverse payment scenarios in the evolving digital currency landscape.
Specification
Status Note
BRC-54 is a DPP payment-mode extension. It is not implemented by the current bsv-blockchain/ts-sdk or bsv-blockchain/wallet-toolbox wallet API surface. Current SDK/toolbox payment support uses BRC-100 wallet actions, BRC-29 remittance metadata, and the HTTP payment profiles in BRC-105/BRC-118/BRC-121.
Treat this document as an external or legacy DPP extension unless a project explicitly opts into BRC-27 DPP.
HybridPaymentMode (BRFCID: ef63d9775da5) will be described together with related Payment and PaymentACK objects. It is the first defined payment mode capable of fulfilling numerous requirements due to its flexible nature.
HybridPaymentMode Structure
Options {
"ID": Transactions // required, min one key-value pair.
}
The Hybrid Payment Mode contains a dictionary of various options (options are OR relation, so they are alternative sets of outputs, and the customer or their wallet will pick one).
Options (In PaymentTerms)
Every option contains a set of transactions (AND relation, if the customer chooses the option, they must provide all the required funds to satisfy the transaction). The interface for transaction object and transaction’s internal objects are described below.
Transaction
A transaction object is a set that contains 3 parts:
- Outputs: A way of specifying a Bitcoin transaction output, including the value and script for various token standards.
- Inputs: A way of declaring which specific inputs should be used (useful for multisig, payment_channels, etc).
- Policies: A way of requesting specific TX policies like fees, SPV, nLockTime, etc.
Transaction {
outputs // list of output objects. required
inputs // list of input objects. optional
policies // additional properties and requirements for transaction. optional
}
Outputs
List of outputs – payment destinations.
Outputs {
native // list of native output objects. optional.
brfcXYZ // list of brfc objects of XYZ token. optional.
tokenABC // list of ABC token objects. optional.
...
}
Native output
This is a regular native BSV output which specifies the amount and recipient in bitcoin script form (usually p2pkh).
Native output {
amount // number. required.
script // string. required. hexadecimal script.
description // string. optional. must not have JSON string length of greater than 100.
}
STAS output
This output is used for getting tokens using the STAS protocol. It is required to define tokenId (with symbol), amount, and recipient.
STAS output {
tokenId // string. required.
amount // number. required.
recipient // string. bitcoin address or paymail.
}
TokenXYZ
The structure for this object is specific to each particular token standard. It may be based on the BRFC reference if the token standard hasn't published a name yet, or otherwise based upon a particular token's name.
brfc1234 {
properties_1
properties_2
...
}
unicornToken {
tokenId // string. required
script // string. required. hexadecimal script.
...
}
Inputs
A list of input objects contains data needed to specify the required inputs which should be used.
Input {
scriptSig // string. required.
txid // string. required.
vout // integer. required.
value // integer. required.
nSequence// number. optional.
}
Policies
An object containing some policy information like fees or SPV envelope.
Policies {
fees // dictionary. optional. Nested dictionary which include on Fee objects on 3rd level.
SPVRequired // boolean. optional. default is false.
lockTime // number. optional.
}
Mode (In Payment)
This object defines fields required by HybridPaymentMode. In this mode, important data are the chosen payment option (paymentId) and a list of transactions which fulfill this option:
"ef63d9775da5" {
optionId // string. ID of chosen payment options
transactions // a list of raw transactions. required
ancestors // object. optional.
}
Mode (In PaymentACK)
This object defines fields required by HybridPaymentMode:
{
transactionIds // a list of transaction ids. required
peerChannel // object. optional
}
Example
An example of a Hybrid Payment Mode implementation is provided below:
Payment
{
optionId: "choiceID1",
transactions: [
" RAW_TRANSACTION for 'choiceID1.transactions[0]' ",
" RAW_TRANSACTION for 'choiceID1.transactions[1]' ",
],
ancestors: {
" TXID of RAW_TRANSACTION for 'choiceID1.transactions[1]' ": {
/* This object has the ancestors of 'choiceID1.transactions[1]' */
}
}
}
PaymentACK
{
transactions: [
" TXID of transaction for 'choiceID1.transactions[0]' ",
" TXID of transaction for 'choiceID1.transactions[1]' ",
],
// Things like peer_channel should probably still be defined at the paymentAck root level. Different transactions should probably not have different peer_channel-s.
peerChannel: {
host: "peerchannels:25009",
token: "token",
channel_id: "channelid",
}
}
The BRC-54 Hybrid Payment Mode specification provides a comprehensive structure for enabling diverse payment scenarios within the Direct Payment Protocol. By carefully following the structures, processes, and context described in this document, a developer can create a compatible implementation within the BRC-54 specification.