Business::OnlinePayment::WorldPay::Junior version 1.00 ====================================================== This module provides a simple way to handle transactions sent to WorldPay for payment when using the WorldPay Select Junior service. This module aims for simplicity. All it does is track the transaction and then verify the callback data supplied by WorldPay after a payment has been made. The module is designed with the requirement to immediately verify that a payment has been made and is as expected in mind. See the USAGE section below for details on how to integrate this module in your scripts. INSTALLATION To install this module type the following: perl Makefile.PL make make install You will also need to create a couple of tables in a mysql database as per the mysql.schema file in this distribution. Optionally you can also set up cron to run the included get-rates.pl script each evening. This should be run between 18:00 and 23:59 (GMT/BST - ie UK time) and will obtain the exchange rates for the next working day. While this is not compulsory without it the module will not work where your customer has changed the currency for the transaction at WorldPay. DEPENDENCIES This module requires these other modules and libraries: DBI DBD::mysql This module requires MySQL in order to store the transaction details and is written to make use of MySQL specific functions. The module only requires one table - called "worldpay" so you can use an existing database if you need to although you should be careful to ensure that the permissions on the database you use are suitable given that it will contain financially sensitive data. The file mysql-schema included with the distribution of this details the schema for the MySQL "worldpay" table. The get-rates.pl script also depends upon the following: LWP::UserAgent Crypt::SSLeay USAGE In order to use this module you must register your transaction with the module before sending the user to WorldPay for payment. Then when WorldPay callback to your server with the transaction confirmation details you simply pass all of the CGI parameters to the module to confirm that the transaction is valid. Remember that you need to configure your WorldPay account (using the WorldPay Merchant Management pages at http://support.worldpay.com/admin/) to use the Callback facility which can be pointed at either a dedicated callback processing script or the script that originally sent the user to WorldPay for payment processing - or, indeed, any other script. As far as the module is concerned it does not matter what script handles the callback. Note that this module does not generate any output for either the user or WorldPay. That is the job of your script. To start using WorldPay::Junior you need to initialise the module in your script using the "new" method like so: use Business::OnlinePayment::WorldPay::Junior; my $wp = Business::OnlinePayment::WorldPay::Junior->new( db => 'worldpay', dbuser => 'worldpay', dbpass => 'wppass', host => 'localhost' ); The db, dbuser and dbpass parameters are compulsory and should be the database that the worldpay table is located within and the mysql username and password with select, insert and update privileges on that table. Optionally you can specify a host parameter to point to the host where the database is located. If this is not specified it defaults to localhost. Do remember to test that the call to new succeeded as if you have not correctly passed the required details it will fail. This does the trick nicely: if ( ! $wp ) { # deal with it. Note that there should be an error message in # $Business::OnlinePayment::WorldPay::Junior::errstr detailing why it failed. } Once you have initialised the module you can carry on to either register a new transaction, process a callback or check whether a given transaction has already been authorised. To register a new transaction you use the "register" method like so: my $cartId = $wp->register(\%transaction_details); As you can see the actual transaction details are passed as a reference to a hash. The hash typically looks like this: my %transaction_details = ( amount => 12.50, desc => "A Test Transaction", instId => '99999', currency => 'GBP', ); The details above are the only ones that are necessary to register a new transaction and all correspond to the standard WorldPay parameters - do note that they are case sensetive. The $cartId variable returned should be used for the WorldPay cartId parameter. It is generated by an auto-incrementing field in the database so it's pretty much guaranteed to be unique for that database. Once you have registered your transaction you should send the user to the WorldPay website for payment - I usually just print a simple page to the user informing them of the amount owing and what it is for with a simple "Click here to pay" button. It's a simple HTML form. The Callback WorldPay offer a facility whereby they will connect to a designated URL on your website (configured via the Merchant Management Pages) and immediately confirm to you whether the payment was completed successfully or was cancelled (you'll never be told of a declined transaction - see the WorldPay website for details) and the full details of a completed transaction. Web forms, as used in the Select Junior system, are not safe from users tampering with them so it is important to verify that the authorised payment details are correct before acting upon them. To do this you use the "callback" method. Before you actually verify the callback data, however, you need to ensure that the callback is authentic - ie that it originates from the WorldPay callback servers and, optionally, that the callback password is correct. To check that the source of the callback is authentic you simply call the "valid_callback_host" method like this: if ( ! $wp->valid_callback_host($cgi->remote_host) ) { # Invalid callback host - handle the error. # You should probably bring this security violation to the attention of # a real person within your organisation. } Note that remote_host is the CGI method so you need to have the CGI module loaded for this, which I've assumed you will as you are handling data provided by that means anyway. Also note that this module assumes that you are not carrying out reverse resolution on connections to your web site so it expects a standard IPv4 address - ie something like 192.168.234.12. If you have specified that there should be a callback password check this in your script. Assuming that the callback source is authentic and, optionally, that the callback password is valid you can carry on to process the actual callback data. Like the "register" method, detailed above, the "callback" method expects you to pass the details via a reference to a hash. If you tell the CGI module that you want to use the functionality of cgi-lib - by using CGI with qw (:cgi-lib) as an arguement - you can make use of the CGI "Vars" method which is the easiest way to this this: my %callback_data = $cgi->Vars; if ( ! $wp->callback(\%callback_data) ) { # The data supplied in the callback is not valid # You can get more information about the problem by calling # $wp->errstr which will return an error string } The "callback" method only verifies that the data in the callback is correct and matches a registered transaction. It does not tell you whether the transaction was authorised or not. To check whether a transaction was authorised by WorldPay use the "authorised" method like so: my $cartId = $cgi->param('cartId); if ( ! $wp->authorised($cartId) ) { # This transaction was NOT authorised } That is all there is to using this module. Note that the "callback" method stores all the relevant information about the transaction in the worldpay table in the database so you can check this any time you wish to verify the cardholder details, etc. COPYRIGHT AND LICENCE Copyright (C) 2002 Jason Clifford This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. A copy of the GNU General Public License is in the accompanying COPYING file.