I appreciate you helping me with this problem, thank you. I have lots of pages in my shop, they are all <form> Add to Cart and the View Cart, they both work when I make a 1p sale, but I don't get the option of paying with PayPal, just my Debit card. Here is my button code, it's the same format on all my pages, it's just the code that's different.

I use a test-listener.htm (which is also in the root directory on my server) and it finds the IPN and it goes straight to where it lives on the thankyou.php page.
Thee thankyou.php page has html which assures the customer his/her transaction is received.
BUT, there's no download urls for the customer's order to be downloaded, even though they're in the PayPal 'return url' box.

This is completely baffling me and has been since before Xmas, I trid to install the smart buttons but lordy, that one was a maze, I had to give upon it!
I'd be so grateful for any clues, I get good hits on my site, but my sales have been zilch, apart from the odd one or two that slipped in somehow. I watch ms clarity and see the cart buttons clicked on, so there is activity.
Regards and gratitude, I hope I've explained it OK, from Steve

Recommended Answers

I'm really sorry, but I guess my confusion is:

  1. How is the existing functionality different from the expected functionality? Is it just that the user cannot use a credit card but only their debit card?
  2. Upon paying for the digital goods, is the user presented with a way of …
Jump to Post

OK, I think there's some confusion going on here.

You are showing me a screenshot of PayPal where you have the page "take customers to this URL when they have finished checkout" set to ...shop/acceptM/accept......htm ... Whatever value you have here, you are overwriting this value in your HTML when …

Jump to Post

Again, please, please, please tell me what you're trying to do that isn't working as desired. I don't understand what you think isn't working.

Yes, please, please, tell me :)

Jump to Post

For those following this discussion, Steve wrote the following to me privately:

Yes, it's difficult, but basically, my customers are not able to complete their purchase, whether it be with smart buttons or the <form>. When I try my page in Sandbox, there's no option to pay by PayPal, …

Jump to Post

I tried sending the thankyou.htm by attatchment Dani, but it failed. Steve

What error message did you get?

Try posting your code in the message. Click the third button from the left in the editor toolbar (where it says 'Code') and copy/paste your code there. It formats it …

Jump to Post

All 32 Replies

I'm really sorry, but I guess my confusion is:

  1. How is the existing functionality different from the expected functionality? Is it just that the user cannot use a credit card but only their debit card?
  2. Upon paying for the digital goods, is the user presented with a way of downloading them? Or is that the part that isn't working?
  3. What are the contents of your thankyou.php page? I know that you've been having a difficult time posting code, so posting it here as an attachment should work just as well.
  4. What are you hoping that utilizing IPN will accomplish for you?

I left a message for you Dani, PayPal have said the my IPN is configured correctly, but I'd be grateful if you'd have a look for me?
In answer to your questions, this Reply page has covered your message, but I remember number 1.
When a buyer clicks on Add to Cart, s/he is taken to the cart OK. It goes back to the page they were on when the click Continue Shopping.
All's well until they go to Checkout, then there's no choice to pay by PayPal, it's either credit or debit card.
Because I am selling digital goods, there's NO_SHIPPING so no address field comes up which is what I want.
Here's my button code:

<form target="_self" action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="no_shipping" value="1">
<input type="hidden" name="currency_code" value="GBP">
<input type="hidden" name="return" value="http://www.website.com/thankyou.htm">
<input type="hidden" name="business" value="xxxxxx@gmail.com">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="notify_url" value="https://www.website.com/thankyou.php">
<input type="hidden" name="shopping_url" value="https://www.website.com/shop/pages/cartoons.htm">
<input type="hidden" name="hosted_button_id" value="YN5WHJPWYTEXE">
<input type="image" src="https://www.paypalobjects.com/en_GB/i/btn/btn_cart_LG.gif" border="0" name="submit" alt="PayPal – The safer, easier way to pay online!">
<img alt="" border="0" src="https://www.paypalobjects.com/en_GB/i/scr/pixel.gif" width="1" height="1">
</form>

