API Documentation

This document will outline the API and the high-level requirements of completing a custom Zip API integration as a payment gateway for a merchant's website.

API Endpoint Documentation is available here

Functional Flow

This is a basic description of how an integration to the Zip payment gateway via our API would look.

  1. Customer selects Zip as their payment method during checkout on merchant's site.
  2. Customer on merchant's site does a form POST to the Zip /orders/authorize API endpoint containing basic information the order.
  3. Zip redirects to the Zip checkout.
  4. Customer completes payment process on Zip site.
  5. Zip redirects customer back to merchant site via a confirm or cancel URL (depending on whether they completed payment successfully or not). These URLs are set by merchant when creating the order.
  6. In addition to the customer navigating through the supplied confirm URL, the merchant will also receive a server-side POST from Zip to confirm the order authorization.

Gateway API

The API Endpoint Documentation references our well-supported Gateway API that is used for custom integrations.

The Gateway API was built with additional resiliency and scalability in mind. Implementations with the Gateway have the following features:

  • Zip will make a server-side webhook callback API request to the merchant's platform to confirm the success/failure of all operations, such as order authorizations, refunds, captures, and voids. This removes the need to poll for order processing updates from Zip.

  • The merchant will receive data on callbacks and user redirects to create the order in their system with all the data needed instead of multiple subsequent calls to Zip's API.

  • Requests to the Zip gateway API must contain a header with a signature to secure requests. This implementation results in less API calls to authenticate from our identity provider and no need for the merchant to manage credential caching.

  • Support for deferred order confirmation.

Gateway API Endpoints

To build your integration, you will utilize the Orders endpoints listed below. Later sections cover how to receive requests and the format of the webhooks that you will use to get updates about Zip orders initiated through the gateway API.

5702

Endpoints and Environments

You will be given unique credentials for the sandbox and production environments. It is best to build your integration against the sandbox environment and enable in production upon successful certification.

Production - US - https://gateway.us.zip.co/
Sandbox (Test) - US - https://gateway.sand.us.zip.co/

Production - CA - https://gateway.ca.zip.co/
Sandbox (Test) - CA - https://gateway.sand.ca.zip.co/

Sent from the user's browser via a form POST, will start a checkout session within Zip. It will automatically redirect the user to our Zip checkout. You need to ensure you provide your merchant ID, merchant reference (the unique ID you use for the order in your system), confirm/cancel URLs, and the order amount. The order amount should include all shipping, tax, and discount charges. You do not need to provide the order ID as that will be generated for you. Passing as much customer information as possible will improve the user experience by pre-filling data fields and improving conversion. Required fields are:

  • merchantId - Your identifier provided by Zip
  • merchantReference - Your unique order identifier for this order in your system
  • callbackUrl - A URL that will receive the webhook request about the result of this operation
  • amount - The total amount of the order, including cart value, shipping, tax, and all fees
  • redirectCancelUrl - Where the user should go upon abandoning their cart
  • redirectConfirmUrl - Where the user should go upon order completion (will include the aforementioned query parameters)

Example

Request URL: https://gateway.us.zip.co/orders/authorize
POST Body:

{
  "merchantId": "44444444-4444-4444-4444-444444444444",
  "merchantReference": "ref",
  "order": {
    "currency": "USD",
    "amount": 123.45,
  },
  "test": true,
  "capture": true,
  "redirectCancelUrl": "https://www.bing.com",
  "redirectConfirmUrl": "https://www.google.com",
  "callbackUrl": "https://api.merchant.com"
}

Same as the above endpoint but data is passed as query string parameters with a GET request.

Example

Request URL: https://gateway.us.zip.co/orders/authorize?merchantId=44444444-4444-4444-4444-444444444444&merchantReference=TH-20200707-1da6&order.firstName=Aaron&order.lastName=Smith&order.email=869765666.test%40quadpay.com&order.phone=5555555555&order.billingAddress.line1=123+Main+St&order.billingAddress.city=New+York&order.billingAddress.state=NY&order.billingAddress.postalCode=10003&order.billingAddress.country=US&order.amount=100.00&capture=True&callbackUrl=https%3a%2f%2fapi.merchant.com%2forder%2fcomplete&redirectCancelUrl=https%3a%2f%2fapi.merchant.com%2forder%2fcancel&redirectConfirmUrl=https%3a%2f%2fapi-ci.quadpay.com%2forder%2fcomplete&X-QP-Signature=3f3oc6tACuGIs%2fX7bhWP3PkstZ8UmI6fSZ%2buPQE8Wfo%3d

