payments integration guide integration guid… · integration burden of managing payment coins....

20
Payments Integration guide (Draft v0.5.6 2019-03-20) By Ricky Rand - Carrot ® © RMP Protection Ltd. Introduction This integration guide describes how a web Merchant may; request a payment from a Bitcoin-express web Wallet, verify the payment Coins, and return a payment acknowledgement. We include the essential elements for a full integration using any back-end system, and compare this with the use of a Merchant Gateway. System components Component name Description Wallet loader (BitcoinExpress.js) A Javascript module to be included on any web page that wishes to accept Bitcoin-express payments or display a Bitcoin-express Client Wallet. It is the means by which a buyer gets to access to 1 of 20

Upload: others

Post on 04-May-2020

12 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Payments Integration guide Integration Guid… · integration burden of managing payment Coins. Public Merchant Gateway A public service that reduces the back-end integration burden

Payments Integration guide(Draft v0.5.6 2019-03-20) By Ricky Rand - Carrot®

© RMP Protection Ltd.

IntroductionThis integration guide describes how a web Merchant may; request a payment from a Bitcoin-express web Wallet, verify the payment Coins, and return a payment acknowledgement.

We include the essential elements for a full integration using any back-end system, and compare this with the use of a Merchant Gateway.

System components

Component name Description

Wallet loader(BitcoinExpress.js)

A Javascript module to be included on any web page that wishes to accept Bitcoin-express payments or display a Bitcoin-express Client Wallet. It is the means by which a buyer gets to access to

1 of 20

Page 2: Payments Integration guide Integration Guid… · integration burden of managing payment Coins. Public Merchant Gateway A public service that reduces the back-end integration burden

their selected Wallet. When activated, the Wallet is shown as an overlay directly on the Merchant's sales page.

Wallet Supplier The domain where Bitcoin-express Wallet software will be fetched (e.g. bitcoin-e.org).

Merchant A Web site that accepts Bitcoin-express payments. Each merchant must include the BitcoinExpress.js library if they wish to receive payments from browser based Web Wallets.To receive payments from device resident Wallet's only, the bitcoin-e: uri method may be used in place of the JS library (not described here).

Client Browser A buyer may select their preferred Wallet whilst initially visiting the merchant's site and this causes the selected Wallet to be loaded into an iframe from the supplier's domain.Note: The browser enforces cross-domain rules to restrict the host site directly accessing Coins in the Wallet. Only the Wallet is able to access Coins that are stored with the same domain wherethe Wallet was fetched.

Coins Digital cash tokens that represent cryptocurrency funds.

Issuer α A Bitcoin-express service favoured by the buyer where α Coins are issued, verified and redeemed.

Issuer β A Bitcoin-express service favoured by the seller where β Coins are issued, verified and redeemed.

Private Merchant Gateway

A locally run Node.js based gateway that reduces the back-end integration burden of managing payment Coins.

Public Merchant Gateway

A public service that reduces the back-end integration burden of managing payment Coins.

Basic protocolThe Bitcoin-express Payment protocol (v1) is facilitated by the passing of Json objects between a seller and a buyer's Wallet. The PaymentRequest Json object allows a seller toprecisely describe the values and conditions of an 'offer to sell', and the buyer's Walletwill interpret the offer and respond with a Payment object containing suitable payment Coins. Finally, the seller will acknowledge receipt of the payment with a PaymentAck json object.

Please see Bitcoin-express Payment specification for full details.

We will also show how using a Merchant Gateway can simplify the process while at thesame time provide maximum safety and security.

2 of 20

Page 3: Payments Integration guide Integration Guid… · integration burden of managing payment Coins. Public Merchant Gateway A public service that reduces the back-end integration burden

1. Initiating a payment request• Include the following script on each sales page:

<script src="https://bitcoin-e.org/js/vendor/BitcoinExpress.js"></script>

• Provide a Buy button of your choice to trigger a call to the BitcoinExpress library. This library uses Promises to manage the asynchronous nature of a payment.

Example:

BitcoinExpress.Wallet.PaymentRequest(payment_details_object).then(function(container) { window.location.replace(container.PaymentAck.return_url);}).catch(function(err) { alert("Payment failed because "+err);});

The payment_details_object is a plain Json object containing fields that describethe details of a specific payment request matching an 'offer to sell'. Below is a typical example of PaymentDetails. A complete list of all possible fields is described in the 'Payments specification'.