All the variables have come from PayPal's Developer pages. Am I missing something? Steve

Part 2
I now have your questions 2, 3 & 4
2) Upon paying for the digital goods, is the user presented with a way of downloading them? Or is that the part that isn't working?
Yes, the buyer gets a download link/page after a few seconds of his/her payment being accepted. That part is working.
3) What are the contents of your thankyou.php page? I know that you've been having a difficult time posting code, so posting it here as an attachment should work just as well.
The thankyou.php page contains text that PayPal ask you to put on (reassurance of order, thank you for using PayPal etc.) It also contains the IPN script (the same one I sent to you by attachment) which is closed off properly before any html. PayPal have OK'd the page.
4) What are you hoping that utilizing IPN will accomplish for you?
Well, now that it seems to be OK - subject to your scrutiny - it seems I have to delve a bit deeper?
As I said in my previous page, the purchase is not being completed. Do you think the IPN History would help me? I think the fault lyes with PayPal.
Thank you for your time, I know you're busy, I am looking all the time for clues so I'm not sitting back relaxing! Steve

It goes back to the page they were on when the click Continue Shopping.

<input type="hidden" name="return" value="http://www.website.com/thankyou.htm"> 

Per your code, it does not go back to where they were originally. It goes to a thankyou.htm page. What are the contents of this thankyou.htm page? What about the thankyou.php page? Please post the full contents of these pages and don't simply describe them to me. If there is a bug, it's contained within the code here.

<input type="hidden" name="hosted_button_id" value="YN5WHJPWYTEXE">

You are using a Hosted Button ID. That means that all of the preferences you would like are not all self-contained within these hidden input fields in the HTML. A lot of the preferences are set from the hosted button which is configured via PayPal's website.

What are you hoping that utilizing IPN will accomplish for you?

I still don't feel as if you've answered this question. What do you mean by the prchase is not beign completed? You say above, "Yes, the buyer gets a download link/page after a few seconds of his/her payment being accepted." The payment shows up in Paypal, and, in exchange, the user is presented a link to download the digital goods. Isn't that the equivalent of payment being accepted? I don't understand what isn't working for you and what you're expecting to be different.

"Per your code, it does not go back to where they were originally. It goes to a thankyou.htm page. What are the contents of this thankyou.htm page? What about the thankyou.php page? Please post the full contents of these pages and don't simply describe them to me. If there is a bug, it's contained within the code here."

<input type="hidden" name="return" value="http://www.website.com/thankyou.htm"> I was under the impression that this is the page the buyer sees on completion of payment. It's the page to the customer from my shop that PayPal wants displayed reassuring the customer. (Attached)

<input type="hidden" name="notify_url" value="https://www.website.com/thankyou.php"> This is the page that I have as the IPN handler, I tried it on the test-listener.htm and this is the page that I told you I sent to PayPal for their verification which they say is correct. The html on the page is merely a repeat 'thankyou' as I'm not sure if this gets sent to the buyer? If it doesn't get sent, there's no harm done. (Attached)

I think there's another question you asked but I can't see your message until I've sent this, so I'll follow up, Steve

I'm not seeing the files you attached.

BUT, there's no download urls for the customer's order to be downloaded, even though they're in the PayPal 'return url' box.

Please clarify what you mean by this? PayPal's return URL is thankyou.htm. What do you mean there's no download URLs? What are the complete contents of thankyou.htm ?? I'm still confused by what you think is not working correctly. You say that the buyer gets a download link and the payment shows up in PayPal. What are you trying to do that isn't working?!

<input type="hidden" name="hosted_button_id" value="YN5WHJPWYTEXE">

You are using a Hosted Button ID. That means that all of the preferences you would like are not all self-contained within these hidden input fields in the HTML. A lot of the preferences are set from the hosted button which is configured via PayPal's website.