Will request a merchant refund to the supplied order and apply it to the customer's payment plan. If you are a pay-on-ship/DFC merchant, you can only apply up to your captured amount. Required fields are:

  • orderId - Zip order ID to refund
  • merchantId - Your identifier provided by Zip
  • currency - The currency to issue the refund in
  • amount - The amount of the refund (not the amount of the order!)
  • merchantReference - An identifier in your system to reference this refund transaction
  • callbackUrl - A URL that will receive the webhook request about the result of this operation

Example

Request URL: https://gateway.us.zip.co/orders/11111111-1111-1111-1111-111111111111/refund
POST Body:

{
  "orderId": "11111111-1111-1111-1111-111111111111",
  "currency": "USD",
  "amount": 123.45,
  "merchantReference": "ref",
  "callbackUrl": "https://api.merchant.com"
}

Only for pay-on-ship/DFC merchants. This captures funds to reflect a fulfilled item in an order. Required fields are:

  • orderId - Zip order ID to capture
  • merchantId - Your identifier provided by Zip
  • currency - The currency to issue the capture in
  • amount - The amount of the capture (not the amount of the order!)
  • merchantReference - An identifier in your system to reference this capture transaction
  • callbackUrl - A URL that will receive the webhook request about the result of this operation
  • singleCapture - True if this will be the only capture for the order and you want the rest to automatically be voided.

Example

Request URL: https://gateway.us.zip.co/orders/11111111-1111-1111-1111-111111111111/capture
POST Body:

{
  "orderId": "11111111-1111-1111-1111-111111111111",
  "currency": "USD",
  "amount": 123.45,
  "merchantReference": "ref",
  "callbackUrl": "https://api.merchant.com",
  "singleCapture": false
}

Only for pay-on-ship/DFC merchants. This voids funds to reflect a cancelled item in an order. Required fields are:

  • orderId - Zip order ID to void
  • merchantId - Your identifier provided by Zip
  • currency - The currency to issue the void in
  • amount - The amount of the void (not the amount of the order!)
  • merchantReference - An identifier in your system to reference this void transaction
  • callbackUrl - A URL that will receive the webhook request about the result of this operation

Example

Request URL: https://gateway.us.zip.co/orders/11111111-1111-1111-1111-111111111111/void
POST Body:

{
  "orderId": "11111111-1111-1111-1111-111111111111",
  "currency": "USD",
  "amount": 123.45,
  "merchantReference": "ref",
  "callbackUrl": "https://api.merchant.com"
}

Merchants using the Standard Checkout with the mobile SDK will allow customers to use the Zip checkout without starting an order until this API call is made by the merchant. This same feature can be leveraged for standard online checkouts as well. The payment plan for the customer will not begin until a successful callback is received by the merchant for this operation. This operation does allow merchants to add shipping/taxes after the Zip checkout for the order. This will be processed with the currency of the original order. This functionality is enabled upon request. Please work with the integration team during onboarding if this is needed in your implementation. Required fields are:

  • orderId - Zip order ID to confirm
  • merchantReference - An identifier in your system to reference this confirm transaction
  • callbackUrl - A URL that will receive the webhook request about the result of this operation

Optionally, you can provide the following:

  • amount - The new total order amount, including all shipping/tax amounts added in
  • shippingAmount - The final calculated shipping amount
  • taxAmount - The final calculated tax amount

Example

Request URL: https://gateway.us.zip.co/orders/11111111-1111-1111-1111-111111111111/confirm
POST Body:

{
  "orderId": "11111111-1111-1111-1111-111111111111",
  "merchantReference": "ref",
  "callbackUrl": "https://api.merchant.com"
}

Merchants with a merchant fee for payment plan (i.e. MFPP) agreement can use this endpoint to determine the fee amount for a given order. The state/country for the customer should come from the customer's shipping address. When $0 is returned, then there is no fee and does not need to display within the merchant's UX. Required fields are:

  • amount - The total order amount including shipping/tax amounts added in.
  • currency - Defaults to USD if not provided.
  • customerState- The state of the customer's shipping address.
  • customerCountry - The country of the customer's shipping address. Defaults to "US".
  • merchantId - The Merchant ID that fees need to be calculated for.

Example

Request URL: https://gateway.us.zip.co/orders/calculate-merchant-fees
POST Body:

{
  "customerState": "NY",
  "customerCountry": "US",
  "currency": "USD",
  "amount": 123.45,
  "merchantId": "44444444-4444-4444-4444-444444444444"
}

Sample response:

{
  "merchantFeeForPaymentPlan": 1.00,
  "currency": "USD"
}

Signing Requests

