Business-GoCardless
view release on metacpan or search on metacpan
lib/Business/GoCardless/Client.pm view on Meta::CPAN
%{ $data->{redirect_flows} }
);
return $RedirectFlow->redirect_url;
}
sub _confirm_redirect_flow {
my ( $self,$redirect_flow_id,$session_token ) = @_;
# first find the original session token
my $RedirectFlow = Business::GoCardless::RedirectFlow->new(
client => $self,
id => $redirect_flow_id,
);
$RedirectFlow->find_with_client( 'redirect_flows' );
# only the session that started the redirect flow may confirm it
if (
! length( $session_token // '' )
|| ( $RedirectFlow->session_token // '' ) ne $session_token
) {
Business::GoCardless::Exception->throw({
message => "session_token does not match redirect flow $redirect_flow_id",
});
}
# redirect flows backed by a billing request are completed by gocardless
# when the billing request is fulfilled, and trying to complete them again
# is an error, so if we already have a mandate there's nothing left to do
return $RedirectFlow if ( $RedirectFlow->links // {} )->{mandate};
# now confirm the redirect flow
my $data = $self->api_post(
"/redirect_flows/$redirect_flow_id/actions/complete",
{ data => { session_token => $RedirectFlow->session_token } },
);
$RedirectFlow = Business::GoCardless::RedirectFlow->new(
client => $self,
%{ $data->{redirect_flows} }
);
return $RedirectFlow;
}
sub _confirm_resource {
my ( $self,$params ) = @_;
if ( ! $self->signature_valid( $params,$self->app_secret ) ) {
Business::GoCardless::Exception->throw({
message => "Invalid signature for confirm_resource"
});
}
my $data = {
resource_id => $params->{resource_id},
resource_type => $params->{resource_type},
};
my $credentials = encode_base64( $self->app_id . ':' . $self->app_secret );
$credentials =~ s/\s//g;
my $ua = LWP::UserAgent->new;
$ua->agent( $self->user_agent );
my $req = HTTP::Request->new(
POST => join( '/',$self->base_url . $self->api_path,'confirm' )
);
$req->header( 'Authorization' => "Basic $credentials" );
$req->header( 'Accept' => 'application/json' );
$req->content_type( 'application/x-www-form-urlencoded' );
$req->content( $self->normalize_params( $data ) );
my $res = $ua->request( $req );
if ( $res->is_success ) {
my $class_suffix = ucfirst( $params->{resource_type} );
$class_suffix =~ s/_([A-z])/uc($1)/ge;
my $class = "Business::GoCardless::$class_suffix";
my $obj = $class->new(
client => $self,
id => $params->{resource_id}
);
return $obj->find_with_client;
}
else {
Business::GoCardless::Exception->throw({
message => $res->content,
code => $res->code,
response => $res->status_line,
});
}
}
=head1 METHODS
api_get
api_post
api_put
api_delete
Make a request to the gocardless API:
my $data = $Client->api_get( '/merchants/123ABCD/bills',\%params );
In list context returns the links and pagination headers:
my ( $data,$links,$info ) = $Client->api_get( ... );
All of the methods take an optional hashref of additional headers to send with
the request as the third argument:
my $data = $Client->api_post(
'/payments',
{ payments => { ... } },
{ 'Idempotency-Key' => $your_idempotency_key },
);
Failed requests will throw a L<Business::GoCardless::Exception>, and may be
retried before doing so (see L</max_retries>).
=head1 IDEMPOTENCY KEYS
When using the Pro (v2) API all requests that create a resource (POST requests
other than to actions) are sent with an C<Idempotency-Key> header, so that they
can be safely retried without creating duplicate resources (payments, etc). A
random key is generated for each request, or you can pass your own as shown
( run in 1.414 second using v1.01-cache-2.11-cpan-3f962061493 )