On this Edit PayPal button page, I use my secure Merchant Account ID and I also use the 'Advanced Features' eg: Customer's Instructions, Cancel, Download Link url and Shopping url (Continue Shopping) and PayPal produce the unique code as above. (See Attached) Steve

Dani_SavedButton.png

Dani_AdvancedFeatures.png

OK, I think there's some confusion going on here.

You are showing me a screenshot of PayPal where you have the page "take customers to this URL when they have finished checkout" set to ...shop/acceptM/accept......htm ... Whatever value you have here, you are overwriting this value in your HTML when you set a return URL to thankyou.htm

So, just so we're on the same page, the URL customers should go to when they finish checkout will be thankyou.htm ... not that accept1_234Rtd.htm page.

As far as your IPN code being correct, that depends on what correct means. Yes, it's syntactically correct, and it does check for a valid IPN. However, it is configured ot not actually do anything.

Again, please, please, please tell me what you're trying to do that isn't working as desired. I don't understand what you think isn't working.

Dani wrote:
OK, I think there's some confusion going on here.
You are showing me a screenshot of PayPal where you have the page "take customers to this URL when they have finished checkout" set to ...shop/acceptM/accept......htm ... Whatever value you have here, you are overwriting this value in your HTML when you set a return URL to thankyou.htm
So, just so we're on the same page, the URL customers should go to when they finish checkout will be thankyou.htm ... not that accept1_234Rtd.htm page.
As far as your IPN code being correct, that depends on what correct means. Yes, it's syntactically correct, and it does check for a valid IPN. However, it is configured ot not actually do anything.
Again, please, please, please tell me what you're trying to do that isn't working as desired. I don't understand what you think isn't working.

Again, please, please, please tell me what you're trying to do that isn't working as desired. I don't understand what you think isn't working.

Yes, please, please, tell me :)

For those following this discussion, Steve wrote the following to me privately:

Yes, it's difficult, but basically, my customers are not able to complete their purchase, whether it be with smart buttons or the <form>. When I try my page in Sandbox, there's no option to pay by PayPal, only by credit card, sometimes it just goes to Guest. when I queried this with PayPal help, the person said an IPN would help, but he also said that PayPal don't do an IPN script, so I went on the hunt for one, I configured it to work with the IPN handler, I got a handshake when I dd the IPN simulator. I figured that was it?

Okay, I see. So basically what you're saying is the problem is that you want your customers to be able to pay by PayPal and not just by credit card and you feel like that isn't working. That has absolutely nothing to do with IPN.

PayPal IPN is something that notifies your server when someone has processed a payment, so that your server can then do something. For example, everytime someone clicks the DaniWeb donate button, I may wish to send them an email saying thanks. Or everytime someone buys my software, I may wish to email them their license key.

The IPN script that you are using has all the correct code in place to notify your server that someone has successfully made a payment, but then it doesn't actually do anything. It doesn't email them. It doesn't add a record to your database. It doesn't actually do anything with that acknowledgement, other than dismissing it.

My confusion was that I thought that what wasn't working was that you wanted to use IPN to email the customer a link to download the software after they paid, but then you kept saying that they were already being presented the download link and that was working fine. So I was not understanding what you wanted to use IPN for.

So now that I understand that your question has nothing to do with IPN, I went and created a new dummy HTML page in which I put the following code:

<form target="paypal" action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank"> 
<input type="hidden" name="no_shipping" value="1">
<input type="hidden" name="currency_code" value="GBP">
<input type="hidden" name="return" value="http://www.website.com/thankyou.php"> 
<input type="hidden" name="business" value="retrocascade@gmail.com">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="shopping_url" value="https://www.website.com/shop/pages/cartoons.htm">
<input type="hidden" name="hosted_button_id" value="YN5WHJPWYTEXE"> 
<input type="image" src="https://www.paypalobjects.com/en_GB/i/btn/btn_cart_LG.gif" border="0" name="submit"
alt="PayPal  The safer, easier way to pay online!">
<img alt="" border="0" src="https://www.paypalobjects.com/en_GB/i/scr/pixel.gif" width="1" height="1">
</form>

