package WWW::ModulrFinance;
use strict;
use 5.008_005;
our $VERSION = '0.02';
use LWP::UserAgent;
use HTTP::Date qw/time2str/;
use Digest::HMAC_SHA1 qw(hmac_sha1);
use MIME::Base64;
use URI::Escape qw/uri_escape/;
use Carp qw/croak/;
use JSON;
sub new {
my $class = shift;
my %params = @_ % 2 ? %{$_[0]} : @_;
$params{api_key} or croak "api_key is required";
$params{hmac_secret} or croak "hmac_secret is required";
$params{base_url} ||= 'https://api-sandbox.modulrfinance.com/api-sandbox/';
$params{ua} ||= LWP::UserAgent->new(agent => "WWW-ModulrFinance-$VERSION");
return bless \%params, $class;
}
sub get_accounts {
(shift)->request('GET', 'accounts', @_);
}
sub get_account {
my ($self, $id) = @_;
return $self->request('GET', 'accounts/' . $id);
}
sub update_account {
my ($self, $id, $data) = @_;
return $self->request('PUT', 'accounts/' . $id, $data);
}
sub get_customer_accounts {
my ($self, $cid, $params) = @_;
return $self->request('GET', 'customers/' . $cid . '/accounts', $params);
}
sub create_customer_account {
my ($self, $cid, $data) = @_;
return $self->request('POST', 'customers/' . $cid . '/accounts', $data);
}
sub get_transactions {
my ($self, $id, $params) = @_;
return $self->request('GET', 'accounts/' . $id . '/transactions', $params);
}
sub get_payments {
my ($self, $params) = @_;
$self->request('GET', 'payments', $params);
}
sub post_payments {
my ($self, $data) = @_;
return $self->request('POST', 'payments', $data);
}
sub post_batchpayments {
my ($self, $data) = @_;
return $self->request('POST', 'batchpayments', $data);
}
sub get_batchpayment {
my ($self, $id) = @_;
return $self->request('GET', 'batchpayments/' . $id);
}
sub request {
my ($self, $method, $uri, $data) = @_;
my $url = $self->{base_url} . $uri;
if ($method eq 'GET' and $data) {
my $uri = URI->new($url);
$uri->query_form($data);
$url = $uri->as_string;
$data = undef; # don't be in POST content
}
my $req = HTTP::Request->new($method => $url => $self->__signature());
$req->content(encode_json($data)) if $data;
# print Dumper(\$req); use Data::Dumper;
my $res = $self->{ua}->request($req);
if ($res->header('Content-Type') =~ 'json') {
return decode_json($res->content);
}
croak $res->status_line unless $res->is_success;
return $res->content;
}
sub __signature {
my ($self) = @_;
my $date = time2str(time());
my $nonce = time() . '-' . $$ . '-' . rand(100000);
my $str = "date: $date\nx-mod-nonce: $nonce";
my $sig = uri_escape(encode_base64(hmac_sha1($str, $self->{hmac_secret}), ''));
# Authorization: Signature keyId="57502612d1bb2c0001000025fd53850cd9a94861507a5f7cca236882",algorithm="hmac-sha1",headers="date x-mod-nonce",signature="WBMr%2FYdhysbmiIEkdTrf2hP7SfA%3D"
return [
'Date' => $date,
'x-mod-nonce' => $nonce,
'Authorization' => qq~Signature keyId="~ . $self->{api_key} . qq~",algorithm="hmac-sha1",headers="date x-mod-nonce",signature="$sig"~,
"Content-Type" => "application/json;charset=UTF-8",
];
}
1;
__END__
=encoding utf-8
=head1 NAME
WWW::ModulrFinance - Modulr API
=head1 SYNOPSIS
use WWW::ModulrFinance;
my $modulr = WWW::ModulrFinance->new(
api_key => $ENV{MODULR_APIKEY},
hmac_secret => $ENV{MODULR_HMAC_SECRET},
);
my $res = $modulr->get_accounts;
say Dumper(\$res);
=head1 DESCRIPTION
WWW::ModulrFinance is for L<https://modulr-technology-ltd.cloud.tyk.io/portal/api-overview/>
=head1 METHODS
=over 4
=item * get_accounts
=item * get_account($id)
=item * update_account($id, $data)
=item * get_customer_accounts($cid)
=item * create_customer_account($cid, $data)
=item * get_transactions($id, { size => 100, ... })
=item * get_payments
=item * post_payments
=item * post_batchpayments
=item * get_batchpayment($id)
=back
=head1 AUTHOR
Fayland Lam E<lt>fayland@gmail.comE<gt>
=head1 COPYRIGHT
Copyright 2016- Fayland Lam
=head1 LICENSE
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
=head1 SEE ALSO
=cut