Common Payment Interface
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


Travis CI build status


Business::CPI - Common Payment Interface


# the objects are created with the same keys
my $paypal = Business::CPI->new(
    gateway     => "PayPal",
    receiver_id => "",
my $pagseguro = Business::CPI->new(
    gateway     => "PagSeguro",
    receiver_id => "",

# 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,


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.

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 => '',

    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 => '',
        name  => 'Mr. Buyer',
        # ...

    id          => 'ref123',
    description => 'X-Burguer',
    price       => 10.50,
    quantity    => 1,

    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 %]

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

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 $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. notify parses the request, and returns a standard hash ref.

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


Aware -


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


André Walker


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