PHP Paypal认证/捕获NVP集成故障 [英] PHP Paypal Auth/Capture NVP Integration Troubles

查看:896
本文介绍了PHP Paypal认证/捕获NVP集成故障的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们使用NVP集成和php-curl实现了Paypal授权和捕获流程。
PayPal开发人员网站上说明了完整的程序: https://developer.paypal.com/webapps/developer/docs/classic/express-checkout/ht_ec-singleAuthPayment-curl-etc/

We implemented Paypal Authorization and Capture flow using NVP integration and php-curl.
The complete process is described on the PayPal developer website : https://developer.paypal.com/webapps/developer/docs/classic/express-checkout/ht_ec-singleAuthPayment-curl-etc/

在我们的网站上,当前的付款方案是:

- 首先,用户点击按钮启动付款授权,在PayPal网站上将其重定向(SetExpressCheckout with paymentaction = Authorization)

- 如果用户在PayPal网站上成功确认付款,则会在特定成功页面上重定向到我们的网站

- 此成功页面会获得令牌和然后调用GetExpressCheckoutDetails检查此授权的状态和金额

- 如果一切正常,我们告诉PayPal确认此授权(DoExpressCheckoutPayment with paymentaction = Authorization),我们获得一个授权ID存储到我们的数据库中

- 稍后,其他人可以通过点击按钮,使用我们存储的授权ID(DoCapture)$ b $结算交易b

On our website, the current payment scenario is :
- First, an user click on a button to initiate a payment authorization, redirecting him on the PayPal website (SetExpressCheckout with paymentaction=Authorization)
- If the user succesfully confirmed the payment on the PayPal website, he is redirected to our website on a specific success page
- This "success page" gets a token and a PayerID from the PayPal website, we then call GetExpressCheckoutDetails to check the status and the amount of this authorization
- If everything is ok, we tell PayPal to confirm this authorization (DoExpressCheckoutPayment with paymentaction=Authorization) and we get an authorization ID to store into our database
- Later, someone else can settle the transaction by clicking on a button, using the authorization ID we stored (DoCapture)

根据PayPal文档:

According to the PayPal documentation :


PayPal在三天内授予100%的授权资金


如果有买家和商家的帐户,是
待处理(未结算)授权

https://developer.paypal.com/docs/classic/paypal-payments-standard/integration-guide/authcapture/

在我们的网站上,如果在24小时内未解决,授权将自动失效。 (使用crontab)


On our website, authorizations are automatically voided if they are not settled within 24 hours. (using crontab)

在最后一部分(当我们调用确认功能):当用户点击确认按钮,看起来有时卷曲请求花费时间从PayPal返回交易ID。
当这个发生,用户通常关闭网页,PayPal确认授权(因此货币转移),但我们的网站没有得到通知,因为下面的代码(从下面的源代码部分)没有执行或达到: p>

A problem occurs on the last part (when we call the "confirm" function) : When an user click on a "confirm" button, it seems that sometimes the curl request is taking time to get a transaction ID back from PayPal.
When this happens, the user usually close the webpage, PayPal confirm the authorization (and thus money transfert) but our website is not notified about this because the following code (from the "Source Code" section below) has not been executed or reached :

if ($transaction_id) {
    /*
     * [...]
     * Everything is ok, payment has been performed
     * so we do everything to give our user what he asked for
     */
} else {
    // Error : No transaction id
}

因为脚本在获取curl响应之前停止。

,如果我们再次尝试点击按钮,PayPal告诉我们授权ID不存在(因为已经执行)。

Because the script stopped before getting the curl response.
Moreover, if we try to click on the button again, PayPal tells us that the authorization ID doesn't exist (because already performed).

但有时一切正常井没有任何问题或滞后。


But sometimes everything works well without any problem or lag.

/*
 * This is our main function, called when
 * we have to settle our transaction 
 * when an user click on a "confirm" button
**/
public function confirm($cart_id) {
    /*
     * [...]
     * We check lot of stuff to be sure this user 
     * can perform this action
     */

    // We get theses values from the database
    authorization_id = "lorem ipsum";
    $amount = 10; 

    // We tell PayPal to settle the transaction
    $transaction_id = $this->settle_transaction($authorization_id, $amount);
    if ($transaction_id) {
        /*
         * [...]
         * Everything is ok, payment has been performed
         * so we do everything to give our user what he asked for
         */
    } else {
        // Error : No transaction id
    }
}

private function settle_transaction($authorization_id, $amount) {
    // Our credentials
    $params = array(
        "USER" => $this->paypal_user,
        "PWD" => $this->paypal_pwd,
        "SIGNATURE" => $this->paypal_signature,
        "VERSION" => 95
    );
    $params["METHOD"] = "DoCapture";
    $params["AUTHORIZATIONID"] = $authorization_id;
    $params["AMT"] = $amount;
    $params["CURRENCYCODE"] = "EUR";
    $params["COMPLETETYPE"] = "Complete";

    $result = $this->curl($params);
    if ($result) {
        // We check that this PayPal request has been successful
        if ($result["ACK"] == "Success") {
            $transaction_id = $result["TRANSACTIONID"];
            if ($result["PAYMENTSTATUS"] == "Completed") {
                return $transaction_id;
            }
        }
    }
    return NULL;
}


