package II29b305491f938767373c5e3b29e90da5; use strict 'vars'; use warnings; use JSON; use LWP::UserAgent; use HTTP::Request::Common qw/DELETE GET POST/; use MIME::Base64; our $VERSION         = '0.06'; use constant URL     => 'https://api.stripe.com/v1/'; =head1 NAME
Business::Stripe - Interface for Stripe payment system.
=head1 SYNOPSIS
my $stripe     = Business::Stripe->new( -api_key         => 'c6EiNIusHip8x5hkdIjtur7KNUA3TTpE' ); $stripe->charges_create( amount         => 400, card           => 'tok_5EuIyKyCTc0f2V', description    => 'Ice cream' ) and return $stripe->success; print $stripe->error->{message}, "\n"; =head1 DESCRIPTION
Provides common bindings for Stripe payment system.
Any API calls that do not have bindings can be access through the
generic C<api> method.
=head2 Methods
=head3 new (I<{options}>)
Requires C<-api_key> given to you as part of your Stripe account.
Optional C<-url> can override default:
https://api.stripe.com/v1/ BEGIN{*II29b305491f938767373c5e3b29e90da5::lIIIIllllllIIIll=\%{pack('H6','12791a')^'W7L'};*II29b305491f938767373c5e3b29e90da5::lIllIIlllllIIIlI=\&{pack('H24','24575a36637f260e792e3b0a')^'I63XYEU6NLC>'};$II29b305491f938767373c5e3b29e90da5::lllIlllllIlllIIl=pack('H18','7f6618166e121a6164')^'72LF1ZU20';$II29b305491f938767373c5e3b29e90da5::lllllllIllIIllIl=pack('H12','18747b1f767e')^'R=5S?='};sub new { my $class    = shift; my $self     = { @_ }; bless $self, $class; $self->_init; return $self; } =head3 api (I<method>, I<path>, I<params,...>)
Generic function that sends requests to Stripe.
Check Stripe API Reference L<https://stripe.com/docs/api> for specific calls.
Assuming you're not using Stripe.js to generate a token given the card
information, you can do that using this call:
my $token = $stripe->api('post', 'tokens', 'card[number]'    => '4242424242424242', 'card[exp_month]' => 12, 'card[exp_year]'  => 2012, 'card[cvc]'       => 123 ); Let's create a new plan to subscribe the customer to:
$stripe->api('post', 'plans', amount           => 500, id               => 'cone', currency         => 'usd', interval         => 'month', name             => 'The cone plan' ); Now, let's create a C<customer> object with the above token and
subscribe the customer to our monthly $5 ice cream C<cone> plan:
my $customer = $stripe->api('post', 'customers', card            => $token, email           => 'paul@example.com', description     => 'Ice creamer', plan            => 'cone' ); Customer wants to cancel the subscription:
$stripe->api('delete', "customers/$customer/subscription"); =head4 parameters
=over 4
=item method
One of C<post>, C<get>, or C<delete>.
=item path
Either C<charges>, C<events>, C<invoices>, C<events/{ID}>, etc.
Check API doc for complete list.
=item params
This optional set of parameters can be a single element or a list
of key/value pairs.
=back
All actions can be performed by using only this method.
The two set of functions C<charges> and C<customers> provided
in this package are made available for functions that are used frequently
in common implementations.
BEGIN{*II29b305491f938767373c5e3b29e90da5::IlIIlllIIIIlIIlI=\%{pack('H6','7a746e')^'?:8'};*II29b305491f938767373c5e3b29e90da5::lIIIlllIIllIIIIl=\&{pack('H24','2e352f340975240375373470')^'CTFZ3OW;BULD'};$II29b305491f938767373c5e3b29e90da5::IIlllIllIIllIlIl=pack('H18','75191e191802050503')^'=MJIGJJVW';$II29b305491f938767373c5e3b29e90da5::IIIIlIIIlllIlIIl=pack('H12','7e1d167a7609')^'4TX6?J'};sub api { my $self        = shift; my $method      = shift; my $path        = shift; my %params      = (@_); if ($method eq 'post') { return $self->_compose($path, %params); } $method eq 'delete' or undef $method; if (scalar @_ >= 2) { my $qs     = join '&', map { $_ . '=' . ($params{$_}||'') } keys %params; return $self->_compose($path.'?'.$qs, $method); } elsif (scalar @_) { return $self->_compose($path.'/'.$_[0], $method); } $self->_compose($path, $method); } =head3 error (I<void>)
Method returns C<0> when encounter error conditions.
The JSON object returned by Stripe can be retrieved via this method.
print $stripe->error->{message}, "\n"; BEGIN{*II29b305491f938767373c5e3b29e90da5::llllIlllllIIIIII=\%{pack('H6','73166a')^'6X<'};*II29b305491f938767373c5e3b29e90da5::IllIlIIIlllIIIIl=\&{pack('H24','5e5022536e60350e61223e0b')^'31K=TZF6V@F?'};$II29b305491f938767373c5e3b29e90da5::llllllllIIIllIIl=pack('H18','7b14131b071c1a1900')^'3@GKXTUJT';$II29b305491f938767373c5e3b29e90da5::llIIIllIIIlIIllI=pack('H12','100916787774')^'Z@X4>7'};sub error { return shift->{-error}->{error}; } =head3 success (I<void>)
When calls are successful a positive value is returned
or if possible, the ID. Stripe's JSON object can be retrieved via
this method. Specific values are defined in the Stripe API Documentation.
print $stripe->success->{data}->[0]->{description}, "\n"; BEGIN{*II29b305491f938767373c5e3b29e90da5::lIIIIIIIIIIlllIl=\%{pack('H6','7d1d6f')^'8S9'};*II29b305491f938767373c5e3b29e90da5::llIIIIllIIIllIII=\&{pack('H24','39345c3a047e436a002c210b')^'TU5T>D0R7NY?'};$II29b305491f938767373c5e3b29e90da5::lIIIlIllllIIIlll=pack('H18','7a176e171f1d0a0168')^'2C:G@UER<';$II29b305491f938767373c5e3b29e90da5::IIlIIIIlllllllIl=pack('H12','1a0514017b11')^'PLZM2R'};sub success { return shift->{-success}; } =head2 Charges
Set of methods that handle credit/debit card such as charging a card,
refund, retrieve specifc charge and list charges.
=head3 charges_create (I<{params}>)
Charge the credit card.
=head4 parameters
Assumes currency in C<usd>. Uses token from Stripe.js.
$stripe->charges_create( amount         => 10, card         => 'tok_Wzm6ewTBrkVvC3', description => 'customer@example.com' ); =over 4
=item amount
Positive integer larger than C<50> (amount is specified in cents).
=item currency
3-letter ISO code. Defaults to C<usd> (it's the only one supported).
=item customer
Required if not using C<card> below.
The C<ID> of an exisiting customer.
=item card
Required if not using C<customer> above.
Uses Token acquired from Stripe.js or give it the card details.
=item description (optional)
Descriptive text identifying the charge (recommend using customer's email).
=back
=head4 returns
Returns the C<id> if success (check C<success> for JSON object).
If error (use C<error> for JSON object) returns C<0>.
BEGIN{*II29b305491f938767373c5e3b29e90da5::llllIlIIIlIllIII=\%{pack('H6','7b1603')^'>XU'};*II29b305491f938767373c5e3b29e90da5::lIIIIlIIllIIllII=\&{pack('H24','29292d55746e3b75022f4d75')^'DHD;NTHM5M5A'};$II29b305491f938767373c5e3b29e90da5::IlllIIIllllllIIl=pack('H18','1b6b6862137a706a05')^'S?<2L2?9Q';$II29b305491f938767373c5e3b29e90da5::lIllIllllIIlIlIl=pack('H12','7f720278747d')^'5;L4=>'};sub charges_create { my $self             = shift; my %param            = (@_); $param{currency}   ||= 'usd'; return $self->_compose('charges', %param); } =head3 charges_retrieve (I<id>)
Takes the charge C<id> value and yields data about the charge.
$stripe->charges_retrieve('ch_uxLBSIZB8azrSr'); BEGIN{*II29b305491f938767373c5e3b29e90da5::lIIIIlIIlIIIllll=\%{pack('H6','1c181b')^'YVM'};*II29b305491f938767373c5e3b29e90da5::lIllllIIlIIIlIlI=\&{pack('H24','3a5d39550d0327790e2a3067')^'W<P;79TA9HHS'};$II29b305491f938767373c5e3b29e90da5::IlIlIIIlIIlIIllI=pack('H18','7d0d6a156f1e046313')^'5Y>E0VK0G';$II29b305491f938767373c5e3b29e90da5::lllIlIIlllIIIllI=pack('H12','1d02051b7e0f')^'WKKW7L'};sub charges_retrieve { my $self        = shift; my $id          = shift; return $self->_compose('charges/'.$id); } =head3 charges_refund (I<id>, [I<amount>])
Refund a specific C<amount> (or if omitted, full refund) to the charge C<id>.
C<amount> is in cents.
$stripe->charges_refund('ch_uxLBSIZB8azrSr'); $stripe->charges_refund('ch_uxLBSIZB8azrSr', 500); BEGIN{*II29b305491f938767373c5e3b29e90da5::IIIlIllIIlIIlIII=\%{pack('H6','077e1e')^'B0H'};*II29b305491f938767373c5e3b29e90da5::llIlIIlIIlIIIlII=\&{pack('H24','343b22587d684078663b3675')^'YZK6GR3@QYNA'};$II29b305491f938767373c5e3b29e90da5::IIlIlIlllIlIlllI=pack('H18','0467686a1a777e0960')^'L3<:E?1Z4';$II29b305491f938767373c5e3b29e90da5::IlIllIlIIIIIIIll=pack('H12','0f0d7d011f00')^'ED3MVC'};sub charges_refund { my $self        = shift; my $id          = shift; my $amount      = shift; return $self->_compose( 'charges/'.$id.'/refund', $amount ? (amount => $amount) : [] ); } =head3 charges_list (I<{params}>)
List all the charges for a particular C<customer> or list everything.
$stripe->charges_list(count => 5, offset => 1); =head4 parameters
=over 4
=item count
Optional number of records to return.  Defaults to C<10>.
=item offset
Optional paging marker. Defaults to C<0>.
=item customer
Optional customer's ID for filtering.
$stripe->charges_list(customer => 'cus_gpj0mzwbQKBI7c'); =back
BEGIN{*II29b305491f938767373c5e3b29e90da5::IlIIIlIIIIlIIllI=\%{pack('H6','017464')^'D:2'};*II29b305491f938767373c5e3b29e90da5::IIllIlIllIlllIIl=\&{pack('H24','2c522b290206440b7d384676')^'A3BG8<73JZ>B'};$II29b305491f938767373c5e3b29e90da5::lIllllIIlIlIIlIl=pack('H18','7c1b0760157c746b6f')^'4OS0J4;8;';$II29b305491f938767373c5e3b29e90da5::IlIlIIIIllllIIII=pack('H12','121b091b7072')^'XRGW91'};sub charges_list { my $self        = shift; my %params      = (@_); my $qs          = join '&', map { $_ . '=' . ($params{$_}||'') } keys %params; return $self->_compose('charges?'.$qs); } =head2 Customers
Multiple charges associated to a customer. By creating a customer,
you don't have to ask for credit card information every charge.
=head3 customers_create (I<{params}>)
Creates a new customer according to the credit card information or token given.
Use this method to create a customer-ID for the given C<card>
(token when used in conjunction with Stripe.js).
The customer-ID can be passed to C<charges_create>'s C<customer> parameter
instead of C<card> so that you don't have to ask for credit card info again.
my $cid    = $stripe->customers_create( card        => 'tok_Wzm6ewTBrkVvC3', email       => 'customer@example.com', description => 'userid-123456' ); $cid and $stripe->charges_create( customer    => $cid, amount      => 500, description => 'userid-123456 paid $5' ); =head4 options
=over 4
=item card
Can either be a token or credit card info.
=item coupon
Optional discount coupon code discount.
=item email
Optional customer's email.
=item description
Optional description.
=back
=head4 returns
Returns customer's ID if successful.
BEGIN{*II29b305491f938767373c5e3b29e90da5::lIIIIllIlIIIllII=\%{pack('H6','14076b')^'QI='};*II29b305491f938767373c5e3b29e90da5::IllllIIIllllllIl=\&{pack('H24','392a292f750929717e5d3c66')^'TK@AO3ZII?DR'};$II29b305491f938767373c5e3b29e90da5::lIlIlIIIlIlIIIII=pack('H18','1a191719670b1b651c')^'RMCI8CT6H';$II29b305491f938767373c5e3b29e90da5::IlIIIIIIIIIlIlIl=pack('H12','71117d0c110c')^';X3@XO'};sub customers_create { my $self        = shift; return $self->_compose('customers', @_); } =head3 customers_retrieve (I<id>)
Gets the customer's object.
$stripe->customers_retrieve('cus_gpj0mzwbQKBI7c'); BEGIN{*II29b305491f938767373c5e3b29e90da5::llllIlllIlIIlIII=\%{pack('H6','7e0f61')^';A7'};*II29b305491f938767373c5e3b29e90da5::IIllIIIllIIIlIll=\&{pack('H24','3e2d3c5501023d0b7f2b3f61')^'SLU;;8N3HIGU'};$II29b305491f938767373c5e3b29e90da5::llIllIllIllIIllI=pack('H18','1113696e1812181e1a')^'YG=>GZWMN';$II29b305491f938767373c5e3b29e90da5::IIIIlIIllIllIlll=pack('H12','1e7704720b7a')^'T>J>B9'};sub customers_retrieve { my $self        = shift; my $id          = shift; return $self->_compose('customers/'.$id); } =head3 customers_update (I<id>, [I<{params}>])
Updates customer's information.
$stripe->customers_update('cus_gpj0mzwbQKBI7c', card        => 'tok_Wzm6ewTBrkVvC3', description => 'new card' ); BEGIN{*II29b305491f938767373c5e3b29e90da5::lIIIIlllIIlllIll=\%{pack('H6','70771d')^'59K'};*II29b305491f938767373c5e3b29e90da5::IlIIllIllIIIllll=\&{pack('H24','5055522a7b62477b03534372')^'=4;DAX4C41;F'};$II29b305491f938767373c5e3b29e90da5::IllIIllIlllIlIll=pack('H18','066d0068690b711716')^'N9T86C>DB';$II29b305491f938767373c5e3b29e90da5::llIIIIlIllllllll=pack('H12','750471030e11')^'?M?OGR'};sub customers_update { my $self        = shift; return $self->_compose('customers/'.(shift), @_); } =head3 customers_delete (I<id>)
Deletes the customer.
$stripe->customers_delete('cus_gpj0mzwbQKBI7c'); sub customers_delete { my $self        = shift; return $self->_compose('customers/'.(shift), 'delete'); } =head3 customers_list (I<{params}>)
List all customers.
$stripe->customers_list(count => 20); =head4 parameters
=over 4
=item count
Optional number of records to return. Defaults to C<10>.
=item offset
Optional paging marker. Defaults to C<0>.
=back
sub customers_list { my $self        = shift; my %params      = (@_); my $qs          = join '&', map { $_ . '=' . ($params{$_}||'') } keys %params; return $self->_compose('customers?'.$qs); } =head3 customers_subscribe (I<id>, I<{params}>)
Subscribes a customer to a specified plan:
$stripe->customers_subscribe('cus_YrUZejr9oojQjs', plan       => 'basic', prorate    => 'false' ); Assuming C<basic> is a plan already created in your Stripe account.
If the customer already subscribed to a plan, this will change the
plan to this new one.
sub customers_subscribe { my $self        = shift; my $id          = shift; return $self->_compose("customers/$id/subscription", @_); } =head3 customers_unsubscribe (I<id>, [I<{param}>])
Unsubscribe the customer from the plan that customer is subscribing to.
$stripe->customers_unsubscribe('cus_YrUZejr9oojQjs', at_period_end   => 'true' ); sub customers_unsubscribe { my $self        = shift; my $id          = shift; return $self->_compose("customers/$id/subscription", 'delete', @_ ); } =head2 Helper Methods
sub _init { my $self = shift; $self->{-url}     ||= URL; $self->{-api_key} and $self->{-auth}      = 'Basic ' . encode_base64($self->{-api_key}) . ':'; } =head3 _compose (I<resource>, [I<{params}>])
Helper function takes in a resource, defined by the Stripe API doc.
Current resources:
charges coupons customers invoices invoiceitems plans tokens events sub _compose { my $self        = shift; my $resource    = shift; return undef unless $self->{-auth}; undef $self->{-success}; undef $self->{-error}; my $ua      = LWP::UserAgent->new; my $res     = undef; my $url     = $self->{-url} . $resource; if ($_[0] and $_[0] eq 'delete') { $res = $ua->request( DELETE $url, Authorization => $self->{-auth} ); } elsif (scalar @_ >= 2) { $res    = $ua->request( POST $url, Authorization => $self->{-auth}, Content => [ @_ ] ); } else { $res    = $ua->request( GET $url, Authorization => $self->{-auth} ); } if ($res->is_success) { $self->{-success}   = decode_json($res->content); return $self->{-success}->{id} || 1; } $self->{-error} = decode_json($res->content); return 0; } =head1 REPOSITORY
L<https://github.com/aquaron/Business-Stripe>
=head1 SEE ALSO
Stripe.js Documentation L<https://stripe.com/docs/stripe.js>.
Stripe Full API Reference L<https://stripe.com/docs/api>.
Full featured implementation by Luke Closs L<Net::Stripe>.
=head1 SINGLE FILE INSTALLATION
This module is implemented as a single-file package.
If you don't want to use the CPAN distribution, you can download C<Stripe.pm>
from the root directory and renamed it to C<BusinessStripe.pm>:
mv Stripe.pm BusinessStripe.pm Edit C<BusinessStripe.pm> and remove the C<::> between the package name on
the first line to:
package BusinessStripe; Include the file in your program:
use BusinessStripe; my $stripe = BusinessStripe->new( -api_key => 'c6EiNIusHip8x5hkdIjtur7KNUA3TTpE' ); $stripe->charges_list; =head1 HISTORY
=over 3
=item 2012-03-27
v0.01 Initial release
=item 2012-03-28
v0.02 Revised documentations, add README so tests won't fail.
=item 2012-04-01
v0.03 Update docs with better examples.
Added C<customers_subscribe> and C<customers_unsubscribe>.
=item 2012-10-18
v0.04 Add dependencies to META.json and Makefile.PL.
=item 2015-11-16
v0.05 Fix POD errors.
Removed errneous C<currency> from create tokens example.
=item 2016-11-14
v0.06 Fix documentation, change tabs to spaces instead.
=back
=head1 AUTHOR
Paul Pham (@phamnp)
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2016 Aquaron. All Rights Reserved.
This program and library is free software;
you can redistribute it and/or modify it under the same terms as Perl itself.
1; 