Hosted Payment Page

Hosted Payment page API Reference

Overview

Zapper Hosted Payment Page is a quick set-up, PCI DSS compliant service that enables customers to complete transactions on a secure payment page hosted by Zapper.

How it works

All encryption is handled internally and cardholder data will not be transmitted between Zapper and the merchant sites.

  1. Create Session and Receive RedirectUrl

    The merchant initiates the payment process by creating a session using Zapper's API. The merchant receives a redirectUrl, which is used to redirect user to the Hosted Payment Page for payment processing.

  2. Redirect User to Zapper's Hosted Payment Page

    The merchant is required to redirect the user to the Hosted Payment Page, where they are presented with payment options, such as QR code or card payment.

  3. User Completes the Payment

    The user completes the payment process on the Hosted Payment Page.

  4. Zapper Notifies Merchant via Webhook

    After payment, Zapper sends a payment notification to the merchant's notificationUrl (provided by the merchant when the session is created). The merchant is required to implement a webhook endpoint to receive these payment notifications. It is recommended that the merchant validate the signature.

  5. Zapper Redirects User Back to Merchant's Store

    Upon completing the payment process, Zapper redirects the user back to the merchant's store.

Integration Workflow

API Reference

Create a new session

POST https://gateway.zapper.com/api/v3/sessions

Headers

Request Body

{
    "sessionId": "9a1e2b26-d9c3-4b2a-9fe1-e6a3cd97af06",
    "redirectUrl": "https://zapper.zmsa-tech.com/pay?sessionId={guid}",
    "status": "Success",
    "errors": []
}

Create Session Request Example:

curl --location 'https://gateway.zapper.com/api/v3/sessions' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'merchantId: 1234' \
--header 'merchantSiteId: 1234' \
--header 'x-api-key: cb67xxxxxx0546f68806b62a36xxxxxx' \
--data '{
  "merchantOrderId": "c93d99c8-20e1-4fc6-95b8-10d50eb9a90e",
  "amount": 1000,
  "currencyISOCode": "ZAR",
  "notificationUrl": "https://merchantstore.com/somePaymentNotificationPath",
  "returnUrl": "https://merchantstore.com/someReturnPath",
  "cancelUrl": "https://merchantstore.com/someCancelPath",
  "requestId": "ad7234d5-4e6b-4acf-8e29-451c056b2bdc",
  "origin": "https://merchantstore.com",
  "customFields":[
      {
          "key": "FieldLabel",
          "value": "FieldValue"
      }
  ]
}'

Get payments by sessionId

GET https://gateway.zapper.com/api/v3/payments

Query Parameters

Headers

{
  "status": "Success",
  "errors": [],
  "merchantOrderId": "dea3d7a0-5e11-497a-8fa8-c3987623bce4",
  "paymentReference": "NN7WE7WXXDNR4925PW",
  "amount": 500,
  "currencyISOCode": "ZAR",
  "paymentStatus": "Failed",
  "userMessage": "Declined",
  "sessionId": "9a1e2b26-d9c3-4b2a-9fe1-e6a3cd97af06",
  "paymentUTCDate": "2023-06-20T12:29:11.6664948Z"
}

Get Payments by SessionId Request Example:

curl --location 'https://gateway.zapper.com/api/v3/payments?sessionId=20908573-a1ea-412d-8a25-26e48e58c548' \
--header 'Accept: application/json' \
--header 'merchantId: 8712' \
--header 'merchantSiteId: 8727' \
--header 'x-api-key: cb67xxxxxx0546f68806b62a36xxxxxx'

Get payment by paymentReference

GET https://gateway.zapper.com/api/v3/payments/{paymentReference}

Path Parameters

Headers

{
  "status": "Success",
  "errors": [],
  "merchantOrderId": "dea3d7a0-5e11-497a-8fa8-c3987623bce4",
  "paymentReference": "NN7WE7WXXDNR4925PW",
  "amount": 500,
  "currencyISOCode": "ZAR",
  "paymentStatus": "Failed",
  "userMessage": "Declined",
  "sessionId": "9a1e2b26-d9c3-4b2a-9fe1-e6a3cd97af06",
  "paymentUTCDate": "2023-06-20T12:29:11.6664948Z"
}

Get Payments by PaymentReference Request Example:

curl --location 'https://gateway.zapper.com/api/v3/payments/XZR8K9QKWVYE2E159L' \
--header 'Accept: application/json' \
--header 'merchantId: 8712' \
--header 'merchantSiteId: 8727' \
--header 'x-api-key: cb67xxxxxx0546f68806b62a36xxxxxx'