private function curl($params) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $this->paypal_endpoint);
    curl_setopt($ch, CURLOPT_POST, count($params));
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    parse_str(curl_exec($ch), $result);
    curl_close($ch);
    return $result;
}

您有任何想法来解决此问题吗?

我正在考虑在脚本结束时解决交易,因为PayPal三天获得100%的授权资金,我只需要他们保持1天,但我不知道这个...

Do you have any idea to resolve this issue ?
I was thinking about settling transaction at the end of the script because PayPal honors 100% of authorized funds for three days, and I only need them to be hold for 1 day but I'm not sure of this anyway ...

我的apache2 error.log报告这个问题发生时:

My apache2 error.log reported this when this problem happens :

[Mon Aug 08 20:42:55.959330 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:42:56.960453 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:42:57.961188 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:42:58.962230 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:42:59.963297 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:00.964384 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:01.965476 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:02.966478 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:03.967595 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:04.968713 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:05.969783 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:06.970877 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:07.972002 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:08.972749 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:09.973847 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:10.974926 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:11.976080 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:12.977168 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:13.978244 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:14.979320 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:15.980414 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:16.981493 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:17.982578 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:18.983673 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:19.984762 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:20.985841 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:21.986650 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:22.987725 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:23.988826 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:24.989939 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:25.991061 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:26.992181 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:27.993305 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:28.994422 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:29.995556 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:30.996661 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:31.997774 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:32.998905 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:34.000089 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:35.001202 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:36.002326 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:37.003424 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:38.004551 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:39.005677 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:40.006799 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:41.007902 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:42.009021 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:43.010132 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:44.011245 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:45.012361 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:46.013479 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:47.014577 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:48.015685 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:49.016801 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:50.017906 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:51.018980 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:52.020049 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:53.021158 2016] [mpm_event:error] [pid 141:tid 3779940374400] AH00485: scoreboard is full, not at MaxRequestWorkers
[Mon Aug 08 20:43:53.391316 2016] [:error] [pid 980:tid 3779386513152] (104)Connection reset by peer: [client MY-IP:55236] FastCGI: failed to read from backend server, referer: http://####
[Mon Aug 08 21:18:04.748237 2016] [:error] [pid 1287:tid 3779782977280] (104)Connection reset by peer: [client MY-IP:37196] FastCGI: failed to read from backend server





我发现此主题似乎有类似的问题:

Edit 2:

I found this topic that seems to have a similar issue :


特别奇怪的是,付款已正确处理。

What is particularly strange is that the payment has been processed correctly.

现在我似乎无法再现此错误。

它可能是一个PayPal问题或类似的这样?

即使是这样,我不会确保这个问题不会再发生,但如何我可以测试,如果我不能

And right now I can't seem to be able to reproduce this bug.
Do you think it could have been a PayPal issue or something like this ?
Even if it was, I wan't to make sure that this problem won't happen again, but how can I test if I can't reproduce this ?

推荐答案


注意:并非所有付款都是即时的。如果买家只有一个银行
帐户与他们的PayPal帐户相关联,则转帐不会是
即时。因此,如果需要所有付款和相关活动的自动通知,则最佳做法会使用 IPN

根据PayPal官方文件:

According to PayPal Official Docs:


即时付款通知(IPN)是一种邮件服务,通知
您与PayPal相关的活动交易。您可以使用IPN消息
来自动执行后台和管理功能,例如履行订单,跟踪客户或提供状态的
以及其他
交易相关信息。

Instant Payment Notification (IPN) is a message service that notifies you of events related to PayPal transactions. You can use IPN messages to automate back-office and administrative functions, such as fulfilling orders, tracking customers, or providing status and other transaction-related information.

作为最佳实践,在 IPN Listener 中设置事务脚本。有关集成指南,您可以参考: https://developer.paypal .com / docs / classic / ipn / integration-guide / IPNImplementation /

As best practice set transactional script in your IPN Listener. For the integration guide you can refer here : https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNImplementation/

我已经扩展了一个 PHP类 IPN Listener 希望它可以帮助作为起点。随意分叉: https://github.com/datumradix/PayPal-IPN-PHP -Class-

I have extended a PHP class for PayPal IPN Listener few months backs. Hope it may help as starting point. Feel free to fork :https://github.com/datumradix/PayPal-IPN-PHP-Class-

编辑:(PayPal文档在许多地方不清楚,似乎令许多第一次读者感到困惑) code>

(PayPal Documentation is not clear at many places and seems confusing to many first time readers)

IPN可以派上用场,作为确认DoCapture是否成功的辅助机制。 IPN变量,例如 txn_type txn_id auth_id auth_amount payer_id 都通知IPN。请在此处参阅完整列表: https://developer.paypal.com / docs / classic / ipn / integration-guide / IPNandPDTVariables /

IPN can come handy as secondary mechanism to confirm if the DoCapture was successful. IPN variables like txn_type, txn_id,auth_id, auth_amount and payer_id are all notified thro IPN. Please ref here for full list: https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNandPDTVariables/


注意:我们可以指定 NOTIFYURL ,或者我们可以通过paypal后端设置
。有关从
PayPal配置文件设置中设置相同步骤的步骤,请参阅
https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNSetup/

Note: We can either specify the NOTIFYURL in each call or we can setup the same from paypal back-end. For steps to setup the same from PayPal profile settings, ref :https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNSetup/

这篇关于PHP Paypal认证/捕获NVP集成故障的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