Paypal 没有收到付款

Posted

技术标签:

【中文标题】Paypal 没有收到付款【英文标题】:Paypal not proceeding to receive the payment 【发布时间】:2017-02-03 20:41:37 【问题描述】:

我正在尝试使用this URL 通过贝宝捐款。当我登录 PayPal 并付款时,我收到以下消息

我确实有后端代码,如下所示。

<?php
use PayPal\Rest\ApiContext;
use PayPal\Auth\OAuthTokenCredential;
use PayPal\Api\Payer;
use PayPal\Api\Details;
use PayPal\Api\Amount;
use PayPal\Api\Transaction;
use PayPal\Api\Payment;
use PayPal\Api\RedirectUrls;
use PayPal\Api\PaymentExecution;

require __DIR__ . DIRECTORY_SEPARATOR . '../vendor/autoload.php';

/**
* Edri PayPal Pyment
*/
class Edri_PayPal_Payment

    
    private $api;

    private $payer;

    private $details;

    private $amount;

    private $transaction;

    private $payment;

    private $redirectUrls;


    function __construct()
    
        $this->api = $this->setup_PayPal_Api();
    

    private function debug($val)
    
        echo '<pre>';
        var_dump($val);
        echo '</pre>';
    

    private function setup_PayPal_Api()
    
        $api = new ApiContext(
            new OAuthTokenCredential(
                'MyPayPalClientID',
                'MyClientSecret'
            )
        );

        $api->setConfig(array(
            'mode' => 'live',
            'http.ConnectionTimeOut' => 30,
            'Log.LogEnabled' => false,
            'Log.FileName' => '',
            'Log.LogLevel' => 'FINE',
            'validation.level' => 'log'
        ));

        return $api;
    

    private function setupPayer()
    
        $this->payer = new Payer();

        $this->payer->setPayment_method('paypal');
    

    private function setupDetails($amount)
    
        $this->details = new Details();
        $this->details->setShipping('0.00')
            ->setTax('0.00')
            ->setsubTotal($amount);
    

    private function setupAmount($amount)
    

        $this->amount = new Amount();

        $this->amount->setCurrency('EUR')
            ->setTotal($amount)
            ->setDetails($this->details);
    
    
    private function setupTransaction($amount)
    

        $this->transaction = new Transaction();

        $this->transaction->setAmount($this->amount)
            ->setDescription('Make a donation of €' . $amount .  ' to EDRi');
    
    
    private function setupPayment()
    
        $this->payment = new Payment();

        $this->payment->setIntent('sale')
            ->setPayer($this->payer)
            ->setTransactions(array($this->transaction))
            ->setRedirectUrls($this->redirectUrls);
    

    private function setupRedirectUrls()
    
        $this->redirectUrls = new RedirectUrls();

        $this->redirectUrls->setReturnUrl('https://edri.org/payment?pppa=true')
            ->setCancelUrl('https://edri.org/payment?pppa=false');
    

    public function prepare_payment ($paymentCredtials) 
        $amount = str_replace(',', '', number_format($paymentCredtials['edriPayment_amount'], 2));

        $this->setupPayer();
        $this->setupDetails($amount);
        $this->setupAmount($amount);
        $this->setupTransaction($amount);
        $this->setupRedirectUrls();
        $this->setupPayment();  

        try 

            $this->payment->create($this->api);

            $paymentID = $this->payment->getId();
        
         catch (Exception $e) 
            $this->log($e);
            
            header('Location: https://edri.org/donation-oops');

            return false;
        

        return $paymentID;

    

    private function log($log)

        $file = __DIR__ . DIRECTORY_SEPARATOR . '../logs/paypal_log.txt';


        // Open the file to get existing content
        $current = file_get_contents($file);
        // Append a new person to the file
        $current .=  $prefix . ' ' . date('m/d/Y h:i:s a', time()) . ' //// ' . "\n";
        $current .=  self::var_dump_str($log) . "\n";
        // Write the contents back to the file
        file_put_contents($file, $current);
    

    public function execute_payment($paymentCredentials)
    
        $this->debug($paymentCredentials);

        $payment = Payment::get($paymentCredentials['paymentId'], $this->api);

        $execution = new PaymentExecution();

        $execution->setPayerId($paymentCredentials['PayerID']);


        try 

            echo $payment->execute($execution, $this->api);
        
         catch (Exception $e) 
            $this->log($e);
            
            header('Location: https://edri.org/donation-oops');

            return false;
        

        return $payment->state = 'approved' ? true : false;
        
    

    public function kickoff_payment()
    

        foreach ($this->payment->getLinks() as $link) 
            if ($link->getRel() == 'approval_url') 
                $redirectUrl = $link->getHref();
            
        

        header('Location: ' . $redirectUrl);
    


我检查了日志,没有任何报告。 API 调用似乎也很好。

任何使这项工作的建议都会有所帮助。

【问题讨论】:

能否请您先通过this way 验证您的贝宝帐户。如果您的代码没问题,那么这一步可能会解决您的问题。 【参考方案1】:

您的var_dump() 语句有可能违反了“标头前无内容输出”规则,因此,在header('Location: ' . $redirectUrl); 可以之前,用户的付款流程会在您的代码中停止重定向到 PayPal 以完成工作。

尝试删除那些var_dumps,并改为使用error_log(printf($val, true)),以免中断对header()的调用。

编辑 - 来自http://php.net/manual/en/function.header.php:

请记住,header() 必须在发送任何实际输出之前调用,无论是通过普通 html 标记、文件中的空白行还是通过 PHP。使用 include 或 require 函数或其他文件访问函数读取代码并在调用 header() 之前输出空格或空行是一个非常常见的错误。使用单个 PHP/HTML 文件时也存在同样的问题。

<html>
<?php
/* This will give an error. Note the output
 * above, which is before the header() call */
header('Location: http://www.example.com/');
exit;
?>

【讨论】:

嗨@cameron-hurd 你的意思是我应该 var_dump($val) 上面的代码并用 error_log(printf($val, true)) 替换它 没错 - error_log 不输出任何内容,并将 true 作为第二个参数传递给 printf 返回,而不是输出值。如果输出之前的内容是问题,这将让您在检查变量值的同时回避这个问题。 我做了替换,现在它只打印单词“Array”而不是之前的消息(如图):( 我看到你在这个类的某个地方有一个var_dump_str 函数......这是被调用的吗?它可以输出Array 文本吗?游戏的名称是寻找输出的来源,以测试header()无法重定向用户的论点。 我在前端页面中调用 $current .= self::var_dump_str($log) 。 "\n";其定义如下 static function var_dump_str() $argc = func_num_args(); $argv = func_get_args(); if ($argc > 0) ob_start(); call_user_func_array('var_dump', $argv); $result = ob_get_contents(); ob_end_clean();返回$结果; 返回 '';

以上是关于Paypal 没有收到付款的主要内容,如果未能解决你的问题,请参考以下文章

在 PayPal 的 REST API 中执行付款后,有时我没有收到电子邮件

如何使用 django-paypal 获取付款通知

PayPal 的协议 API 未发送付款通知

Paypal 定期付款或一次性付款

无法接收 PayPal IPN - PayPal 总是收到 403 错误

Paypal 按钮问题