【问题标题】:PayPal Smart Button server side implementation - Problems with capturing transaction - PHPPayPal Smart Button 服务器端实现 - 捕获交易的问题 - PHP
【发布时间】:2021-01-28 16:31:44
【问题描述】:

我一直在尝试完成 PayPal 智能按钮的服务器端实现,但在捕获交易时遇到了困难。我正在使用沙盒帐户。我不确定问题是否出在订单 ID 上。

我在尝试捕获交易时得到的响应:

Fatal error: Uncaught PayPalHttp\HttpException: 
{"name":"RESOURCE_NOT_FOUND",
 "details[{"field":"order_id",
     "value":"$orderId",
     "location":"path",
     "issue":"INVALID_RESOURCE_ID",
     "description":"Specified resource ID does not exist. Please check the resource ID and try again."}],
 "message":"The specified resource does not exist.",
 "debug_id":"df5cdbddfc1ea",
 "links":[{"href":"https://developer.paypal.com/docs/api/orders/v2/#error-INVALID_RESOURCE_ID",
 "rel":"information_link","method":"GET"}]} in /usr/local/ampps/www/shop-files/vendor/paypal/paypalhttp/lib/PayPalHttp/HttpClient.php:215
 Stack trace: #0 /usr/local/ampps/www/shop-files/vendor/paypal/paypalhttp/lib/PayPalHttp/HttpClient.php(100): PayPalHttp\HttpClient->parseResponse(Object(PayPalHttp\Curl)) 
#1 /usr/local/ampps/www/shop-files/capture-transaction.php(29): PayPalHttp\HttpClient->execute(Object(PayPalCheckoutSdk\Orders\OrdersCaptureRequest))
 #2 /usr/local/ampps/www/shop-files/capture-transaction.php(62): Sample\CaptureIntentExamples\CaptureOrder::captureOrder('$orderId', in /usr/local/ampps/www/shop-files/vendor/paypal/paypalhttp/lib/PayPalHttp/HttpClient.php on line 215

我在创建事务时得到的响应:

{
    "id": "1XB529992P492602W",
    "intent": "CAPTURE",
    "status": "CREATED",
    "purchase_units": [
        {
            "reference_id": "default",
            "amount": {
                "currency_code": "GBP",
                "value": "12.00"
            },
            "payee": {
                "email_address": "sb-lxq8v1263761@business.example.com",
                "merchant_id": "SUHPR7WSYJPJQ"
            }
        }
    ],
    "create_time": "2020-10-14T08:36:00Z",
    "links": [
        {
            "href": "https://api.sandbox.paypal.com/v2/checkout/orders/1XB529992P492602W",
            "rel": "self",
            "method": "GET"
        },
        {
            "href": "https://www.sandbox.paypal.com/checkoutnow?token=1XB529992P492602W",
            "rel": "approve",
            "method": "GET"
        },
        {
            "href": "https://api.sandbox.paypal.com/v2/checkout/orders/1XB529992P492602W",
            "rel": "update",
            "method": "PATCH"
        },
        {
            "href": "https://api.sandbox.paypal.com/v2/checkout/orders/1XB529992P492602W/capture",
            "rel": "capture",
            "method": "POST"
        }
    ]
}

我用于创建交易的 php 代码:

<?php
namespace Sample\CaptureIntentExamples;
session_start();
require __DIR__ . '/vendor/autoload.php';

use Sample\PayPalClient;
use PayPalCheckoutSdk\Orders\OrdersCreateRequest;
require 'paypal-client.php';

class CreateOrder {
  public static function createOrder() {
    $request = new OrdersCreateRequest();
    $request->prefer('return=representation');
    $request->body = self::buildRequestBody();
 
    $client = PayPalClient::client();
    $response = $client->execute($request);
 
    echo json_encode($response->result, JSON_PRETTY_PRINT);

    return $response;
  }
    private static function buildRequestBody() {
      return array(
        'intent'=>'CAPTURE',
        'application_context'=>
          array(
            'return_url'=>'https://localhost/basket.php',
            'cancel_url'=>'https://localhost/basket.php'
          ),
        'purchase_units'=>
          array(
            0=>
              array(
                'amount'=>
                  array(
                    'currency_code'=>'GBP',
                    'value'=>$_SESSION['total']
                  )             
              )
          )
      );
    }
}

if (!count(debug_backtrace()))
{
  CreateOrder::createOrder(true);
}
?>

捕获交易的代码:

<?php