All operations are secured with an HMAC-SHA256 one-way hash that is performed using a shared secret key between Zip and the merchant. This secret key will be provided to you.

Signatures are generated based on the request type.

  • POST JSON Requests sign the entire request body contents.
  • POST Form Requests sign all the keys + values contained in the form request in alphabetical order except for the signature.
  • GET Requests sign all the keys + values contained in the query string in alphabetical order except for the signature.

The header or query parameter name is always X-QP-Signature.

Implementing this is language specific. Here are examples using C# and PHP that can generate these hashes for you:

public class HmacSha256Signature
    {
        private static Encoding encoding = Encoding.UTF8;

        /// 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.GetBytes(secretKey)))
            {
                var hash = hmacsha256.ComputeHash(bytes);

                return Convert.ToBase64String(hash);
            }
        }

        /// Given a dictionary that contains all the values from a GET or form POST request, this will return your correct hash
        public string Compute(string secretKey, IDictionary<string, string> values)
        {
            var builder = new StringBuilder();

            // Form Keys Sorted Alphabetically
            foreach (var item in values.OrderBy(i => i.Key))
            {
                if (!item.Key.Equals(Constants.SignatureKey, StringComparison.OrdinalIgnoreCase))
                {
                    builder.Append(item.Key);
                    builder.Append(item.Value);
                }
            }

            var message = builder.ToString();

            return this.Compute(secretKey, encoding.GetBytes(message));
        }

        public string Compute(string secretKey, string json)
        {
            var bytes = encoding.GetBytes(json);

            return this.Compute(secretKey, bytes);
        }

        /// This can take any object and turn it into a dictionary to be used for hash creation
        public IDictionary<string, string> GenerateKeyValues(object model)
        {
            var jsonObject = JObject.FromObject(model, JsonSerializer.Create(Constants.KeyGenSerializerSettings));
            var jTokens = jsonObject.Descendants().Where(p => p.Count() == 0);
            var keyValues = jTokens.Aggregate(
                new Dictionary<string, string>(),
                (
                    properties,
                    jToken) =>
                {
                    properties.Add(jToken.Path, jToken.ToString());
                    return properties;
                });

            return keyValues;
        }
    }
$signature = base64_encode(hash_hmac('sha256', $data, $secret, true));

Callbacks

All of the endpoints listed above include a callbackUrl parameter. This URL will be used by Zip to update you on the result of each of these operations. The content of this webhook is as follows:

{
    "timestamp": "2020-04-27T12:34:56.000000Z",
    "merchantId": "44444444-4444-4444-4444-444444444444",
    "orderId": "11111111-1111-1111-1111-111111111111",
    "currency": "USD",
    "amount": 123.45,
    "merchantReference": "1234-abc",
    "test": false,
    "success": true,
    "metadata": {
      "property1": "value1"
    }

The merchantReference value will match the value you provided for the original operation. You also may pass metadata properties to add other important attributes you may need to use to identify your order.

Each of these callbacks will have a X-QP-Signature header that contains the signature that you can use to verify and trust the HTTP request.

These callbacks are issued for every operation (order authorization, refund, void, and capture transactions).

Important! This data will also be provided to you as query string parameters on your supplied confirm URL when creating an order. You can use this to verify order completion within your system by verifying the signature and utilizing the other parameters to store the Zip order ID. Here is a sample URL showing how this information is added. Also note that we pass you the Zip customer information as part authorize order callbacks:

https://yoursite.com/order/complete?timestamp=04%2F27%2F2020%2023%3A27%3A22&merchantId=44444444-4444-4444-4444-444444444444&orderId=11111111-1111-1111-1111-111111111111&currency=USD&amount=123.45&merchantReference=1234-abc&test=False&success=True&customer.firstName=Test&customer.lastName=Test&[email protected]&customer.phone=%2B15555555555&customer.address.line1=123%20Main%20St&customer.address.city=New%20York&customer.address.state=NY&customer.address.postalCode=10000&customer.address.country=US&X-QP-Signature=PdkC29bSMbRG5DR6E0xQt781AgvaZa6Ov9V26Ez2OHU%3D

Test Data

You may use the below testing data while working with the Zip checkout in your development environment.

FieldTest Data
PhoneA US-based mobile phone number. You may use VOIP services for development if needed.
EmailCan be real or fake valid email address (‘@example.com’ for fake)
Verification CodeCode received via SMS
NameAnything
AddressAnything valid
BirthdateAnything 22+ years old
Billing AddressAnything valid
Card Holder NameAnything
Card Number4242 4242 4242 4242
Expiration date02 / 22
CVC222