| Business::OnlinePayment::Ogone - Online payment processing via Ogone |
Business::OnlinePayment::Ogone - Online payment processing via Ogone
use common::sense;
use Data::Dumper;
use Business::OnlinePayment;
my $tx = new Business::OnlinePayment('Ogone', pspid => 'fred',
login => 'bedrock_api',
password => 'fl1nst0ne' );
$tx->test_transaction(1); # remove when migrating to production env
$tx->content(
alias => 'Customer 1', # store (or use) an alias to the card_number (optional)
card_number => 4111111111111111,# you can use this number for testing
expiration => 12/15, # for testing: like MM/YY, but in the future
cvc => 432, # for testing: anything like /d{3}/
invoice_number => 54321, # primary transaction identifier
amount => 23.4, # only 2 decimals after . allowed
currency => 'EUR', # optional currency (EUR, USD, GBP, CHF, ...)
sha_type => 512, # optional SHA checksum (1, 256, 512)
sha_key => 'a_secret_key', # the key with which to salt (required if sha_type is defined)
address => 'Somestreet 234', # optional customer address
city => 'Brussels', # optional customer city
zip => 1000 # optional customer zip code
country => 'BE', # optional customer country (iso?)
);
eval { $tx->submit() };
if ($@) { die 'failed to submit to remote because: '.$@ };
if ( $tx->is_success() ) {
print 'transaction successful\n';
print Dumper({
ogone_ncerror => $tx->result_code,
ogone_payid => $tx->authorization });
} else {
print 'transaction unsuccessful: remote has raised an error\n';
print Dumper({
ogone_ncerrorplus => $tx->error_message,
http_post_args => $tx->http_args,
ogone_xml_response => $tx->result_xml,
ogone_raw_response => $tx->server_response });
}
This module interfaces Business::OnlinePayment with Ogone, a European Payment Provider. It is based on the Ogone DirectLink API.
Ogone accepted credit cards: American Express, MasterCard, VISA, AIRPLUS, Aurore, Billy, Cofinoga, Diners Club, JCB, Laser, Privilège, Solo, MaestroUK, UATP
is_success() check, Ogone::Status has more details
You have a choice when implementing credit card processing. You can pocess the money transfer in one or more steps. If you choose to go with one step, customers will be billed directly.
new()Not used directly. Creates a new instance. It's possible to pass credential infomation in the constructor.
my $tx = new Business::OnlinePayment('Ogone', pspid => 'fred', login => 'bedrock_api', password => 'fl1nst0ne');
content()This method takes a lot of parameters to prepare the transaction to be submitted. Depending on these parameters the
payment processor will act on them in different ways, you can consider it a sort of dispatch table. The main actors are
action, alias, win3ds.
content() internal parameter mappings
# credentials
login => 'USERID',
password => 'PSWD',
PSPID => 'PSPID',
# primary identifier
invoice_number => 'orderID',
# transaction identifiers (action = query)
payid => 'PAYID',
payidsub => 'PAYIDSUB',
# credit card data
card_number => 'CARDNO',
cvc => 'CVC',
expiration => 'ED',
alias => 'ALIAS',
# financial data
currency => 'Currency',
amount => 'amount',
# Ogone specific arguments
operation => 'Operation', # REN, DEL, DES, SAL, SAS, RFD, RFS
eci => 'ECI', # defaults 7: e-commerce with ssl (9: recurring e-commerce)
accepturl => 'accepturl',
declineurl => 'declineurl',
exceptionurl => 'exceptionurl',
paramplus => 'paramplus',
complus => 'complus',
language => 'LANGUAGE',
# Business::OnlinePayment common
description => 'COM',
name => 'CN',
email => 'EMAIL',
address => 'Owneraddress',
zip => 'OwnerZip',
city => 'ownertown',
country => 'ownercty',
phone => 'ownertelno',
# client authentication (not used directly, only here as valid HTTP POST arg)
SHASign => 'SHASign', # see sha_key, sha_type
# 3d secure arguments
flag3d => 'FLAG3D',
win3ds => 'win3ds',
http_accept => 'HTTP_ACCEPT',
http_user_agent => 'HTTP_USER_AGENT',
content() required parametersDepending on what action you are triggering a number of parameters are required. You can use the following pseudo perl code as a reference to what exactly is required depending on the parameters.
my @args_basic = qw/login password PSPID action/;
my @args_ccard = qw/card_number expiration cvc/;
my @args_alias = qw/alias cvc/;
my @args_new = @args_basic, qw/invoice_number amount currency/, has_cc_number() ? @args_ccard : @args_alias;
my @args_post = @args_basic, qw/invoice_number/;
my @query = @args_basic, qw/invoice_number/;
for ($action) {
qr/authorization only/i => required_arguments( @args_new ),
qr/normal authorization/i => required_arguments( @args_new ),
qr/post authorization/i => required_arguments( @args_post ),
qr/query/i => required_arguments( @query ),
}
content() examples
my %auth = ( pspid => 'fred', login => 'bedrock_api', password => 'fl1nst0ne' );
my $id = $session->get('orderid');
my $res = new Business::OnlinePayment('Ogone', %auth);
$res->content( invoice_number => $id, action => 'authorize only', alias => 'wilma flinstone', ... );
$res->submit();
if ( $res->is_success() ) {
$dbh->do('insert into tx_status_log (id,status) values (?,?)',undef,$id,"RES OK");
};
my $sal = new Business::OnlinePayment('Ogone', %auth);
$sal->content( invoice_number => $is, action => 'post authorization', ...);
$res->submit();
if ( $res->is_success() ) {
$dbh->do('insert into tx_status_log (id,status) values (?,?)',undef,$id,"SAL OK");
};
my $res = new Business::OnlinePayment('Ogone',%auth);
$res->content(alias => 'wilma flinstone', cvc => 123, ...);
$res->submit();
if ( $res->is_success() ) {
$dbh->do('insert into tx_status_log (id,status) values (?,?)',undef,$id,"RES OK");
};
Client Ogone HTTPS Bank
------------------------------------------------------------------------
1 +---|Authorize Only| orderID=1----------->. [RES]
|
2 *<---STATUS=5 ----------------------------'
=head2 Post Authorize
Client Ogone HTTPS Bank
------------------------------------------------------------------------
1 +---|Post Authorize| orderID=1----------->. [SAL]
|
2 *<---STATUS=91 PAYID=.. PAYIDSUB=.. ------+ (processing)
|
3 `----------->.
| (processed) +$
4 STATUS=9 .<-----------'
post authorize request (defaults to SAL)
=head2 Refund
Client Ogone HTTPS Bank
------------------------------------------------------------------------
1 .->+---|Query| orderID or PAYID,PAYIDSUB= -->.
| |
| .<----------------------------------------'
| |
2 STATUS == 9
|
3 `---|Refund| orderID or PAYID,PAYIDSUB= ->. [RFD]
|
4 *<-- STATUS=81 ---------------------------+ (processing)
|
5 `----------->.
| (processed) -$
6 STATUS=8 .<-----------'
To test this module you will need to set your credentials in the environment. Put the following in a file in your hoe directory e.g. ~/.ogone The password is not the same as the PSPID password, you will need to enter the API users' password.
OGONE_PSPID=bob
OGONE_USERID=bob_api
OGONE_PSWD=foobar
Limit access to the F<~/.ogone> file
chmod 600 ~/.ogone
Then load this file into your env en perform the testcases:
source ~/.ogone
perl -I lib/ t/*.t
[fred@triceratops ~/business-online-payment-ogone] $ curl -L http://cpanmin.us | perl - --self-upgrade
[fred@triceratops ~/business-online-payment-ogone] $ cpanm -S Devel::REPL
[fred@triceratops ~/business-online-payment-ogone] $ re.pl
001:0> use lib './lib';
002:0> use Business::OnlinePayment::Ogone;
003:0> my $tx = new Business::OnlinePayment('Ogone', pspid => 'fred', login => 'bedrock_api', password => 'fl1nst0ne');
bless( {
login => "bedrock_api",
passwprd => "fl1nst0ne",
port => 443,
processor => "Ogone",
pspid => "fred",
server => "secure.ogone.com"
}, 'Business::OnlinePayment::Ogone' )
004:0>
Ogone claims to encrypt your password where in fact in only hashes it using the SHA-1 algorithm. I suppose someone else wrote the accompanying texts, because the url states hash_pwsd.
Ofcourse hashing your password is a good thing. An intruder can only steal the hashed password and use it for the specified service until the password is changed and the hash becomes invalid. The advantage is the intruder could never 'read' your real typed in password should you have used it on other services.
But Ogone has made the hashing straight without a salt, which is a serious issue if you take rainbow tables into account. Using the rainbow table technique on an unsalted string allows an attacker to reverse engineer the password rather quickly.
Login into your test environment and goto https://secure.ogone.com/ncol/test/hash_pswd.asp to verify.
echo -n yourpass | sha1sum
It takes a while to approve your transaction. You will need to wait for its status to drop from 91 to 9. If your account type allows it, it's possible to refund by using another transaction. It was however not tested.
Ogone's support helpdesk will answer promptly within a day, also for test accounts. You will need to contact them if you would like to add some features like for example 3d-secure. Most of my helpdesk request have been resolved in matter of days.
You need to create a subaccount to access the API. Use that subaccount as the USERID or login. You will need to login with the password of the api user.
If you try to submit requests with a bad username or password your account can get blocked. To unblock your account you should go into the users panel and reactivate the account.
Configure the Ogone Test Backend or Ogone Prod Backend using the following settings:
$sha_type
$sha_key
| Business::OnlinePayment::Ogone - Online payment processing via Ogone |