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:

  1. Retrieval of the computed signature from the server-side.
  2. A reference to our CDN-hosted JavaScript library.
  3. HTML DOM element to attach the click event to call the openCheckout function
  4. 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 get unique credentials for each environment to use it:

  • 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

PropertiesTypeOptional/RequiredDescription
customercustomer objectRequiredThis contains information the customer enters in the Zip checkout. Merchants sometimes collect this data to store in their systems.
merchantFeeForPaymentPlannumberOptionalUsed in express flows, the customer's shipping address is returned on the result object.
orderIdstringOptionalSets 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": "44444444-4444-4444-4444-444444444444",
        "merchantReference": "your-unique-order-id",
        "order": {
          
        },
          
        "callbackUrl": "your-url-for-callbacks",
        "capture": "true"
}
PropertiesTypeOptional/RequiredDescription
merchantIdGUIDRequiredYour identifier provided by Zip
merchantReferenceAddress objectRequiredAn identifier in your system to reference this refund transaction
orderOrder objectRequiredA custom object representing the order. Example below.
callbackUrlStringOptionalA 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.
captureBooleanRequired (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: '44444444-4444-4444-4444-444444444444',
            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

PropertiesTypeOptional/RequiredDescription
amountnumberRequiredThe amount of the order. It should include all fees, taxes, shipping, and discount codes calculated in its value.
shippingAmountnumberOptionalThe cost of shipping.
taxAmountnumberOptionalThe cost of taxes.
currencystringRequiredThe currency in which the customer is transacting.
customerCustomer objectOptionalCustomer 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.
lineItemsLine Items objectOptionalLine items object is used to share specific information about the order such as item description, item cost, and SKU data.
addressAddress objectOptionalAddress object is used to share both billing and shipping (express) address data.
merchantFeeForPaymentPlannumberOptionalThe per-order fee amount, set as part of the customer contribution model.

Customer

PropertiesTypeOptional/RequiredDescription
firstNamestringOptionalCustomer's first name
lastNamestringOptionalCustomer's last name
emailstringOptionalCustomer's email address
phoneNumberstringOptionalCustomer's phone number
address1stringOptionalCustomer's primary address information
address2stringOptionalCustomer's secondary address information. May contain - Apartment number, Care of, Attention
citystringOptionalCustomer's address city
statestringOptionalCustomer's address state, in ISO 3166-2:US format (two letter state code)
postalCodestringOptional5 digit state postal/zip code
countrystringOptionalCustomer's address country, in ISO_3166-2 (two letter country code)

Line Item

PropertiesTypeOptional/RequiredDescription
namestringOptionalThe name of the item
descriptionstringOptionalThe description of the item.
(n.b. the description should have max 100 characters, if it exceeds this limit it will be truncated)
quantitynumberOptionalThe quantity of the item in the order.
pricenumberOptionalThe price of 1 item.
skustringOptionalThe Stock Keeping Unit number.
isPreOrderbooleanOptionalWhether the item is a pre-order item.
releaseDatedateOptionalThe anticipated shipment date of the item.

Address

PropertiesTypeOptional/RequiredDescription
line1stringRequiredPrimary shipping address information.
line2stringOptionalSecondary shipping address information. May contain - Apartment number, Care of, Attention.
citystringRequiredThe city of the customer's shipping address.
statestringRequiredThe state of the customer's shipping address, in ISO 3166-2:US format.
countrystringRequiredThe country of the customer's shipping address in ISO_3166-2 (two letter country code).
postalCodestringRequired5 digit state postal/zip code.