Confirming Paypal Payment

Soldato
Joined
28 Apr 2011
Posts
15,221
Location
Barnet, London
I've built a very simple php shop on my site. You add and remove items, click the Paypal button and it uses Paypal express checkout to charge the user through Paypal.

The javascript function looks like this -

Code:
// onAuthorize() is called when the buyer approves the payment
onAuthorize: function(data, actions) {
        // Make a call to the REST api to execute the payment
        return actions.payment.execute().then(function() {
        <?php
            $_SESSION['paid'] = 1;
        ?>
        window.location.href = "shop_success.php";
        });
}

In the function I'm trying to set a session variable that can then be checked on the success page, where the database gets updated and an email gets sent to me with the order.

My problem is, the php code, setting the variable happens even if the payment isn't authorised, so you can load things into the basket, load the success page and the database gets updated and I get an email.

So, what method can I use to let the success page know it's been called because this function was run, that can't be spoofed by someone? I'm sure I should know, but can't think how :(

Thanks!
 
You can't set a PHP variable from the client, it will be getting executed when the server sends the page so it's probably always be getting set to 1.

Do you have a way of identifying the users on your site? User accounts, or session IDs, etc? You're going to need to keep track of the user's 'basket' and store that on the server (maybe in the session or database?), and then after a payment is attempted you'll need to send a request to your server instructing it to update your database and send emails based on whether the payment was successful or not. It would make sense to do this via an Ajax post, and be sure to verify the user to ensure they are making a valid request.
 
So I keep their basket and running cost in session variables. The code above is the bit that gets executed once payment is confirmed on Paypal. I assume something useful is held in data or actions? (I've not really done much Javascript before)

In that function is the call to load shop_success.php (where database is updated and mail sent), but I need to pass something to let the page know that the payment is made, otherwise you can just load the page and it does it all.

Thanks.
 
I imagine you will need to send a post request to your success page and pass it some parameters about the user and the transaction, rather than just redirecting to the success page. Then in the code for the success page you will need to process the post data, verify it's a valid request (check it against the session etc.), and then do whatever processing you need to do for a successful payment. Then you can render the success page to the user.
If you're using jQuery, have a look at https://api.jquery.com/jquery.post/ for sending the post request.

I realise you're getting PayPal to actually take the payment, but handling transactions, shopping baskets and user data has many risks so it may be worth getting someone else to help if you don't have much coding experience.

Never trust user inputs, validate and verify everything.
 
I did this with PayPal last year but unfortunately it was on a clients site in my old employment so I do not have access to it.

What I remember doing is generating a UUID in PHP for that transaction. That was then sent along to PayPal with other details and then PayPal sent it back once the payment was confirmed. I set the return address in the PayPal account however and I the details were sent back as POST/GET I can't remember so I could just grab them and handle them however I wanted on the success page.

I realise this is little help. I hoped I had a copy of the files but it seems not. I'll do some digging later.
 
Don't use anything client-side to validate payments. Read the response returned from paypal and use that to validate.
I've not used paypal like this before but I'd think there would be some kind of status code returned from the execute method which you could use.

Something like this maybe (i'm just guessing at property names and things though):

Code:
// onAuthorize() is called when the buyer approves the payment
onAuthorize: function(data, actions) {
        // Make a call to the REST api to execute the payment
        return actions.payment.execute().then(function(event) {
        if(event.status == "success"){
            //update order in database 
           window.location.href = "shop_success.php";
        }
        else{
            window.location.href = "payment_error.php";
       }
        });
}

It's fine to allow users access to the shop_success.php page if they type the URL directly because that page should only show some text. All the logic to set the order as confirmed executes before redirecting the user to the success page.
 
Thanks. To confirm though, I can't use <?php include 'update_database.php'; ?> where you say to update db, as they will run regardless of that if statement being true?

Javascript is next on my list to learn, I'd probably better get cracking...
 
That's correct, it'll need to be some javascript code in there. Commonly, a post to another page (as somebody mentioned earlier) with the data.

$.post("update_database.php",
{
orderID: xxxx,
authCode: event.authCode
});

This will post the orderID and authCode parameters to the update_database.php URL.
You then have your php file called update_database.php and you get these parameters using
$_POST['orderID'] and $_POST['authCode'] then you can update the order in the database.
The website user never gets directed to the update_database.php url, this is done in the background, all the user would see is a redirect to shop_success.php when the payment is successful.
 
Thanks, I had similar code, but I think maybe I was using a ; in the orderID bit.

Something's not working still though. I'm going straight to shop_success.php, like this -

Code:
$.post("shop_success.php", {
                                paid: 1
                            });

And then in shop_success.php -

Code:
if (isset($_POST['paid'])){
    $paid = $_POST['paid'];
}

...

<?php
                    if($paid == 1){
                ?>
// run code to update database and mail me the order

But it's not running the code?

I was about to separate out the two pages (updating db and send email and success page), but want to check I'm on the right track first?
 
You might need to change the 1 to a string ("1"). The paramaters are passed in the url (like "www.yourdomain.com/shop_success.php?paid=1") so they will all be treated as strings.
Use the developer tools in your browser and watch the network tab. You should see the post sent to shop_success.php in there. You'll also be able to see if the parameter is sent correctly with the post.

Also worth checking your php error log for any clues to errors you might be getting.
 
Back
Top Bottom