Business-TrueLayer
view release on metacpan or search on metacpan
v0.05
# SYNOPSIS
my $TrueLayer = Business::TrueLayer->new(
# required constructor arguments
client_id => $truelayer_client_id,
client_secret => $truelauer_client_secret,
kid => $truelayer_kid,
private_key => '/path/to/private/key',
# optional constructor arguments (with defaults)
host => 'truelayer.com',
api_host => 'api.truelayer.com',
auth_host => 'auth.truelayer.com',
);
# valid your setup (neither required in live usage):
$TrueLayer->test_signature;
my $access_token = $TrueLayer->access_token;
v0.05
=head1 SYNOPSIS
my $TrueLayer = Business::TrueLayer->new(
# required constructor arguments
client_id => $truelayer_client_id,
client_secret => $truelauer_client_secret,
kid => $truelayer_kid,
private_key => '/path/to/private/key',
# optional constructor arguments (with defaults)
host => 'truelayer.com',
api_host => 'api.truelayer.com',
auth_host => 'auth.truelayer.com',
);
# valid your setup (neither required in live usage):
$TrueLayer->test_signature;
my $access_token = $TrueLayer->access_token;
lib/Business/TrueLayer.pm view on Meta::CPAN
v0.05
=head1 SYNOPSIS
my $TrueLayer = Business::TrueLayer->new(
# required constructor arguments
client_id => $truelayer_client_id,
client_secret => $truelauer_client_secret,
kid => $truelayer_kid,
private_key => '/path/to/private/key',
# optional constructor arguments (with defaults)
host => 'truelayer.com',
api_host => 'api.truelayer.com',
auth_host => 'auth.truelayer.com',
);
# valid your setup (neither required in live usage):
$TrueLayer->test_signature;
my $access_token = $TrueLayer->access_token;
lib/Business/TrueLayer/Request.pm view on Meta::CPAN
has payment_host => (
is => 'ro',
isa => 'Str',
required => 0,
lazy => 1,
default => sub ( $self ) {
return join( '.','payment',$self->host );
}
);
has 'private_key' => (
is => 'ro',
isa => 'EC512:PrivateKey',
coerce => 1,
required => 0,
);
has '_ua' => (
is => 'ro',
isa => 'UserAgent',
required => 0,
lib/Business/TrueLayer/Request.pm view on Meta::CPAN
);
has 'signer' => (
is => 'ro',
isa => 'Signer',
lazy => 1,
default => sub ( $self ) {
Business::TrueLayer::Signer->new(
kid => $self->kid,
private_key => $self->private_key,
);
},
);
sub idempotency_key ( $self ) {
return Data::GUID->new->as_string;
}
sub api_post (
$self,
lib/Business/TrueLayer/Signer.pm view on Meta::CPAN
use Business::TrueLayer::Types;
use Crypt::JWT qw/ encode_jwt /;
has 'kid' => (
is => 'ro',
isa => 'Str',
required => 1,
);
has 'private_key' => (
is => 'ro',
isa => 'EC512:PrivateKey',
coerce => 1,
required => 1,
);
sub sign_request (
$self,
$http_verb,
$absolute_path,
$idempotency_key,
$serialized_http_request_body = undef,
) {
$http_verb = uc( $http_verb );
my $jws_token = encode_jwt(
alg => 'ES512',
key => $self->private_key,
extra_headers => {
kid => $self->kid,
tl_version => "2",
tl_headers => "Idempotency-Key",
},
payload => join(
"\n",grep { defined }
"$http_verb $absolute_path",
t/business/truelayer/signer.t view on Meta::CPAN
use FindBin qw/ $Bin /;
use Crypt::JWT qw/ decode_jwt /;
use Crypt::PK::ECC;
use_ok( 'Business::TrueLayer::Signer' );
# private key for test generated with:
# openssl ecparam -genkey -name secp521r1 -noout \
# -out ec512-private-key-FOR-TEST.pem
my $private_key = "$Bin/../../ec512-private-key-FOR-TEST.pem";
my $public_key = "$Bin/../../ec512-public-key-FOR-TEST.pem";
isa_ok(
my $Signer = Business::TrueLayer::Signer->new(
kid => "9f2b7bd6-c055-40b5-b616-120ccfd33c49",
private_key => $private_key,
),
'Business::TrueLayer::Signer',
);
foreach my $serialized_http_request_body (
'{"currency":"GBP","amount_in_minor":100}',
undef,
) {
ok(
my ( $jws_detached,$jws_full ) = $Signer->sign_request(
t/business/truelayer/webhook.t view on Meta::CPAN
use Mojo::JWT;
use Mojo::JSON;
use Crypt::OpenSSL::RSA;
use_ok( 'Business::TrueLayer::Webhook' );
# generate a JWT we can use for testing - we can't use anything from
# TrueLayer as we a) don't know their private key for signing the JWT,
# and b) can't be sure the the details from the jwks will not change
my $private_key = "-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDLy/mVwBQmT76UNIilJd+d3t0SxjMWDthb77WgfNZ2f3/TxhUH
re3Mr/AgNSTzXz8GQSuWwgY9HwiDcp6c6eHnQWY/mF0/ig3BDDHIWjySaFc09Kfb
V4sWpte5KhS3M+FTzMtbdfZtp48R0wp8HHnduKchlrh6Vt+fNCdlXCzBYwIDAQAB
AoGAL9eFkvMRh+Dmk3I1tddLRItiCJtAuOfpQMPoNnG4Av9xaayxmSjqj0eqLlVr
hDqS2AwKiIyp3EVhwUHyHFIHdtAp/DhLMNymA6cOYZ+pSIQyF+1e/Q7KsitKrQht
YHzjC8P7lWMK5nfzrSEz9ykRtqO0yRMUJ+E12I4O/xkgV4kCQQDq0qGaSHl/cYcI
ibQJEUbHGhOscsSg61MmbsSQt2pfMPo7oP1fPaYcysLRmbg+ZTx8YfDDMR6R+CDX
uVl2D6udAkEA3i0LXB8JolUBEoxle/e59X3SmjVqFNMp/ClA9NeRttyiMsesCOf6
OouEMBAiDAZKlgznFPfoyJYQOakdSQMQ/wJBANKrXWg5FSeNBoRWZjqsUT9W2ceg
v19PQC3+ukLLCpeULStJ54aGnHzAO8AnlPAFixpcE9BKRQ7X+T8Qfn442NECQEwT
t/business/truelayer/webhook.t view on Meta::CPAN
algorithm => 'RS512',
header => {
kid => "3f1266344cc2e6c2d8ede78240de88",
jku => 'https://webhooks.truelayer-sandbox.com/.well-known/jwks',
},
claims => {
"type" => "mandate_authorized",
"event_version" => 1,
"authorized_at" => "2024-08-23T07:26:33Z"
},
secret => $private_key,
);
my $jwt = Mojo::JWT->new( %payload )->encode;
my $Webhook = Business::TrueLayer::Webhook->new({
jwks => $jwkset,
jwt => $jwt,
});
isa_ok( $Webhook,'Business::TrueLayer::Webhook','with jwks' );
/path/to/working/business-truelayer > cat business-truelayer-credentials.json
{
"application_name" : "your_test_application_name",
"client_id" : "your_client_id"",
"client_secret" : "your_client_secret"",
"host" : "truelayer-sandbox.com",
"api_host" : "api.truelayer-sandbox.com",
"auth_host" : "auth.truelayer-sandbox.com",
"kid" : "your_kid"",
"private_key" : "/path/to/working/business-truelayer/your-ec512-private-key.pem"
}
you will need to update the various values as defined by your sandbox
setup, and create yourself a private and public key (see TrueLayer's)
docs for that
having created that you can run:
TRUELAYER_CREDENTIALS=business-truelayer-credentials.json prove -lr xt/
( run in 0.275 second using v1.01-cache-2.11-cpan-4d50c553e7e )