0

我对 paypal api 很陌生,我已经按照教程进行了操作,并根据我的需要调整了代码。

我想通过 3 个步骤进行基本的授权和捕获,但我总是无法捕获

  1. 客户登陆 paypal_pay_redirect.php 以登录 paypal 并进行付款
  2. 付款很好,我们登陆 paypal_success.php,在这里我请求授权并保留 TRANSACTIONID 以供下一步
  3. paypal_capture.php 我使用 transactionid 捕获付款,但我总是得到“10609:Transaction id is invalid”

代码在这里,错误在哪里?

谢谢

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);

?>
4

1 回答 1

1

两件事情:

首先,在 paypal_pay_redirect.php 中,PAYMENTREQUEST_0_PAYMENTACTION => 'Authorization'添加$orderParams.

其次,在 paypal_success.php 中,更改PAYMENTACTIONTO PAYMENTREQUEST_0_PAYMENTACTION

原因如下:

在您的 SetExpressCheckout 调用中,如果您不设置PAYMENTREQUEST_0_PAYMENTACTION,PayPal 会假定它是Sale。如果在您的 SetExpressCheckout 调用中将其设置为Sale,那么 PayPal 将只允许您在 DoExpressCheckoutPayment 调用中将其设置为Sale

此外,在您的 DoExpressCheckoutPayment 调用中,您混合了新式和旧式变量名称。PAYMENTACTION(当 PayPal 为 Express Checkout 引入并行支付时, 一些变量被重命名。PAYMENTACTION是旧样式;PAYMENTREQUEST_0_PAYMENTACTION是新样式。)当您像这样混合旧样式和新样式名称时,PayPal 使用一种样式识别变量,并忽略另一个。在您的情况下,PAYMENTREQUEST_0_AMT并且PAYMENTREQUEST_0_CURRENCYCODE正在被识别,但PAYMENTACTION被忽略。

这两个因素的组合意味着您的交易最有可能作为销售交易而不是授权运行。由于您无法针对销售交易进行捕获(因为它在技术上已被捕获),因此 PayPal 会通过说交易 ID 无效来响应。

于 2013-02-08T16:36:09.450 回答