From b0afd7d93fd851ddd31cacc11ea22aa0b4c0f6cd Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Tue, 16 Dec 2014 12:19:23 -0500 Subject: [PATCH] Docs: Added general Payment Protocol documentation --- docs/PaymentProtocol.md | 179 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 docs/PaymentProtocol.md diff --git a/docs/PaymentProtocol.md b/docs/PaymentProtocol.md new file mode 100644 index 000000000..7acb5f6ad --- /dev/null +++ b/docs/PaymentProtocol.md @@ -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', []); + +// 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(); + +// 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', []); // 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). \ No newline at end of file