When I loaded the page, it me a yellow "Add to Cart" button. When I clicked the button, it lets me buy Cartoons for one pound, and I can either use my PayPal accoutn to check out or I can Check Out without a Paypal account.

Here is a screenshot:

Screen_Shot_2021-05-24_at_2_54_46_PM.png

So, do you think I should turn off the IPN and remove the listener from the server?
If you say I don't need it and with your amended code that got a result, I should definitly give it a go.
So where does the customer's download url(s) go to make a proper job? There has to be a way to do it so it's by return surely?
Steve

So, do you think I should turn off the IPN and remove the listener from the server?

If you don't have a use for it, then yes, turn it off.

If you say I don't need it and with your amended code that got a result, I should definitly give it a go.

I did not amend your code at all. I used your exact code, and I am presented with the ability to use my PayPal account. I am not seeing the problem you say you're countering.

So where does the customer's download url(s) go to make a proper job?

You can use IPN to email the customer a download link after their payment has been processed successfully. This is the ideal use case for IPN. However, IPN has nothing to do with letting the user use their PayPal vs debit account to pay.

If you wish to do this, then this is the part of the IPN code you have that you need to change:

if ($res == self::VALID) {

    // Instead of just returning true, send an email to the user with a download link here
    // return true;

} else {

    return false;

}

Yes, on further inspection I see that you left the 'thankyou.php' in the variables and not the 'thankyou.htm' is that what I want?
If so, do I keep the IPN turned on? Steve

It depends on what you want your website's functionality to be. Do you want to provide a download link on the thank you page? Or to the user via email?

That is why I kept asking you to show me the contents of thankyou.htm

It depends on what you want your website's functionality to be. Do you want to provide a download link on the thank you page? Or to the user via email?
That is why I kept asking you to show me the contents of thankyou.htm

Idealy the download link(s) would go to the buyer's email address because thankyou.htm is for everyone, it's not unique to the purchase.
I tried sending the thankyou.htm by attatchment Dani, but it failed. Steve

I tried sending the thankyou.htm by attatchment Dani, but it failed. Steve

What error message did you get?

Try posting your code in the message. Click the third button from the left in the editor toolbar (where it says 'Code') and copy/paste your code there. It formats it properly for you.

I just did a reply using the </> and I went to post the reply and it wouldn't move, I'll have another try . . .

2nd go
I have found the part you referred to in the IPN script, this is what you sent me to amend/add to:

if ($res == self::VALID) {

    // Instead of just returning true, send an email to the user with a download link here
    // return true;

} else {

    return false;

}

and this is what I wrote where you // commented:

  if ($res == self::VALID) {If you didn't get your download page, please send your PayPal transaction 
        number to retrocascade@gmail.com
                    return true;
        } else {
            return false;
        }
    }

Is the above correct? I think I did it right but I'm sending to you for verification. If it needs altering I'd be grateful if you would, Steve

Hi Steve,

No, you still are not understanding what I'm saying.

PayPal IPN operates as a background task between Paypal's server and your server communicating. This is outside the flow of the end-user making a purchase. Nothing in the IPN flow can be something that can be shown to the end-user.

Instead, you can use it to send an email to the end-user, but you need a working mail server and PHP email library to do that. You can also use it to update your database. You can use it to do background tasks. NOT to display HTML to an end-user.

Also, the code you have now is not valid PHP, anyways, because you just added regular english sentences before the return true;.

Going back to what I was saying before, please show the full code for thankyou.htm, which is where you are sending the user after they pay. Does thankyou.htm contain a link for the end user to download the digital goods? If not, how are they getting the digital goods after they pay?

Thank you for your response Dani, I'm grateful.
Here is the code to my thankyou.htm that you've asked for.

<?php