namespace Sample\CaptureIntentExamples;

require __DIR__ . '/vendor/autoload.php';
use Sample\PayPalClient;
use PayPalCheckoutSdk\Orders\OrdersCaptureRequest;
require 'paypal-client.php';

class CaptureOrder
{ 
  public static function captureOrder($orderId)
  {
    $request = new OrdersCaptureRequest($orderId);

    $client = PayPalClient::client();
    $response = $client->execute($request);
  
      echo json_encode($response->result, JSON_PRETTY_PRINT);

    return $response;
  }
}
if (!count(debug_backtrace()))
{
  CaptureOrder::captureOrder('$orderId', true);
}
?>

JavaScript:

createOrder: function(data) {
      return fetch('/shop-files/create-order.php', {
        method: 'post',
      }).then(function(res) {
        return res.json();
      }).then(function(orderData) {
        return orderData.id;
      });
    },
    onShippingChange: function(data, actions) {
      if (data.shipping_address.country_code !== "GB") {
        return actions.reject();
      }
      return actions.resolve();
    },
    onApprove: function(data) {
      return fetch('/shop-files/capture-transaction.php', {
        method: 'post',
        headers: {
          'content-type': 'application/json'
        },
      }).then(function(res) {
          return res.json();
      }).then(function(orderData) {
          if (errorDetail && errorDetail.issue === 'INSTRUMENT_DECLINED') {
              return actions.restart();
          }
          if (errorDetail) {
              var msg = 'Sorry, your transaction could not be processed.';
              if (errorDetail.description) msg += '\n\n' + errorDetail.description;
              if (orderData.debug_id) msg += ' (' + orderData.debug_id + ')';
              return alert(msg);
          }
          alert('Transaction completed by ' + orderData.payer.name.given_name);
      });
    }
  }).render('#paypal-button-container');

【问题讨论】:

  • 是否可以提供指向示例“capture-transaction.php”的链接,或者在没有敏感信息的情况下分享您的链接?我一直在关注 PayPal 地狱中的链接,以获取 PHP 脚本的当前工作示例,以捕获从 PayPal Checkout 按钮交易返回的内容。

标签: php paypal


【解决方案1】:

这是你的问题行:

CaptureOrder::captureOrder('$orderId', true);

您实际上是在将单引号内的文本字符串:'$orderId'发送到 PayPal。 $ 和这 7 个字母将发送到 PayPal。您没有发送您的 $orderId 变量的内容

去掉你的字符串引号:

CaptureOrder::captureOrder($orderId, true);

顺便说一下,关于 PHP(顺便说一下,像 bash 之类的 shell 语言)的一些细节你可能不知道:

注意:与双引号和heredoc语法不同,特殊字符的变量和转义序列在出现在单引号字符串中时不会被扩展。

参考:https://www.php.net/manual/en/language.types.string.php#language.types.string.parsing

基本上,双引号和单引号在这方面表现不同。

【讨论】:

  • 谢谢。我删除了单引号,结果发现$orderIdCaptureOrder::captureOrder($orderId, true); 中未定义captureOrder($orderId) 内部我尝试了$orderId = $response-&gt;result-&gt;id,但它仍然说该变量未定义。
  • 似乎您的 onApprove 代码也没有做任何事情来将订单的 ID 值发送到您的服务器。它必须作为获取 URL 的一部分或作为数据有效负载,然后您的服务器需要从发送它的任何位置读取它以在使用它之前设置 $orderId
【解决方案2】:

这是我添加到用于捕获交易以获取订单 ID 的代码中的内容,位于 require 'paypal-client.php'; 下方:

// Get JSON row data from the request
$json = file_get_contents('php://input');
// Convert JSON string into array
$data = json_decode($json, true);
// Get the value of the key 'orderID'
$orderId = $data['orderID'];

我不确定 cmets 是否准确解释了正在发生的事情,因此欢迎任何更正。

此外,JavaScript 代码与此有点不同:

body: JSON.stringify({
  orderID: data.orderID
})

添加到下方

headers: {
  'content-type': 'application/json'
},

它现在正在工作。非常感谢 Preston PHX 再次为我指明了正确的方向。

【讨论】:

    猜你喜欢
    • 2021-01-14
    • 2020-06-16
    • 2012-01-23
    • 2012-03-13
    • 2021-04-22
    • 2012-07-28
    • 2014-04-29
    • 2014-11-04
    • 2019-08-10
    相关资源
    最近更新 更多