Hybrid Payment Mode for DPP


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.


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.


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.


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


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.


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 {
unicornToken {
  tokenId // string. required
  script // string. required. hexadecimal script.


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.


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


An example of a Hybrid Payment Mode implementation is provided below:


  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]' */


  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.

Last updated