【发布时间】: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));
}
【问题讨论】: