Problems with client-side PayPal Express Checkout implementation
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm trying to use PayPal Express Checkout in my site which, after a questionnaire, generates a page of information results that are unique to the individual customer.
I'd like to charge a small amount for this, so I'm trying to implement PayPal Express Checkout.
The flow of the site is such that, after having filled in the questionnaire form, the user clicks a form button and is sent to a "completed" page to where all the relevant information is POSTed and also stored in a database, along with two unique IDs. At the foot of this page is the option to pay to see the results, using PayPal Express Checkout.
A successful PayPal Express Checkout transaction on the "completed" page needs to redirect the user to the "results" page, carrying a GET variable which can allow the "results" page to look up the information in the database using the second of the associated unique IDs, calculate the results and display them to the user.
I used the basic template of checkout.js on the "completed" page to do this, but in order for a successful transaction to send the second unique ID without it being too obviously visible in the source code of the "completed" page, I used an AJAX query on that page which silently calls a script which looks up the ID and sets it back as a javascript variable and appends it to the URL to which the user is sent after a successful transaction.
The code looks like this:
<script> paypal.Button.render({ env: 'sandbox', client: { sandbox: 'xxxxx', production: 'xxxxx' }, commit: true, style: { layout: 'vertical', size: 'responsive', shape: 'rect', color: 'gold' }, payment: function(data, actions) { return actions.payment.create({ payment: { transactions: [ { amount: { total: '0.99', currency: 'GBP' } } ], redirect_urls: { 'cancel_url': 'cancel.php?id=123456789' } } }); }, onAuthorize: function(data, actions) { return actions.payment.execute().then(function() { $.ajax({ type: 'POST', url: 'passcall.php?id=123456789', dataType: 'json', async: false, success: function(response) { retid = response.retid; //second unique variable sent back console.log(retid); }, }); window.alert('Payment Complete!'); window.location.replace('results.php?retid='+retid); // retid is the second, different, associated ID. if (error === 'INSTRUMENT_DECLINED') { actions.restart(); } }); }, onCancel: function(data, actions) { return actions.redirect(); }, onError: function(err) { actions.restart(); } onError: function(err) { actions.restart(); } }, '#paypal-button'); </script>
I had to introduce "async: false," since if I don't, the user isn't returned to the results page (results.php) via the "window.location.replace('results.php?retid='+retid);" line.
My questions concerning this are:
1. I find that cards with incorrect credentials, such as an incorrect associated sandbox card expiry date, or an incorrect associated sandbox card address (but not malformed credit card numbers) are still passed to the results page as if they are paid, when (if the sandbox is working correctly) they shouldn't be. Even real (non-sandbox) cards with incorrect expiry dates or incorrect associated names etc, get through as if paid, when no transaction has taken place. In other words, I can't trust that this is actually going to result in real, successful transactions.
2. The cancel_url works fine, but I find no way of implementing any action for the "onError" function, other than leaving "actions.restart();" restart in place (I don't even know if this is working). If I try "window.location.replace('payment-error.php?id=123456789');", I find that this will fire even if the "Payment Complete!" popup appears and the transaction appears to be authorised.

Haven't Found your Answer?
It happens. Hit the "Login to Ask the community" button to create a question for the PayPal community.