Using the Moneris Hosted Payment Page with data preload to reduce card testing fraud
If you use Moneris for payment processing, its Hosted Payment Page with data preload increases security, reduces fraud, and ultimately saves the merchant money by reducing chargeback fees incurred by fraudulent card testing.
The What, Who, and Why?
Using the Hosted Payment Page integration without data preload allows third parties to abuse a merchant's payment page to test stolen credit card numbers more easily.
This integration type uses a form that has all the key information (hpp_key, ps_store_id and charge total) needed to call the payment page on Moneris' end directly to run such tests in quick succession.
This leads to issues for merchants as banks may issue chargebacks once the cards used are discovered stolen.
Furthermore, it can also lead to the merchant being banned or restricted by Moneris if too many fraudulent transactions are recorded against their account.
A Hosted Payment Page with data preload integration removes key pieces of information from public access and links each transaction to specific order values and individual user sessions that can only be used once. This makes it much harder for malicious actors to abuse the payment page.
A closer look at the preload solution
The preload feature and user flow are outlined as part of the Moneris developer documentation. We'll take a closer look at each step to outline the implementation and any gotchas along the way.
The Data Preload feature allows merchants to preload transaction data into the Hosted Pay Page through a direct server to server request. The Hosted Pay Page then returns an XML response containing a “ticket”. The ticket is then sent with the ps_store_id through the shopper’s browser in a request to the Hosted Pay Page. The Hosted Pay Page will then link the preloaded data to the browser request by using the ticket information after which the process will proceed as a regular Hosted Pay Page transaction. In a typical shopping cart checkout experience you must manage and ensure that preload requests correspond to the correct shopper’s browser session.
The steps required to achieve this are as follows:
- The customer arrives on the merchant’s website (application). At this point the merchant must determine the amount of the transaction and also collect any additional data.
- Once the cardholder is ready to pay, the merchant’s checkout page will submit an HTTPS POST using a server side programming language to the Moneris Hosted Pay Page (HPP) sending over all of the transaction data. NOTE: the cardholder will not be redirected yet.
- The Hosted Pay Page (HPP) will store this transaction data and respond back to the merchant’s site by sending an XML response containing a ticket number.
- The merchant’s checkout site will need to collect this response data, and build a new form POST to the Moneris Hosted Pay Page. At this time, the customer will be redirected from the merchant’s website to the Moneris Hosted Pay Page URL.
- On the Hosted Pay Page, the cardholder will fill in their secure payment details such as their card number and submit the transaction. At this time, Moneris will process the transaction and build a response.
- Once the merchant receives the response details they must provide a receipt to the customer and then may store these details for future purposes such as reporting or tracking.
Steps 1 and 2 seem to be the greatest source of confusion when dealing with the preload process. Developers might assume they need to redirect the user in order to get the preload data, and they get stuck trying to work out how to accomplish that without user interaction.
The good news is you don't need to, as Moneris notes in their documentation (emphasis added).
You can trigger the request for the data preload once the customer is ready to pay. This may be as they transition to the last page or last step of you checkout process, depending on whether you have a multi-page or single-page setup.
In a multi-page checkout, you can handle the request behind the scenes as the last page in your checkout process loads. All information for the order should be available at this point. Once the preload request has been made and its response is processed, you can then add a form with the preload ticket information and hosted payment page URL to that last page. Once the user submits that form, they're taken to a Moneris page to complete their payment.
In a single-page checkout, you could handle the request via an AJAX call to a script on your side as the user proceeds to the last step. Your script would handle the call to Moneris and process the response. It would then return the ticket information required to build the form. You could also let your script return the pre-built form HTML so it can be injected into the page directly. (See below for examples)
As with the multi-page checkout, once the user submits the form, Moneris takes over.
Example preload request/response handling script in PHP
// Moneris test gateway $url = 'https://esqa.moneris.com/HPPDP/index.php'; $post_data = array ( 'ps_store_id' => $ps_store_id, 'hpp_key' => $hpp_key, 'hpp_preload' => '', 'charge_total' => $charge_total, 'order_id' => $order_id ); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); // verifying the peer's certificate curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); // 2 to check the existence of a common name and also verify that it matches the hostname provided curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true ); curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); $response = curl_exec($ch); // not shown: handling no or invalid response curl_close($ch); // convert XML to array $xml = simplexml_load_string($response, "SimpleXMLElement", LIBXML_NOCDATA); $json = json_encode($xml); $response_data = json_decode($json, true); // not shown: check response data // - response code should be > 50 // - hpp_id, ticket and order_id should be present
Example preload response data
<?xml version="1.0" standalone="yes"?> <response> <hpp_id>2BIKLtb011</hpp_id> <ticket>hppEqsgxBTZe1Eb118ki</ticket> <order_id>my_order_id_123</order_id> <response_code>1</response_code> </response>
Example checkout form with preload ticket data
<form action="https://esqa.moneris.com/HPPDP/index.php" method="POST"> <input type="hidden" name="hpp_id" VALUE="2BIKLtb011"/> <input type="hidden" name="hpp_preload"/> <input type="hidden" name="ticket" VALUE="hppEqsgxBTZe1Eb118ki"/> <input type="submit" name="submit" VALUE="Continue to secure payment page"/> </form>
Note: The example uses Moneris' test gateway URL
This step is entirely on the Moneris end. How it looks and behaves is controlled by the various options available to configure the Hosted Payment Pages. Detailed documentation for these options is available.
How and if the customer returns to your store once Moneris has processed the transaction depends on the Response Method set in the Hosted Pay Page's Basic configuration.
If your implementation provides a payment confirmation, you select the POST, POST (XML), or GET response methods. The Accept URL and Decline URL for the script(s) that handle the response data on your side need to be set accordingly.
Hopefully the outline can help your client, board member, or boss understand the value of the preload feature, while the technical parts provide some additional insight on how to set up the integration.
If you have questions about any of the above, please get in touch or leave a comment below.