header( "HTTP/1.1 200 OK" ); 

class PaypalIPN
{

    /** @var bool Indicates if the sandbox endpoint is used. */
    private $use_sandbox = false;
    /** @var bool Indicates if the local certificates are used. */
    private $use_local_certs = true;

    /** Production Postback URL */
    const VERIFY_URI = 'https://ipnpb.paypal.com/cgi-bin/webscr';
    /** Sandbox Postback URL */
    const SANDBOX_VERIFY_URI = 'https://ipnpb.sandbox.paypal.com/cgi-bin/webscr';

    /** Response from PayPal indicating validation was successful */
    const VALID = 'VERIFIED';
    /** Response from PayPal indicating validation failed */
    const INVALID = 'INVALID';

    /**
     * Sets the IPN verification to sandbox mode (for use when testing,
     * should not be enabled in production).
     * @return void
     */
    public function useSandbox()
    {
        $this->use_sandbox = false;
    }

    /**
     * Sets curl to use php curl's built in certs (may be required in some
     * environments).
     * @return void
     */
    public function usePHPCerts()
    {
        $this->use_local_certs = false;
    }

    /**
     * Determine endpoint to post the verification data to.
     *
     * @return string
     */
    public function getPaypalUri()
    {
        if ($this->use_sandbox) {
            return self::SANDBOX_VERIFY_URI;
        } else {
            return self::VERIFY_URI;
        }
    }

    /**
     * Verification Function
     * Sends the incoming post data back to PayPal using the cURL library.
     *
     * @return bool
     * @throws Exception
     */
    public function verifyIPN()
    {
        if ( ! count($_POST)) {
            throw new Exception("Missing POST Data");
        }

        $raw_post_data = file_get_contents('php://input');
        $raw_post_array = explode('&', $raw_post_data);
        $myPost = array();
        foreach ($raw_post_array as $keyval) {
            $keyval = explode('=', $keyval);
            if (count($keyval) == 2) {
                // Since we do not want the plus in the datetime string to be encoded to a space, we manually encode it.
                if ($keyval[0] === 'payment_date') {
                    if (substr_count($keyval[1], '+') === 1) {
                        $keyval[1] = str_replace('+', '%2B', $keyval[1]);
                    }
                }
                $myPost[$keyval[0]] = urldecode($keyval[1]);
            }
        }

        // Build the body of the verification post request, adding the _notify-validate command.
        $req = 'cmd=_notify-validate';
        $get_magic_quotes_exists = false;
        if (function_exists('get_magic_quotes_gpc')) {
            $get_magic_quotes_exists = true;
        }
        foreach ($myPost as $key => $value) {
            if ($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) {
                $value = urlencode(stripslashes($value));
            } else {
                $value = urlencode($value);
            }
            $req .= "&$key=$value";
        }

        // Post the data back to PayPal, using curl. Throw exceptions if errors occur.
        $ch = curl_init($this->getPaypalUri());
        curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
        curl_setopt($ch, CURLOPT_SSLVERSION, 6);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);

        // This is often required if the server is missing a global cert bundle, or is using an outdated one.
        if ($this->use_local_certs) {
            curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . "/cert/cacert.pem");
        }
        curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'User-Agent: PHP-IPN-Verification-Script',
            'Connection: Close',
        ));
        $res = curl_exec($ch);
        if ( ! ($res)) {
            $errno = curl_errno($ch);
            $errstr = curl_error($ch);
            curl_close($ch);
            throw new Exception("cURL error: [$errno] $errstr");
        }

        $info = curl_getinfo($ch);
        $http_code = $info['http_code'];
        if ($http_code != 200) {
            throw new Exception("PayPal responded with http code $http_code");
        }

        curl_close($ch);

        // Check if PayPal verifies the IPN data, and if so, return true.
        if ($res == self::VALID) {If you didn't get your download page, please send your PayPal transaction 
        number to retrocascade@gmail.com
                    return true;
        } else {
            return false;
        }
    }
}

