=head1 NAME

Business::GoCardless::Upgrading

=head1 DESCRIPTION

How to move from Business::GoCardless[::Basic] to Business::GoCardless::Pro

=head1 First a little history

GoCardless first released their API sometime in 2011, this is now called the v1 (basic)
API and will be switched off in October 2017. The v1 API only features hosted pages so
there was little that could really be done in the API other than requesting some links
to hosted pages and then retrieving data + webhooks.

GoCardless released the v2 (Pro) API sometime in 2015. This is a much more feature rich
API and allows much more control from the client side without the need for hosted pages.
The interface was also cleaned up, simplified, and some terminology was changed.

GoCardless decided to deprecate the v1 API in 2017. The v2 API still features hosted
pages, now called "redirect flows" so it is possible to migrate to the v2 API without
having to rewrite from scratch. The L<Business::GoCardless> distribution has been updated
to add back compatibility methods in L<Business::GoCardless::Pro> to make this easier.

=head1 Second check the gocardless docs

You can see the docs for the v1 API at L<https://developer.gocardless.com/legacy/#the-legacy-gocardless-api>.

You can see the docs for the v2 API at L<https://developer.gocardless.com/api-reference/>.

GoCardless have their own upgrading guide at L<https://support.gocardless.com/hc/en-us/articles/115000451505-Guide-to-upgrading>.

=head1 Third create a sandbox account

Visit GoCardless and create a sandbox account. You will need to go through the various
steps eventually ending with the generation of an API access token

=head1 Fourth check and use the end to end test

Download this distribution and run the v2 end to end test using the following script in
the t directory of the distribution. Note you will need L<Mojolicious> to run the callback
reader:

    #!/bin/bash

    pkill -lf 'gocardless_callback_reader';
    sleep 1;

    set -x -e

    if [ "$port" == "" ]; then
        port=3000
    fi

    set -u

    morbo ./t/gocardless_callback_reader.pl -v -l "http://*:$port" &
    sleep 2;

    # run end_to_end tests
    GOCARDLESS_ENDTOEND=1 \
        GOCARDLESS_TOKEN=$YOUR_GOCARDLESS_ACCESS_TOKEN \
        GOCARDLESS_URL=https://api-sandbox.gocardless.com \
        GOCARDLESS_DEBUG=1 \
        prove -lrv t/004_end_to_end_pro.t

    # stop emulator
    pkill -lf 'gocardless_callback_reader';

If you have everything setup correctly then you are good to move onto the next step

=head1 Fifth modify your application code

The first thing you might want to do is to diff the two end to end tests included with
this distribution to see what kind of changes are made: t/002_end_to_end.t compared
to t/004_end_to_end_pro.t. Also refer to the L<Business::GoCardless::Pro> perldoc.

You will see that you need to now create a L<Business::GoCardless::Pro> object rather
than a L<Business::GoCardless> object. The new_.*?url methods require some changes to
the params that are passed, and the structure of webhooks has changed slightly.

Note the session_token that is now passed to these methods - the best way to use this
is to set a signed JWT that contains any state you need to get back after the user
has completed the page hosted at GoCardless (user id, amounts, etc). Since using JWTs
properly (see L<Mojo::JWT>) means they can't be fiddled with you can be confident of
sending state data to GoCardless for use when the data comes back to your app.

To migrate our app involved reasonably simple changes:

    4 files changed, 94 insertions(+), 69 deletions(-)

There were also changes to the tests:

    3 files changed, 135 insertions(+), 41 deletions(-)

=head1 Sixth test your application code changes against the sandbox

Self explanatory. Note there is some consideration required for existing customers
who you wish to continue billing - see the GoCardless docs: L<https://support.gocardless.com/hc/en-us/articles/115000451505-Guide-to-upgrading>

=head1 Seventh "go live"

Go live, this involves creating a live account and then adding the details (token)
to your app.

Submit bug reports when you find them.

=head1 Terminology changes

A Bill is now a Payment, calling C<confirm_resource> on the ::Pro object from data
generated using C<new_bill_url> will return a L<Business::GoCardless::Payment> object.
Also calling C<bill> or C<bills> on the ::Pro object will return Payment objects.

A PreAuthorization is now a RedirectFlow, calling C<pre_authorizations> is meaningless
on the ::Pro object so an exception will be thrown if you do that. C<pre_authorization>
is still supported, which just returns a RedirectFlow object.

User is now Customer. There are C<customer> and C<customers> methods on the ::Pro object
but also C<users> will just pass through to C<customers>.

Webhook is Webhook::V2 in the ::Pro API as these have been changed to have C<events> so
when examining a webhook you need to call C<events>.

=head1 How do I continue to bill mandates (pre_authorizations) created in the v1 API?

Call the create_payment method on the ::Pro class with the mandate id:

    my $Payment = $GoCardless->create_payment(
        amount   => 100, # note minor unites
        currency => 'EUR',
        links    => {
            mandate => $mandate
        },
    );

See L<https://developer.gocardless.com/api-reference/#payments-create-a-payment> for more
information. Also see the C<Mandate restrictions> section in the GoCardless upgrading docs
(L<https://support.gocardless.com/hc/en-us/articles/115000451505-Guide-to-upgrading>) as
there are some considerations depending on the mandate type.

=head1 What about legacy webhooks

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 V2 Webhook object has
logic to check this:

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

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

See the docs for L<Business::GoCardless::Webhook::V2> and
L<Business::GoCardless::Webhook>. Note that to support this you will also need to
make sure either you set the value of $ENV{'GOCARDLESS_APP_SECRET'} to your previous
Basic API app_secret or your new webhook_secret is the same as your old app_secret otherwise signatures will not be valid.

=head1 AUTHOR

Lee Johnson - C<leejo@cpan.org>

This library is free software; you can redistribute it and/or modify it under
the same terms as Perl itself. If you would like to contribute documentation,
features, bug fixes, or anything else then please raise an issue / pull request:

    https://github.com/Humanstate/business-gocardless

=cut

1;

# vim: ts=4:sw=4:et

