Business-GoCardless

 view release on metacpan or  search on metacpan

lib/Business/GoCardless/Pro.pm  view on Meta::CPAN

package Business::GoCardless::Pro;

=head1 NAME

Business::GoCardless::Pro - Perl library for interacting with the GoCardless Pro v2 API
(https://gocardless.com)

=head1 DESCRIPTION

Module for interacting with the GoCardless Pro (v2) API.

B<You should refer to the official gocardless API documentation in conjunction>
B<with this perldoc>, as the official API documentation explains in more depth
some of the functionality including required / optional parameters for certain
methods. L<https://developer.gocardless.com>, specifically the docs for the
v2 GoCardless API at L<https://developer.gocardless.com/api-reference>.

Note that this module is currently incomplete and limited to being a back
compatiblity wrapper to allow migration from the v1 (Basic) API. The complete
API methods will be added at a later stage (also: patches welcome).

Also note this class also currently inherits from L<Business::GoCardless>
so has all attributes and methods available on that class (some of which may not
make sense from the context of the Pro API).

=head1 SYNOPSIS

The following examples show instantiating the object and getting a resource
(Payment in this case) to manipulate. For more examples see the t/004_end_to_end_pro.t
script, which can be run against the gocardless sandbox (or even live) endpoint
when given the necessary ENV variables.

    my $GoCardless = Business::GoCardless::Pro->new(
        token           => $your_gocardless_token
        client_details  => {
            base_url       => $gocardless_url, # defaults to https://api.gocardless.com
            webhook_secret => $secret,
        },
    );

    # create URL for a one off payment
    my $new_bill_url = $GoCardless->new_bill_url(
        session_token        => 'foo',
        description          => "Test Payment",
        success_redirect_url => "http://example.com/rflow/confirm?jwt=$jwt",
    );

    # having sent the user to the $new_bill_url and them having complete it,
    # we need to confirm the resource using the details sent by gocardless to
    # the redirect_uri (https://developer.gocardless.com/api-reference/#redirect-flows-complete-a-redirect-flow)
    my $Payment = $GoCardless->confirm_resource(
        redirect_flow_id => $id,
        type             => 'payment', # bill / payment / pre_auth / subscription
        amount           => 0,
        currency         => 'GBP',
    );

    # get a specfic Payment
    $Payment = $GoCardless->payment( $id );

    # cancel the Payment
    $Payment->cancel;

    # too late? maybe we should refund instead (note: needs to be enabled on GoCardless end)
    $Payment->refund;

    # or maybe it failed?
    $Payment->retry if $Payment->failed;

    # get a list of Payment objects (filter optional: https://developer.gocardless.com/#filtering)
    my @payments = $GoCardless->payments( %filter );

    # on any resource object:
    my %data = $Payment->to_hash;
    my $json = $Payment->to_json;

=head1 PAGINATION

Any methods marked as B<pager> have a dual interface, when called in list context
they will return the first 100 resource objects, when called in scalar context they
will return a L<Business::GoCardless::Paginator> object allowing you to iterate
through all the objects:

    # get a list of L<Business::GoCardless::Payment> objects
    # (filter optional: https://developer.gocardless.com/#filtering)
    my @payments = $GoCardless->payments( %filter );

    # or using the Business::GoCardless::Paginator object:
    my $Pager = $GoCardless->payments;

lib/Business/GoCardless/Pro.pm  view on Meta::CPAN

}

=head2 webhook

Get a L<Business::GoCardless::Webhook::V2> object from the data sent to you via a
GoCardless webhook:

    my $Webhook = $GoCardless->webhook( $json_data,$signature );

Note that GoCardless may continue to send old style webhooks even after you have
migrated from the Basic to the Pro API, so to handle this the logic in this method
will check the payload and if it is a legacy webhook will return a legacy Webhook
object. You can check this like so:

    if ( $Webhook->is_legacy ) {
        # process webhook using older legacy code
        ...
    } else {
        # process webhook using new style code
        ...
    }

=cut

sub webhook {
    my ( $self,$data,$signature ) = @_;

    my $webhook = Business::GoCardless::Webhook::V2->new(
        client     => $self->client,
        json       => $data,
        # load ordering handled by setting _signature rather than signature
        # signature will be set in the json trigger
        _signature => $signature,
    );

    return $webhook->has_legacy_data
        ? $webhook->legacy_webhook
        : $webhook;
}

# payout methods are in the SUPER class
=head1 Payout Methods

See L<Business::GoCardless::Payout> for more information on Payout operations.

=head2 payouts (B<pager>)

Get a list of L<Business::GoCardless::Payout> objects.

    my @payouts = $GoCardless->payouts

=head2 payout

Get an individual payout, returns a L<Business::GoCardless::Payout> object:

    my $Payout = $GoCardless->payout( $id );

=cut

sub _list {
    my ( $self,$endpoint,$filters ) = @_;

    my $class = {
        payments       => 'Payment',
        redirect_flows => 'RedirectFlow',
        customers      => 'Customer',
        subscriptions  => 'Subscription',
        webhooks       => 'Webhook::V2',
        payouts        => 'Payout',
    }->{ $endpoint };

    $filters //= {};

    my $uri = "/$endpoint";

    if ( keys( %{ $filters } ) ) {
        $uri .= '?' . $self->client->normalize_params( $filters );
    }

    my ( $data,$links,$info ) = $self->client->api_get( $uri );

    $class = "Business::GoCardless::$class";
    my @objects = map { $class->new(
        client => $self->client,

        # webhooks come back with stringified JSON
        # so we need to further decode that
        $endpoint eq 'webhooks'
            ? (
                json => $_->{request_body},
                # load ordering handled by setting _signature rather than signature
                # signature will be set in the json trigger
                _signature => $_->{request_headers}{'Webhook-Signature'}
            )
            : ( %{ $_ } )
    ); } @{ $data->{$endpoint} };

    return wantarray ? ( @objects ) : Business::GoCardless::Paginator->new(
        class   => $class,
        client  => $self->client,
        links   => $links,
        info    => $info ? JSON->new->decode( $info ) : {},
        objects => \@objects,
    );
}

################################################################
#
# BACK COMPATIBILITY WITH V1 (BASIC) API SECTION FOLLOWS
# the Pro version of the API is built on "redirect flows" when
# using their hosted pages, so we can make it back compatible
#
################################################################

=head1 BACK COMPATIBILITY METHODS

These methods are provided for those who want to move from the v1 (Basic)
API with minimal changes in your application code.

=head2 new_bill_url

=head2 new_pre_authorization_url

=head2 new_subscription_url

Return a URL for redirecting the user to to complete a direct debit mandate that
will allow you to setup payments.

See L<https://developer.gocardless.com/api-reference/#redirect-flows-create-a-redirect-flow>
for more information.

    my $url = $GoCardless->new_bill_url(

        # required
        session_token        => $session_token,
        success_redirect_url => $success_callback_url,

        # optional
        scheme               => $direct_debit_scheme
        description          => $description,
        prefilled_customer   => { ... }, # see documentation above
        links                => { ... }, # see documentation above
    );

=cut

sub new_bill_url {
    my ( $self,%params ) = @_;
    return $self->_redirect_flow_from_legacy_params( 'bill',%params );
}

sub new_pre_authorization_url {
    my ( $self,%params ) = @_;
    return $self->_redirect_flow_from_legacy_params( 'pre_authorization',%params );
}



( run in 0.512 second using v1.01-cache-2.11-cpan-98e64b0badf )