【问题标题】:Duplicate Request in DoExpressCheckoutPayment (Digital Goods Checkout Express)DoExpressCheckoutPayment 中的重复请求(数字商品结账快递)
【发布时间】:2013-12-11 19:55:25
【问题描述】:

长话短说,我相信我已经正确地实现了流程,但是在最后的 DoExpressCheckoutPayment 上我得到了:

ACK => SuccessWithWarning  
L_ERRORCODE0 => 11607
L_SHORTMESSAGE0 => Duplicate Request
L_LONGMESSAGE0 => A successful transaction has already been completed for this token

这仅仅是因为我在此之前正在执行 GetExpressCheckoutDetails 请求吗? (GetExpressCheckoutDetails ACK 为“成功”)

请注意,从 DoExpressCheckoutPayment 返回的其他数据看起来不错:

PAYMENTINFO_0_PAYMENTSTATUS => Completed
PAYMENTINFO_0_ACK => Success

我应该只查找 PAYMENTINFO_0_ACK 而忽略其余部分吗?

旁注-如果感兴趣,我在https://github.com/thenbrent/paypal-digital-goods 使用 PHP 库,尽管我将示例 return.php 中的内容更改为新类的 GetExpressCheckoutDetails,因为当然,使用它没有任何意义每次购买数据都相同,而且必须是动态的

编辑:好吧,我很困惑。如果我调用GetExpressCheckoutDetails,那么响应是:

CHECKOUTSTATUS => PaymentActionNotInitiated

但是,如果我调用 GetExpressCheckoutDetails,然后调用 DoExpressCheckoutPayment,前面的 GetExpressCheckoutDetails 的响应将变为:

CHECKOUTSTATUS => PaymentActionCompleted(由此可见后续DoExpressCheckoutPayment的结果有Duplicate Request的错误)

这有什么意义?!香草 PHP 刚刚变得异步了吗?贝宝有足够的钱买一台时光机吗?我可能遗漏了一些非常基本的东西,但我真的还没有看到:\

EDIT 2 一些示例代码(没有将其剥离以使其成为 100% 香草,但应该非常简单):

public static function completePaypalPurchase() {
    self::configurePaypal(''); // Not relevent, just some setting of API keys and stuff
    $paypalAPI = new PayPal_Purchase(); // Just to get purchase info so we can form the real purchase request
    $response = $paypalAPI->get_checkout_details(); // Uses token from GET automatically

    echo("RESPONSE FROM GET CHECKOUT");
    print_r($response);

    $ack = strtoupper($response['ACK']);
    $userID = (int)$response['CUSTOM']; // This was passed earlier and is retrieved correctly
    $numCredits = (int)$response['L_QTY0'];

    //NOTE: If I comment out the below, then the $response above has CHECKOUTSTATUS => PaymentActionNotInitiated
    //      BUT If I do not comment it out, leaving it as-is then the $response above has CHECKOUTSTATUS => PaymentActionCompleted
    //      That's the core of the problem and where I'm stuck

    if($ack == "SUCCESS" && $numCredits && $userID && $userID == $loggedInUserID) {
        $paypalAPI = self::getPaypalPurchaseCredits($userID, $numCredits); // This creates a new PayPal_Purchase() with this info. In fact, it's the same method and therefore should return the same sort of object as the one used at the beginning of the flow
        $response = $paypalAPI->process_payment();
        $ack = strtoupper($response['ACK']);

        echo("RESPONSE FROM DO PAYMENT");
        print_r($response);
        if(isset($response['PAYMENTINFO_0_TRANSACTIONID']) && $ack == "SUCCESS") {
            $transactionID = $response['PAYMENTINFO_0_TRANSACTIONID'];
            return(new APIReturn(true, array('ack'=>$ack, 'userid'=>$userID, 'numcredits'=>$numCredits, 'transactionid'=>$transactionID)));
        }
    }
    return(new APIReturn(false, self::ERROR_NORESULT));
}

【问题讨论】:

    标签: php paypal


    【解决方案1】:

    调用的正确顺序是 SetExpressCheckout、GetExpressCheckoutDetails,然后是 DoExpressCheckoutPayment。如果您收到重复订单错误,那么您必须以某种方式调用 DECP 两次。您需要单步执行您的代码并确切了解这是如何发生的。它可能是您正在使用的课程中的某些东西。

    请注意,您可能有兴趣改用look at my class。它使一切变得非常简单,因为它将所有内容都转换为 PHP 数组并为您处理繁琐的工作。

    但是,如果您不想从新类重新开始,那么,您需要逐步了解您的代码发生了什么,并通过类方法来查看它被发布两次的位置。

    我注意到的另一件事是您只检查 ACK = Success。这意味着当 ACK = SuccessWithWarning 时,它将被视为失败。您需要同时处理 Success 和 SuccessWithWarning(体面的类库会为您处理。)

    抱歉,我没有更明确的答案,但同样,在您的代码或库中的某个地方,它必须被发布两次。您是否在记录原始 API 请求和响应?如果是这样,您将能够确认它被击中两次,因为您将记录 2 组 DECP 请求和响应。

    【讨论】:

    • 谢谢。由于我绝对不会调用 DoExpressCheckoutPayment 两次,所以它一定是库中的一些奇怪的错误。由于我只做一件事——通过快速结账对数字商品进行单一结账,我想我会尝试自己动手,看看我的结局如何。如果我再次卡住,我会试试你的代码。仍然 - 对 GetExpressCheckoutDetails 的 preceding 调用失败似乎很奇怪:\
    • 如果你要“自己动手”,那是使用我的图书馆的最佳时机。它不会试图为你做太多。它只是列出了所有内容,因此您所要做的就是填写参数。对于 PayPal 平台中可用的每个 Classic API 调用,它都有一个单独的模板文件,它将真正为您节省大量时间。我真的建议你看看它。您可以在大约 10 分钟内完成有效的 Express Checkout 设置。
    • 我决定使用官方的 paypal 东西以及我从玩其他库中学到的东西来推出自己的产品。我相信你的库很棒,但我真的只想要一些最小的代码,以便我可以轻松地看到它是如何工作的,以防我需要调试。好消息是我成功了 :) 这是我的课程...我认为将我的存根留给实际用例对任何想要在生产中使用它的人都有帮助:gist.github.com/anonymous/7925377
    • 对我来说这看起来不像是最少的代码,但我很高兴你让它工作了! :)
    • 你在开玩笑吗?您的包含大约 7600 行代码。我的是 392 - 其中包括一些工作抽象和 html 示例......其中大部分是 cmets!我无法想象它怎么能比这更小
    猜你喜欢
    • 1970-01-01
    • 2017-08-18
    • 2013-03-29
    • 2011-07-24
    • 1970-01-01
    • 2011-07-10
    • 2013-05-23
    • 2013-03-20
    • 2013-12-05
    相关资源
    最近更新 更多