Business-TrueLayer

 view release on metacpan or  search on metacpan

README.md  view on Meta::CPAN

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;

README.pod  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.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' );

xt/README  view on Meta::CPAN


    /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 )