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:
    • https://api.zuora.com/rest/v1/rsa-signatures if you are on the production environment
    • https://apisandbox-api.zuora.com/rest/v1/rsa-signatures if you are on the API Sandbox environment
  • uri:  The URL that the Payment Page will be served from. Set it to:
    • https://www.zuora.com/apps/PublicHostedPageLite.do if you are on the production environment
    • https://apisandbox.zuora.com/apps/PublicHostedPageLite.do 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.
    GetPageId.png

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

curl -i -k -H "apiAccessKeyId:superadmin@myCompany.com" -H "apiSecretAccessKey:password" -H "Accept:application/json" -H "Content-Type:application/json" -X POST https://api.zuora.com/rest/v1/rsa-signatures -d '
{
   "uri": "https://www.zuora.com/apps/PublicHostedPageLite.do",
   "method": "POST",
   "pageId":"ff80808145b3bf9d0145b3c6812b0008"
}';

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 scenario. When an expired signature is used, your user will receive the specified error code.

Page Load or Page Submit When Expires Error Code Returned
In the Payment Page load request When a Payment Page is not loaded within 30 minutes of the signature generation Invalid_Security error code
In the Payment Page load request When a signature is used by a Direct POST request Attempt_Exceed_Limitation
In the Payment Page load request When a signature is used to successfully render the page  Attempt_Exceed_Limitation
In the Payment Page submit request When the page is not submitted within 24 hours after its generation Invalid_Security error code
In the Payment Page submit request When a signature is used to submit page more than the threshold Attempt_Exceed_Limitation

 

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.

Prevent Multiple Renderings with One Signature 

Starting in the June 2017 release, you can render a Payment Page only once with one generated signature. You need to re-generate a signature if you want to re-render a Payment Page in callback code such as in the Inline Button Outside mode. If you attempt to re-render the page with a used signature, an error will be displayed on the Payment Page. 

Limit on Number of Payment Page Submissions 

In the June 2017 release, a new tenant level limit on the maximum number of Payment Page submissions is implemented. When an end user hits this threshold by repeatedly submitting incorrect information on the Payment Page, they will see the error message and will be blocked from further submission. When the submission limit is reached, you need to provide your end users a way to re-render the page, which requires a regeneration of a signature.

Contact Zuora Global Support if you want to increase the tenant level threshold for submitting Payment Pages.

Enable the New Security Checks 

By default, the above two security checks are disabled. 

To enable the security checks, first go through the following checklist to set up the Payment Page, and contact Zuora Global Support to enable the setting or adjust the limits.

  1. Generate a signature for each Payment Page render.
  2. Generate a signature in your callback code before re-rendering a Payment Page when a previous submission fails.
  3. Generate a signature for each Direct POST request.
  4. Customize the error message for the Attempt_Exceed_Limitation error code. See Error Handling for Payment Pages 2.0 for the steps.
  5. Provide a way for end users to re-render the Payment Page when they hit the limits.

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("uri", 
           "https://apisandbox.zuora.com/apps/PublicHostedPageLite.do");
        requestObject.put("method","POST");
        requestObject.put("pageId", "2c92c0f849369b9401493aab4b111111");
        RequestEntity requestEntity = 
           new StringRequestEntity(
              requestObject.toString(), "application/json", "UTF-8");
                
        PostMethod postRequest = new PostMethod(
           "https://apisandbox.zuora.com/apps/v1/rsa-signatures");  
        postRequest.addRequestHeader(
           "apiAccessKeyId", $ZuoraUserName);
        postRequest.addRequestHeader("apiSecretAccessKey", $ZuoraPassword);
        postRequest.addRequestHeader("Accept", "application/json");
        postRequest.setRequestEntity(requestEntity);
        HttpClient httpClient = new HttpClient();
        if(httpClient.executeMethod(postRequest) != 200) {
            System.out.println("Fail to get signature.");
            return;
        }
        
        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");
          
        System.out.printf(
           "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 = ‘https://api.zuora.com/rest/v1/rsa-signatures’
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 = requests.post(rest_call_url, 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
17:13, 16 Jun 2017

Tags

Classifications

(not set)