Skip to content
breadwild edited this page Dec 12, 2017 · 8 revisions

Webservice::Stripe applied in e-commerce

use WebService::Stripe;
use JSON;
#use CGI::Application::Plugin::JSON ':all';  as well, but see how from_json gets treated below
use HTTP::Response;
use Data::Dumper;

my ($obj, $exc);

my $stripe = WebService::Stripe->new(
    api_key => 'sk_test_DG8__________________YrWxdP'
);

#Warning from Stripe: handling any card information, as create_token does, on the server-side will require your site to undergo its own PCI Scan and will make you ineligible for Stripe's Radar program. They highly recommend using their Elements or Checkout APIs on the front end and then passing the token returned to your Perl. See below for HTML and Javascript
 
my $token = eval {  $stripe->create_token({ 
                    'card[number]'    => '4000000000000002', #bad card
                    #'card[number]'    => '4242424242424242', #good card
                    'card[exp_month]' => 12,
                    'card[exp_year]'  => 2018,
                    'card[cvc]'       => 123
                     })  
                };
             
if ($exc = $@) { #thank you, Naveed
    $obj = from_json($exc->content); #if using something like CGI::App...::Plugin::JSON, use $self->from_json
    print "Token: ".$obj->{'error'}->{'message'}."\n";
} else {
    print "Token: success\n";
}
 
my $charge = eval { $stripe->create_charge({
                    "amount" => 1000,
                    "currency" => "usd",
                    "source" => $token->{'id'}, #access hash for needed id
                    #alternative if not creating the token above in compliance with Stripe:
                    #"source" => $self->query->param('token_from_form'),
                    "description" => "Example charge"
                    })  
                  };

if ($exc = $@) {
    $obj = from_json($exc->content); #if using something like CGI::App...::Plugin::JSON, use $self->from_json
    print "Charge: ".$obj->{'error'}->{'message'}."\n";
} else {
    print "Charge: success\n";
}     

print Dumper($token); #if success  

Returns:

Token: success
Charge: Your card was declined.

$VAR1 = {
          'client_ip' => '175.456.456.23',
          'created' => 1469971634,
          'used' => bless( do{\(my $o = 0)}, 'JSON::XS::Boolean' ),
          'type' => 'card',
          'livemode' => $VAR1->{'used'},
          'card' => {
                      'tokenization_method' => undef,
                      'address_city' => undef,
                      'address_line1' => undef,
                      'address_country' => undef,
                      'brand' => 'Visa',
                      'address_line2' => undef,
                      'address_zip' => undef,
                      'customer' => undef,
                      'exp_month' => 12,
                      'address_zip_check' => undef,
                      'dynamic_last4' => undef,
                      'funding' => 'credit',
                      'cvc_check' => undef,
                      'last4' => '0002',
                      'address_state' => undef,
                      'address_line1_check' => undef,
                      'name' => undef,
                      'metadata' => {},
                      'country' => 'US',
                      'fingerprint' => 'EZ6FkkogdqK3dj02',
                      'exp_year' => 2018,
                      'id' => 'card_18dJyICJ_________pUHPFTay',
                      'object' => 'card'
                    },
          'object' => 'token',
          'id' => 'tok_18dJyIC________aULYPj'
        };

Example of JSON string if error:

print Dumper($exc->content);

$VAR1 = '{
  "error": {
    "message": "Your card was declined.",
    "type": "card_error",
    "code": "card_declined",
    "charge": "ch_18dK8RCJAurfnBjvuiBC8Sn0"
  }
}
';

Example of access to success hash:

print $token->{'type'};
card

print $token->{'card'}{'brand'};
Visa

Client-side HTML & Javascript

<p class="wrap stripe">
    <label for="card_number" class="blabel">Credit or debit card</label>
    <span id="card-element" class="card-input"></span>
</p>
    
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>    
<script src="https://js.stripe.com/v3/"></script>
<script>
    <!-- https://stripe.com/docs/elements/examples -->                
    var stripe = Stripe('pk_test_dE_______________Twh');
    //create instance of elements
    var elements = stripe.elements();
    //create instance of a card
    var card = elements.create('card'); 
    //insert form
    card.mount('#card-element');
    
    //run and validate card
    card.addEventListener('blur', function(event) {
        stripe.createToken(card).then(function(result) {
            if (result.error) {
                // Inform the user if there was an error
                $('label[for=card_number]').text(result.error.message).addClass('error_label');
                return false;
            } else {
                $('.error').hide();
                $('#code').val(result.token.id);
                $('label[for=card_number]').text("Credit or debit card").removeClass('error_label');
            }
        });  
    });     
    window.preSubmit = function preSubmit (event, cb) {
        stripe.createToken(card).then(function(result) {
            if (result.error) {
                // Inform the user if there was an error
                $('label[for=card_number]').text(result.error.message).addClass('error_label');
                $('#overlay').fadeOut('fast');
                 return;
            } else { //put approval token into hidden field to pass to Perl
                $('.error').hide();
                $('#token').val(result.token.id);
                $('label[for=card_number]').text("Card information is correct").removeClass('error_label');
                cb(event);
            }
        });
    }         
    
    //submit the form
    $('#stripepay').ajaxForm({
        type: "POST",
        url: $(this).attr('action'),
        datatype: "json",
        beforeSubmit: function() {
            //...do stuff ...
        },
        success: function(result){
           //...do stuff ...
            }); 
        } 
    });
</script>
Clone this wiki locally