Secure token request

Secure token request

The secure token request is the recommended method for sending parameters to QuickStream with non-repudiation. It allows the parameters to be validated on your server and then sent directly from your server to QuickStream. Use a secure token request with QuickWeb or QuickConnect, to perform payments or register details into QuickVault.

To perform a secure token request you will require:

The secure token handoff has two steps:

  1. Secure token request. Your server requests a Security Token from QuickStream.
  2. Handoff. Your website uses the Secure Token to hand off your customer to QuickWeb or QuickConnect, to perform payments or register details into QuickVault.

Example secure token request from your server

POST /CommunityTokenRequestServlet HTTP/1.1
Host: ws.qvalent.com
Accept: text/plain
Content-Type: application/x-www-form-urlencoded

cancelUrl=https%3A%2F%2Fyoursite.com.au%2Fcancelled
&connectionType=QUICKWEB
&currencyCode=AUD
&errorEmailToAddress=errors%40yoursite.com.au
&password=<YOUR_FACILITY_PASSWORD>
&product=RECURRING
&returnUrl=https%3A%2F%2Fyoursite.com.au%2Fthankyou
&serverReturnUrl=https%3A%2F%2Fyoursite.com.au%2FreceiveRequest
&supplierBusinessCode=<YOUR_SUPPLIER_BUSINESS_CODE>
&username=<YOUR_FACILITY_USERNAME>

Example response from QuickStream to your server

token=OicksakIMkD3OiZpyE7MadwJkZSrSqgjviXCEomVD3ZzEmZ6Vlxecg

Example handoff from a web page

<form action="https://quickweb.westpac.com.au/OnlinePaymentServlet3" method="POST">
    <input type="hidden" name="token" value="OicksakIMkD3OiZpyE7MadwJkZSrSqgjviXCEomVD3ZzEmZ6Vlxecg"/>
    <input type="hidden" name="communityCode" value="<YOUR_COMMUNITY_CODE>"/>
    <input type="submit" value="Make Payment"/>
</form>

QuickStream validates the IP address of a secure token request. Whitelist your allowed IP addresses in the QuickStream portal.

A security token is valid for 1 hour after it is created and can only be used once.

Parameters for the secure token request

Sign in to QuickStream Portal to get these values in each environment. See View your connection details.

Parameter Name Required Description
username Yes Your username.
password Yes Your password.
supplierBusinessCode Yes Your supplier business code indicates the merchant facility you wish to settle funds to.
connectionType Yes QUICKWEB, QUICKFRAME, INVOICING, QUICKCONNECT
product Yes RECURRING, INVOICING, QUICKVAULT, QUICKWEB
accountType No Restrict a payer to credit card or bank account payments only. Choose CREDIT_CARD, DIRECT_DEBIT.
registerPaymentAccount No Requires QuickVault. Set to true to register the payment account in QuickVault.
currencyCode Yes AUD or NZD
principalAmount No Provide the amount for the payment. When blank, the payer can enter this amount. Surcharges are calculated on top of this amount.
customerReferenceNumber No Provide a customer reference number.
paymentReference No Provide a payment reference for the transaction.
returnUrl No Provide the HTTPS URL to redirect the customer from the receipt page or to by-pass the receipt page and host your own.
cancelUrl No Provide the HTTPS URL to redirect to when the payer cancels the payment process.
errorEmailToAddress No Receive an email when the server to server notification fails. Override the value set in your QuickStream Portal security settings.
serverReturnUrl No Send the server to server notifications to this HTTPS URL. Override the value set in your QuickStream Portal security settings.
receiptEmailAddress No Provide an email address to instruct QuickWeb to send a payment receipt.
custom<ParameterName>
For example, customTitle or customPayeeName
No QuickWeb can display this data on the screen and/or pass it back to you in the payment notification. The parameter name must start with "custom" followed by an uppercase letter. Maximum 100 characters per parameter.

Parameters for handoff

Parameter Name Description
communityCode Your community code. See View your connection details.
token The token received as a response to the secure token request.

Linking from your website

To help explain how the handoff process works we will use the following example using QuickWeb. Your solution may have different webpages, however the actual handoff steps will be the same.

Secure token request handoff

This example has three pages. The first two pages are an example of what your website may display to the customer before you handoff to QuickWeb. The third page is an example of what QuickStream may display to the customer after the handoff.

Page Description
1 The 'Enter Details' page instructs the customer to enter their amount and payment reference. When the customer clicks the 'Next' button your website validates the data.
2 The 'Summary' page displays the amount and payment reference as read only fields. When the customer clicks the 'Next' button your website will handoff to QuickWeb. The amount and payment reference are passed to QuickWeb during the handoff.
3 The 'Payment Details' page displays the amount and payment reference as read only fields. Additional fields are also provided for the customer to enter their credit card details.