Example:

let payment_details_object = {

3 of 20

Page 4: Payments Integration guide Integration Guid… · integration burden of managing payment Coins. Public Merchant Gateway A public service that reduces the back-end integration burden

"currency": "XBT", "amount": "0.00123", "description": "Monthly subscription to jTunes", "acceptable_issuers": ["*.carrotpay.com"], "order_id": "ref123456", "payment_url": "https://merchantSite.com/payments/bitcoin-express"}

• The currency field indicates the currency of the request.• The amount field indicates the total amount to be paid.• The description field is a short description of the product or service

being sold.• The acceptable_issuers field describes the list of Issuers domains that

this Merchant is willing to accept Coins from. In this example the "*" indicates any Issuer from the carrotpay.com group.

• The order_id field will be passed along with the payment Coins and may be anything that helps a Merchant identify a particular sale.

• The payment_url should link to an endpoint on the Merchant's back-end server that will accept a Payment object containing Coins. The Payment object will also contain a wallet_id generated by the Wallet and a copy ofthe order_id to aid the Merchant with the management of this sale.

… when using a Gateway

When using a Merchant Gateway, the PaymentDetails object is constructed by the Gateway using configuration settings and values passed to /transactions. The payment_details element of the Json object returned from /transactions may then be used directly in place of the payment_details_object used in the example above.

A Gateway typically adds a transaction_id to the PaymentDetails, which it used to track individual payments across all accounts registered on the Gateway. This id may be used in the path of the payment_url and if also present in the PaymentDetails, it too will be echoed in the Payment object.

The payment_url will point to the Gateway rather than the Merchant's own site, so the Gateway also adds a seller element to the PaymentDetails and this prompts the buyer's Wallet to display the seller's domain name to make it easier for the buyer to recognise who will ultimately receive the payment funds.

2. Validate the payment CoinsThe Merchant's payment endpoint (in our example "https://merchant.com/payments/bitcoin-express"), will receive a Payment json object containing Coins having a sum value of the requested amount and currency. These Coins should be sent for verification at the

4 of 20

Page 5: Payments Integration guide Integration Guid… · integration burden of managing payment Coins. Public Merchant Gateway A public service that reduces the back-end integration burden

Merchant's Home Issuer. In order for this to be done safely for both the buyer and theMerchant, the Merchant should perform the following steps:

1 Recover the product or service being sold using either; parameters from the payment_url or (as in our example) using Payment.order_id, which will typically be a sales reference of some sort (e.g. invoice number).

1.1 If the sale cannot be identified, returnPaymentAck.status = "rejected"

2 Check that the face value of the Coins received is sufficient to pay for the sale.

2.1 If the face value of the Coins is insufficient, returnPaymentAck.status = "failed"

See Appendix A for a method of calculating the face value of a list of Coins. NOTE payment Coins should only be verified when the face value appears to be sufficient.

3 Persist the Payment object.

4 Call /begin at the Home Issuer to obtain a transaction id ( tid ).

5 Call /verify at the Home Issuer sending the tid and Coins received in the Payment object. The Issuer will return an issuerResponse Json object (see Issuer specification for full details). The issuer response will indicate the actual value of the Coins in the verifyInfo Json object, together with the fee etc. The actual value is expected to be the same as the computed face value.

...when using a Gateway

Steps 1 to 5 are automatically performed by the Gateway.

The Gateway will be able to identify the specific payment using the unique transaction_id and Coins will be validated according to the currency and amount provided to /transactions. See the next section on 'Using a Merchant Gateway' for further details.

3. Acknowledge the payment 6 Construct a PaymentAck ready to return to the buyer. Check

issuerResponse.verifyInfo.actualValue to ensure that the received value is sufficient to pay for the product.

6.1 If ( actualValue ≥ product cost ) set PaymentAck.status = "ok" and set PaymentAck.return_url and/or PaymentAck.notification to a suitable value. Persist the returned Coins from issuerResponse.coin[].

5 of 20

Page 6: Payments Integration guide Integration Guid… · integration burden of managing payment Coins. Public Merchant Gateway A public service that reduces the back-end integration burden

6.2 If ( actualValue < product cost ) set PaymentAck.status = "failed" and set PaymentAck.coins[] to issuerResponse.coin[] if it is not empty. In this way, the buyer will have their payment Coins returned to them.

