Идентификатор транзакции недействителен 10609

Я очень плохо знаком с PayPal API, я следовал этому руководству и адаптировал код для своих нужд.

Я хотел бы сделать базовую авторизацию и захват в 3 шага, но мне всегда не удается захватить

  1. Клиент приземлится до paypal_pay_redirect.php для входа в PayPal и внесения платежа
  2. Оплата в порядке, и мы попадаем на paypal_success.php, здесь я запрашиваю авторизацию и сохраняю TRANSACTIONID для следующего шага
  3. paypal_capture.php Я использую идентификатор транзакции для захвата платежа, но всегда получаю "10609: идентификатор транзакции недействителен"

здесь код, где ошибка?

Спасибо

paypal_lib.php

<?php
  // code from http://coding.smashingmagazine.com/2011/09/05/getting-started-with-the-paypal-api/
class Paypal {
  /**
   * Last error message(s)
   * @var array
   */
  protected $_errors = array();

  /**
   * API Credentials
   * Use the correct credentials for the environment in use (Live / Sandbox)
   * @var array
   */
  protected $_credentials = array(
                  'USER' => 'xxxxxxxxxxxxxxxxxxxx',
                  'PWD' => 'xxxxxxxxxxxxx',
                  'SIGNATURE' => 'xxxxxxxxxxxxxxxxxxxxxxxxx'
                  );
  /**
   * API endpoint
   * Live - https://api-3t.paypal.com/nvp
   * Sandbox - https://api-3t.sandbox.paypal.com/nvp
   * @var string
   */
  protected $_endPoint = 'https://api-3t.sandbox.paypal.com/nvp';

  /**
   * API Version
   * @var string
   */
  protected $_version = '74.0';

  /**
   * Make API request
   *
   * @param string $method string API method to request
   * @param array $params Additional request parameters
   * @return array / boolean Response array / boolean false on failure
   */
  public function request($method,$params = array()) {
    $this -> _errors = array();
    if( empty($method) ) { //Check if API method is not empty
      $this -> _errors = array('API method is missing');
      return false;
    }

    //Our request parameters
    $requestParams = array_merge(
                 array(
                       'METHOD' => $method,
                       'VERSION' => $this -> _version
                       ),
                 $this -> _credentials
                 );

    //Building our NVP string
    $request = http_build_query(array_merge($requestParams, $params));

    //cURL settings
    $curlOptions = array (
              CURLOPT_URL => $this -> _endPoint,
              CURLOPT_VERBOSE => 1,
              CURLOPT_SSL_VERIFYPEER => true,
              CURLOPT_SSL_VERIFYHOST => 2,
              CURLOPT_RETURNTRANSFER => 1,
              CURLOPT_POST => 1,
              CURLOPT_POSTFIELDS => $request
              );

    $ch = curl_init();
    curl_setopt_array($ch,$curlOptions);

    //Sending our request - $response will hold the API response
    $response = curl_exec($ch);

    //Checking for cURL errors
    if (curl_errno($ch)) {
      $this -> _errors = curl_error($ch);
      curl_close($ch);
      return false;
      //Handle errors
    } else {
      curl_close($ch);
      $responseArray = array();
      parse_str($response,$responseArray); // Break the NVP string to an array
      return $responseArray;
    }
  }
}

?>

paypal_pay_redirect.php

<?php
require("paypal_lib.php");

//Our request parameters
$requestParams = array(
               'RETURNURL' => 'https://www.domain.com/paypal_success.php',
               'CANCELURL' => 'https://www.domain.com/paypal_fail.php'
               );

$orderParams = array(
             'PAYMENTREQUEST_0_AMT' => "57.00",
             'PAYMENTREQUEST_0_SHIPPINGAMT' => '0',
             'PAYMENTREQUEST_0_CURRENCYCODE' => 'EUR',
   'PAYMENTREQUEST_0_ITEMAMT' => "57.00"
             );

