无法让 Paypal 在上下文中 checkout.js v4 与 REST API 一起使用

Posted

技术标签:

【中文标题】无法让 Paypal 在上下文中 checkout.js v4 与 REST API 一起使用【英文标题】:Trouble getting Paypal in-context checkout.js v4 work with REST API 【发布时间】:2017-08-17 21:09:53 【问题描述】:

我是 Paypal 和 php 的新手,所以也许我做错了(或没做), 我正在尝试让 Paypal 上下文结帐 v4 使用服务器端工作,以便能够在付款完成后进行操作。我遵循了 Paypal 指南(https://github.com/paypal/paypal-checkout/blob/master/docs/button.md 和 https://github.com/paypal/paypal-checkout/blob/master/docs/paypal-rest-api.md)并进行了大量研究,但目前没有一个有用。

我在调用创建付款后遇到问题,Paypal 窗口不显示 Paypal 登录信息,而是向我显示消息 "返回商家 目前,我们无法处理您的请求。请返回并尝试其他选项。”

这是我服务器端的代码:

class ExpressCheckout 

    private $request = null;

    function createPayment()

        $token = $this->getConnectionToken();

        $this->request = curl_init();
        $paypalmode = (PPL_MODE=='sandbox') ? '.sandbox' : '';

        $data = $this->getDataFromSession();
        $url = 'https://api'.$paypalmode.'.paypal.com/v1/payments/payment';
        $this->setDefaultRequest();
        curl_setopt($this->request, CURLOPT_HTTPHEADER, array("Authorization: Bearer $token",
                                                             'Content-Type: application/json')); 

        curl_setopt($this->request, CURLOPT_POSTFIELDS, $data);
        curl_setopt($this->request, CURLOPT_URL, $url);
        $response = $this->sendHttp($url);
        return '"paymentID":"'.$response->id.'"';
    

    function executePayment()

        $token = $this->getConnectionToken();

        $entryData = json_decode(file_get_contents('php://input'), true);
        $paymentId = $entryData["paymentID"];
        $payerId = $entryData["payerID"];

        $this->request = curl_init();
        $paypalmode = (PPL_MODE=='sandbox') ? '.sandbox' : '';

        $data = '"payer_id":"'.$payerID.'"';
        $url = 'https://api'.$paypalmode.'.paypal.com/v1/payments/payment/'.$paymentId.'/execute';
        $this->setDefaultRequest();
        curl_setopt($this->request, CURLOPT_HTTPHEADER, array("Authorization: Bearer $token",
                                                   'Content-Type: application/json')); 

        curl_setopt($this->request, CURLOPT_POSTFIELDS, $data);
        curl_setopt($this->request, CURLOPT_URL, $url);
        $response = $this->sendHttp($url);
        return $response;
    

    function getConnectionToken()
        $this->request = curl_init();
        $userName = PPL_REST_API_CLIENT_ID;
        $password = PPL_REST_API_SECRET;
        $paypalmode = (PPL_MODE=='sandbox') ? '.sandbox' : '';
        $url = 'https://api'.$paypalmode.'.paypal.com/v1/oauth2/token';
        $data = 'grant_type=client_credentials';

        $this->setDefaultRequest();
        curl_setopt($this->request, CURLOPT_USERPWD, "$userName:$password");
        curl_setopt($this->request, CURLOPT_POSTFIELDS, $data);

        $response = $this->sendHttp($url);
        return $response->access_token;
    

    private function setDefaultRequest()
        curl_setopt($this->request, CURLOPT_VERBOSE, 1);
        curl_setopt($this->request, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($this->request, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($this->request, CURLOPT_TIMEOUT, 45);
        curl_setopt($this->request, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($this->request, CURLOPT_POST, 1);
    

    private function sendHttp($url)
        curl_setopt($this->request, CURLOPT_URL, $url);
        $responseJson = json_decode(curl_exec($this->request));
        curl_close ($this->request); 
        return $responseJson;
    

我的客户的代码是:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <script src="https://code.jquery.com/jquery-3.2.0.min.js"></script>
</head>
<body>
    <div id="paypal-button2"></div>
    <script src="https://www.paypalobjects.com/api/checkout.js" data-version-4></script>


    <script>
        paypal.Button.render(
            locale: 'en_US',
            style: 
                size: 'small',
                color: 'gold',
                shape: 'pill',
                label: ''
            ,

            payment: function(resolve, reject) 
                jQuery.post('http://dummy_url_site.com/create_payment.php')
                .done(function(data)
                    alert(data);
                    var myJson = JSON.parse(data);
                    alert(myJson.paymentID); 
                    resolve(myJson.paymentID);
                )
                .fail(function(err)reject(err); );
            ,

            onAuthorize: function(data, actions) 
                console.log('The payment was authorized!');
                console.log('Payment ID = ',   data.paymentID);
                console.log('PayerID = ', data.payerID);
                // At this point, the payment has been authorized, and you will need to call your back-end to complete the
                // payment. Your back-end should invoke the PayPal Payment Execute api to finalize the transaction.
                /*
                jQuery.post('http://dummy_url_site.com/execute_payment.php',  paymentID: data.paymentID, payerID: data.payerID )
                    .done(function(data)  alert(data.toString()); )
                    .fail(function(err)     );
            ,
            onCancel: function(data, actions) 
                return actions.redirect();
            ,
onError: function(data, actions) 
// Show an error page here. You may try restarting payment execution.
alert('Something went wrong with payment approval' Data: ' + data.toSource());
return actions.restart();
            
        , '#paypal-button2');
    </script>
</body>

</html>

【问题讨论】:

【参考方案1】:

如果您正在调用沙盒来设置付款,您可能需要在paypal.Button.render() 中传递env: 'sandbox'

【讨论】:

以上是关于无法让 Paypal 在上下文中 checkout.js v4 与 REST API 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

Paypal 的 Express Checkout 上下文集成

让 PayPal Express Checkout 验证地址

PayPal Express Checkout Classic API 入门

PayPal Checkout:无法在印度境内进行美元付款

为啥我的 PayPal Checkout 按钮无法打开指向 PayPal Sandbox 的链接?

如何为paypal上下文快速结账创建反应组件?