Models

Payment Notification Webhook Model

PaymentStatus

ResponseStatus

Error

Custom Fields

Additional information that is needed by the merchant in the payment details.

Signature Validation

To ensure the authenticity and integrity of the payment notification data, validating the signature is recommended. The PaymentNotificationWebhook is used along with the merchant's x-api-key when creating a SHA256 signature hash. The following are an examples of signature validation:

C#

private bool IsSignatureValid(string signature, ZapperEcomAPIV3Client.PaymentNotificationWebhook paymentNotificationWebhook, string x-api-key)
{
    string signatureInput = $"{x-api-key}|{paymentNotificationWebhook.SessionId}|{paymentNotificationWebhook.Amount}|{paymentNotificationWebhook.CurrencyISOCode}|{paymentNotificationWebhook.MerchantOrderId}|{paymentNotificationWebhook.PaymentReference}|{paymentNotificationWebhook.paymentStatus}|{paymentNotificationWebhook.PaymentUTCDate}|{paymentNotificationWebhook.UserMessage}";

    using (SHA256 sha = SHA256.Create())
    {
        byte[] hashBytes = sha.ComputeHash(Encoding.UTF8.GetBytes(signatureInput));
        StringBuilder builder = new StringBuilder();

        foreach (byte b in hashBytes)
        {
            builder.Append(b.ToString("x2"));
        }

        string generatedSignature = builder.ToString();

        return generatedSignature.Equals(signature, StringComparison.OrdinalIgnoreCase);
    }
}

JavaScript:

const crypto = require('crypto');

function isSignatureValid(signature, paymentNotificationWebhook, x-api-key) {
  const signatureInput = `${x-api-key}|${paymentNotificationWebhook.SessionId}|${paymentNotificationWebhook.Amount}|${paymentNotificationWebhook.CurrencyISOCode}|${paymentNotificationWebhook.MerchantOrderId}|${paymentNotificationWebhook.PaymentReference}|${paymentNotificationWebhook.paymentStatus}|${paymentNotificationWebhook.PaymentUTCDate}|${paymentNotificationWebhook.UserMessage || ""}`;
  const generatedSignature = sha256Hash(signatureInput);
  return generatedSignature.toLowerCase() === signature.toLowerCase();
}

function sha256Hash(value) {
  const hash = crypto.createHash('sha256');
  const hashBytes = hash.update(value, 'utf-8').digest();
  return hashBytes.toString('hex');
}

Java:

private static boolean isSignatureValid(String signature, PaymentNotificationWebhook paymentNotificationWebhook, String x-api-key) {
       String signatureInput = x-api-key + "|" +
                paymentNotificationWebhook.getSessionId() + "|" +
                paymentNotificationWebhook.getAmount() + "|" +
                paymentNotificationWebhook.getCurrencyISOCode() + "|" +
                paymentNotificationWebhook.getMerchantOrderId() + "|" +
                paymentNotificationWebhook.getPaymentReference() + "|" +
                paymentNotificationWebhook.getPaymentStatus() + "|" +
                paymentNotificationWebhook.getPaymentUTCDate() + "|" +
                paymentNotificationWebhook.getUserMessage();

        String generatedSignature = sha256Hash(signatureInput);
        return generatedSignature.equalsIgnoreCase(signature);
  }

 private static String sha256Hash(String value) {
       
    MessageDigest digest = MessageDigest.getInstance("SHA-256");
    byte[] hashBytes = digest.digest(value.getBytes(StandardCharsets.UTF_8));

    StringBuilder builder = new StringBuilder();
    for (byte b : hashBytes) {
        builder.append(String.format("%02x", b));
    }
    return builder.toString();
 }

Payments: The payment process is as follows:

  1. When the user selects the Zapper payment option on checkout and proceeds to finalize their order, they will be presented with Zapper Hosted Payment page.

  2. If the user prefers the familiar convenience of our dynamic QR code solution, they can proceed by using the Zapper mobile app to effortlessly scan the on-screen QR Code. For users accessing the store from a mobile device, the QR Code is seamlessly replaced with a deep-link button, ensuring a smooth transition to the Zapper application.

  3. However, if the user prefers to use their credit or debit card for payment, they can now opt for the new card payment option. This straightforward method allows users to directly input their card details and complete the payment process right on the spot.

  4. Once the payment is successfully processed – whether through QR code scanning or card payment – users will receive a confirmation in the form of a checkmark symbol. With this assurance of payment, they will then be seamlessly redirected back to the store's default payment confirmation page.

The order on the merchants store will automatically be updated with payment complete.

Last updated