I have built an application, that sends a notification url with the GUID of the logged in user to PayPal, and upon completion of purchase, the url is called, and after verification, the user database entry updates the column purchased
from 0 to 1.
The user then clicks the return to app button, and the premium functionality displays based on the purchased
column.
I have been testing this over the last few months in the sandbox. 100% of the times tested (including after this issue), the premium tab displays after purchase completion.
Client is thrilled, and gives the go ahead to move to production. I have set up IPN with the exact same URL, I have changed literally nothing except switching from www.sandbox.paypal.com to www.paypal.com and changing the account listed from the sandbox business to the personal business.
Ths issue is, the button now doesn't show up, until, you refresh the screen. Clicking the "return to app" button, which previously was working as expected, now doesn't display the premium tab. Once I click refresh - it then shows up. If I switch everything back to the sandbox settings, boom - it works just fine again.
Here is the BuyNow button code with 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 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
{
// Did Not Process IPN Properly
}
});
REALLY hoping this is just something incredibly dumb on my part. Any help/guidance is appreciated.