File Coverage

blib/lib/Business/OnlinePayment/Braintree.pm
Criterion Covered Total %
statement 12 14 85.7
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 17 19 89.4


line stmt bran cond sub pod time code
1             package Business::OnlinePayment::Braintree;
2              
3 1     1   13045 use 5.006;
  1         2  
4 1     1   3 use strict;
  1         0  
  1         15  
5 1     1   3 use warnings;
  1         3  
  1         27  
6              
7 1     1   443 use Business::OnlinePayment 3.01;
  1         2307  
  1         21  
8 1     1   422 use Net::Braintree;
  0            
  0            
9              
10             use base 'Business::OnlinePayment';
11              
12             =head1 NAME
13              
14             Business::OnlinePayment::Braintree - Online payment processing through Braintree
15              
16             =head1 VERSION
17              
18             Version 0.020
19              
20             =cut
21              
22             our $VERSION = '0.020';
23              
24             =head1 SYNOPSIS
25              
26             use Business::OnlinePayment;
27              
28             $tx = new Business::OnlinePayment('Braintree',
29             merchant_id => 'your merchant id',
30             public_key => 'your public key',
31             private_key => 'your private key',
32             );
33              
34             $tx->test_transaction(1); # sandbox transaction for development and tests
35            
36             $tx->content(amount => 100,
37             card_number => '4111 1111 1111 1111',
38             expiration => '1212');
39              
40             $tx->submit();
41              
42             if ($tx->is_success) {
43             print "Card processed successfully: " . $tx->authorization . "\n";
44             } else {
45             print "Card was rejected: " . $tx->error_message . "\n";
46             }
47              
48             =head1 DESCRIPTION
49              
50             Online payment processing through Braintree based on L<Net::Braintree>.
51              
52             The documentation for L<Net::Braintree> is located at
53             L<https://www.braintreepayments.com/docs/perl>.
54              
55             =head1 NOTES
56              
57             This is supposed to cover the complete Braintree Perl API finally.
58              
59             =head1 METHODS
60              
61             =head2 submit
62              
63             Submits transaction to Braintree gateway.
64              
65             =cut
66              
67             sub submit {
68             my $self = shift;
69             my $config = Net::Braintree->configuration;
70             my %content = $self->content;
71             my ($action, $result, $transaction, $result_code);
72              
73             # sandbox vs production
74             if ($self->test_transaction) {
75             $config->environment('sandbox');
76             }
77             else {
78             $config->environment('production');
79             }
80              
81             # transaction
82             $action = lc($content{action});
83              
84             if ($action eq 'normal authorization' ) {
85             $result = $self->sale(1);
86             }
87             elsif ($action eq 'authorization only') {
88             $result = $self->sale(0);
89             }
90             elsif ($action eq 'post authorization') {
91             $result = Net::Braintree::Transaction->submit_for_settlement($content{order_number}, $content{amount});
92             }
93             elsif ($action eq 'credit' ) {
94             $result = Net::Braintree::Transaction->refund($content{order_number}, $content{amount});
95             }
96             elsif ($action eq 'void' ) {
97             $result = Net::Braintree::Transaction->void($content{order_number});
98             }
99             else {
100             $self->error_message( "unsupported action for Braintree: $content{action}" );
101             return 0;
102             }
103              
104             my %result_codes = (
105             2000 => 'declined',
106             2001 => 'nsf',
107             2002 => 'nsf',
108             2003 => 'nsf',
109             2010 => 'declined',
110             2012 => 'declined',
111             2013 => 'declined',
112             2014 => 'declined',
113             2022 => 'declined',
114             2038 => 'declined',
115             2041 => 'declined',
116             2044 => 'declined',
117             2046 => 'declined',
118             2047 => 'pickup',
119             2053 => 'stolen',
120             );
121              
122             $transaction = $result->transaction;
123              
124             if ( $transaction ) {
125             $result_code = $transaction->processor_response_code;
126              
127             $self->result_code($result_code);
128             $self->order_number($transaction->id);
129             }
130              
131             if ($result->is_success()) {
132             $self->is_success(1);
133             $self->authorization($transaction->id);
134             $self->card_token($transaction->id);
135             }
136             else {
137             $self->is_success(0);
138             $self->error_message($result->message);
139             $self->failure_status($result_codes{$result_code})
140             if ( $result_code && $result_codes{$result_code} );
141             }
142             }
143              
144             =head2 sale $submit
145              
146             Performs sale transaction with Braintree. Used both
147             for settlement ($submit is a true value) and
148             authorization ($submit is a false value).
149              
150             =cut
151              
152             sub sale {
153             my ($self, $submit) = @_;
154             my %content = $self->content;
155              
156             # get rid of slash inside expiration value
157             $content{expiration} =~ s%/%%;
158              
159             my %args = (
160             amount => $content{amount},
161             order_id => $content{invoice_number},
162             credit_card => {
163             number => $content{card_number},
164             expiration_month => substr($content{expiration},0,2),
165             expiration_year => substr($content{expiration},2,2),
166             cvv => $content{cvv},
167             },
168             billing => {
169             first_name => $content{first_name},
170             last_name => $content{last_name},
171             company => $content{company},
172             street_address => $content{address},
173             locality => $content{city},
174             region => $content{state},
175             postal_code => $content{zip},
176             country_code_alpha2 => $content{country}
177             },
178             options => {
179             submit_for_settlement => $submit,
180             }
181             );
182              
183             if (exists $content{merchant_account_id}
184             && $content{merchant_account_id}) {
185             $args{merchant_account_id} = $content{merchant_account_id};
186             }
187              
188             my $result = Net::Braintree::Transaction->sale(\%args);
189              
190             return $result;
191             }
192              
193             =head2 set_defaults
194              
195             Sets defaults for the Braintree merchant id, public and private key.
196              
197             =cut
198            
199             sub set_defaults {
200             my ($self, %opts) = @_;
201             my $config = Net::Braintree->configuration;
202              
203             $self->build_subs(qw(card_token));
204              
205             $config->merchant_id($opts{merchant_id});
206             $config->public_key($opts{public_key});
207             $config->private_key($opts{private_key});
208              
209             return;
210             }
211              
212             =head1 AUTHOR
213              
214             Stefan Hornburg (Racke), C<< <racke at linuxia.de> >>
215              
216             =head1 BUGS
217              
218             Please report any bugs or feature requests to C<bug-business-onlinepayment-braintree at rt.cpan.org>, or through
219             the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Business-OnlinePayment-Braintree>. I will be notified, and then you'll
220             automatically be notified of progress on your bug as I make changes.
221              
222             You can find documentation for this module with the perldoc command.
223              
224             perldoc Business::OnlinePayment::Braintree
225              
226              
227             You can also look for information at:
228              
229             =over 4
230              
231             =item * Github issues (report bugs here)
232              
233             L<https://github.com/interchange/Business-OnlinePayment-Braintree/issues>
234              
235             =item * AnnoCPAN: Annotated CPAN documentation
236              
237             L<http://annocpan.org/dist/Business-OnlinePayment-Braintree>
238              
239             =item * CPAN Ratings
240              
241             L<http://cpanratings.perl.org/d/Business-OnlinePayment-Braintree>
242              
243             =item * Search CPAN
244              
245             L<http://search.cpan.org/dist/Business-OnlinePayment-Braintree/>
246              
247             =back
248              
249              
250             =head1 ACKNOWLEDGEMENTS
251              
252             Grant for the following enhancements (RT #88525):
253              
254             =over 4
255              
256             =item billing address transmission
257              
258             =item order number transmission
259              
260             =item refund ability
261              
262             =item added submit_for_settlement to complete the "sale" action
263              
264             =back
265              
266             Peter Mottram for the following enhancements (GH #5):
267              
268             =over 4
269              
270             =item Failure status
271              
272             Set failure status from error codes provided by Braintree.
273              
274             =item CVV
275              
276             Pass cvv to Braintree.
277              
278             =back
279              
280             Evan Brown (GH #7, #8):
281              
282             Add support for post authorization action.
283             Add support for the void action and the card_token transaction result method.
284              
285             =head1 LICENSE AND COPYRIGHT
286              
287             Copyright 2011-2016 Stefan Hornburg (Racke).
288              
289             This program is free software; you can redistribute it and/or modify it
290             under the terms of either: the GNU General Public License as published
291             by the Free Software Foundation; or the Artistic License.
292              
293             See http://dev.perl.org/licenses/ for more information.
294              
295             =head1 SEE ALSO
296              
297             L<Net::Braintree>
298              
299             =cut
300              
301             1; # End of Business::OnlinePayment::Braintree