It may also be beneficial to the buyer, if the error object returned by the Issuer is passed on to the buyer's Wallet through the PaymentAck.

6.3 If a malformed response is received, or no response is received within a specific time budget (see Payment specification PaymentDetails.time_budget), set PaymentAck.status to failed or deferred depending on the nature of the error.

7 Call /end with a tid to the Home Issuer to close the transaction.

...when using a Gateway

Steps 6 and 7 are automatically performed by the Gateway.

Responding to a successful paymentAn appropriate response to a successful payment will largely depend on what exactly has been sold. Broadly there are two classes of sale; 1) digital items that are delivered immediately and 2) entitlements for goods or services that will be delivered over time, or through some means other than the browser (i.e. physical goods).

The immediate delivery of a digital item is best achieved by returning a custom return_url where the sales page links to a new location where the buyer's item may be collected.

BitcoinExpress.Wallet.PaymentRequest(payment_details_object).then(function(container) {

window.location.replace(container.PaymentAck.return_url);

}).catch(function(err) { alert("Payment failed because "+err);});

There are many ways that this can be done in practice, but the example above is probably the most direct.

When the payment is for an entitlement (such as a subscription), the seller may simplywish to acknowledge that the payment has been successful, which can be achieved by sending a notification in the PaymentAck. In this case the Wallet will record and display the notification and the sales page may also display the notification on the page or in an overlay window etc. The sales page may leave the Wallet open or force itto close as it sees fit.

6 of 20

Page 7: Payments Integration guide Integration Guid… · integration burden of managing payment Coins. Public Merchant Gateway A public service that reduces the back-end integration burden

BitcoinExpress.Wallet.PaymentRequest(payment_details_object).then(function(container) {

alert(container.PaymentAck.notification);

}).catch(function(err) { alert("Payment failed because "+err);});

Note: We don't actually recommend you use alerts to signal to your customers, it's just a simple way for us to demonstrate the principal.

Using a Merchant GatewayWhen using a Merchant Gateway the process is greatly simplified. The seller simply uses the /transactions endpoint at their chosen Gateway supplier to POST the specifics of a sale. The gateway will merge the Merchant's configuration settings before returning a PaymentDetails Json object for attachment to a suitable Buy button on the sales page.

7 of 20

Page 8: Payments Integration guide Integration Guid… · integration burden of managing payment Coins. Public Merchant Gateway A public service that reduces the back-end integration burden

The Merchant Gateway will merge the specifics of a particular payment request with the settings data held by the gateway on behalf of the Merchant. For example:

Suppose the parameters sent to [POST]/transactions are:

{ "amount": "0.002", "description": "Monthly subscription", "notification": "Thank you. Monthly subscription now paid in full.", "order_id": "999264"}

And the relevant settings data is as follows:

domain "FutureTV.com"

home_issuer "eu.carrotpay.com"

default_payment_timeout "300"

default_payment_currency "BCH"

email_customer_contact "[email protected]"

provide_receipt_via_email true

provide_refund_via_email false

return_url "https://FutureTV.com/BE/confirmation"

The result of calling [POST]/transactions will be a json object something like this:

{ "success":true, "body":[{

..."payment_details": {

"amount":"0.002", "currency":"BCH",

"description":"Monthly subscription","order_id":"999264","expires":"2018-10-18T23:14:39.429Z","time":"2018-10-18T23:09:39.429Z","seller":"FutureTV.com","transaction_id":"e3891860-d32a-11e8-933e-d1a653d6c6c6","acceptable_issuers":["(eu.carrotpay.com)"],"email_customer_contact":"[email protected]","payment_url":"https://gw.eu.carrotpay.com/v1/transactions/e389...6c6c6/payment","polices":{

"receipt_via_email":true,"refund_via_email":false

}},...

}]}

8 of 20

Page 9: Payments Integration guide Integration Guid… · integration burden of managing payment Coins. Public Merchant Gateway A public service that reduces the back-end integration burden

On the sales page, it can be arranged that a payment request be triggered by attaching the PaymentDetails object to a button, something like this:

Line Code

1 document.getElementById("payment_button").

2 addEventListener('click', function() {

3 BitcoinExpress.Wallet.PaymentRequest(result.body[0].payment_details).

4 then(function(container) {

5 window.location.replace(container.PaymentAck.return_url);

6 }).

7 catch(function(err) {

8 console.log("PaymentRequest error returned ", err);

9 });

10 });

