The Direct Payment Protocol (DPP) is a comprehensive standard for invoice-based peer-to-peer payments on the Bitcoin SV network, encompassing the evolution of BIP70 through BIP270 and its related invoicing standards, including BIP271, BIP272, BIP273, BIP274, BIP275, and BIP282. The DPP harmonizes extensions to these standards, allowing for various payment options and combinations, while maintaining a well-maintained and up-to-date source of information for developers and industry players. The protocol facilitates communication between a payment host (e.g., merchant, payment processor, recipient's wallet) and sender (e.g., customer, acquaintance, IoT device) to enhance customer experience, simplify wallet infrastructure, enable advanced wallet features, and improve wallet security against payment process attacks.
The current state of BIP270, BIP271, BIP272, BIP273, BIP274, BIP275, and BIP282 lacks a unified standard owned by a dedicated committee, leading to multiple versions on GitHub that do not accurately represent field implementations. This situation makes it challenging for new players to implement invoice-based payments correctly from the outset. Furthermore, industry representatives have expressed the need for extensions to the existing standards, such as accommodating meta-assets or accepting discount coupons, which lower the amount of BSV required to satisfy the invoiced amount.
The DPP addresses these challenges by re-evaluating and baselining the existing standards to align with common field implementations, while maintaining backward compatibility. The protocol seeks input from industry players on extension needs and aims to find the smallest denominator for such needs, allowing for future custom extensions without compromising backward compatibility.
The Direct Payment Protocol (DPP) is a standard for facilitating direct payments between a customer and a merchant by specifying the necessary messages, objects, and components required for secure and efficient transactions. This section outlines the high-level concepts involved in the DPP standard.
The DPP protocol consists of three main messages: PaymentTerms, Payment, and PaymentACK. These messages are communicated between the customer and the payment host's server, serving to initiate, execute, and acknowledge payment transactions.
The DPP protocol relies on JSON objects to represent and exchange data throughout the payment process. These objects are used to define payment details, payment host and customer information, and payment acknowledgment information.
PaymentTerms is the first message in the DPP protocol, sent by the payment host's server in response to a customer's payment initiation. It contains details about the required payment, such as the available payment modes, beneficiary information, and policies.
PaymentModes define the various ways a customer can make a payment. The PaymentTerms message lists the supported modes, and the customer must choose one of these modes to proceed with the payment. Each mode has its own specific requirements and format for the Payment and PaymentACK messages.
The Beneficiary object contains information about the merchant, such as their name, email, address, and payment reference. This data can be used by the payment host to identify and associate PaymentTerms with the merchant.
Policies define any additional requirements set by the merchant for processing the Payment. These can include required originator fields or other constraints that the customer must adhere to when submitting the Payment message.
The Payment message is sent by the customer after they have authorized the payment. It specifies the chosen payment mode and provides the necessary data required for that mode, such as transaction details, originator information, and any mode-specific objects.
The Originator object contains information about the payer, which can be used for identification, refunds, and other purposes. This data can include the payer's name, paymail, return address, return script, and other optional data.
The PaymentACK message is the final message in the DPP protocol, sent from the payment host's server to the customer's wallet in response to a Payment message. It acknowledges receipt of the payment and provides any mode-specific data or additional information, such as a secure peer channel for direct communication or a redirect URL.
Now that we have covered the basic concepts, we specify the data structures necessary to achieve compliance with the DPP protocol.
The DPP consists of three primary messages: PaymentTerms, Payment, and PaymentACK. Each message is a JSON object with specific fields and requirements.
The PaymentTerms message provides the customer with the necessary information to make a payment to the payment host. It includes details about the required payment, expiration data, and additional metadata:
PaymentTerms Field | Description |
---|---|
network (string, required) |
Identifies the blockchain network. In production, this should always be "bitcoin-sv". |
version (string, required) |
Specifies the DPP version. |
outputs (array of outputs, optional, deprecated) |
Deprecated, for backward compatibility only. |
creationTimestamp (number, required) |
Unix timestamp (seconds since 1-Jan-1970 UTC) when the PaymentTerms was created. |
expirationTimestamp (number, optional) |
Unix timestamp (UTC) after which the PaymentTerms should be considered invalid. |
memo (string, optional) |
A note to be displayed to the customer, explaining the purpose of the PaymentTerms. Maximum length is 50 characters. |
paymentUrl (string, required) |
Secure HTTPS location where a Payment message will be sent to obtain a PaymentACK. |
beneficiary (object, optional) |
Contains data about the merchant. |
modes (key-value map, required) |
A dictionary of possible payment modes specified by ID, each mode describing detailed instructions about payment requirements. |
policies (object, optional) |
Specifies special merchant requirements according to the Payment object. |
The Payment message is sent after the customer has authorized the payment. It specifies the chosen payment mode and provides the required data for that mode.
Payment Field | Description |
---|---|
modeId (string, required) |
The ID of the chosen mode from the PaymentTerms message. |
mode (object, required) |
The Payment object for the specific mode used. |
originator (object, optional) |
Payer data needed for identification and refund purposes. |
transaction (hex-formatted string, optional, deprecated) |
A fully-signed and valid Bitcoin transaction. Deprecated. |
memo (string, optional) |
A plain-text note from the customer to the payment host. |
The PaymentACK message is the final message in the DPP, sent from the payment host's server to the Bitcoin wallet in response to a Payment message.
PaymentACK Field | Description |
---|---|
modeId (string, required) |
The ID of the chosen mode from the PaymentTerms message. |
mode (object, required) |
The Payment object for the specific mode used. |
peerChannel (object, optional) |
Provides data needed to communicate via the created channel in a secure manner. |
redirectUrl (string, optional) |
An optional URL to redirect the customer after the payment is completed. |
Several components are used within the messages described above. This section provides a detailed description of each component.
PaymentModes define the various ways a customer can make a payment. The PaymentTerms message lists the supported modes, and the customer must choose one of these modes to proceed with the payment. Each mode has its own specific requirements and format for the Payment and PaymentACK messages. The main part of the PaymentTerms object is the Modes component. For now, we propose one flexible payment mode called HybridPaymentMode, which can be used to pay with BSV, tokens, or a combination of funding sources. In the future, if HybridPaymentMode cannot fulfill some requirements, other PaymentModes can be specified.
Mode Field | Description |
---|---|
modeId (string, required) |
Unique identifier for the payment mode. |
description (string, required) |
A short description of the payment mode. |
requirements (object, required) |
An object containing the required fields and data for the chosen payment mode. |
The Beneficiary object contains information about the merchant, such as their name, email, address, and payment reference. This data can be used by the payment host to identify and associate PaymentTerms with the merchant.
Beneficiary Field | Description |
---|---|
name (string, required) |
Name of the merchant. |
email (string, required) |
Official merchant email. |
address (string, required) |
Merchant's address. |
paymentReference (string, required) |
ID of the payment/invoice. |
avatar (string, optional) |
URL to an avatar. |
extendedData (object, optional) |
Additional optional data as a freestyle object. |
Policies define any additional requirements set by the merchant for processing the Payment. These can include required originator fields or other constraints that the customer must adhere to when submitting the Payment message.
Policies Field | Description |
---|---|
requiredOriginatorFields (array of strings, optional) |
List of the fields which are required by the merchant to process the payment (regardless of whether DPP defines them as optional ones). |
The Originator object contains information about the payer, which can be used for identification, refunds, and other purposes. This data can include the payer's name, paymail, return address, return script, and other optional data.
Originator Field | Description |
---|---|
name (string, required) |
Name of the payer. |
paymail (string, optional) |
Payer's paymail (where, e.g., refunds will be sent, identity can be used somehow, etc.). |
return_address (string, optional) |
Payer's return bitcoin address on which the merchant can refund the payment back if there is such a case (if paymail cannot be used, another way paymail is a better option). |
return_script (string, optional) |
Similar to the above but a script instead of a raw address (it is more flexible, e.g., the payer might want to have a refund in a stable coin). |
avatar (string, optional) |
URL to an avatar. |
extendedData (object, optional) |
Additional optional data as a freestyle object. |
The PeerChannel object describes and defines the format of the peerChannel
field in the PaymentACK message. It is used to provide data that specifies a created channel for secure direct communication between the payer and the merchant.
PeerChannel Field | Description |
---|---|
host (string, required) |
The hostname and port of the server handling the secure direct communication channel. |
token (string, required) |
A unique token used for authentication and authorization within the secure communication channel. |
channel_id (string, required) |
A unique identifier for the specific communication channel established between the payer and the merchant. |
We use JSON as JSON is naturally extensible. Any property of the objects not specified in this standard is a candidate to convey information for extensions. Other standards can be created to denote specific payment modes. One such standard is BRC-54, which defines the Hybrid Payment Mode. This protocol defines an abstract messaging layer with JSON objects, but other standards such as BRC-55 can stipulate concrete transport mechanisms and such as HTTPS.
The Direct Payment Protocol (over HTTPS) is implemented in this example from Jad Wahab.