?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">


<meta name="robots" content="noindex,nofollow"/>
<meta content="en-us" http-equiv="Content-Language" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" type="text/css" href="styleroot.css" />

<style type="text/css">
.auto-style1 {
    color: #FF0000;
}
.auto-style2 {
    text-decoration: underline;
}
</style>

</head>

<body>
<p>Thank you for your order. </p>
<p>Your payment is complete.</p>
<p>Yours is a Digital Download, there's no physical street mailing.</p>
<p><b>PayPal is undergoing the changing of IP addresses which may interfere with Cascade's communication with its buyers.
Cascade appologises for this temporary blip, we have been assured that any interference will be kept to the absolute minimum. Cascade apologises if you have been inconvenienced.</b></p>
<p>You would have been given the link(s) for your download(s) automatically on a separate screen/window after your successful payment 
to PayPal.<br />
If you didn't receive the link(s) please let Cascade know and your download link(s) will be re-sent to you by e-mail in the strictest confidence. No addresses are put on a 
mailing list nor sold on.</p>
<p><b>If your download link <span class="auto-style2">doesn't</span> show up within 6 hours (which is highly 
unlikely) please e-mail
</b>
<a href="mailto:retrocascade@gmail.com?subject=Download Link" class="auto-style1">Cascade 
HERE</a> <strong>with the number of your PayPal transaction.</strong></p>
<p class="style4">(retrocascade@gmail.com?subject=Download Link) <br/> </p>
<p><b>PayPal</b> is the safer, easier way to pay.</p>


</body>

</html>

You also ask where to buyer gets their download link from, I have put the link url in the 'return url' box in the PayPal hosted button page.
Although it works, I would still like to know how it is done with the IPN as there are dozens of download links for different pages of my site.
Steve

Are you sure that's not thankyou.php but that it's thankyou.htm?

Your code redirects the end-user to thankyou.htm and it uses thankyou.php for IPN. You should NOT be redirecting the end-user to the IPN code. That is not what IPN is designed for.

Regardless, you tell the end-user:

You would have been given the link(s) for your download(s) automatically on a separate screen/window after your successful payment to PayPal.

What screen/window are you referring to? Where does the end-user get these download links from? What code do you have that opens this separate window?

success_url.png

Here is the link to the picture of the box in the buttons set up, this download url is sent instantly upon payment. I sent it before to you, but it was a lot smaller.
PayPal have verified that this is OK.
I will change the customer's thankyou.htm to just an html page (the html & php code I sent you was all on one page, but to the customer, only the html was visible.
I will put the listener.php on a separate page in my server's root directory. Steve

Steve,

The return URL page that you have set in the PayPal website is being overruled by your html code where you are sending them to thankyou.htm instead. The visitor does not see both. They get redirected to one location only. You have the default location set to the download page in PayPal, but you are overriding that default in your HTML code.

Also, this is not ideal because anyone can visit that webpage and download the software without paying.

<form target="paypal" action="https://www.paypal.com/cgi-bin/webscr" method="post"> 
<input type="hidden" name="business" value="email@gmail.com">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="YN5XXXXEXE"> 
<input type="hidden" name="shopping_url" value="https://www.website.com/shop/pages/cartoons.htm">
<input type="image" src="https://www.paypalobjects.com/en_GB/i/btn/btn_cart_LG.gif" border="0" name="submit"
alt="PayPal  The safer, easier way to pay online!">
<img alt="" border="0" src="https://www.paypalobjects.com/en_GB/i/scr/pixel.gif" width="1" height="1">
</form>

I have taken out both the 'thankyou' return to pages from the <form>, I have renamed the listener .php and made the adjustments so the customer just gets redirected to the coded download url in the PayPal box in my page settings on the PayPal 'create button' page.
The "shopping url" is there for the cart's Continue Shopping link.
I have been all through my site and re-done the <form> so every one of them look similar to the above.
I shall run a purchase in the Sandbox this afternoon.
I really am grateful for your help Dani, many a time I have been lost, or cannot find the correct PayPal instructions written in layman's language.
At least I can begin to understand the format the way you've phrased it, thank you, Steve