Lines 1&2: Is a typical example of how to attach a click event to an element with id=payment_button. Many other methods are equally valid.

Line 3: When clicked, the button triggers a call to the BitcoinExpress library1, passing the PaymentDetails exactly as it was returned from the Merchant Gateway.

The buyer's Wallet will then take over, display the sales details, wait for confirmation from the buyer and then send payment Coins to the payment_url, which points to an endpoint on the Merchant Gateway site.

When /transactions was called at the beginning of the process, the Merchant Gateway immediately had all the information it needed to receive, verify and store payment Coins on behalf of the seller. Therefore, as soon as a Payment is received at the payment_url, it is processed and a PaymentAck Json object is then created and returned. The returned PaymentAck is first passed to the buyer's Wallet where the payment details are recorded, then passed to the host sales page so that the seller can finalise the sale.

Line 4: The PaymentAck is wrapped in a container and passed to the function defined in the .then() clause of the promise. The PaymentAck will typically have a return_url that may be used to jump to a 'Thank you' page. Many other scenarios are equally valid.

Line 8: If there is an error during the payment, control will pass to the function definedin the .catch() clause of the promise.

1 Included like this: <script src="https://bitcoin-e.org/js/vendor/BitcoinExpress.js"></script>

9 of 20

Page 10: Payments Integration guide Integration Guid… · integration burden of managing payment Coins. Public Merchant Gateway A public service that reduces the back-end integration burden

A worked exampleLet's suppose that FutureTV LTD. (FTV) sells a subscription service for viewing TV seriesBox sets online, and wants to provide an option for its customers to pay using a cryptocurrency. FTV wants to trial the new Bitcoin-express payment system as soon aspossible and so decides to use a public Merchant Gateway from a local supplier.

After registration with 'Crypto Gateway Ltd.', FTV receives an authentication token and securely adds it to its back-end process ready to create a new buy button during check-out. When a customer next goes to pay their monthly subscription they will see a new payment option. The new button style is entirely up to FTV.

To create the new button on the sales page, FTV does 3 things; 1) prepares the billing information, 2) creates a payment request at the Gateway and 3) adds the buy button to the page.

Step 1: Preparing the billing information

When setting up the configuration for Bitcoin-express payments, FTV is able to select aHome Issuer. By default, Crypto Gateway Ltd. will use its own preferred Issuer but FTVmay change this at any time. If the Home Issuer supports FTV's natural billing currency(i.e. EUR), then payments may be requested in that currency, otherwise FTV must select an alternative payment currency and exchange that currency at a later date. In this case the default Home Issuer of Crypto Gateway Ltd. does not support EUR so FTV

10 of 20

Page 11: Payments Integration guide Integration Guid… · integration burden of managing payment Coins. Public Merchant Gateway A public service that reduces the back-end integration burden

selects Bitcoin2 as the payment currency.

Having chosen to request and accumulate Bitcoin, FTV must calculate the equivalent BTC for the billing amount of EUR 4.99. There are many sources where up-to-date exchange rates may be obtained and FTV should select the supplier they most trust, which is probably the supplier they also use when exchanging BTC for EUR.

Get the EUR to BTC exchange rate

For example rates may be obtained from coinmarketcap.com like this:

https://api.coinmarketcap.com/v1/ticker/?convert=EUR

This will return a Json object containing various rates including BTC to EUR, which can be used to determine exactly how much BTC to charge.

Let's assume EUR4.99 is equivalent to BTC 0.00088900 and the sale will be described as “Monthly subscription”.

Step 2: Create a payment request at the Gateway

To create a payment request, the FTV back-end process will call [POST]/transactions atthe Merchant Gateway service supplied by Crypto Gateway Ltd. This endpoint also requires that the Merchant's authentication token be added to the http request header “BE-MG-Auth-Token:”

Suppose FTV uses the following parameters in the body of the POST:{ "type": "payment", "amount": "0.000889", "description": "Monthly subscription", "notification": "Monthly subscription now paid in full.", "order_id": "999264"}

• type must be set to “payment” to create a PaymentRequest• amount as calculated from the EUR to BTC exchange rate.• description will be displayed to the buyer at the point of sale.• notification will be displayed to the buyer upon a successful payment.• order_id will be carried along with the payment and may be referenced by FTV

or the buyer at a future time. In this case FTV has chosen to use its standard invoice number, which is knows will be unique.

