Merchant Integration Tutorial
Apruve.js is a JavaScript library that you can use to embed the Apruve checkout into your online store. With a little bit of server-side code, and a little bit of Javascript, you can be up and running with Apruve in no time. This tutorial will provide an overview, along with links to more detailed information where appropriate.
Step 0: Prerequisites
- You've read our Merchant Technical Overview to get the big picture.
- You've created an account on test.apruve.com with a Merchant account and an API Key.
Step 1: Server-side prep
Apruve relies on information provided by your store to feed our approval and payment workflows. Because of this, it's important that you provide the most accurate and complete order information you can. To do this, create an Apruve Order object in JSON using the contents of your shopping cart. Then sign that data with a secure hash to prevent tampering.
Pro Tip
If you are using ruby, we have a gem that will create the order object and secure hash for you.
1a: Creating an Order JSON Object
Here's an example:
{
"merchant_id": "4d556524255a8e65385f9da2a2693cf1",
"merchant_order_id": "WidgetCo-001",
"amount_cents": 1150,
"currency": "USD",
"tax_cents": 50,
"shipping_cents": 100,
"expire_at": "2014-07-15T10:12:27-05:00",
"po_number": "PO-1234ABC",
"order_items": [
{
"description": "Description for a widget",
"title": "A Widget",
"sku": "SKU-ABCD",
"price_total_cents": 900,
"price_ea_cents": 920,
"quantity": 1,
"discount_total_cents": 20
},
{
"description": "Description for another widget",
"title": "Another Widget",
"sku": "SKU-EFGH",
"price_total_cents": 100,
"price_ea_cents": 100,
"quantity": 1,
"discount_total_cents":0
}
]
}
Refer to the documentation for the Order and OrderItems objects for details on order and order item fields.
PO Number
PO Number is usually entered by the shopper as part of the checkout process, but if you know this value ahead of time you can specify it in the
po_number
field of your order JSON. This will pre-populate the field in the Apruve checkout with that PO Number.
1b: Creating a Secure Hash
To create the secure hash, make a string by concatentating your API Key and all the values of your order object, then perform a SHA256 hex digest function on it. The ordering of the fields is critical and must be in the order specified below.
ProTip: If an optional field has no value, you may leave it out of the hash...just be sure there is no whitespace in the JSON value, either.
Ordering of fields in the Order object
Note: Not all order and order item fields are included in the hash. Only include the fields specified below!
Ordering | Field Name | Required |
---|---|---|
1 | merchant_id | yes |
2 | merchant_order_id | no |
3 | amount_cents | yes |
4 | currency | no |
5 | tax_cents | no |
6 | shipping_cents | no |
7 | expire_at | no |
8 | accepts_payment_terms | no |
9 | finalize_on_create | no |
10 | invoice_on_create | no |
Then for each Order Item, in order:
1 | title | yes |
2 | price_total_cents | no |
3 | price_ea_cents | no |
4 | quantity | no |
5 | discount_total_cents | no |
6 | merchant_notes | no |
7 | description | no |
8 | variant_info | no |
9 | sku | no |
10 | vendor | no |
11 | view_product_url | no |
Note that even though some fields are optional, if they are in the order object you send in the payload then it must be in the hash as well.
After you create the order string, we prepend the entire thing with your API Key.
For example, consider the example Order above. The string to sign would be all of the values from that object, in the order provided above, concatenated into one long string. Before the API key, we get:
Note: This is one long string, with no line breaks!
4d556524255a8e65385f9da2a2693cf1WidgetCo-0011150USD501002014-07-15T10:12:27-05:00A Widget900920120Description for a widgetSKU-ABCDAnother Widget10010010Description for another widgetSKU-EFGH
Let's say your API Key is 945d7e36fed1cd8ebaf4eb472eca4dca
. Then, the entire string we're going to hash becomes:
945d7e36fed1cd8ebaf4eb472eca4dca4d556524255a8e65385f9da2a2693cf1WidgetCo-0011150USD501002014-07-15T10:12:27-05:00A Widget900920120Description for a widgetSKU-ABCDAnother Widget10010010Description for another widgetSKU-EFGH
Finally, we use the SHA256 algorithm to create a digital signature. Most languages have it built-in. Here's an example in Ruby:
require 'digest'
secure_hash = Digest::SHA256.hexdigest('945d7e36fed1cd8ebaf4eb472eca4dca4d556524255a8e65385f9da2a2693cf1WidgetCo-0011150USD501002014-07-15T10:12:27-05:00A Widget900920120Description for a widgetSKU-ABCDAnother Widget10010010Description for another widgetSKU-EFGH')
=> "f3a9662162f90e3e8b9c75b674af094f3295ee789e9e80197850649c4bd9fbc5"
OK, so now we have the Order JSON object, and our secure hash. We're ready to load apruve.js
.
Step 2: Add apruve.js
to your checkout view
apruve.js
to your checkout viewapruve.js
is the JavaScript library that manages the Apruve button on your checkout page. First, import the script.
Then initialize it with your Payment Request, your secure hash, and other variables. Last, register a call-back
function. Then put a special <DIV>
on the page where we want the button to appear.
For more information, see the Apruve.js Reference
2a: Import apruve.js
apruve.js
Declare the apruve.js
script in your HTML markup.
<script src="https://test.apruve.com/js/v4/apruve.js" type="text/javascript"></script>
Test vs. Production URLs
We recommend that you use environment variables to ensure you get the correct script from
test.apruve.com
orapp.apruve.com
, as appropriate.
2b: Initialize apruve.js
apruve.js
Initialize apruve.js
with the order JSON and the secure hash that we created on the server.
ProTip: Keep in mind that we want to give
apruve.js
the value of the JSON object, so do NOT surround it with quotes! The secure hash is a string, so it should be in quotes.
Initializing apruve.js
(example shown is written in Ruby ERB)
<script type="text/javascript">
apruve.setOrder(<%= @order.to_json %>, '<%= @order.secure_hash %>');
</script>
2c: Register JavaScript Callbacks
apruve.js
can notify you when events happen during the checkout process. We recommend that you register at least one callback function on the apruve.APRUVE_COMPLETE_EVENT
that will be fired when there is an Order ID available for you to capture.
Event | Description |
---|---|
apruve.APRUVE_LAUNCHED_EVENT | Fires when the shopper clicks on the Apruve button. |
apruve.APRUVE_COMPLETE_EVENT | Fires when the Apruve lightbox has closed, and the shopper has successfully created an Order. When this event fires, the Order ID will be passed as a parameter to your callback function. |
apruve.APRUVE_CLOSED_EVENT | Fires when the Apruve lightbox has closed, but the shopper has NOT successfully created an Order. Usually, this is because the shopper has cancelled the process before completing it. Sometimes this happens if there was an error during checkout. It would be good to check and log apruve.errors . |
Here is an example of our Javascript block, extended from the one above. Note that apruve.paymentRequest
and the apruve.secureHash
variables are set via server-side parameters. As above, the example here uses Embedded Ruby. You should use what is appropriate for your server platform. Also, we use JQuery in the callback we registered. Again, this is a convenient example, and you should use whatever means is appropriate to post the apruve.orderId
to your server.
<script type="text/javascript">
apruve.setOrder(<%= @order.to_json %>, '<%= @order.secure_hash %>');
apruve.registerApruveCallback(apruve.APRUVE_COMPLETE_EVENT, function (orderId) {
// The order ID is passed into your callback function as a parameter
// Use any mechanism, such as a hidden form field, to post the ID to your server.
$('#orderId').val(orderId)
$('#confirmOrderForm').show()
});
</script>
2d: Place the Apruve <DIV> tag
Determine where you want the Apruve button to appear on your checkout page, and place a DIV there with id='apruveDiv'
, like the following:
<div id="apruveDiv"></div>
Step 3: Post the orderId to your server
Your checkout page is almost complete. If you try it out, it should even work! But we're not quite done. Apruve has created an orderId to represent the transaction, which you will need for all other communication related to this order.
You need to get the orderId that apruve.js created, attach it to your order, and save it in your database. You are free to do this however you like. Here are some suggestions:
- If you have a "review and confirm" page where the shopper must review their order before it is placed, you should put the orderId in a hidden field on that form. Then, when the shopper clicks your "Place Order!" button, it gets sent to your server. This is a very common scenario.
- Use AJAX in the callback you registered to send the ID to your server. As long as you are registering the callback to run on the
APRUVE_COMPLETE_EVENT
,apruve.orderId
will have been set.
By default, when checkout completes, Apruve will finalize the Order, generate an Invoice based on the Order's contents, issue that Invoice to the buyer, and charge the buyer's bank account (if applicable for the given payment method).
Step 4: (Optional) POST an Invoice to Apruve
Some stores might need to exercise a little more control over the lifecycle of the Order. They might not have shipping and tax amounts available at checkout, or they might want to wait to generate an Invoice until products are in stock. Apruve can support virtually any scenario via the Order object's finalize_on_create
and invoice_on_create
flags more information available here.
If your use case requires that you create Invoices yourself, you can do so using Apruve's Invoice API.
Here's what a simple Invoice JSON document looks like. There's lots of information about it in the API docs for Invoices . If you haven't read it already, you'll also want to review the Apruve REST API documents for how to use your API Key for authentication, set request headers, etc.
The request body of a Invoice POST:
{
"amount_cents":1150,
"currency":"USD",
"tax_cents": 50,
"shipping_cents": 100,
"expire_at": "2014-07-15T10:12:27-05:00",
"invoice_items": [
{
"description": "Description for a widget",
"title": "A Widget",
"sku": "SKU-ABCD",
"price_total_cents": 900,
"quantity": 1
},
{
"description": "Description for another widget",
"title": "Another Widget",
"sku": "SKU-EFGH",
"price_total_cents": 100,
"quantity": 1
}
]
}
We're going to POST this to Apruve. If we get an HTTP 201 response back, you've created your Invoice! Your response body will include a status. If the status is closed
, you've been paid. If it is open
, you are still awaiting payment for the invoice. This could be because the buyer still needs to provide a payment method, etc.
Step 5: (Optional) Register a Web Hook
If you want to be notified when Orders are approved or rejected, when invoices are paid, or when payment terms for an order are accepted, you can register a web hook. There's lots more detail about the different webhooks and what they mean in the Webhooks section of the API documentation. We strongly recommend that you set up a web hook handler for your store, as web hooks are the simplest, most reliable way to decide when to fulfill an order.
5a: Create a Web Service to Receive The Web Hook Notification
First, create a service that will receive the web hook. Apruve will automatically post a small JSON blob to that URL whenever a certain events occur.
Example Web Hook Notification for an Invoice
{
"uuid":"abcdefghi",
"created_at":"2016-02-01T06:00:00",
"event":"invoice.closed",
"entity": {
"amount_cents":1150,
"currency":"USD",
"tax_cents": 50,
"shipping_cents": 100,
"expire_at": "2014-07-15T10:12:27-05:00",
"invoice_items": [
{
"description": "Description for a widget",
"title": "A Widget",
"sku": "SKU-ABCD",
"price_total_cents": 900,
"quantity": 1
},
{
"description": "Description for another widget",
"title": "Another Widget",
"sku": "SKU-EFGH",
"price_total_cents": 100,
"quantity": 1
}
]
}
}
5b: Set a Web Hook URL On Your Merchant Account
If you edit your Merchant Account in Apruve, you'll see this field:
Enter the URL for your endpoint in the 'Webhook URL' field and click the Save button. That's it! Apruve should now be sending you notifications for changes in your orders and invoices, allowing you to complete processing of the order appropriately.
Demo application
To see all of these principles in action, check out our demo store at https://merchant-demo.herokuapp.com. This store is a very simple Ruby/Sinatra app, and the source code can be found at https://github.com/apruve/apruve-ruby-demo.
Updated almost 3 years ago