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.
Summary
- Why
- Merchants needed a way to ask for payment that could flex across multiple currencies, token types, and transaction requirements instead of demanding one fixed BSV output.
- What
- BRC-54 defines the Hybrid Payment Mode, a plug-in for the Direct Payment Protocol that lets a merchant offer multiple alternative sets of payment requirements, mixing BSV and other token types, for a wallet to choose from.
- How
- A payment host lists a set of options (each option a bundle of required transactions with outputs, optional inputs, and policies), the wallet picks one option and returns raw transactions plus an optionId in the Payment object, and the receiver acknowledges with transaction IDs in the PaymentACK.
What this lets you do
- Offer a customer several alternative payment options in one request
- Combine BSV outputs with token outputs (like STAS tokens) in a single payment option
- Require multiple transactions to be paid together to satisfy one option
- Specify exact inputs, fees, SPV requirements, or lock times a payment must meet
- Let a wallet pick whichever offered option best matches the user's available funds
Written by claude-sonnet-5 from the specification text. Where the two differ, the original is correct.
Reference for an AI
Everything an assistant needs to answer questions about BRC-54 accurately, including what it depends on.
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.