2 Although FTV will accumulate Bitcoin through the sales process, it can minimise exchange risk by moving the Bitcoin to a crypto exchange of its choice and converting to Euro. FTV may do this as frequently as it wishes, being mindful only of the Bitcoin miner fees.

11 of 20

Page 12: Payments Integration guide Integration Guid… · integration burden of managing payment Coins. Public Merchant Gateway A public service that reduces the back-end integration burden

Note: No currency or return_url was included. This is because FTV had previously set up the default payment currency3 and return url (along with various other options), and these settings will be merged with the specific payment parameters to create a fully compliant PaymentDetails Json object.

Example

curl -H "BE-MG-Auth-Token: <auth_token>"-H "Accept: application/json" -H "Content-type: application/json"-d {"amount":"0.000889", "description":"Monthly subscription", "notification":"Monthly subscription now paid in full.", "order_id":"999264"}"https://crypto-gateway.com/v1/transactions"

Step 3: Add a buy button to the html page

The response from [POST]/transactions is a Json object containing a body element which is an array of objects. The first element of this array as a PaymentDetails object which can easily be added to the script of an html page as previously shown.

Example{ "body" : [ { "payment_details" : { "amount":"0.00088900", "currency":"XBT", "description":"Monthly subscription", "order_id":"999264", "expires":"2018-10-11T23:14:39.429Z", "time":"2018-10-11T23:09:39.429Z", "seller":"FutureTV.com", "email_customer_contact":"[email protected]", "payment_url": "https://crypto-gateway.com/v1/transaction/e38...c6c6/payment", "polices":{ "receipt_via_email":true, "refund_via_email":false, "issuer_refund_via_email":true }, "transaction_id":"e3891860-d32a-11e8-933e-d1a653d6c6c6", "acceptable_issuers":["(eu.carrotpay.com)"] } } ]}

3 In actual fact Bitcoin-express uses the ISO standard currency identifier “XBT” to represent Bitcoin, rather that the more traditional “BTC” which is not standards compliant.

12 of 20

Page 13: Payments Integration guide Integration Guid… · integration burden of managing payment Coins. Public Merchant Gateway A public service that reduces the back-end integration burden

Assuming that the button on the sales page has an id of "be_button", the payment request can be triggered using the following script.

Example

