andrewalker / p5-business-cpi

Common Payment Interface
6 stars 2 forks source link

=encoding utf-8

=begin html

Travis CI build status

=end html

=head1 NAME

Business::CPI - Common Payment Interface

=head1 SYNOPSIS

# the objects are created with the same keys
my $paypal = Business::CPI->new(
    gateway     => "PayPal",
    receiver_id => "test@example.com",
    ...
);
my $pagseguro = Business::CPI->new(
    gateway     => "PagSeguro",
    receiver_id => "test@example.com",
    ...
);

# the method names and arguments are similar
my $pag_transactions = $pagseguro->query_transactions({
    start_date => DateTime->now->subtract({ days => 5 }),
    final_date => DateTime->now,
});
my $pay_transactions = $paypal->query_transactions({
    start_date => DateTime->now->subtract({ days => 5 }),
    final_date => DateTime->now,
});

=head1 DESCRIPTION

Business::CPI intends to create a common interface between different payment gateways interfaces. There are on CPAN a few modules which provide interfaces for payment API's like PayPal (Business::PayPal::*), PagSeguro (PagSeguro::Status), and so forth. But each of these are completely different.

Business::CPI provides a common interface, making it really easy to support several payment gateways in a single application.

=head2 Making payments

This is probably the main point of this module: submit a checkout form to the gateway. Currently, this is only implemented using HTML forms. This may change in the future, as many gateways provide API's for paying using SOAP, NVP, etc.

To submit a payment, first we make a Business::CPI object:

my $cpi = Business::CPI->new(
    gateway     => 'Test',

    # the person who will receive the money
    receiver_id => 'john@doe.com',

    currency    => 'BRL',
    # ...
);

In a persistent environment, such as a Catalyst application, there would be no need to build a new Business::CPI object by request. A single Business::CPI object can handle as many carts as desired.

my $cart = $cpi->new_cart({
    buyer => {
        email => 'buyer@doe.com',
        name  => 'Mr. Buyer',
        # ...
    },
});

$cart->add_item({
    id          => 'ref123',
    description => 'X-Burguer',
    price       => 10.50,
    quantity    => 1,
});

$cart->add_item({
    id          => 'ref33',
    description => 'Orange juice',
    price       => 3.00,
    quantity    => 2,
});

my $form = $cart->get_form_to_pay( $id ); # HTML::Element form

In your template, you could have, for instance:

[% form.as_HTML %]

=head2 Querying payments

Sometimes it is useful to query all the transactions that were made in your account in a given period of time.

For instance:

my $payments = $cpi->query_transactions({
    start_date => DateTime->now()->subtract({ days => 7 }),
    final_date => DateTime->now(),
    page       => $page,
});

$payments would look something like:

{
    results_in_this_page => 50,
    total_pages          => 2,
    current_page         => 1,
    transactions         => [ {}, {}, {}, ... ],
}

Please note that some gateways (such as PayPal) do not support paging. So the page number will always be 1.

If you already know the code of the payment you need information about:

my $transaction = $cpi->get_transaction_details($code);

=head2 Automatic notification

Gateways provide a way to automatically inform your application when the payments are completed, or fail. Using Business::CPI, the only thing you need to do is hand the request to C<< $cpi->notify() >>.

You can save the notification url used in your app when building the Business::CPI object, like this:

my $cpi = Business::CPI->new(
    # ...
    notify_url => 'https://myserver/myapp/notification/' . $gateway_name,
    # ...
);

This way, this url will be sent to the gateway when the checkout form is sent.

Then, in your application, the action corresponding to the URL above, you would have:

my $data = $cpi->notify($req);
$db->find($data->{payment_id})->update({ status => $data->{status} });

The above code would work without change with any gateway. C< notify > parses the request, and returns a standard hash ref.

C< $req > can be a CGI object, or anything compatible, such as Catalyst::Request.

=head1 SPONSORED BY

Aware - http://www.aware.com.br

=head1 CAVEATS

This is alpha software. The interface is unstable, and may change without notice.

=head1 AUTHOR

André Walker

=head1 LICENSE

This library is free software. You can redistribute it and/or modify it under the same terms as Perl itself.