API Javascript SDK Implementation
Overview
The JavaScript SDK is a client-side initiated version of our Gateway API integration. It removes the need for a full-page redirect by managing the in-context rendering of the Zip checkout flow in a modal, the same way our Virtual Checkout solution does currently.
Zip takes care of the initial authorization API call through the openCheckout method, which is used with a custom DOM element, and will launch checkout in a popup window (or iframe depending on provided parameters). Read more below.
Zip communicates the results via a Webhook to a predefined endpoint on the merchant side, additionally to return the result on the client-side.
Each consecutive operation, such as void, capture, refund, or other, must be completed on the server side. Please refer to our API documentation.
Flow Diagrams
Depending on how the capture model works for an order, there may be no need to make additional calls to our API to complete an order.
Auto capture
This will enable minimal server-side integration, and the order will be completed after the consumer has completed the Zip checkout flow. This also means that the installment plan will start right away and the order will be captured immediately upon order placement. This is recommended for instant orders or digital goods.
Delayed capture
This use-case is targeted for payment with a delay between the initial authorization and the order capture. This can also be used if the order requires multiple captures on the same authorization. The installment plan will start on the initial authorization, not on the capture. Please refer to our API documentation.
Implementation
Client-side Implementation
The client-side integration is based on four components:
- Retrieval of the computed signature from the server-side.
- A reference to our CDN-hosted JavaScript library.
- HTML DOM element to attach the click event to call the openCheckout function
- JavaScript code to attach one or many callback functionality(s) and customize the payment flow.
Javascript Reference
There are two environments available, and you'll receive unique credentials for each:
- Sandbox (Test) - US:
https://cdn.sand.us.zip.co/v1/zip.js
- Production - US:
https://cdn.us.zip.co/v1/zip.js
Adding the sandbox script will automatically integrate with our sandbox services for testing. Importing the production script will result in real transactions.
The script can be loaded by adding a tag like:
<script src="https://cdn.us.zip.co/v1/zip.js" type="text/javascript"></script>
The script can be added anywhere in the body or head area and loaded asynchronously. If loaded asynchronously, be sure to wait for its load to complete before invoking any operations against the library.
Start Checkout
To start the Zip checkout, the openCheckout function needs to be attached to a DOM element with an event such as onClick.
Zip provides a Branded button asset by using:
<zip-button id="QPButton" integrationType="api"></zip-button>
Integration Type
Please ensure to add
integrationType="api"
to initiate API checkout, or else Virtual Card Checkout will be initiated instead.
The below example is a button element, but this can be anything from radio buttons, drop-downs, or images.
<input type="button" id="ZipButton" value="Pay with Zip" />
Open Checkout Function
The openCheckout function is attached to a DOM element and initiates the Zip checkout flow with the requestBody and signature input. An example is below:
zipButton.addEventListener('click', () => {
window.quadpay.apiCheckout.openCheckout(requestBody, signature);
})
Callback Events
After the openCheckout function is called, Zip will communicate results back via callback events that the merchant must subscripe to.
onComplete
The onComplete Callback accepts a function as a parameter that will be invoked when a customer successfully completes the Zip checkout. In the Standard flow, this contains - the customer information and order id. In the Express flow, this contains the customer's shipping address.
This callback may be invoked asynchronously.
window.quadpay.zipApiCheckout.onComplete((result) => {
// merchant onComplete callback code should be registered here
});
OnComplete Result Object
Properties | Type | Optional/Required | Description |
---|---|---|---|
customer | customer object | Required | This contains information the customer enters in the Zip checkout. Merchants sometimes collect this data to store in their systems. |
merchantFeeForPaymentPlan | number | Optional | Formerly MFPP and now referred to as a consumer fee, this is a customer contribution model that includes an incremental order amount. Used in express flows, the customer's shipping address is returned on the result object. |
orderId | string | Optional | Sets the unique ID to use for order creatio |
onClose
The onClose callback is invoked whenever the user closes the Zip checkout. This optional callback may happen if the customer closes the window or their session times out. The callback may be asynchronous as it is awaited. The callback will accept one parameter:
message (string): Message about why the checkout was closed.
Code Example
///On close callback event
const onCloseCallback = function (result) {
};
window.quadpay.zipApiCheckout.onClose(onCloseCallback);
onError
The onError callback handler will be invoked if the parameters supplied to the openCheckout method are invalid or missing. This optional callback handles technical errors while loading the Zip checkout flow. The callback may be asynchronous as it is awaited. The callback will return error messages in the format of an array of strings representing error messages about what validation failed.
Code Example:
// On error callback event
const onErrorCallback = function (result) {
};
//Attaching the on error callback event
window.quadpay.zipApiCheckout.onError(onErrorCallback);
Server-side Implementation
To enable secure communication between the SDK and our server, all operations are secured with an HMAC-SHA256 one-way hash that is performed using a shared secret key. The key is provided by Zip and will differ depending on the environment used. The Signatures are generated based on the requests to sign the entire Zip requestBody object.
JSON RequestBody example:
{
"merchantId": "[Insert merchant Id]",
"merchantReference": "your-unique-order-id",
"order": {
},
"callbackUrl": "your-url-for-callbacks",
"capture": "true"
}
Properties | Type | Optional/Required | Description |
---|---|---|---|
merchantId | GUID | Required | Your identifier provided by Zip |
merchantReference | Address object | Required | An identifier in your system to reference this refund transaction |
order | Order object | Required | A custom object representing the order. Example below. |
callbackUrl | String | Optional | A URL that will receive the webhook request about the result of this operation. If capture is set to true, a callbackUrl is required to verify the order details. |
capture | Boolean | Required (default true) | Indicated is the order will be auto-captured or additional operations for capture will be completed to capture. |
JSON Order Example
Order object reference
const order = {
amount: 123.45,
currency: 'USD',
merchantReference: 'your-unique-order-id',
shippingAmount: 10,
taxAmount: 13.45,
email: '[email protected]',
firstName: 'John',
lastName: 'Doe',
phoneNumber: '+15555555555',
billingAddress: {
line1: '123 street',
address2: '',
city: 'New York',
state: 'NY',
postalCode: '10001',
country: 'US'
},
lineItems: [
{
name: 'Item Name',
description: 'Item description',
quantity: 1,
price: 123.45,
sku: '12345678',
},
]
};
Calculating the Signature — Code Examples
Implementing this is language specific. Here are examples using C#, PHP, and Node.js that can generate these hashes for you:
/// Takes the secret key and the JSON in string format
public string Compute(string secretKey, string json)
{
var bytes = Encoding.UTF8.GetBytes(json);
return this.Compute(secretKey, bytes);
}
/// If your entire request body is passed in as bytes (e.g. POST JSON request), this will give you the correct hash
public string Compute(string secretKey, byte[] bytes)
{
using (var hmacsha256 = new HMACSHA256(Encoding.UTF8.GetBytes(secretKey)))
{
var hash = hmacsha256.ComputeHash(bytes);
return Convert.ToBase64String(hash);
}
}
$signature = base64_encode(hash_hmac('sha256', $data, $secret, true));
// Calculate signature
const data = JSON.stringify(requestBody);
const key = 'your_api_key_here';
const signature = crypto
.createHmac('sha256', key)
.update(data)
.digest('base64');
Webhooks
Zip provides an async webhook message for events when a consumer completes the Zip checkout flow and when API calls are completed.
Webhook message format
Authorization (at user completion of Zip checkout)
Example implementation code
window.quadpay.apiCheckout.onComplete(function (result) {
// merchant onComplete callback code should be registered here
// Handle any post-checkout business then manually route customer to order confirmation page
// For example: window.location.href = "orderConfirmationPage.com"
});
window.quadpay.zipApiCheckout.onClose(function (message) {
// merchant onClose callback code should be registered here
});
window.quadpay.zipApiCheckout.onError(function (message) {
// merchant onError callback code should be registered here
});
const order = {
amount: 123.45,
currency: 'USD',
merchantReference: 'your-unique-order-id',
shippingAmount: 10,
taxAmount: 13.45,
email: '[email protected]',
firstName: 'John',
lastName: 'Doe',
phoneNumber: '+15555555555',
billingAddress: {
line1: '123 street',
address2: '',
city: 'New York',
state: 'NY',
postalCode: '10001',
country: 'US'
},
lineItems: [
{
name: 'Item Name',
description: 'Item description',
quantity: 1,
price: 123.45,
sku: '12345678',
},
]
};
const requestBody = {
merchantId: '[Insert merchant Id]',
merchantReference: 'merchant-order-id',
order,
callbackUrl: 'http://merchant-url',
capture: true,
checkoutFlow: 'standard'
}
const signature = 'abc-123' // merchant should get signature from their backend
window.quadpay.apiCheckout.openCheckout(requestBody, signature);
Order in JSON Format
const order = {
amount: 123.45,
currency: 'USD',
merchantReference: 'your-unique-order-id',
shippingAmount: 10,
taxAmount: 13.45,
email: '[email protected]',
firstName: 'John',
lastName: 'Doe',
phoneNumber: '+15555555555',
billingAddress: {
line1: '123 street',
address2: '',
city: 'New York',
state: 'NY',
postalCode: '10001',
country: 'US'
},
lineItems: [
{
name: 'Item Name',
description: 'Item description',
quantity: 1,
price: 123.45,
sku: '12345678',
},
]
};
Functions
focusCheckout
This method allows you to programmatically bring focus to the pop-up window once checkout has been opened.
Code Example:
JavaScript
window.quadpay.zipApiCheckout.focusCheckout();
closeCheckout
This method force-closes the Zip checkout window and ends the user's Zip session.
Code Example:
JavaScript
window.quadpay.zipApiCheckout.closeCheckout();
Object Models
Order
Properties | Type | Optional/Required | Description |
---|---|---|---|
amount | number | Required | The amount of the order. It should include all fees, taxes, shipping, and discount codes calculated in its value. |
shippingAmount | number | Optional | The cost of shipping. |
taxAmount | number | Optional | The cost of taxes. |
currency | string | Required | The currency in which the customer is transacting. |
customer | Customer object | Optional | Customer object is used to prefill data in the Zip checkout to improve the user experience and conversion. This is typically based on the customer's supplied billing or shipping details entered earlier in the checkout process. |
lineItems | Line Items object | Optional | Line items object is used to share specific information about the order such as item description, item cost, and SKU data. |
address | Address object | Optional | Address object is used to share both billing and shipping (express) address data. |
merchantFeeForPaymentPlan | number | Optional | Formerly MFPP and now referred to as a consumer fee, this is a customer contribution model that includes an incremental order amount. |
Customer
Properties | Type | Optional/Required | Description |
---|---|---|---|
firstName | string | Optional | Customer's first name |
lastName | string | Optional | Customer's last name |
string | Optional | Customer's email address | |
phoneNumber | string | Optional | Customer's phone number |
address1 | string | Optional | Customer's primary address information |
address2 | string | Optional | Customer's secondary address information. May contain - Apartment number, Care of, Attention |
city | string | Optional | Customer's address city |
state | string | Optional | Customer's address state, in ISO 3166-2:US format (two letter state code) |
postalCode | string | Optional | 5 digit state postal/zip code |
country | string | Optional | Customer's address country, in ISO_3166-2 (two letter country code) |
Line Item
Properties | Type | Optional/Required | Description |
---|---|---|---|
name | string | Optional | The name of the item |
description | string | Optional | The description of the item. (n.b. the description should have max 100 characters, if it exceeds this limit it will be truncated) |
quantity | number | Optional | The quantity of the item in the order. |
price | number | Optional | The price of 1 item. |
sku | string | Optional | The Stock Keeping Unit number. |
isPreOrder | boolean | Optional | Whether the item is a pre-order item. |
releaseDate | date | Optional | The anticipated shipment date of the item. |
Address
Properties | Type | Optional/Required | Description |
---|---|---|---|
line1 | string | Required | Primary shipping address information. |
line2 | string | Optional | Secondary shipping address information. May contain - Apartment number, Care of, Attention. |
city | string | Required | The city of the customer's shipping address. |
state | string | Required | The state of the customer's shipping address, in ISO 3166-2:US format. |
country | string | Required | The country of the customer's shipping address in ISO_3166-2 (two letter country code). |
postalCode | string | Required | 5 digit state postal/zip code. |
Updated 4 months ago