Server-to-server notification
Server-to-server notifications allow you to receive payment or registration details after each payment or registration is made. This is done via a HTTPS POST
from QuickStream to your server. QuickStream posts the details as form parameters or as XML. This is also known as the server-to-server postback.
HTTPS
requests with parameters or XML
.
To receive a server to server notification
- Your website must provide the
serverReturnUrl
parameter in a secure token request, or configure your server to server notifications in the QuickStream portal. - Configure the domain whitelist in the QuickStream portal.
- Have a valid SSL certificate issued by a trusted certificate authority. Sending the notification over SSL ensures that the encrypted notification cannot be read by a malicious third-party. As your SSL certificate was issued by a trusted certificate authority, it also guarantees that QuickStream is connecting to your web server (and not another fraudulent server as in the case of DNS attacks).
- Have a dynamic backend which can receive and parse
HTTPS
requests with parameters or can parseXML
.
A server to server notification is sent after a successful payment or registration attempt.
When you receive a server to server notification
Your system perform these steps:
# | Step | Notes |
---|---|---|
1 | Check that the IP address matches the expected QuickStream IP address. | If they do not match you will return a status of 403 Forbidden . See IP addresses in Test and in Production. |
2 | Check that the Basic Auth username and password in the Authorization header match your credentials in QuickStream. |
If they do not match you will return a status of 403 Forbidden . |
3 | Extract the details. | The way you do this will depend on the way QuickStream has posted the details. You will either extract the details from the form parameters or extract the details from the XML. |
4 | Check to make sure you have not already processed a notification. | To do this for payments: compare the receiptNumber to the receipt numbers you have already processed. To do this for registrations: compare the preregistrationCode and customerReferenceNumber to the record you have already processed. |
5 | Save the registration details to your database. | |
6 | Your server returns a status of 200 OK . |
If an error occurred and you were unable to save the details, your server will instead return a status of 500 Internal Server Error . |
Note:
- If you are sending an account token
preregistrationCode
to make a payment, save a copy of the account token in your database or update that it was successfully registered. - If your system will calculate a card surcharge during payment, you may need to store the card scheme in your database now. This is only necessary if you intend to apply different surcharges to different card schemes.
- If your system is going to report expiring cards you will need to store the card expiry date.
Web payment notification parameters
These parameters can be sent for:
If you choose to receive the data as XML, the parameters listed below will instead be built into an XML document. This document will be passed to your server in the body of the request. The request will have a content-type of application/xml
.
Example HTTPS POST request
POST /payments HTTP/1.1
Authorization: Basic QVZURVNUOlFWVEXTVA==
Host: yourwebsite.com.au
Accept: text/html, text/xml, image/gif, image/jpeg, *; q=.2, */*; q=.2
User-Agent: Qvalent iConnect 7.0
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 436
surchargeAmount=0.03&cardScheme=VISA&paymentReference=123456&createdDateTime=06+Mar+2019+11%3A44%3A33&settlementDate=20190306&paymentAmount=32.11&summaryCode=0&responseCode=08&successFlag=true&sourceCode=net&responseDescription=Approved+or+completed+successfully&supplierBusinessCode=YOURBUSINESS&id_batch_entry=1241373591&receiptNumber=1241373591&communityCode=YOURCOMMUNITY&username=QUICKSTREAM_USERNAME&password=QUICKSTREAM_PASSWORD
Example XML POST request
POST /payments HTTP/1.1
Authorization: Basic QVZURVNUOlFWXEVTVA==
Host: yourwebsite.com.au
Accept: text/html, text/xml, image/gif, image/jpeg, *; q=.2, */*; q=.2
User-Agent: Qvalent iConnect 7.0
Connection: close
Content-Type: application/xml
Content-Length: 749
<PaymentResponse><sourceCode>net</sourceCode><receiptNumber>1241373591</receiptNumber><communityCode>YOURCOMMUNITY</communityCode><supplierBusinessCode>YOURBUSINESS</supplierBusinessCode><customerReferenceNumber></customerReferenceNumber><paymentReference>123456</paymentReference><paymentAmount>32.11</paymentAmount><surchargeAmount>0.03</surchargeAmount><cardScheme>VISA</cardScheme><settlementDate>20190306</settlementDate><createdDateTime>06 Mar 2019 11:44:33</createdDateTime><responseCode>08</responseCode><responseDescription>Approved or completed successfully</responseDescription><summaryCode>0</summaryCode><successFlag>true</successFlag><username>QUICKSTREAM_USERNAME</username><password>QUICKSTREAM_PASSWORD</password></PaymentResponse>
Parameter Name | Description |
---|---|
sourceCode |
The payment channel used to make the transaction. The values are net , adhoc and phone . |
receiptNumber |
The unique receipt number generated by QuickStream. This value can be used later to locate this payment in the QuickStream portal. |
communityCode |
Your community code. Provided in communityCode during the handoff. See View your connection details in the QuickStream portal. |
supplierBusinessCode |
Your supplier business code. Provided in supplierBusinessCode during handoff. See View your connection details in the QuickStream portal. |
paymentReference |
Provided in paymentReference during the handoff or entered by the payer. |
customerReferenceNumber |
A customer-level reference. Provided in customerReferenceNumber during the handoff or entered by the payer. |
paymentAmount |
The payment amount including surcharges. |
surchargeAmount |
The surcharge amount. |
cardScheme |
The card scheme. One of: VISA , MASTERCARD , AMEX , DINERS , UNIONPAY , JCB . |
settlementDate |
The settlement date of the payment. See Transaction settlement. |
createdDateTime |
The date and time of the transaction on the QuickWeb server in Sydney. Format: dd MMM yyyy HH:mm:ss . |
responseCode |
The two digit response code. See Response Codes. |
responseDescription |
The description of the response code. See Response Codes. |
summaryCode |
The one digit summary code. See Response Codes. |
successFlag |
true when the transaction was successful, otherwise false . |
Custom fields | Any custom parameters that you included in the handoff will be sent back to you. That is, any parameters prefixed with custom will be included in this notification. For example: customTitle , customPayeeName |
Web recurring payment notification parameters
These parameters can be sent for:
Parameter Name | Description |
---|---|
recurringScheduleCode |
The unique recurring payment schedule identifier. This value is provided in the Secure token handoff or generated by QuickWeb. |
recurringScheduleFirstDate |
The first date of the recurring payment schedule in yyyyMMdd format. For example, 20170110 . |
recurringScheduleFrequency |
The frequency. One of: DAILY , WEEKLY , FORNIGHTLY , MONTHLY , QUARTERLY , SIXMONTHLY , YEARLY . See Payment schedule frequencies. |
recurringSchedule |
The recurring payment schedule type. One of: CONTINUE_UNTIL_FURTHER_NOTICE , CONTINUE_UNTIL_DATE , STOP_AFTER_SET_NUMBER_OF_PAYMENTS , STOP_AFTER_SET_AMOUNT , ONE_OFF . See Payment schedule types. |
recurringScheduleTotalAmount |
The total amount of the schedule. |
recurringScheduleNumberOfPayments |
The number of payments remaining in the schedule. |
recurringScheduleContinueUntilDate |
The last payment date of the schedule. Provided for CONTINUE_UNTIL_DATE schedule types only. |
Web invoice payment notification parameters
These parameters can be sent for:
Parameter Name | Description |
---|---|
invoice/invoiceNumber |
An invoice number allocated to this transaction. |
invoice/paymentAmount |
The amount allocated to the invoice, paid by this transaction. |
comment |
The dispute/comment box text. |
Web tokenisation notification parameters
These parameters can be sent for QuickVault Web registration.
If you choose to receive the data as XML, the parameters listed in the table above will instead be built into an xml document. This document will be passed to your server in the body of the request. The request will have a content-type of application/xml.
Example HTTPS POST request
POST /accounts HTTP/1.1
Authorization: Basic QVZURVNUOlFWXEVTVA==
Host: yourwebsite.com.au
Accept: text/html, text/xml, image/gif, image/jpeg, *; q=.2, */*; q=.2
User-Agent: Qvalent iConnect 7.0
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 338
product=QUICKVAULT&customerReferenceNumber=123456&cardScheme=VISA&cardholderName=Jane+Smith&supplierBusinessCode=YOURBUSINESS&expiryDateYear=2022&preregistrationCode=1WKRMZ4242&connectionType=QUICKWEB&maskedCardNumber=424242...242&expiryDateMonth=01&communityCode=YOURCOMMUNITY&username=QUICKSTREAM_USERNAME&password=QUICKSTREAM_PASSWORD
Example XML POST request
POST /accounts HTTP/1.1
Authorization: Basic QVZURVNUOlFWXEVTVA==
Host: yourwebsite.com.au
Accept: text/html, text/xml, image/gif, image/jpeg, *; q=.2, */*; q=.2
User-Agent: Qvalent iConnect 7.0
Connection: close
Content-Type: application/xml
Content-Length: 594
<PaymentResponse><connectionType>QUICKWEB</connectionType><product>QUICKVAULT</product><communityCode>YOURCOMMUNITY</communityCode><supplierBusinessCode>YOURBUSINESS</supplierBusinessCode><customerReferenceNumber>123456</customerReferenceNumber><cardScheme>VISA</cardScheme><cardholderName>Jane Smith</cardholderName><maskedCardNumber>424242...242</maskedCardNumber><expiryDateMonth>01</expiryDateMonth><expiryDateYear>2022</expiryDateYear><preregistrationCode>1WKRMZ4242</preregistrationCode><username>QUICKSTREAM_USERNAME</username><password>QUICKSTREAM_PASSWORD</password></PaymentResponse>
Parameter Name | Description |
---|---|
product |
This will be hardcoded to QUICKVAULT . |
communityCode |
Your QuickStream community code. You will be notified of your community code during the implementation. Note, this is the same value that you will pass to QuickVault during the handoff. |
supplierBusinessCode |
Your QuickStream supplier business code. This value will be provided to you during the implementation. Note, this is the same value that you will pass to QuickVault during the handoff. |
connectionType |
QUICKWEB , QUICKCONNECT |
customerReferenceNumber |
The same customerReferenceNumber value you provided in the handoff. |
cardholderName |
The cardholder name entered by the customer. For example: John Smith |
maskedCardNumber |
The masked card number. For example: 456471...004 |
expiryDateMonth |
The expiry month entered by the customer. Format: MM For example: 01 |
expiryDateYear |
The expiry year entered by the customer. Format: YYYY For example: 2017 |
cardScheme |
The type of card the customer registered. QuickVault will return one of the following values: VISA , MASTERCARD , AMEX , DINERS , UNIONPAY , JCB |
bsb |
The BSB number entered by the customer. For security reasons the number will be masked. For example: xxx-000 |
accountNumber |
The account number entered by the customer. For security reasons the number will be masked. For example: xxxxxx678 |
accountName |
The account name entered by the customer. |
preregistrationCode |
The account token. |
Custom fields | Any custom parameters you included in the handoff will be sent back to you. That is, any parameters prefixed with custom will be included in the postback. For example: customTitle , customAddress |
Sample code for consuming the notification
Sample for consuming the notification
public class NotificationConsumer extends HttpServlet
{
...
@Override
protected void doPost( final HttpServletRequest request,
final HttpServletResponse response ) throws IOException
{
try
{
if( !request.getRemoteAddr().equals( QUICKSTREAM_IP_ADDRESS ) ) {
response.sendError( HttpServletResponse.SC_FORBIDDEN );
return;
}
final String authorization = request.getHeader( "Authorization" );
if( authorization == null ) {
return;
}
String base64Credentials = authorization.substring( "Basic".length() ).trim();
String credentials = new String( Base64.getDecoder().decode( base64Credentials ), Charset.forName( "UTF-8" ) );
final String[] values = credentials.split(":",2);
if( !QUICKSTREAM_USERNAME.equals( values[0] ) || !QUICKSTREAM_PASSWORD.equals( values[1] ) ) {
response.sendError( HttpServletResponse.SC_FORBIDDEN );
return;
}
response.setStatus( HttpServletResponse.SC_OK );
for( final String name : request.getParameterMap().keySet() ) {
for( final String value : request.getParameterMap().get( name ) ) {
// Consume
}
}
}
catch( final Exception e ) {
response.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
}
return;
}
}
<?php
header( "Content-Type: text/plain" );
if ( $_SERVER["REMOTE_ADDR"] != QUICKSTREAM_IP_ADDRESS ) {
header("HTTP/1.1 403 FORBIDDEN");
return;
}
if ( !isset($_SERVER['PHP_AUTH_USER'] ) || !isset( $_SERVER['PHP_AUTH_PW'] ) ) {
header("HTTP/1.1 401 UNAUTHORIZED");
return;
}
if ( $_SERVER['PHP_AUTH_USER'] != QUICKSTREAM_USERNAME || $_SERVER['PHP_AUTH_PW'] != QUICKSTREAM_PASSWORD ){
header("HTTP/1.1 403 FORBIDDEN");
return;
}
if( $_SERVER["REQUEST_METHOD"] === "POST" ) {
try {
foreach( $_POST as $key => $value ) {
// consume
}
header("HTTP/1.1 200 OK");
} catch (Exception $e) {
header("HTTP/1.1 500 INTERNAL SERVER ERROR");
}
}
return;
?>