【问题标题】:PHP Paypal error when customer places second order on express checkout API客户在快速结帐 API 上下第二单时 PHP Paypal 错误
【发布时间】:2016-01-28 06:59:43
【问题描述】:

当我有客户下 Paypal 订单时,第一个订单可以顺利完成。如果他们立即下另一个订单,则会出现此错误:

已成功完成此令牌的交易。

有什么想法可以解决这个问题,以便他们可以立即下订单吗?

getExpressCheckout

function PPHttpPost($methodName_, $nvpStr_) {


$API_UserName = PAYPAL_USER;
$API_Password = PAYPAL_PASS;
$API_Signature = PAYPAL_SIGNATURE;
$version = PAYPAL_VERSION;

$API_Endpoint = "https://api-3t.paypal.com/nvp";
if ("sandbox" === PAYPAL_ENVIRONMENT || "-sandbox" === PAYPAL_ENVIRONMENT) {
    $API_Endpoint = "https://api-3t." . PAYPAL_ENVIRONMENT . ".paypal.com/nvp";
}

//$version = urlencode('63.0');
// Set the curl parameters.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
curl_setopt($ch, CURLOPT_VERBOSE, 1);

// Turn off the server and peer verification (TrustManager Concept).
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);

// Set the API operation, version, and API signature in the request.
$nvpreq = "METHOD=$methodName_&VERSION=$version&PWD=$API_Password&USER=$API_UserName&SIGNATURE=$API_Signature$nvpStr_";

// Set the request as a POST FIELD for curl.
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);

// Get response from the server.
$httpResponse = curl_exec($ch);

if (!$httpResponse) {
    exit('$methodName_ failed: ' . curl_error($ch) . '(' . curl_errno($ch) . ')');
}

// Extract the response details.
$httpResponseAr = explode("&", $httpResponse);

$httpParsedResponseAr = array();
foreach ($httpResponseAr as $i => $value) {
    $tmpAr = explode("=", $value);
    if (sizeof($tmpAr) > 1) {
        $httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
    }
}

if ((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr)) {
    exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.");
}

return $httpParsedResponseAr;
}

// Obtain the token from PayPal.
if (!array_key_exists('token', $_REQUEST)) {
    exit('Token is not received.');
}

// Set request-specific fields.
$token = urlencode(htmlspecialchars($_REQUEST['token']));

// Add request-specific fields to the request string.
$nvpStr = "&TOKEN=$token";

// Execute the API operation; see the PPHttpPost function above.
$httpParsedResponseAr = PPHttpPost('GetExpressCheckoutDetails', $nvpStr);

if ("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"])) {
    // Extract the response details.
    $payerID = $httpParsedResponseAr['PAYERID'];
    $fname = $httpParsedResponseAr['FIRSTNAME'];
    $lname = $httpParsedResponseAr['LASTNAME'];
    $street1 = $httpParsedResponseAr["PAYMENTREQUEST_0_SHIPTOSTREET"];
    if (array_key_exists("PAYMENTREQUEST_0_SHIPTOSTREET2", $httpParsedResponseAr)) {
        $street2 = $httpParsedResponseAr["PAYMENTREQUEST_0_SHIPTOSTREET2"];
    }
    $city_name = $httpParsedResponseAr["PAYMENTREQUEST_0_SHIPTOCITY"];
    $state_province = $httpParsedResponseAr["PAYMENTREQUEST_0_SHIPTOSTATE"];
    $postal_code = $httpParsedResponseAr["PAYMENTREQUEST_0_SHIPTOZIP"];
    $country_code = $httpParsedResponseAr["PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE"];

//    $_SESSION['st_fname'] = htmlspecialchars(urldecode($fname));
//    $_SESSION['st_lname'] = htmlspecialchars(urldecode($lname));
//    $_SESSION['st_address'] = htmlspecialchars(urldecode($street1));
//    $_SESSION['st_address2'] = htmlspecialchars(urldecode($street2));
//    $_SESSION['st_city'] = htmlspecialchars(urldecode($city_name));
//    $_SESSION['st_state'] = htmlspecialchars(urldecode($state_province));
//    $_SESSION['st_zip'] = htmlspecialchars(urldecode($postal_code));
    $_SESSION['pp_token'] = htmlspecialchars(urldecode($httpParsedResponseAr['TOKEN']));
    $_SESSION['pp_payerid'] = htmlspecialchars(urldecode($httpParsedResponseAr['PAYERID']));
    $_SESSION['pp_email'] = htmlspecialchars(urldecode($httpParsedResponseAr['EMAIL']));
    $_SESSION['pp_phone'] = htmlspecialchars(urldecode($httpParsedResponseAr['PHONE']));
    $_SESSION['paymentType'] = "paypal";





    //echo 'Get Express Checkout Details Completed Successfully: '.print_r($httpParsedResponseAr, true);
    header('Location: ' . $path . '/paypal_do.php');
} else {
    $_SESSION['cc_msg'] = "Paypal payment failed.  Please try again";
    //print_r($httpParsedResponseAr);
    header('Location: ' . $path . '/pay.php');

    //exit('GetExpressCheckoutDetails failed: ' . print_r($httpParsedResponseAr, true));
}