The following sequence diagram shows how the handoff works using the secure token request.

Note:

  • The section highlighted shows the handoff steps. They begin when the customer clicks the last button (or link) on your website.
  • Additional steps have been included before and after the grey box. These steps are specific to this particular example. They are not part of the handoff. They have been included to help demonstrate how the handoff can fit into the overall solution.

Sequence diagram for the handoff using a secure token

The steps for the sequence diagram are as follows:

Step Name Description
1 Enter data & click 'Next' Your website displays the 'Enter Details' page to the customer. The customer enters their amount and payment reference then clicks the 'Next' button.
2 Post form The customer's browser posts the form to your server.
3 Store data Your server validates the amount and payment reference. It then stores the data appropriately so that it can be retrieved later for the handoff.
4 Return html for summary page Your server produces html for the 'Summary' page. The summary page includes the amount and payment reference as read only data. This data is not included as hidden fields. Your server sends the html to the customer's browser.
5 Click 'Next' The 'Summary' page is displayed to the customer. The customer checks to make sure the data is correct then clicks the 'Next' button. The handoff begins here.
6 Send request The customer's browser sends the request to your server to initiate handoff.
7 Retrieve data Your server builds the parameter list that will be sent to QuickWeb as part of the secure token request.
8 Request security token Your server makes an outbound HTTPS connection to the QuickWeb server. The parameter list is included in the token request.
9 Generate security token & store parameters QuickWeb generates a security token and stores your parameter list. A unique token is created for every token request. For example: token=m378813qtvOtylVTvVvpWA7PT14QHltr-AqX2gZ-RFM. Note, the security token is valid for 1 hour after it is created and can only be used once.
10 Return security token QuickStream returns the security token to your server.
11 Redirect Your server tells the customer's browser to redirect to QuickWeb. A list of parameters is included in the redirect.
12 Request payment page The customer's browser redirects to QuickWeb. The list of parameters is included in the redirect.
13 Verify security token & lookup parameters QuickStream verifies the security token to make sure it has not been tampered with. It then uses the token to lookup the parameters that your server passed to QuickWeb during the security token request. The token is then destroyed.
14 Return html for payment page QuickWeb produces html for the 'Payment Details' page and sends it to the customer's browser. The handoff ends here.
15 Enter payment details The 'Payment Details' page is displayed to the customer. The customer enters their credit card details.

Sample code for the secure token request

Sample code for the secure token request

package com.qvalent.demo;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;

public class TokenRequestExample
{
    // This is the HTTP proxy configuration section.
    // To use basic authentication, other options
    // will have to be specified. This example
    // uses Windows domain-based NTLM authentication.
    // To use a direct connection, set USING_PROXY to false.
    private static final String HTTP_PROXY_URL_STRING =
        "proxy.yourdomain.com.au";
    private static final int HTTP_PROXY_PORT = 8080;
    private static final boolean USING_PROXY = true;
    private static final String TOKEN_REQEST_URL_STRING =
        "https://<environment_url>/CommunityTokenRequestServlet";

    // Here we are initialising a java.net.URL object.
    private static final URL TOKEN_REQUEST_URL =
        new URL( TOKEN_REQEST_URL_STRING );

    public static void main( final String[] args ) throws Exception
    {

        // Add username, password and customer reference number parameters
        // to the request.
        final Map<String, String> params =
            new HashMap<String, String>();
        params.put( "username", "username" );
        params.put( "password", "password" );
        params.put( "customerReferenceNumber", "CUSTOMER1" );
        final String content = getQuery( params );

        // Control block to use either proxy or direct connection.
        final HttpsUrlCOnnection connection;
        if( USING_PROXY )
        {
            final Proxy proxy = new Proxy( Proxy.Type.HTTP,
                                               new InetSocketAddress(
                                                   HTTP_PROXY_URL_STRING,
                                                   HTTP_PROXY_PORT ) );
            connection = (HttpsURLConnection)TOKEN_REQUEST_URL.openConnection( proxy );
        }
        else
        {
            connection = (HttpsURLConnection)TOKEN_REQUEST_URL.openConnection();
        }

        // Token request should be a HTTP POST for enhanced security.
        connection.setRequestMethod( "POST" );

        // The parameters are sent using url form encoding.
        connection.setRequestProperty(
            "Content-Type",
            "application/x-www-form-urlencoded" );

        // Add the content length and language.
        connection.setRequestProperty(
            "Content-Length",
            Integer.toString( content.length() ) );
        connection.setRequestProperty(
            "Content-Language",
            "en-au" );

        // We're going to write out post data and get the response (token),
        // so set both output and input.
        connection.setDoOutput( true );
        connection.setDoInput( true );
        // Set up a writer to write the http post data out.
        final BufferedWriter writer =
           new BufferedWriter(
               new OutputStreamWriter( connection.getOutputStream() ) );
        writer.write( content );
        writer.close(); // This will send the content.

        // Set up a reader to get the token result back from
        // the connection. Build it all up into one string.
        final BufferedReader reader =
           new BufferedReader(
               new InputStreamReader( connection.getInputStream() ) );
        String response = "";
        String buff;
        while( ( buff = reader.readLine() ) != null )
        {
            response += buff;
        }
        reader.close();

        // Print the full response.
        System.out.println( "Response: " + response );

        // Print the token, which will occur after "token="
        // and should be the only response parameter parameter.
        final String token =
            URLDecoder.decode(
                response.substring(
                    response.indexOf( "=" ) + 1 ) ,
                "UTF-8" );
        System.out.println( "Token: " + token );
    }

