#!/usr/bin/perl
 
use CGI qw/:standard/;
use JSON::MaybeXS qw(encode_json decode_json);
use Data::Dumper;
use LWP::UserAgent;
 
# API Credentials
$payload{'SIGNATURE'}='YOUR SIGNATURE FROM PAYPAL';
$payload{'USER'}='YOUR API ID FROM PAYPAL, NOT THE PAYPAL LOGIN';
$payload{'PWD'}='YOUR API PASSWORD, NOT THE PAYPAL LOGIN PASSWORD';
 
$payload{'VERSION'}='56.0';             # Don't Modify these unless
$payload{'METHOD'}='DoDirectPayment';   # you know what you
$payload{'PAYMENTACTION'}='Sale';       # are doing.
 
$payload{'IPADDRESS'}='8.8.8.8';        # IP of client captured by your backend code
$payload{'ITEMAMT'}='90';               # Subtotal of purchase costs
$payload{'SHIPPINGAMT'}='10';           # Shipping Costs
$payload{'AMT'}='100';                  # Total Amount to charge, this has to equal SHIPPINGAMT + ITEMAMT
$payload{'ACCT'}='4111111111111111';    # Fake Visa Credit card number will work with PayPal Sandbox
$payload{'CREDITCARDTYPE'}='VISA';      # Card ID
$payload{'EXPDATE'}='012021';           # Expiration, MMYYYY
$payload{'CVV2'}='123';                 # Card Security Code
 
$payload{'FIRSTNAME'}='JANE';          
$payload{'LASTNAME'}='DOE';
$payload{'STREET'}='123 MAIN STREET';
$payload{'CITY'}='LITTLE ROCK';
$payload{'STATE'}='AR';
$payload{'ZIP'}='72103';
$payload{'COUNTRYCODE'}='US';
$payload{'EMAIL'}='soccermom@aol.com';
 
@chars = ( 1 .. 9 );
$randomOrderNo = join("", @chars[ map { rand @chars } (1 .. 6) ]);
$payload{'INVNUM'} = $randomOrderNo;    # Random Order Number.  This has to be unique between tests.
 
$payload{'SHIPTONAME'} = 'JANE DOE';
$payload{'SHIPTOSTREET'} = '123 MAIN STREET';
$payload{'SHIPTOSTREET2'} = 'Apt. 1';
$payload{'SHIPTOCITY'} = 'LITTLE ROCK';
$payload{'SHIPTOSTATE'} = 'AR';
$payload{'SHIPTOZIP'} = '72103';
$payload{'SHIPTOCOUNTRY'} = 'US';
 
foreach $key (keys %payload){
    $restpayload .= "$key=$payload{$key}&";
}
 
$ua = LWP::UserAgent->new(ssl_opts => { SSL_version => 'tlsv12' });
$uri = "https://api-3t.sandbox.paypal.com/nvp"; # Sandbox Endpoint
#$uri = "https://api-3t.paypal.com/nvp";        # Production Endpoint
 
# Post payload hash to PayPal, store response for later
$response = $ua->post($uri,Content => $restpayload);
 
# Parse response from PayPal
@pairs = split(/&/,$response->{'_content'});
 
foreach $line (@pairs){
    ($key,$value) = split(/=/,$line);
 
    $value =~ s/\+/ /g;
    $value =~ s/%(..)/pack("c",hex($1))/ge;
 
    $transaction{$key} = $value;
}
 
# Print exit status from PayPal
if($transaction{'ACK'} eq 'Failure'){
    print "Card process failed\n";
    $transactionstring = encode_json(\%transaction);
    print Dumper $transactionstring;
}
elsif($transaction{'ACK'} eq 'Success'){
    print "Card process success\n";
    $transactionstring = encode_json(\%transaction);
    print Dumper $transactionstring;
}