Knowledge Center

Knowledge Center > Commerce > Hosted Commerce Pages > Payment Pages 2.0 > Generate the Digital Signature for Payment Pages 2.0

Generate the Digital Signature for Payment Pages 2.0

This section describes how to generate the digital signature for the Payment Pages 2.0.

Request the Digital Signature

The REST API used in Payment Pages 2.0 are CORS (Cross-Origin Resource Sharing) enabled and therefore requires a digital signature. You need to pass the generated signature to your client for it to access Payment Pages 2.0.

To generate the digital signature and token for your Payment Pages 2.0 form, you issue a Zuora CORS REST request to the Zuora server. The CORS REST response contains a token, a signature, and a public key. The following information is required for the request:

  • API endpoint URL: The endpoint URL for the CORS Rest API. Set it to:
    • if you are on the production environment
    • if you are on the API Sandbox environment
  • uri:  The URL that the Payment Page will be served from. Set it to:
    • if you are on the production environment
    • if you are on the API Sandbox environment
  • method: The type of the request. Set it to POST.
  • pageId: The page id of your Payment Pages 2.0 form. Click Show Page Id next to the Payment Page name in the Hosted Page List to retrieve the page id.

Here is a sample Curl request to generate a token and a digital signature.

curl -i -k -H "" -H "apiSecretAccessKey:password" -H "Accept:application/json" -H "Content-Type:application/json" -X POST -d '
   "uri": "",
   "method": "POST",

Receive the Digital Signature

Write the server side code to receive the digital signature for the Payment Pages 2.0 form. You need to pass the necessary information in the response to your client. A successful call returns the following, all of which your client needs to load your Payment Pages form:

  • signature: Digital signature generated
  • token: Token generated
  • tenantId: ID of your Zuora tenant
  • key: Public key generated
  • success: True if the request is successful

Signature Expiration

Your Payment Page signature expires in the following cases:

  • In the page load request: The signature is expired if it is not loaded within 30 minutes of the signature generation. This prevents the same static URL being used for an extended period of time.
  • In the page submit request: The signature is expired if it is not submitted within 24 hours after its generation.

When the signature is expired, the Invalid_Security error code is returned to your user.

If the signature expires, resend the request to get a new signature and validate again. 

If you are implementing a Payment Page with the Submit button outside, see Validate the Digital Signature for Payment Pages 2.0 for validating the digital signature in your callback page.

Troubleshoot Failed Signature Validation

A signature validation failure could be a result of several possible causes. Examples are:

  • A failure caused by your implementation
  • If you are constructing the integration for the first time, check the process of validation in the following areas:
    • Did you use the correct username and password to send signature POST request? 
    • Was the signature request sent to the correct end point?
    • Was the POST response received successfully and parsed correctly?
    • Was the signature decrypted correctly? Debug the decryption action.
    • Were the correct parameters used to validate the signature?
  • If your integration has worked for a while before you started seeing validation failures, it may be a security issue. Perform security-related checks.
  • If none of above is the cause of the signature validation failure, contact Zuora Global Support with the error message for help.

Sample Code to Generate the Digital Signature

Here is a sample code in Java that requests the digital signature and other information from Zuora:

package com.zuora.hpm;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.json.JSONObject;

