Merge pull request #767 from braydonf/docs/payment-protocol

Docs: Payment Protocol
This commit is contained in:
Esteban Ordano 2014-12-16 18:39:21 -03:00
commit 8eb7b010ea
1 changed files with 179 additions and 0 deletions

179
docs/PaymentProtocol.md Normal file
View File

@ -0,0 +1,179 @@
# Payment Protocol
`PaymentProtocol` and associated functions and methods will serialize, deserialize, sign and verify payment protocol messages both in Node.js and web browsers. Both X.509 and [bitcoin identity protocol](https://en.bitcoin.it/wiki/Identity_protocol_v1) are supported. For detailed technical information, please view [BIP70](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki).
```javascript
var bitcore = require('bitcore');
var PaymentProtocol = bitcore.PaymentProtocol;
```
## Make Payment Details
Here the merchant's server will construct the payment details message:
```javascript
var now = Date.now() / 1000 | 0;
// construct the payment details
var details = new PaymentProtocol().makePaymentDetails();
details.set('network', 'test');
details.set('outputs', outputs);
details.set('time', now);
details.set('expires', now + 60 * 60 * 24);
details.set('memo', 'A payment request from the merchant.');
details.set('payment_url', 'https://localhost/-/pay');
details.set('merchant_data', new Buffer({size: 7})); // identify the request
```
For more information about these fields please visit [BIP70](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki#paymentdetailspaymentrequest)
## Sign a Payment Request
The merchant's server will then construct a payment request and send it to the customer:
```javascript
// load the X509 certificate
var certificates = new PaymentProtocol().makeX509Certificates();
certificates.set('certificate', [<file_of_x509_der_cert>]);
// form the request
var request = new PaymentRequest().makePaymentRequest();
request.set('payment_details_version', 1);
request.set('pki_type', 'x509+sha256');
request.set('pki_data', certificates.serialize());
request.set('serialized_payment_details', details.serialize());
request.sign(<file_of_x509_private_key>);
// serialize the request
var rawbody = request.serialize();
// Example HTTP Response Headers:
// Content-Type: PaymentProtocol.PAYMENT_REQUEST_CONTENT_TYPE
// Content-Length: request.length
// Content-Transfer-Encoding: 'binary'
```
## Verify a Payment Request
The customers wallet would then verify the payment request as follows (after asking for the payment request message):
```javascript
// Example HTTP Request Headers:
// Method: GET
// Accept: PaymentProtocol.PAYMENT_REQUEST_CONTENT_TYPE, PaymentProtocol.PAYMENT_ACK_CONTENT_TYPE
// Content-Type: 'application/octet-stream'
// Content-Length: 0
var body = PaymentProtocol.PaymentRequest.decode(rawbody);
var request = new PaymentProtocol().makePaymentRequest(body);
var version = pr.get('payment_details_version');
var pki_type = pr.get('pki_type');
var pki_data = pr.get('pki_data');
var serializedDetails = pr.get('serialized_payment_details');
var signature = pr.get('signature');
// Verify the signature
var verified = request.verify();
// Get the payment details
var decodedDetails = PaymentProtocol.PaymentDetails.decode(serializedDetails);
var details = new PaymentProtocol().makePaymentDetails(decodedDetails);
var network = details.get('network');
var outputs = details.get('outputs');
var time = details.get('time');
var expires = details.get('expires');
var memo = details.get('memo');
var payment_url = details.get('payment_url');
var merchant_data = details.get('merchant_data');
```
## Send a Payment
After the request is verified a payment can be sent to the merchant, from the customer's wallet:
```javascript
// send the payment transaction
var payment = new PaymentProtocol().makePayment();
payment.set('merchant_data', merchant_data);
payment.set('transactions', [<transaction_with_outputs>]); // as from payment details
// define the refund outputs
var refund_outputs = [];
var outputs = new PaymentProtocol().makeOutput();
outputs.set('amount', 0);
outputs.set('script', script.toBuffer()); // an instance of script
refund_outputs.push(outputs.message);
payment.set('refund_to', refund_outputs);
payment.set('memo', 'Here is a payment');
// serialize and send
var rawbody = pay.serialize();
// Example Request Headers:
// Method: 'POST',
// Accept: PaymentProtocol.PAYMENT_REQUEST_CONTENT_TYPE, PaymentPrococl.PAYMENT_ACK_CONTENT_TYPE
// Content-Type: PaymentProtocol.PAYMENT_CONTENT_TYPE
// Content-Length: payment.length
// Content-Transfer-Encoding: 'binary'
```
## Receive a Payment
The merchant would then receive the payment as follows:
```javascript
var body = PaymentProtocol.Payment.decode(rawbody);
var payment = new PaymentProtocol().makePayment(body);
var merchant_data = payment.get('merchant_data');
var transactions = payment.get('transactions');
var refund_to = payment.get('refund_to');
var memo = payment.get('memo');
// send the transaction to the bitcoin network
```
## Send a Payment Acknowledgement
After the payment has been broadcasted, a payment acknowledgement can be sent in response:
```javascript
// make a payment acknowledgement
var ack = new PaymentProtocol().makePaymentACK();
ack.set('payment', payment.message);
ack.set('memo', 'Thank you for your payment!');
var rawbody = ack.serialize();
// Example Response Headers:
// Content-Type: PaymentProtocol.PAYMENT_ACK_CONTENT_TYPE
// Content-Length: ack.length
// Content-Transfer-Encoding: 'binary'
```
## Receive an Acknowledgement
The customer's wallet can then receive an acknowledgement of payment as follows:
```javascript
var body = PaymentProtocol.PaymentACK.decode(rawbody);
var ack = new PaymentProtocol().makePaymentACK(body);
var serializedPayment = ack.get('payment');
var memo = ack.get('memo');
var decodedPayment = PaymentProtocol.Payment.decode(serializedPayment);
var payment = new PaymentProtocol().makePayment(decodedPayment);
var tx = payment.message.transactions[0];
```
For detailed diagram of the exchange of messages, please see the [Protocol section of BIP70](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki#protocol).