Business-WebMoney
view release on metacpan or search on metacpan
lib/Business/WebMoney.pm view on Meta::CPAN
package Business::WebMoney;
use 5.008000;
use strict;
use warnings;
use utf8;
our $VERSION = '0.11';
use Carp;
use LWP::UserAgent;
use XML::LibXML;
use HTTP::Request;
use File::Spec;
use POSIX();
sub new
{
my ($class, @args) = @_;
my $opt = parse_args(\@args, {
p12_file => 'mandatory',
p12_pass => undef,
timeout => 20,
ca_file => undef,
});
my $ca_file = $opt->{ca_file};
$ca_file or ($ca_file) = grep(-r $_, map(File::Spec->catdir($_, qw(Business WebMoney WebMoneyCA.crt)), @INC));
$ca_file or warn "Business/WebMoney/WebMoneyCA.crt missing";
my $self = {
p12_file => $opt->{p12_file},
p12_pass => $opt->{p12_pass},
timeout => $opt->{timeout},
ca_file => $ca_file,
};
return bless $self, $class;
}
sub parse_args
{
my ($args_list, $fields) = @_;
if (@$args_list % 2) {
croak 'Unpaired arguments';
}
my %args;
while (@$args_list) {
my $key = shift @$args_list;
my $value = shift @$args_list;
exists($fields->{$key}) or croak "Unknown argument $key";
exists($args{$key}) and croak "Argument $key specified multiple times";
$args{$key} = $value;
}
while (my ($key, $value) = each(%$fields)) {
unless (exists($args{$key})) {
if ($value && $value eq 'mandatory') {
croak "Mandatory argument $key not specified";
} else {
lib/Business/WebMoney.pm view on Meta::CPAN
POSIX::setlocale(&POSIX::LC_ALL, $old_locale);
return $res;
}
sub do_request
{
my ($self, %args) = @_;
$self->{errstr} = undef;
$self->{errcode} = undef;
my $req_fields = parse_args($args{args}, { %{$args{arg_rules}}, debug_response => undef });
my $doc = XML::LibXML::Document->new('1.0', 'UTF-8');
my $request = $doc->createElement('w3s.request');
$doc->setDocumentElement($request);
my $node = $doc->createElement('reqn');
$request->appendChild($node);
$node->appendChild($doc->createTextNode($req_fields->{reqn}));
delete $req_fields->{reqn};
my $data_node = $doc->createElement($args{req_tagname});
$request->appendChild($data_node);
while (my ($key, $value) = each %$req_fields) {
next unless defined $value;
next if $key eq 'debug_response';
my $node = $doc->createElement($key);
$data_node->appendChild($node);
$node->appendChild($doc->createTextNode($value));
}
my $res = eval {
local $SIG{__DIE__};
# Warning! Thread unsafe!
local %ENV = %ENV;
$ENV{HTTPS_PKCS12_FILE} = $self->{p12_file};
$ENV{HTTPS_PKCS12_PASSWORD} = $self->{p12_pass};
$ENV{HTTPS_CA_FILE} = $self->{ca_file};
my $req_data = $doc->serialize;
utf8::encode($req_data) if utf8::is_utf8($req_data);
my $res_content;
unless ($res_content = $req_fields->{debug_response}) {
my $ua = LWP::UserAgent->new;
$ua->timeout($self->{timeout} + 1);
my $req = HTTP::Request->new;
$req->method('POST');
$req->uri("https://w3s.wmtransfer.com/asp/XML$args{func}Cert.asp");
$req->content($req_data);
my ($res, $timeout);
eval {
local $SIG{__DIE__};
local $SIG{ALRM} = sub {
$timeout = 1;
};
alarm($self->{timeout});
$res = $ua->request($req);
alarm(0);
};
if ($timeout) {
$self->{errcode} = -1001;
$self->{errstr} = 'Connection timeout';
return undef;
} elsif (!$res->is_success) {
$self->{errcode} = $res->code;
$self->{errstr} = $res->message;
return undef;
}
$res_content = $res->content;
}
my $parser = XML::LibXML->new;
my $doc = $parser->parse_string($res_content);
if (my $retval = $doc->findvalue('/w3s.response/retval')) {
$self->{errcode} = $retval;
$self->{errstr} = $doc->findvalue('/w3s.response/retdesc');
return undef;
}
my ($result_node) = $doc->getElementsByTagName($args{result_tag});
if ($args{result_format} eq 'list') {
[ map { result_node($_) } grep { $_->isa('XML::LibXML::Element') } $result_node->childNodes ];
} elsif ($args{result_format} eq 'hash') {
result_node($result_node);
} else {
1;
}
};
( run in 0.645 second using v1.01-cache-2.11-cpan-acf6aa7dc9e )