Yes, if you take those out of the form, then the buyer will be redirected to accept1_234Rtd.htm after paying.

They will never see any contents of thankyou.htm or thankyou.php and you will not be using IPN.

The problem with doing it this way is that accept1_234Rtd.htm is a publicly accessible HTML page. Someone can make the purchase, be directed to that page, and then share a link to that page with all their friends or on their social media. The next thing you know, everyone knows about that page and can download the digital goods without paying.

This is where IPN comes in. IPN is a backend notification from PayPal's server to your server. It tells your server "Someone with these credentials just paid, so you may wish to update your own database to record the buyer, or email the buyer, or do whatever you want to do on your end with this piece of knowledge."

When you use your PayPal IPN code, as you have it written, set as the notify_url specified in the form HTML, then what was happening was by having it there, your server was saying, "Paypal, have your server contact me at this PHP page when someone makes a payment, so I can process that payment on my end." Then, PayPal was sending a little behind-the-scenes notice to your server, saying "Someone with these credentials just paid." Your server was then saying, "OK, thanks. Bye." and literally not doing anything with that piece of information. That makes IPN, the way your code was, useless. That's why I was suggesting to you that instead of just return true; that you actually do something with that piece of information, such as email the customer saying, "Thanks for your payment. Here's a download link." or something. Otherwise, there was no point in using IPN.

To make this even more confusing, it seems like what you actually want to do is something called PayPal PDT. PDT is very similar to IPN. The difference is that IPN is a little behind-the-scenes notification between PayPal's server and your server, so you can do some backend processing. PDT does the same check that IPN does to see when a valid payment came in, but it is user-facing. That means that you add the PDT code to the return page (thankyou.php for example), and you can use it to actually verify that a unique customer made a payment, and if they did, show the HTML for the download link. However, if the end-user visits that page and didn't just make a payment with PayPal, they will see an error message.

More information about PDT can be found here https://developer.paypal.com/docs/api-basics/notifications/payment-data-transfer/

Dani Wrote:
Yes, if you take those out of the form, then the buyer will be redirected to accept1_234Rtd.htm after paying.
They will never see any contents of thankyou.htm or thankyou.php and you will not be using IPN.

Reply:
The thankyou.htm message is duplicated on the accept1_234Rtd.htm download page anyway, along with the reassurance of order text etc. that PayPal want including, so the buyers don't miss anything from my end.

So for the meantime, this would be fine, as I have a sale and the buyer has the product, so main goal achieved, it's all a shop wants really.

Your explanation of the workings of the IPN is now understandable, thanks for that and I feel the PDT is the way to go for me.
But I feel I have taken advantage of your patience and time Dani, so if you want to close this thread off I'll be fine with it, I shall get to the bottom of my no sales mystery with PayPal, it's not up to you to solve their problems, although you're much more reliable and talk more sense. Steve

I'm glad you understand.

Feel free to close this discussion (since it was started for IPN help), and then start a new one if you need help with PayPal PDT.

Understand that, when you were asking Paypal if IPN was implemented correctly, they were saying yes because your code was successfully implementing PayPal's IPN in the sense of: your code was telling Paypal how to notify your server; PayPal was sending those notifications; Your server was acknowledging and verifying the accuracy and legitimacy of those notifications. It just wasn't doing anything beyond that, which is beyond the scope of Paypal. At that point, PayPal's job is done, and it would be up to you to decide how you wanted to handle the knowledge of a successful payment (either by emailing the new buyer, adding the record to your database, etc.)

Make sense?

Good luck!! Feel free to post any PDT questions you may have.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of 1.21 million developers, IT pros, digital marketers, and technology enthusiasts learning and sharing knowledge.