1
0
mirror of https://github.com/bitcoinbook/bitcoinbook synced 2024-11-27 02:18:25 +00:00
bitcoinbook/selected BIPs/bip-0070.asciidoc

430 lines
17 KiB
Plaintext

--------------------------------------------------
BIP: 70
Title: Payment Protocol
Author: Gavin Andresen <gavinandresen@gmail.com>
Status: Draft
Type: Standards Track
Created: 2013-07-29
--------------------------------------------------
[[abstract]]
Abstract
~~~~~~~~
This BIP describes a protocol for communication between a merchant and
their customer, enabling both a better customer experience and better
security against man-in-the-middle attacks on the payment process.
[[motivation]]
Motivation
~~~~~~~~~~
The current, minimal Bitcoin payment protocol operates as follows:
1. Customer adds items to an online shopping basket, and decides to pay
using Bitcoin.
2. Merchant generates a unique payment address, associates it with the
customer's order, and asks the customer to pay.
3. Customer copies the Bitcoin address from the merchant's web page and
pastes it into whatever wallet they are using OR follows a bitcoin: link
and their wallet is launched with the amount to be paid.
4. Customer authorizes payment to the merchant's address and broadcasts
the transaction through the Bitcoin p2p network.
5. Merchant's server detects payment and after sufficient transaction
confirmations considers the transaction final.
This BIP extends the above protocol to support several new features:
1. Human-readable, secure payment destinations-- customers will be
asked to authorize payment to "example.com" instead of an inscrutable,
34-character bitcoin address.
2. Secure proof of payment, which the customer can use in case of a
dispute with the merchant.
3. Resistance from man-in-the-middle attacks that replace a merchant's
bitcoin address with an attacker's address before a transaction is
authorized with a hardware wallet.
4. Payment received messages, so the customer knows immediately that
the merchant has received, and has processed (or is processing) their
payment.
5. Refund addresses, automatically given to the merchant by the
customer's wallet software, so merchants do not have to contact
customers before refunding overpayments or orders that cannot be
fulfilled for some reason.
[[protocol]]
Protocol
~~~~~~~~
This BIP describes payment protocol messages encoded using Google's
Protocol Buffers, authenticated using X.509 certificates, and
communicated over http/https. Future BIPs might extend this payment
protocol to other encodings, PKI systems, or transport protocols.
The payment protocol consists of three messages; PaymentRequest,
Payment, and PaymentACK, and begins with the customer somehow indicating
that they are ready to pay and the merchant's server responding with a
PaymentRequest message:
[[messages]]
Messages
~~~~~~~~
The Protocol Buffers messages are defined in
link:bip-0070/paymentrequest.proto[paymentrequest.proto].
[[output]]
Output
^^^^^^
Outputs are used in PaymentRequest messages to specify where a payment
(or part of a payment) should be sent. They are also used in Payment
messages to specify where a refund should be sent.
---------------------------------------------
message Output {
optional uint64 amount = 1 [default = 0];
optional bytes script = 2;
}
---------------------------------------------
[cols=",",]
|=======================================================================
|amount |Number of satoshis (0.00000001 BTC) to be paid
|script |a "TxOut" script where payment should be sent. This will
normally be one of the standard Bitcoin transaction scripts (e.g. pubkey
OP_CHECKSIG). This is optional to enable future extensions to this
protocol that derive Outputs from a master public key and the
PaymentRequest data itself.
|=======================================================================
[[paymentdetailspaymentrequest]]
PaymentDetails/PaymentRequest
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Payment requests are split into two messages to support future
extensibility. The bulk of the information is contained in the
PaymentDetails message. It is wrapped inside a PaymentRequest message,
which contains meta-information about the merchant and a digital
signature.
-------------------------------------------------------
message PaymentDetails {
optional string network = 1 [default = "main"];
repeated Output outputs = 2;
required uint64 time = 3;
optional uint64 expires = 4;
optional string memo = 5;
optional string payment_url = 6;
optional bytes merchant_data = 7;
}
-------------------------------------------------------
[cols=",",]
|=======================================================================
|network |either "main" for payments on the production Bitcoin network,
or "test" for payments on test network. If a client receives a
PaymentRequest for a network it does not support it must reject the
request.
|outputs |one or more outputs where Bitcoins are to be sent. If the sum
of outputs.amount is zero, the customer will be asked how much to pay,
and the bitcoin client may choose any or all of the Outputs (if there
are more than one) for payment. If the sum of outputs.amount is
non-zero, then the customer will be asked to pay the sum, and the
payment shall be split among the Outputs with non-zero amounts (if there
are more than one; Outputs with zero amounts shall be ignored).
|time |Unix timestamp (seconds since 1-Jan-1970 UTC) when the
PaymentRequest was created.
|expires |Unix timestamp (UTC) after which the PaymentRequest should be
considered invalid.
|memo |UTF-8 encoded, plain-text (no formatting) note that should be
displayed to the customer, explaining what this PaymentRequest is for.
|payment_url |Secure (usually https) location where a Payment message
(see below) may be sent to obtain a PaymentACK.
|merchant_data |Arbitrary data that may be used by the merchant to
identify the PaymentRequest. May be omitted if the merchant does not
need to associate Payments with PaymentRequest or if they associate each
PaymentRequest with a separate payment address.
|=======================================================================
The payment_url specified in the PaymentDetails should remain valid at
least until the PaymentDetails expires (or as long as possible if the
PaymentDetails does not expire). Note that this is irrespective of any
state change in the underlying payment request; for example cancellation
of an order should not invalidate the payment_url, as it is important
that the merchant's server can record mis-payments in order to refund
the payment.
A PaymentRequest is PaymentDetails optionally tied to a merchant's
identity:
------------------------------------------------------------------
message PaymentRequest {
optional uint32 payment_details_version = 1 [default = 1];
optional string pki_type = 2 [default = "none"];
optional bytes pki_data = 3;
required bytes serialized_payment_details = 4;
optional bytes signature = 5;
}
------------------------------------------------------------------
[cols=",",]
|=======================================================================
|payment_details_version |See below for a discussion of
versioning/upgrading.
|pki_type |public-key infrastructure (PKI) system being used to identify
the merchant. All implementation should support "none", "x509+sha256"
and "x509+sha1".
|pki_data |PKI-system data that identifies the merchant and can be used
to create a digital signature. In the case of X.509 certificates,
pki_data contains one or more X.509 certificates (see Certificates
section below).
|serialized_payment_details |A protocol-buffer serialized PaymentDetails
message.
|signature |digital signature over a hash of the protocol buffer
serialized variation of the PaymentRequest message, with all fields
serialized in numerical order (all current protocol buffer
implementations serialize fields in numerical order) and signed using
the public key in pki_data. Before serialization, the signature field
must be set to an empty value so that the field is included in the
signed PaymentRequest hash but contains no data.
|=======================================================================
When a Bitcoin wallet application receives a PaymentRequest, it must
authorize payment by doing the following:
1. Validate the merchant's identity and signature using the PKI system,
if the pki_type is not "none".
2. Validate that customer's system unix time (UTC) is before
PaymentDetails.expires. If it is not, then the payment request must be
rejected.
3. Display the merchant's identity and ask the customer if they would
like to submit payment (e.g. display the "Common Name" in the first
X.509 certificate).
PaymentRequest messages larger than 50,000 bytes should be rejected by
the wallet application, to mitigate denial-of-service attacks.
[[payment]]
Payment
^^^^^^^
Payment messages are sent after the customer has authorized payment:
-----------------------------------------
message Payment {
optional bytes merchant_data = 1;
repeated bytes transactions = 2;
repeated Output refund_to = 3;
optional string memo = 4;
}
-----------------------------------------
[cols=",",]
|=======================================================================
|merchant_data |copied from PaymentDetails.merchant_data. Merchants may
use invoice numbers or any other data they require to match Payments to
PaymentRequests. Note that malicious clients may modify the
merchant_data, so should be authenticated in some way (for example,
signed with a merchant-only key).
|transactions |One or more valid, signed Bitcoin transactions that fully
pay the PaymentRequest
|refund_to |One or more outputs where the merchant may return funds, if
necessary. The merchant may return funds using these outputs for up to 2
months after the time of the payment request. After that time has
expired, parties must negotiate if returning of funds becomes necessary.
|memo |UTF-8 encoded, plain-text note from the customer to the merchant.
|=======================================================================
If the customer authorizes payment, then the Bitcoin client:
1. Creates and signs one or more transactions that satisfy (pay in
full) PaymentDetails.outputs
2. Validate that customer's system unix time (UTC) is still before
PaymentDetails.expires. If it is not, the payment should be cancelled.
3. Broadcast the transactions on the Bitcoin p2p network.
4. If PaymentDetails.payment_url is specified, POST a Payment message
to that URL. The Payment message is serialized and sent as the body of
the POST request.
Errors communicating with the payment_url server should be communicated
to the user. In the scenario where the merchant's server receives
multiple identical Payment messages for an individual PaymentRequest, it
must acknowledge each. The second and further PaymentACK messages sent
from the merchant's server may vary by memo field to indicate current
state of the Payment (for example number of confirmations seen on the
network). This is required in order to ensure that in case of a
transport level failure during transmission, recovery is possible by the
Bitcoin client re-sending the Payment message.
PaymentDetails.payment_url should be secure against man-in-the-middle
attacks that might alter Payment.refund_to (if using HTTP, it must be
TLS-protected).
Wallet software sending Payment messages via HTTP must set appropriate
Content-Type and Accept headers, as specified in BIP 71:
-----------------------------------------
Content-Type: application/bitcoin-payment
Accept: application/bitcoin-paymentack
-----------------------------------------
When the merchant's server receives the Payment message, it must
determine whether or not the transactions satisfy conditions of payment.
If and only if they do, if should broadcast the transaction(s) on the
Bitcoin p2p network.
Payment messages larger than 50,000 bytes should be rejected by the
merchant's server, to mitigate denial-of-service attacks.
[[paymentack]]
PaymentACK
^^^^^^^^^^
PaymentACK is the final message in the payment protocol; it is sent from
the merchant's server to the bitcoin wallet in response to a Payment
message:
-------------------------------------
message PaymentACK {
required Payment payment = 1;
optional string memo = 2;
}
-------------------------------------
[cols=",",]
|=======================================================================
|payment |Copy of the Payment message that triggered this PaymentACK.
Clients may ignore this if they implement another way of associating
Payments with PaymentACKs.
|memo |UTF-8 encoded note that should be displayed to the customer
giving the status of the transaction (e.g. "Payment of 1 BTC for eleven
tribbles accepted for processing.")
|=======================================================================
PaymentACK messages larger than 60,000 bytes should be rejected by the
wallet application, to mitigate denial-of-service attacks. This is
larger than the limits on Payment and PaymentRequest messages as
PaymentACK contains a full Payment message within it.
[[localization]]
Localization
~~~~~~~~~~~~
Merchants that support multiple languages should generate
language-specific PaymentRequests, and either associate the language
with the request or embed a language tag in the request's merchant_data.
They should also generate a language-specific PaymentACK based on the
original request.
For example: A greek-speaking customer browsing the Greek version of a
merchant's website clicks on a "Αγορά τώρα" link, which generates a
PaymentRequest with merchant_data set to "lang=el&basketId=11252". The
customer pays, their bitcoin client sends a Payment message, and the
merchant's website responds with PaymentACK.message "σας ευχαριστούμε".
[[certificates]]
Certificates
~~~~~~~~~~~~
The default PKI system is X.509 certificates (the same system used to
authenticate web servers). The format of pki_data when pki_type is
"x509+sha256" or "x509+sha1" is a protocol-buffer-encoded certificate
chain:
---------------------------------------
message X509Certificates {
repeated bytes certificate = 1;
}
---------------------------------------
If pki_type is "x509+sha256", then the PaymentRequest message is hashed
using the SHA256 algorithm to produce the message digest that is signed.
If pki_type is "x509+sha1", then the SHA1 algorithm is used.
Each certificate is a DER [ITU.X690.1994] PKIX certificate value. The
certificate containing the public key of the entity that digitally
signed the PaymentRequest must be the first certificate. This MUST be
followed by additional certificates, with each subsequent certificate
being the one used to certify the previous one, up to (but not
including) a trusted root authority. The trusted root authority MAY be
included. The recipient must verify the certificate chain according to
[RFC5280] and reject the PaymentRequest if any validation failure
occurs.
Trusted root certificates may be obtained from the operating system; if
validation is done on a device without an operating system, the
http://www.mozilla.org/projects/security/certs/included/index.html[Mozilla
root store] is recommended.
[[extensibility]]
Extensibility
~~~~~~~~~~~~~
The protocol buffers serialization format is designed to be extensible.
In particular, new, optional fields can be added to a message and will
be ignored (but saved/re-transmitted) by old implementations.
PaymentDetails messages may be extended with new optional fields and
still be considered "version 1." Old implementations will be able to
validate signatures against PaymentRequests containing the new fields,
but (obviously) will not be able to display whatever information is
contained in the new, optional fields to the user.
If it becomes necessary at some point in the future for merchants to
produce PaymentRequest messages that are accepted *only* by new
implementations, they can do so by defining a new PaymentDetails message
with version=2. Old implementations should let the user know that they
need to upgrade their software when they get an up-version
PaymentDetails message.
Implementations that need to extend messages in this specification shall
use tags starting at 1000, and shall update the
link:bip-0070/extensions.mediawiki[extensions page] via pull-req to
avoid conflicts with other extensions.
[[references]]
References
~~~~~~~~~~
link:bip-0071.mediawiki[BIP 0071] : Payment Protocol mime types
link:bip-0072.mediawiki[BIP 0072] : Payment Protocol bitcoin: URI
extensions
Public-Key Infrastructure (X.509) working group :
http://datatracker.ietf.org/wg/pkix/charter/
Protocol Buffers : https://developers.google.com/protocol-buffers/
[[see-also]]
See Also
~~~~~~~~
Javascript Object Signing and Encryption working group :
http://datatracker.ietf.org/wg/jose/
Wikipedia's page on Invoices: http://en.wikipedia.org/wiki/Invoice
especially the list of Electronic Invoice standards
sipa's payment protocol proposal: https://gist.github.com/1237788
ThomasV's "Signed Aliases" proposal : http://ecdsa.org/bitcoin_URIs.html
Homomorphic Payment Addresses and the Pay-to-Contract Protocol :
http://arxiv.org/abs/1212.3257