设置ExpressCheckout

function PPHttpPost($methodName_, $nvpStr_) {



$API_UserName = PAYPAL_USER;
$API_Password = PAYPAL_PASS;
$API_Signature = PAYPAL_SIGNATURE;
$version = PAYPAL_VERSION;

$API_Endpoint = "https://api-3t.paypal.com/nvp";
if ("sandbox" === PAYPAL_ENVIRONMENT || "-sandbox" === PAYPAL_ENVIRONMENT) {
    $API_Endpoint = "https://api-3t." . PAYPAL_ENVIRONMENT . ".paypal.com/nvp";
}

//$version = urlencode('63.0');
// Set the curl parameters.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
curl_setopt($ch, CURLOPT_VERBOSE, 1);

// Turn off the server and peer verification (TrustManager Concept).
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);

// Set the API operation, version, and API signature in the request.
$nvpreq = "METHOD=$methodName_&VERSION=$version&PWD=$API_Password&USER=$API_UserName&SIGNATURE=$API_Signature$nvpStr_";

// Set the request as a POST FIELD for curl.
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);



// Get response from the server.
$httpResponse = curl_exec($ch);

if (!$httpResponse) {
    exit("$methodName_ failed: " . curl_error($ch) . '(' . curl_errno($ch) . ')');
}

// Extract the response details.
$httpResponseAr = explode("&", $httpResponse);

$httpParsedResponseAr = array();
foreach ($httpResponseAr as $i => $value) {
    $tmpAr = explode("=", $value);
    if (sizeof($tmpAr) > 1) {
        $httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
    }
}

if ((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr)) {
    exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.");
}

return $httpParsedResponseAr;
}

// Set request-specific fields.

$paymentAmount = urlencode(number_format($_SESSION['grandTotal'], 2));
$currencyID = urlencode('USD');       // or other currency code ('GBP', 'EUR', 'JPY', 'CAD', 'AUD')
$paymentType = urlencode('Sale');    // or 'Sale' or 'Order'

$returnURL = urlencode($path . "/paypal_get.php");
$cancelURL = urlencode($path . "/pay.php");

