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:
- a dynamic backend which can send a
HTTPS POSTdirectly to QuickStream. - the ability to make an outbound
HTTPSconnection to QuickStream through your proxy and firewall. - your allowed IP addresses whitelisted in the QuickStream portal.
- your credentials from the QuickStream portal.
- the URLs for the secure token request and handoff in each environment.
The secure token handoff has two steps:
- Secure token request. Your server requests a Security Token from QuickStream.
- 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
¤cyCode=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.
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.
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 );
?>