PayPal 智能按钮返回 JSON 错误

Posted

技术标签:

【中文标题】PayPal 智能按钮返回 JSON 错误【英文标题】:PayPal Smart Buttons returns me JSON error 【发布时间】:2020-08-08 03:08:06 【问题描述】:

我正在 php 中实现 Express Checkout 集成(使用 PayPal 智能按钮),但在尝试付款时出现错误。

调用createOrder函数时触发错误。我相信错误在于服务器端,因为fetch 正在成功执行并且服务器生成了一个 ORDER ID,但是它没有正确地将 ORDER ID 传递给客户端,我最终得到以下错误:

错误:JSON 中位置 0 的意外标记 S

由于我使用的是 PayPal 提供的 SDK,我不知道会出现什么问题

我的客户

 <script>
        // Render the PayPal button into #paypal-button-container
        paypal.Buttons(

            // Set up the transaction
            createOrder: function(data, actions) 
                return fetch('*http://localhost/test/createorder.php', 
                    method: 'post'
                ).then(function(res) 
                    return res.json();
                ).then(function(data) 
                    return data.orderID;
                );
            ,

            // Finalize the transaction
            onApprove: function(data, actions) 
                return fetch('https://api.sandbox.paypal.com/v2/checkout/orders/' + data.orderID + '/capture/', 
                    method: 'post'
                ).then(function(res) 
                    return res.json();
                ).then(function(details) 
                    // Show a success message to the buyer
                    alert('Transaction completed by ' + details.payer.name.given_name + '!');
                );
            ,
            onError: function(err)
                    alert(err)
            


        ).render('#paypal-button-container');
    </script>

我的服务器

<?php

namespace Sample\CaptureIntentExamples;

require __DIR__ . '/vendor/autoload.php';
//1. Import the PayPal SDK client that was created in `Set up Server-Side SDK`.
use Sample\PayPalClient;
use PayPalCheckoutSdk\Orders\OrdersCreateRequest;

class CreateOrder


// 2. Set up your server to receive a call from the client
  /**
   *This is the sample function to create an order. It uses the
   *JSON body returned by buildRequestBody() to create an order.
   */
  public static function createOrder($debug=false)
  
    $request = new OrdersCreateRequest();
    $request->prefer('return=representation');
    $request->body = self::buildRequestBody();
   // 3. Call PayPal to set up a transaction
    $client = PayPalClient::client();
    $response = $client->execute($request);
    if ($debug)
    
      print "Status Code: $response->statusCode\n";
      print "Status: $response->result->status\n";
      print "Order ID: $response->result->id\n";
      print "Intent: $response->result->intent\n";
      print "Links:\n";
      foreach($response->result->links as $link)
      
        print "\t$link->rel: $link->href\tCall Type: $link->method\n";
      

      // To print the whole response body, uncomment the following line
      // echo json_encode($response->result, JSON_PRETTY_PRINT);
    

    // 4. Return a successful response to the client.
    return $response;
  

  /**
     * Setting up the JSON request body for creating the order with minimum request body. The intent in the
     * request body should be "AUTHORIZE" for authorize intent flow.
     *
     */
    private static function buildRequestBody()
    
        return array(
            'intent' => 'CAPTURE',
            'application_context' =>
                array(
                    'return_url' => 'https://example.com/return',
                    'cancel_url' => 'https://example.com/cancel'
                ),
            'purchase_units' =>
                array(
                    0 =>
                        array(
                            'amount' =>
                                array(
                                    'currency_code' => 'USD',
                                    'value' => '220.00'
                                )
                        )
                )
        );
    



/**
 *This is the driver function that invokes the createOrder function to create
 *a sample order.
 */
if (!count(debug_backtrace()))

  CreateOrder::createOrder(true);

?>

我从 PayPal 文档中获得了代码。

更新

当我用这样的东西替换return $response 时:

 $orderID=['orderID'=>$response->result->id];
 echo json_encode($orderID, true);

并删除这部分代码:

  if ($debug)
        
          print "Status Code: $response->statusCode\n";
          print "Status: $response->result->status\n";
          print "Order ID: $response->result->id\n";
          print "Intent: $response->result->intent\n";
          print "Links:\n";
          foreach($response->result->links as $link)
          
            print "\t$link->rel: $link->href\tCall Type: $link->method\n";
          

          // To print the whole response body, uncomment the following line
          // echo json_encode($response->result, JSON_PRETTY_PRINT);
        

它部分有效。 PayPal 灯箱使用生成的令牌打开,但之后立即关闭。当我尝试使用 URL 直接访问它时,它显示“出了点问题”。

【问题讨论】:

将调试添加到服务器端创建顺序,以便您查看发生了什么。 这取决于您的客户端期望收到什么。如果你的客户端解析 json 并读取 result.id 就可以了。 要理解的关键是您正在设计客户端和服务器之间的中间件接口。 PayPal 没有设计这个界面。所以规范由你决定,绝对没有理由需要与你的服务器与 PayPal 通信的 PayPal API 规范相同。重要的是您至少以某种方式正确传输 OrderID。 使用console.logconsole.warn 会比使用警报更好,但由于它是未定义的,您可能需要更深入地查看您获取它的地方出了什么问题。 你可以登录的事实很有趣,如果它真的在使用那个 id。我会从 PayPal 自己的控制台日志中查找调试信息。 【参考方案1】:

我终于找到了一个解决方案,在后端和前端进行了一些修改。

我得到了这个工作

注释这部分代码

  if ($debug=true)
    
      print "Status Code: $response->statusCode\n";
      print "Status: $response->result->status\n";
      print "Order ID: $response->result->id\n";
      print "Intent: $response->result->intent\n";
      print "Links:\n";
      foreach($response->result->links as $link)
      
        print "\t$link->rel: $link->href\tCall Type: $link->method\n";
      

      // To print the whole response body, uncomment the following line
      // echo json_encode($response->result, JSON_PRETTY_PRINT);
    

return $response替换为

$json_obj= array('id'=>$response->result->id);
$jsonstring = json_encode($json_obj);
echo $jsonstring;

并在前端调整货币

错误的货币选项引发异常,导致 PayPal 灯箱关闭(以及信用卡选项)。

【讨论】:

寻找这个答案很久了!我无法相信像 Paypal 这样大的公司在其主要目的上会有如此错误和不完整的文档……在网络上接受付款! Ronald,不幸的是,正如我所注意到的,在这种集成方面,不仅 PayPal 的文档如此糟糕。他们提供了很多文档,但他们没有做基础知识:举例说明如何实现他们的 API。我在他们的页面上留下了反馈。

以上是关于PayPal 智能按钮返回 JSON 错误的主要内容,如果未能解决你的问题,请参考以下文章

PHP 中的 Paypal 智能按钮服务器集成:错误:需要传递一个订单 ID

PayPal Checkout 与智能支付按钮的集成

PayPal 智能按钮不会确认项目列表。想法?

如何在 PayPal 智能按钮交易中发送自定义数据字段

paypal智能支付按钮显示问题

Paypal 智能按钮无法正确呈现