$item = array(
          'L_PAYMENTREQUEST_0_NAME0' => 'xxxxxxxxxx',
          'L_PAYMENTREQUEST_0_DESC0' => 'xxxxxxxxxx',
          'L_PAYMENTREQUEST_0_AMT0' => "57.00",
   'L_PAYMENTREQUEST_0_QTY0' => '1'
          );

$paypal = new Paypal();
$response = $paypal -> request('SetExpressCheckout',$requestParams + $orderParams + $item);
if(is_array($response) && $response['ACK'] == 'Success') { //Request successful
  $token = $response['TOKEN'];
  header( 'Location: https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=' . urlencode($token) );
 }


?>

paypal_success.php

<?php
require("paypal_lib.php");

if( isset($_GET['token']) && !empty($_GET['token']) ) { // Token parameter exists
  // Get checkout details, including buyer information.
  // We can save it for future reference or cross-check with the data we have
  $paypal = new Paypal();
  $checkoutDetails = $paypal -> request('GetExpressCheckoutDetails', array('TOKEN' => $_GET['token']));

  // Complete the checkout transaction
  $requestParams = array(
             'TOKEN' => $_GET['token'],
             'PAYMENTACTION' => 'Authorization',
             'PAYERID' => $_GET['PayerID'],
             'PAYMENTREQUEST_0_AMT' => '57', // Same amount as in the original request
             'PAYMENTREQUEST_0_CURRENCYCODE' => 'EUR' // Same currency as the original request
             );

  $response = $paypal -> request('DoExpressCheckoutPayment',$requestParams);
  if( is_array($response) && $response['ACK'] == 'Success') { // Payment successful
    // We'll fetch the transaction ID for internal bookkeeping
    $transactionId = $response['PAYMENTINFO_0_TRANSACTIONID'];
    echo "OK id: ".$transactionId;
    var_dump($response);
  }

 var_dump($checkoutDetails);

 }
?>

paypal_capture.php

<?php
require("paypal_lib.php");

$paypal = new Paypal();

// Complete the checkout transaction
$requestParams = array(
               'AMT' => '57.00',
               'AUTHORIZATIONID' => 'xxxxxxxxxxxxxxxxxxx', //what I get in paypal_success.php
               'CURRENCYCODE' => 'EUR',
               'COMPLETETYPE' => 'Complete', // Same amount as in the original request
               );

$response = $paypal -> request('DoCapture',$requestParams);

var_dump($response);

?>

1 ответ

Решение

Две вещи:

Сначала в paypal_pay_redirect.php добавьте PAYMENTREQUEST_0_PAYMENTACTION => 'Authorization' в $orderParams,

Во-вторых, в paypal_success.php измените PAYMENTACTION К PAYMENTREQUEST_0_PAYMENTACTION,

Вот почему:

В вашем вызове SetExpressCheckout, если вы не установили PAYMENTREQUEST_0_PAYMENTACTIONPayPal предполагает, что это будет Sale, И если это установлено Sale в вашем вызове SetExpressCheckout, тогда PayPal позволит вам только установить его Sale на ваш звонок DoExpressCheckoutPayment.

Кроме того, в вызове DoExpressCheckoutPayment вы смешиваете новые и старые имена переменных. (Некоторые переменные, такие как PAYMENTACTION, были переименованы, когда PayPal ввел параллельные платежи для Express Checkout. PAYMENTACTION это старый стиль; PAYMENTREQUEST_0_PAYMENTACTION это новый стиль.) Когда вы смешиваете имена в старом и новом стилях, как это, PayPal распознает переменные, используя один стиль, и игнорирует другой. В твоем случае, PAYMENTREQUEST_0_AMT а также PAYMENTREQUEST_0_CURRENCYCODE признаются, но PAYMENTACTION игнорируется.

Сочетание этих двух факторов означает, что ваша транзакция, скорее всего, выполняется как транзакция продажи, а не как авторизация. Поскольку вы не можете получить данные о транзакции продажи (поскольку она технически уже захвачена), PayPal отвечает, что идентификатор транзакции недействителен.

Другие вопросы по тегам