duancan5327 2013-12-16 03:07
浏览 105
已采纳

PayPal生产与沙箱的工作方式不同

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.

  • 写回答

1条回答 默认 最新

  • dongyou26216708 2013-12-18 14:22
    关注

    Essentially the solution here is one of two options -

    1. Build a secondary method of completion - in other words, the IPN is not the first line of defense for a purchased upgrade to software. Everything on my end is working, however the timing of the IPN (notify_url) call is too slow to make instant upgrades not exactly instant. Return them to a page that performs the upgrade then redirects.

    2. Store the upgraded features behind a different route - this was PayPal's suggestion. Essentially, have app.com/basic and app.com/upgraded. This isn't really ideal, nor would I suggest it as a permanent solution.

    Summed up - this is a known issue with PayPal. The sandbox and production workflows are basically different - not by function or API, but in usage - the production level account is getting hit more, and the time it takes to process the notifications are much slower.

    Hope this helps someone.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)