public class SignatureTest {
    public static void main(String[] args) throws Exception {
        JSONObject requestObject = new JSONObject();
        requestObject.put("pageId", "2c92c0f849369b9401493aab4b111111");
        RequestEntity requestEntity = 
           new StringRequestEntity(
              requestObject.toString(), "application/json", "UTF-8");
        PostMethod postRequest = new PostMethod(
           "apiAccessKeyId", $ZuoraUserName);
        postRequest.addRequestHeader("apiSecretAccessKey", $ZuoraPassword);
        postRequest.addRequestHeader("Accept", "application/json");
        HttpClient httpClient = new HttpClient();
        if(httpClient.executeMethod(postRequest) != 200) {
            System.out.println("Fail to get signature.");
        byte[] res = postRequest.getResponseBody();
        JSONObject resultObject = new JSONObject(new String(res));
        String token = resultObject.getString("token");
        String key = resultObject.getString("key");
        String tenantId = resultObject.getString("tenantId");
        String signature = resultObject.getString("signature");
        Boolean success = resultObject.getBoolean("success");
           "success: %s\n token: %s\n tenantId: %s\n signature: %s\n public key: %s\n", 
           success, token, tenantId, signature, key);   

The following is a sample response from the above request:

success: true
token: FZ8Xtefcm5qvZi3Fz4rvTWU0pMVbNCzq
tenantId: 123
signature: Oio9UxQ+sUfHXOy7K5sSyQ6QJNVkoHfPRoGdjlkY70q2dlAOKthpKaZPc8DIUhOY6Oz/jbP0bAiZsjW9fnEMLi43bUV5prBc5HE1urPN4LGFK/mlmXSOkKpTWXF0JnQSvyl57bQCLusd+LLpaSnraC1N3J/DsJQuGpyhCRQeZxM3lUKm/AWUiJAIgGPqiIsNKRj9eS5Zz03hPRajTzDPG00M3jiG8EX+a2MvptXjFc0lJK8eZz1g0/piLaFxNlhI59dJpxwhO0K0onE19EgJWHbkYJzxbi4UMoI6WOi9axa877Z6bijUqV9+F2DvVUdQb47Q2+56foIitKc1NtxCCZ6VuOF97JwjXdkr8oSqF7JKC55IVNyh7clCHziPag2q+tjRW8VqhHa2dont+lDvN14uuA2F1Rro6Txrh0tdJu/gxTCCzgTaqzAQzHjtf4hL3aHH40K6sI9ZIAlL6rqzO1THHkr35kueolDnSIegVfM0sC2u7g799JBfgS9d/3EjSwRCyOxk5jGk4Ec6cmU++bNqIshVsr0DnnNw9gvoKqck6uRRoZkCOWo2NA128CHdm6qhbC62oJaWNadYomByonjF3WY5hbmOvEfIi8V4M2K0F1jbodFJVcCQCemmd9M9ElI0wnG/X0s2Lop/ZhR8lseOgsnQloRoRYfioOAcUj8=
public key: MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA6WzeUhwUnQoshk0QokZlKjwcSiYoDP3/BRIa40lfsmlTzBquhZgOq7qhgYqaSNq1Mqk1oEIAEhPtv6s7EELGO76Avo1niwVJw3A78gMS2T35Li4mjH+Kzf3nqSP6AhsV6EF8frLgQklvHV1nem5HZrMdmqlsqK1j4oc6YwR9mVPrbzzolMMZOnTwap7RsApxfMi5OSYxIWJ7PykQNwPH8G99smY6yb095zlJDl9/yPt9amCKIdjgfCdXlVNqhfIq/633i4R5I+dMqiW6JblxzqoQ3Xg/gP+5LKzXQUBgnMW4G0r8VP7kyZh8yfEplNxRjpGzGFjdmAlm0XhvF525IkUqjQaEY3J8lfMruaf/Rwo44Grb3+8lKNyGZfh39AfnJNkZHO/NFkcPhcq6gOtTV1OFCDrqAJTzGMVwVB05PTAPX0osH1fktvlYERtVa4YrJrZrF+E+1MXdtVx/pxGEzLBdE/AISXxDLN6r11upTbNi8f+H5Hc30iAk32hQSOf12R4nwYSvCPhtHh6O8+/XD9QfBJtLErqo0BnkZRljRA8jF3YFQ7Vwg+k5iqeMA4kt51pgOdEAbD13eeinOQQnx8sBwFO+PELUXOmxEWAMmUxkqklU0rjH6cHyl290hgRK6y9B0Oogd+QfbL8p4+Dwyp7tqwIs0XkJhEHWHVkXz1cCAwEAAQ==

Here is a sample code in Python that requests the digital signature and other information from Zuora:

import requests
import json

rest_call_url = ‘’
my_hosted_page_url = ‘’
my_hosted_page_id = ‘’
my_username = $ZuoraUserName
my_password = $ZuoraPassword

data = {"uri": my_hosted_page_url, "method": "POST", "pageId": my_hosted_page_id}
headers = {'content-type': 'application/json'}

response =, data=json.dumps(data), auth=(my_username, my_password), headers=headers)
response_json = response.json()

token = response_json['token']
signature = response_json['signature']
key = response_json['key']
tenant_id = response_json[‘tenantId’]
Last modified
11:10, 11 May 2017



(not set)