I created an application that sends the notification URL with the GUID of the registered user to PayPal, and after the purchase is completed, the URL is called, and after checking, the entry in the user database updates the purchased column from 0 to 1.
Then the user presses the back button to the application, and the premium functionality is displayed based on the purchased column.
I have tested this over the last few months in the sandbox. 100% time-tested (including after this problem) the premium tab is displayed after the purchase is completed.
The client is delighted, and gives the opportunity to go to production. I configured IPN with the same URL, I didn’t change anything except switching from www.sandbox.paypal.com to www.paypal.com and changing the account specified in the business sandbox to a personal business.
The problem is that the button is no longer displayed, until you refresh the screen. By clicking the "return to application" button, which previously worked as expected, the premium tab is no longer displayed. As soon as I click Refresh, a message will appear. If I switch everything back to the sandbox settings, boom - it works fine again.
Here is the BuyNow button code with the production account:
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" id="buynowForm" target="_top"> <input type="hidden" name="cmd" value="_xclick"> <input type="hidden" name="business" value="ACCOUNT EMAIL"> <input type="hidden" name="lc" value="US"> <input type="hidden" name="item_name" value="Product"> <input type="hidden" name="amount" value="10.00"> <input type="hidden" name="currency_code" value="USD"> <input type="hidden" name="button_subtype" value="services"> <input type="hidden" name="no_note" value="1"> <input type="hidden" name="no_shipping" value="1"> <input type='hidden' name='notify_url' value='http://app.com/purchase/<?php echo $data[0]['uid'] ?>'> <input type='hidden' name='return' value='http://app.com/'> <input type="hidden" name="rm" value="1"> <input type="hidden" name="cbt" value="Return to Product Plus"> <input type="hidden" name="bn" value="PP-BuyNowBF:btn_buynowCC_LG.gif:NonHosted"> <input type="submit" class="hidden-print visible-print" border="0" name="buysubmit" value="Click For Product Plus" alt="Click for Product Plus"> <img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1">
And here is the processing route that is called above:
$app->post('/purchase/:uid', function ($uid) use ($app) { $request = Slim::getInstance()->request(); $inputs = json_decode($request->getBody()); $db_conn = conn(); $req = 'cmd=_notify-validate'; foreach ($_POST as $key => $value) { if (get_magic_quotes_gpc()) { $_POST[$key] = stripslashes($value); $value = stripslashes($value); } $value = urlencode($value); $req .= "&$key=$value"; } $url = "https://www.paypal.com/cgi-bin/webscr"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL,$url); curl_setopt($ch, CURLOPT_FAILONERROR, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); curl_setopt($ch, CURLOPT_TIMEOUT, 3); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $req); $result = curl_exec($ch); curl_close($ch); if (strcmp ($result, "VERIFIED") == 0) { $sql_st = 'UPDATE `user_data` SET `purchased` = 1 WHERE uid=:uid'; $sql = $db_conn->prepare($sql_st); if ($sql->execute(array('uid'=>$uid))) { $data = array('status' => "Ok"); } else { $data = array('status' => print_r(mysql_error())); } } else {
REALLY hoping this is just incredibly stupid of me. Any help / guidance is appreciated.