    // Helper method to construct a URL encoded query from
    // a map of string => string.
    private static String getQuery( final Map<String, String> params )
    throws Exception
    {
        String result = "";
        boolean first = true;
        for( final RequestParameter requestParameter : RequestParameter.values() )
        {
            if( first )
            {
                first = false;
            }
            else
            {
                result += "&";
            }
            result += URLEncoder.encode( requestParameter.getLabel(), "UTF-8" );
            result += "=";
            result += URLEncoder.encode(
                params.get( requestParameter.getLabel() ) == null ?
                "" :
                params.get( requestParameter.getLabel() ),
                "UTF-8" );
        }
        return result;
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Web;
using System.Collections;
namespace TokenRequestExample
{
    class TokenRequestExample
    {
        static void Main(string[] args)
        {
            byte[] byteArray;
            Stream webpageStream;
            StreamReader webpageReader;
            String webpageContent;
            Hashtable parameters = new Hashtable();
            parameters.Add("username", "username");
            parameters.Add("password", "password");
            parameters.Add("customerReferenceNumber", "CUSTOMER1");
            HttpUtility.UrlEncode("");
            String postData = "";
            Boolean first = true;
            foreach( String key in parameters.Keys )
            {
                if(first)
                {
                    first = false;
                }
                else
                {
                    postData += "&";
                }
                postData += key + "=" + HttpUtility.UrlEncode(parameters[key].ToString());
            }
            String URL = "https://<environment_url>/CommunityTokenRequestServlet";
            byteArray = Encoding.UTF8.GetBytes(postData);
            WebRequest request = WebRequest.Create(URL);
            WebProxy proxy = new WebProxy("proxy.yourdomain.com.au", 8080);
            proxy.UseDefaultCredentials = true;
            proxy.BypassProxyOnLocal = true;
            request.Proxy = proxy;
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            request.ContentLength = byteArray.Length;
            webpageStream = request.GetRequestStream();
            webpageStream.Write(byteArray, 0, byteArray.Length);
            webpageStream.Close();
            webpageReader = new StreamReader(request.GetResponse().GetResponseStream());
            webpageContent = webpageReader.ReadToEnd();
            Console.WriteLine(webpageContent);
            Console.ReadKey(true);
        }
    }
}
<?php
    $postFields = array( "username" => "username",
                         "password" => "password",
                         "customerReferenceNumber" => "CUSTOMER1" );
    $postFieldsString = http_build_query( $postFields );
    $curlHandle = curl_init();
    curl_setopt( $curlHandle, CURLOPT_URL, "https://<environment_url>/CommunityTokenRequestServlet" );
    if( array_key_exists( "user", $_POST ) &&
        array_key_exists( "pwd", $_POST ) )
    {
        curl_setopt( $curlHandle, CURLOPT_PROXY, "proxy.yourdomain.com.au:8080" );
        curl_setopt( $curlHandle, CURLOPT_PROXYUSERPWD, $_POST["user"].":".$_POST["pwd"] );
    }
    curl_setopt( $curlHandle, CURLOPT_POST, count( $postFields ) );
    curl_setopt( $curlHandle, CURLOPT_POSTFIELDS, $postFieldsString );
    curl_setopt( $curlHandle, CURLOPT_RETURNTRANSFER, 1 );
    curl_setopt( $curlHandle, CURLOPT_CAINFO, "PCA-3G5.pem" );
    curl_setopt( $curlHandle, CURLINFO_HEADER_OUT, 1 );
    $result = curl_exec( $curlHandle );
?>
<html>
    <head>
    </head>
    <body>
        <p> Header: <?php echo curl_getinfo( $curlHandle, CURLINFO_HEADER_OUT ); ?> </p>
        <?php
            if( curl_errno( $curlHandle ) )
            {
        ?>
                <p> Error: <?php echo curl_error( $curlHandle ); ?> </p>
        <?php
            }
            else
            {
        ?>
                <p> Token: <?php echo $result; ?> </p>
        <?php
            }
        ?>
    </body>
</html>
<?php   
    curl_close( $curlHandle );
?>