GT::Payment::Remote::WorldPay - WorldPay payment handling
One thing to note about WorldPay is that its security system is a little weak - you can't trust a callback post as actually being genuine, unless you use the callback password feature - and even at that it is not a terribly secure solution. In this regard, other payment provides have much cleaner transaction systems. Another shortcoming of WorldPay is that its callback system is somewhat weak - it won't try to inform you very hard: it tries once, but if it doesn't connect it gives up and doesn't try again, making it entirely possible and likely that you will have to manually add (or confirm) missing payments at some point, so supporting at least manual payment approval of initiated payments is absolutely required.
use GT::Payment::Remote::WorldPay;
use GT::CGI;
my $in = new GT::CGI;
GT::Payment::Remote::WorldPay->process(
param => $in,
on_valid => \&valid,
on_cancel => \&cancel,
on_recurring => \&recurring,
on_recurring_failed => \&recurring_failed,
on_recurring_cancelled => \&recurring_cancelled,
password => "123",
on_invalid_password => \&invalid_pw
);
sub valid {
# Update database - the payment has been made successfully.
}
sub cancel {
# Update database - the user has clicked the "Cancel" button, thereby
# cancelling the payment. You should take note of the cancellation.
}
sub on_recurring {
# Update database - a recurring payment has been made successfully.
}
sub on_recurring_failed {
# Update database - a recurring payment has failed.
}
sub on_recurring_cancelled {
# Update database - either the customer or the merchant has cancelled
# this recurring payment
}
sub on_invalid_password {
# Perhaps make a record - a payment callback was received without a
# valid password
}
This module is designed to handle WorldPay payment processing using WorldPay's ``Select Junior'' system and callback.
GT::CGI is the only requirement, however GT::MD5 is required in order to use the md5_signature function.
This module has only two functions. process() does the work of actually
figuring out what to do with a postback, and md5_signature() is used to
generate an MD5 signature for payment verification and security purposes. Both
functions can be imported into your package, and can be called as either method
or function.
process() is the main function provided by this module. It can be called as
either a function or class method, and takes a hash (not hash reference) of
arguments as described below.
process() should be called for WorldPay initiated postbacks. This can be set
up in your main CGI by looking for WorldPay-specific CGI parameters
('transStatus' is a good one to look for) or by making a seperate .cgi file
exclusively for handling WorldPay postbacks.
Additionally, it is strongly advised that database connection, authenticate,
etc. be performed before calling process() to ensure that the payment is
recorded successfully. WorldPay will not attempt to repost the form data if
your script produces an error, and the error will be shown to the customer.
The param argument, either on_valid or
on_recurring, and the password options
are required. Using MD5 signing as well is strongly advised.
You should record a cancelled payment in your application.
on_recurring. on_recurring is called when a successful recurring payment
has been made. on_recurring_failed is called for a failed recurring payment
(e.g. credit card declined). See
the Recurring charges section for more details.
Bear in mind that if you do not set up the on_recurring callback, recurring payments will be ignored.
The md5_signature() function takes a password (this must be set for the
WorldPay account), and a list of values and generates an appropriate WorldPay
MD5 signature, which should be included as the ``signature'' field. See
the MD5 signing section for more details.
To implement WorldPay payment processing, there are a number of steps required in addition to this module. Basically, this module handles only the postback stage of the WorldPay payment process.
Full WorldPay ``Select Junior'' information is available from the ``Select Junior Integration Guide'' available from www.worldpay.com.
This is done by creating a web form containing the following variables. Your
form, first of all, must make a post request to
https://select.worldpay.com/wcc/purchase.
Required fields are as follows:
1234
GBP
Blue T-Shirt, Medium
10a0491.
25.35
Additionally, in order to set up recurring payments, the WorldPay account must have ``FuturePay'' enabled, and then you need to use the following parameters.
The below parameters are used for the ``Regular FuturePay Agreements'' - there is also ``Limited FuturePay Agreements'' in which a maximum overall charge is set. For more information, see Repear Billing With FuturePay.
For FuturePay (recurring) payments, you still pass the required fields as normal, except for the amount field: amount can be passed as 0 or a value - if a value is specified, this will be treated as an immediate payment. So, for example, if you wanted to charge someone a monthly subscription of $10 starting today you would pass the following variables:
instId=1234 # (the merchant's installation reference here)
amount=10
cartId=8456a9264q314 # (Some random ID here that you generate)
currency=USD # (Whatever currency they are charging in goes here)
desc=Subscription For Something Cool # (Description of subscription)
option=0
normalAmount=10
startDelayUnit=3
startDelayMult=1
intervalUnit=3
intervalMult=1
Additionally, using WorldPay's MD5 signature feature is strongly recommended.
To enable this feature, provide a field ``signatureFields'', containing fields separated by ``:''. Although any fields can be used, ``amount:currency:cartId'' is recommended. Then, call:
my $md5 = GT::Payment::Remote::WorldPay::md5_signature(
$password, $amount, $currency, $cartId
);
$password should be a password provided by the user and known only to the user and WorldPay. The value returned should be passed as the ``signature'' variable.
This MD5 protection causes WorldPay to reject any faked payment requests and so is reasonably secure.
Before WorldPay postback notification can occur, you must instruct the user to enable the callback facility in the Customer Management System. Additionally, it is recommended that a proper URL to your CGI be specified there, or else pass along a ``MC_callback'' variable that points to the script _WITHOUT_ a leading http:// or https://. (e.g. MC_callback=www.example.com/callback.cgi).
Note that a WorldPay limitation prevents the callback protocol (http://) from being changed dynamically - whatever protocol is set for your callback URL in the Customer Management System will be used with the dynamic callback URL.
The typical way to implement all of this is as follows:
on_valid and
on_valid). If using a dedicated CGI script for WorldPay
callbacks, it should just call process(); otherwise, check for the CGI
parameter 'transStatus' and if present, call process().
http://support.worldpay.com - WorldPay Knowledge Base, containing many useful WorldPay manuals and instructions.
http://support.worldpay.com/kb/integration_guides/junior/integration/help/sjig.html - Select Junior Integration Guide, from which this documentation and module is primarily derived.
http://support.worldpay.com/kb/product_guides/futurepay/repeatbilling.html - Repeat Billing with FuturePay.
Jason Rhinelander
Copyright (c) 2004 Gossamer Threads Inc. All Rights Reserved. http://www.gossamer-threads.com/
Revision: $Id: WorldPay.pm,v 1.5 2004/02/26 16:55:39 jagerman Exp $
This module is designed for version 4.4 of the Select Junior payment integration.