/*

  $sql = "SELECT * FROM cart WHERE session_id = '".session_id()."'";
  $result = mysql_query($sql) or die(mysql_error());
  $count = 0;

  while($rows=mysql_fetch_array($result)){
  $sql = "SELECT * FROM products WHERE id = ".$rows['item_id'];
  $results = mysql_query($sql);
  $item_row = mysql_fetch_array($results);

  $sql = "SELECT * FROM frame_options WHERE id = ".$rows['frame_id'];
  $results = mysql_query($sql);
  $item_frame = mysql_fetch_array($results);

  //build the item row
  $item = $item_row['width']." x ".$item_row['height']." ".$rows['finish_id'];


  $nvpStr .= "&L_PAYMENTREQUEST_0_NAME".$count."=".$item;
  $nvpStr .= "&L_PAYMENT_REQUEST_0_QTY".$count."=".$rows['qty'];
  $nvpStr .= "&L_PAYMENT_REQUEST_0_AMT".$count."=".$rows['price'];

  $count++;

  }
  if(isset($_SESSION['discount']) && $_SESSION['discount'] <> 0){
  $nvpStr .= "&L_PAYMENTREQUEST_0_NAME".$count."=Discount";
  $nvpStr .= "&L_PAYMENT_REQUEST_0_QTY".$count."=1";
  $nvpStr .= "&L_PAYMENT_REQUEST_0_AMT".$count."=-".$_SESSION['discount'];
  }

  //determine shipping cost

  $sql = "SELECT * FROM shipping_options WHERE id = ".$_SESSION['shipping_option'];
  $result = mysql_query($sql) or die(mysql_error());
  $shipping_row = mysql_fetch_array($result);

  $paymentAmount = $paymentAmount - $shipping_rows['rate'] - $_SESSION['sales_tax'];

  $nvpStr .= "&PAYMENTREQUEST_0_SHIPPINGAMT = ".$shipping_row['rate'];

  $sql = "SELECT SUM(price) as itemTotal FROM cart WHERE session_id = '".session_id()."'";
  $result = mysql_query($sql) or die(mysql_error());
  $itemTotal_row = mysql_fetch_array($result);
  $nvpStr .= "&PAYMENTREQUEST_0_ITEMAMT = ".$itemTotal_row['itemTotal'];
 */
// Add request-specific fields to the request string.
$nvpStr .= "&PAYMENTREQUEST_0_AMT=$paymentAmount&RETURNURL=$returnURL&CANCELURL=$cancelURL&PAYMENTREQUEST_0_PAYMENTACTION=$paymentType&CURRENCYCODE=$currencyID";
$nvpStr .= "&HDRIMG=" . $path . "/images/logo_white_background.png&useraction=commit";






echo $nvpStr;



// Execute the API operation; see the PPHttpPost function above.
$httpParsedResponseAr = PPHttpPost('SetExpressCheckout', $nvpStr);


if ("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"])) {
    // Redirect to paypal.com.
    $token = urldecode($httpParsedResponseAr["TOKEN"]);
    $payPalURL = "https://www.paypal.com/webscr&cmd=_express-checkout&token=$token&useraction=commit";
    if ("sandbox" === $environment || "-sandbox" === $environment) {
        $payPalURL = "https://www.$environment.paypal.com/webscr&cmd=_express-checkout&token=$token";
    }
    header("Location: $payPalURL");
    exit;
} else {
    exit('SetExpressCheckout failed: ' . print_r($httpParsedResponseAr, true));
}

DoExpressCheckout

function PPHttpPost($methodName_, $nvpStr_) {



$API_UserName = PAYPAL_USER;
$API_Password = PAYPAL_PASS;
$API_Signature = PAYPAL_SIGNATURE;       
$version = PAYPAL_VERSION;

$API_Endpoint = "https://api-3t.paypal.com/nvp";
if ("sandbox" === PAYPAL_ENVIRONMENT || "-sandbox" === PAYPAL_ENVIRONMENT) {
    $API_Endpoint = "https://api-3t." . PAYPAL_ENVIRONMENT . ".paypal.com/nvp";
}

 //$version = urlencode('63.0');

// setting the curl parameters.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
curl_setopt($ch, CURLOPT_VERBOSE, 1);

// Set the curl parameters.
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);

// Set the API operation, version, and API signature in the request.
$nvpreq = "METHOD=$methodName_&VERSION=$version&PWD=$API_Password&USER=$API_UserName&SIGNATURE=$API_Signature$nvpStr_";

