martedì 20 giugno 2017

The PayPal express checkout guide that PayPal should have been writing

I needed to write a simple but complete PayPal Express Checkout cart for a PHP / jQuery website.

My needs were just to have an express checkout mechanism for the total amount in the cart and a redirection in order to:

  • verify that the payment was done for the correct amount
  • collect shipping details for compliance with my local e-commerce law
  • track the items bought

PayPal deprecated some stuff recently and it was a real pain to understand the whole process, either from their confused documentation and from fragmented informations I got googlin' around. Ok, my intent is to save you some pain and get the exact flow to have the things done.


  • Firstly you need to signup PayPal with a business / merchant account, they allow a person to have 2 accounts (one personal and one business) so you can signup for the "business" ("merchant") account with your personal details even if you already own a "personal" account. Be careful because the PP docs and the forums you could have visited tend to confuse the 2 terms business / merchant: they basically are synonims.
  • Remember to verify your account
  • After some hours from the email verification, go here https://developer.paypal.com and remember that the mail PP website and the developer website align themselves after 1 day. Without verification and waiting, you have all main the features disabled.
  • On the right top corner, a dropdown menu containing your name will show you 2 options: DASHBOARD and MY ACCOUNT. They basically go to the same page, let's go to MY ACCOUNT: https://developer.paypal.com/developer/accountStatus/
  • If the verification is aligned, you should find almost everything checked with a green checkmark and some features can be enabled via "ENABLE". If you only see a couple of them, please retry tomorrow.
  • Go to MY APPS & CREDENTIALS that it's the same link for DASHBOARD (blame on you PP!): https://developer.paypal.com/developer/applications
  • Press CREATE APP button, give a name and you will get both sandbox and production credentials: you can now safely implement them in your PHP variables.
  • Now you can safely implement your code, I mostly use the Javascript implementation with PHP variables and here you have a working code with all the basic setup

<script src="https://www.paypalobjects.com/api/checkout.js"></script>
<div id="paypal-button-container"></div>
<script>
paypal.Button.render({
env: \'production\',
style: {
label: \'checkout\',
size:  \'small\',
shape: \'pill\',
color: \'blue\'
},
client: {production: \''.$paypal_clientid.'\'},
// Set to "Pay Now"
payment: function() {
return paypal.rest.payment.create(this.props.env, this.props.client,
{
intent: "sale",
payer: { payment_method: "paypal" },
transactions: [ {
amount: { total: \''.floatval($total).'\', currency: \'EUR\' },
description: "Contract ID '.$random_hash.'",
invoice_number: "'.$random_hash.'"
} ],
redirect_urls: {
return_url: "https://www.yourdomain.com/callback/paypal/return",
cancel_url: "https://www.yourdomain.com/callback/paypal/cancel"
}
});
},
commit: true,
onAuthorize: function(data, actions) {
return actions.payment.execute().then(function() {
alert(\'Payment Complete!\');
});
  }
}, \'#paypal-button-container\');
</script>

You need to generate a random hash like e.g.
$random_hash = md5(uniqid(rand(), true));


I track cart items (itemId etc) directly in the transactions db in order for the customer to have little or less space to hack my things.

Here you have everything in place, except that you could need to test your callback script. In that case simply change "env" from "production" to "sandbox" and your ClientID must be the sandbox one created with the CREATE APP.