document.getElementById("be_button") .addEventListener('click', function () { BitcoinExpress.Wallet.PaymentRequest(result.body[0].payment_details) .then(function(container) { //continue from here after payment }) .catch(function(err) { //continue from here after error });});

Buyer's perspectiveWhen the buyer clicks the Bitcoin-express payment button, their Wallet will be displayed4 as an overlay on the the html page.

There are several things worth noting. The most obvious thing is that the buyer must actively CONFIRM PAYMENT before Coins can be sent to FTV. If confirmed the total amount to be deducted from the Wallet will be BTC 0.00089142.

4 The buyer may first need to select their Wallet supplier if they have not recently visited the FTV site. They may also need to provide a password if they previously set up password protection.

13 of 20

Page 14: Payments Integration guide Integration Guid… · integration burden of managing payment Coins. Public Merchant Gateway A public service that reduces the back-end integration burden

The buyer may easily check the EUR amount by clicking the bank symbol in the bottom right corner.

The Wallet now shows the approximate amount of the sale in the buyer's base currency (being EUR in this case). The 'Amount' is as expected but there is also a small 'Split fee' which the buyer must pay to their Home Issuer in order to prepare the exactCoins for the payment.

Things to note about each line item presented by the Wallet.

Line item title Description

Payment to: This is the domain where payment Coins will be sent. As FTV is using a public Merchant Gateway, payment Coins will be sent there for verification. 'crypto-gateway.com' is extracted from PaymentDetails.payment_url.The inclusion of a green lock icon after the domain indicates that the Wallet is sure that Coins will be sent to this domain.

Seller: The Gateway also included a seller in the PaymentDetails to indicate who the payment is ultimately intended for.The inclusion of a red unlock icon after the seller's domain indicates that the Wallet cannot confirm that Coins will ultimately be passed to

14 of 20

Page 15: Payments Integration guide Integration Guid… · integration burden of managing payment Coins. Public Merchant Gateway A public service that reduces the back-end integration burden

this domain.

For: This matches exactly with the description item that was passed to /transactions.

Amount: The amount passed to the Wallet in PaymentDetails.amount together with the currency passed in PaymentDetails.currency.Note: In this case the user's Wallet settings cause the XBT currency to be displayed as BTC.

Split fee: If the Wallet does not have the exact change to make up the amount needed, it must first split one of its Coins (at its Home Issuer) for which there is a small fee.

Billed as: Is the total amount that will be deducted from the Wallet if the payment is confirmed. It is simply the billing amount plus the split fee.

Expires: This is a count-down clock that shows the buyer exactly how long theyhave to complete the payment. The Merchant may explicitly set the time when calling [POST]/transactions, otherwise the Gateway will automatically set it according to the configuration value of default_payment_timeout. Ultimately, the expiry period is passed to the Wallet in PaymentDetails.expires.

This field can be used to minimise exchange drift or to make time limited offers. Once a payment request has actually expired, the html page must be reloaded in order to obtain a revised version of the payment request. As FTV is calculating the Bitcoin price from the EUR exchange rate, it's likely the Bitcoin amount will differ slightly each time the page is loaded.

Include If PaymentDetails.options.receipt_via_email is true, the buyer may click the check box to request a receipt be sent via email. If clicked thebuyer's email address will be sent to FTV in the Payment object. As FTV provides a subscription service it's likely they already have the buyer'semail address, but in other situations this can be an easy way for a seller to obtain the buyer's email without the need for the buyer to explicitly entered it on the sales page.

Note: This option will only become active if the buyer has previously entered their email address into the Wallet settings.

15 of 20

Page 16: Payments Integration guide Integration Guid… · integration burden of managing payment Coins. Public Merchant Gateway A public service that reduces the back-end integration burden

Confirming paymentOnce the buyer confirms the payment, the Wallet constructs a Payment object and sends it to the address defined in PaymentDetails.payment_url - which is on the Gateway site. The Gateway automatically verifies the Coins, records the transaction and returns a PaymentAck to the Wallet. The Wallet first adds the payment details to its history and displays the notification before returning control to the function defined in the .then( ) of the PaymentRequest promise.

Example

var handlePaymentAck = function(container) { ... };var handlePaymentError = function(err) { ... };

document.getElementById("be_button").addEventListener('click', function () { BitcoinExpress.Wallet.PaymentRequest(payment_details) .then(handlePaymentAck) .catch(handlePaymentError);});

The handlePaymentAck function can do anything it wants on the sales page. In this case the script disables the buy buttons updates the text on the page.

Notice that the sales page has dimmed and disabled the two buy buttons and displays “PAID” in place of the original “Pay now”.

16 of 20

Page 17: Payments Integration guide Integration Guid… · integration burden of managing payment Coins. Public Merchant Gateway A public service that reduces the back-end integration burden

If there is a need to pass additional data to a successful sales page, this can be done through the 'ack_passthrough' parameter when creating the original PaymentRequest. The Wallet can also be forcibly closed by calling BitcoinExpress.Wallet.close().

When left open, the Wallet displays the notification text originally sent to [POST]/transactions and reminds the buyer how much was actually paid to the seller. A link is also provided to access the return_url through the “link to item” element. In this case the element links to a simple confirmation page but in other situations it may be a product download page etc.

The Wallet also records details of the purchase which may be viewed at any time.

Finalising a saleOnce the Wallet has persisted the purchase information, control is normally returned to a function on the sales page – as we have already seen. The function that takes control may then signal to the FTV back-end that the payment has been successful (probably using xhr), or by automatically calling the return_url. However, under error conditions (e.g. inopportune loss of power to the buyer's browser), it's possible that the function will never be called and so FTV will not notice that a sale has been successfully completed. For this reason the Merchant Gateways also offers the option of a callback that will automatically be triggered upon the completion of every successful sale.

Just like the return_url, a callback_url can be configured in the gateway settings, and this too will have the transaction_id and the order_id, automatically appended to it. If

17 of 20

Page 18: Payments Integration guide Integration Guid… · integration burden of managing payment Coins. Public Merchant Gateway A public service that reduces the back-end integration burden

FTV wishes to use this feature they will obviously have to arrange to receive calls at thecallback address, then use the transaction_id or order_id to determine which sale hascompleted.

The final step is for the back-end to confirm the status of the sale using either [GET]transaction/{transaction_id} or the [GET]/order/{order_id}. If the resulting Json object includes "status":"resolved", the seller can be sure that the full payment has already been received.

Example

curl -k -H "Accept:application/json" -H "BE-MG-Auth-Token:<auth_token>" "https://crypto-gateway.com/v1/transaction/e9f3e990-d60f-11e8-ace0-39a7a2bfd197"

or

curl -k -H "Accept:application/json" -H "BE-MG-Auth-Token:<auth_token>" "https://crypto-gateway.com/v1/order/999264"

This results in something like this:

{"type":"payment","status":"resolved","transaction_id":"e9f3e990-d60f-11e8-ace0-39a7a2bfd197","created":"2018-10-22T15:34:07.272Z","complete":"2018-10-11T23:13:19.321Z","currency":"XBT","transaction_amount":"0.00088900","total_fee":"0.00000454","net_value":"0.00088446","callback_url":"https://FutureTV.com/BE/callback?transaction_id= e9f3e990-d60f-11e8-ace0-39a7a2bfd197&order_id=999264",

"payment_details" : { "amount":"0.00088900", "currency":"XBT", "description":"Monthly subscription", "expires":"2018-10-11T23:14:39.429Z", "time":"2018-10-11T23:09:39.429Z", "seller":"FutureTV.com", "payment_url": "https://crypto-gateway.com/v1/transaction/e389...6c6c6/payment", "polices":{ "receipt_via_email":true, "issuer_refund_via_email":true }, "email_customer_contact":"[email protected]", "transaction_id":"e3891860-d32a-11e8-933e-d1a653d6c6c6", "order_id":"999264",

18 of 20

Page 19: Payments Integration guide Integration Guid… · integration burden of managing payment Coins. Public Merchant Gateway A public service that reduces the back-end integration burden

"acceptable_issuers":["(eu.carrotpay.com)"]},

"payment" : { "client":"web", "wallet_id":"f52ce2925a4c", "options":{ "send_receipt_to":{"email":"[email protected]"}, "send_issuer_refund_to":{"email":"[email protected]"}, "language_preference":"en-GB" "notification":"1 Street, City, Country, Postcode." }, "transaction_id":"e3891860-d32a-11e8-933e-d1a653d6c6c6", "order_id":"999264", "coins":["ewogICJhIjoiV1d4QVE3TzFtaHNNcUJpU0lPOWtKQmFIV1NrV2plN0oiLAogICJjIjoiWEJUIiwKICAiZCI6IjE5Mi4xNjguMC43OjgwODAiLAogICJlIjoiMjAyMC0xMS0xOFQyMDoyMzowNC4wOFoiLAogICJpIjoiMzM0NzI1NjIyNTM5MzM5ODEyNyIsCiAgInYiOiIwLjAwMDkxNjgxIiwKICAieCI6IjAiCn0="],

"verifyInfo":{ "actualValue":"0.00088900", "changeValue":"0.00000000", "currency":"XBT", "exchangedValue":"0.00000000", "faceValue":"0.00088900", "fees"[ { "domain":"eu.carrotpay.com", "totalFee":"0.00000454", "valueFee":"0.00000454" } ], "issuePolicy":"single", "reference":"67972259-4d91-4a88-b0b0-f525a4c2ce29", "targetValue":"0.00088900", "totalFee":"0.00000454", "verifiedValue":"0.00088446" }},

"payment_ack" : { "wallet_id":"f52ce2925a4c", "notification":"Monthly subscription now paid in full.", "return_url":"https://FutureTV.com/BE/confirmation?transaction_id= e9f3e990-d60f-11e8-ace0-39a7a2bfd197&order_id=999264"}}

This Json object is a record of the complete sale, including the fee (net_fee) and the buyer's email address (payment.options.send_receipt_to.email).

Finally, FTV should send the buyer a receipt using the buyer's email address provided.

19 of 20

Page 20: Payments Integration guide Integration Guid… · integration burden of managing payment Coins. Public Merchant Gateway A public service that reduces the back-end integration burden

Appendix A.

A method of calculating the face value of a list of Coins.

For each Coin string, Base64 decode the string, parse it to a Json object and sum the 'v' elements.

In Javascript the code looks like this:

let SumCoins = function(arr) { let sum=0, x=0; for(x=0; x < arr.length; x++) { //decode the base64 string into an object let coinObj = JSON.parse(atob(arr[x])); sum += coinObj['v']; } return sum;};

let faceValue = SumCoins(coinList);

20 of 20