// Set the request as a POST FIELD for curl.
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);

// Get response from the server.
$httpResponse = curl_exec($ch);

if (!$httpResponse) {
    exit('$methodName_ failed: ' . curl_error($ch) . '(' . curl_errno($ch) . ')');
}

// Extract the response details.
$httpResponseAr = explode("&", $httpResponse);

$httpParsedResponseAr = array();
foreach ($httpResponseAr as $i => $value) {
    $tmpAr = explode("=", $value);
    if (sizeof($tmpAr) > 1) {
        $httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
    }
}

if ((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr)) {
    exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.");
}

return $httpParsedResponseAr;
}

/**
 * This example assumes that a token was obtained from the SetExpressCheckout API call.
 * This example also assumes that a payerID was obtained from the SetExpressCheckout API call
 * or from the GetExpressCheckoutDetails API call.
 */
// Set request-specific fields.
$payerID = urlencode($_SESSION['pp_payerid']);
$token = urlencode($_SESSION['pp_token']);

$paymentType = urlencode("Sale");   // or 'Sale' or 'Order'
$paymentAmount = urlencode(number_format($_SESSION['grandTotal'], 2));
$currencyID = urlencode("USD");      // or other currency code ('GBP', 'EUR', 'JPY', 'CAD', 'AUD')
// Add request-specific fields to the request string.
$nvpStr = "&TOKEN=$token&PAYERID=$payerID&PAYMENTACTION=$paymentType&AMT=$paymentAmount&CURRENCYCODE=$currencyID";

// Execute the API operation; see the PPHttpPost function above.
$httpParsedResponseAr = PPHttpPost('DoExpressCheckoutPayment', $nvpStr);


if ("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || 
        "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"])) {
    $_SESSION['paypal_transaction_id'] = $httpParsedResponseAr['TRANSACTIONID'];

    cartToOrder();


    redirect("order_confirmation.php");
    exit('Express Checkout Payment Completed Successfully: ' . print_r($httpParsedResponseAr, true));
} else {
    exit('DoExpressCheckoutPayment failed: ' . print_r($httpParsedResponseAr, true));
}

【问题讨论】:

  • 也许问题是使用一个令牌在一个会话中添加多个产品?
  • 我建议你考虑是否应该在这个问题中添加一些代码?
  • @pavel 我已经为我正在使用的 paypal express checkout 中的三个步骤添加了代码。如果您需要查看任何其他代码,请告诉我。
  • 您必须在方法 SetExpressCheckout 之后使用方法 GetExpressCheckoutDetails。您将需要由 SetExpressCheckout 设置的 TOKEN。只需更改方法的顺序

标签: php paypal express-checkout


【解决方案1】:

首先,使用一个 TOKEN(在一个 http 请求上),您可以选择创建一个产品会话。如果您使用某些 API 方法(DoExpressCheckoutPayment、CreateRecurringPaymentsProfile 等),您将消耗此令牌!其他选项是使当前令牌的时间过期,但在这种情况下,错误消息将不同于“此令牌的成功交易已经完成。”

所以你必须再次使用 SetExpressCheckout API 方法来获取另一个令牌。

【讨论】:

  • 我正在使用另一个 SetExpressCheckout。每次订单后,我都会再次完成该过程。是否有可能将贝宝令牌保存在会话中并且由于它已经设置而不会被覆盖一秒钟?我想我可以清除贝宝令牌的会话,但我认为这与它没有任何关系。
  • 每个令牌都与使用方法 SetExpressCheckout 设置的产品和详细信息相关联。请提供一些代码
猜你喜欢
  • 2016-07-10
  • 2012-07-02
  • 2020-09-25
  • 2017-10-24
  • 2015-12-02
  • 2016-08-24
  • 2016-07-17
  • 2023-04-08
  • 1970-01-01
相关资源
最近更新 更多