如何将 PayPal 智能支付按钮与 PHP V2 的 REST API SDK 结合起来?

Posted

技术标签:

【中文标题】如何将 PayPal 智能支付按钮与 PHP V2 的 REST API SDK 结合起来?【英文标题】:How to combine PayPal Smart Payment Button with REST API SDK for PHP V2? 【发布时间】:2020-11-29 06:18:00 【问题描述】:

在我包含默认代码 (https://developer.paypal.com/demo/checkout/#/pattern/server) 并将其更改如下后,我的问题就开始了:

<?php

session_start();
require_once '../inc/config.inc.php';

echo '
<!DOCTYPE html>

<head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
</head>

<body>

<div id="paypal-button-container"></div>

<script src="https://www.paypal.com/sdk/js?client-id=' . PAYPAL_CLIENT_ID . '&currency=EUR&disable-funding=credit,card"></script>
';
?>

<script>
    // Render the PayPal button into #paypal-button-container
    paypal.Buttons(
        // Call your server to set up the transaction
        createOrder: function(data, actions) 
            return fetch('01_payPalCheckout.php', 
                mode: "no-cors",
                method: 'post',
                headers: 
                    'content-type': 'application/json'
                
            ).then(function(res) 
                return res.json();
            ).then(function(orderData) 
                return orderData.id;
            );
        ,

        // Call your server to finalize the transaction
        onApprove: function(data, actions) 
            return fetch('01_checkout.php?orderId=' + data.orderID, 
                method: 'post'
            ).then(function(res) 
                return res.json();
            ).then(function(orderData) 
                var errorDetail = Array.isArray(orderData.details) && orderData.details[0];

                if (errorDetail && errorDetail.issue === 'INSTRUMENT_DECLINED') 
                    // Recoverable state, see: "Handle Funding Failures"
                    // https://developer.paypal.com/docs/checkout/integration-features/funding-failure/
                    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 + ')';
                    // Show a failure message
                    return alert(msg);
                

                // Show a success message to the buyer
                alert('Transaction completed by ' + orderData.payer.name.given_name);
            );
        


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

<?php

echo '
</body>
</html>
';

?>

在 createOrder 中,我调用了 01_payPalCheckout.php,它的结构与 PHP SDK 中指定的一样:

<?php

use PayPalCheckoutSdk\Orders\OrdersCreateRequest;

session_start();
require_once '../inc/config.inc.php';

# 1: Environment, Client
$environment = new SandboxEnvironment(PAYPAL_CLIENT_ID, PAYPAL_SECRET);
$client = new PayPalHttpClient($environment);


# 2: Request Order
$request = new OrdersCreateRequest();
$request->prefer('return=representation');
$request->body = [
    "intent" => "CAPTURE",
    "purchase_units" => [[
        "reference_id" => "test_ref_id1",
        "amount" => [
            "value" => "100.00",
            "currency_code" => "USD"
        ]
    ]],
    "application_context" => [
        "cancel_url" => "https://example.com/cancel",
        "return_url" => "https://example.com/return"
    ]
];

try 

    // Call API with your client and get a response for your call
    $response = $client->execute($request);

    // JSON-Encodierung
    $response = json_encode($response);

    // If call returns body in response, you can get the deserialized version from the result attribute of the response
    return $response;

 catch (HttpException $ex) 

    echo $ex->statusCode;
    print_r($ex->getMessage());
    exit();


我在返回 $response 之前添加了 json_encode();生成的 JSON 代码是以下代码:


    "statusCode": 201,
    "result": 
        "id": "4H218056YS3363904",
        "intent": "CAPTURE",
        "status": "CREATED",
        "purchase_units": [
            
                "reference_id": "test_ref_id1",
                "amount": 
                    "currency_code": "USD",
                    "value": "100.00"
                ,
                "payee": 
                    "email_address": "info-facilitator@24960324320.de",
                    "merchant_id": "BYWLB3T6SPG54"
                
            
        ],
        "create_time": "2020-08-10T08:33:40Z",
        "links": [
            
                "href": "https:\/\/api.sandbox.paypal.com\/v2\/checkout\/orders\/4H218056YS3363904",
                "rel": "self",
                "method": "GET"
            ,
            
                "href": "https:\/\/www.sandbox.paypal.com\/checkoutnow?token=4H218056YS3363904",
                "rel": "approve",
                "method": "GET"
            ,
            
                "href": "https:\/\/api.sandbox.paypal.com\/v2\/checkout\/orders\/4H218056YS3363904",
                "rel": "update",
                "method": "PATCH"
            ,
            
                "href": "https:\/\/api.sandbox.paypal.com\/v2\/checkout\/orders\/4H218056YS3363904\/capture",
                "rel": "capture",
                "method": "POST"
            
        ]
    ,
    "headers": 
        "": "",
        "Cache-Control": "max-age=0, no-cache, no-store, must-revalidate",
        "Content-Length": "747",
        "Content-Type": "application\/json",
        "Date": "Mon, 10 Aug 2020 08",
        "Paypal-Debug-Id": "1b04a05438898"
    

在 onApprove 中我调用“'01_payPalCapture.php?orderId=' + data.orderID”(这里我也使用了https://github.com/paypal/Checkout-PHP-SDK提供的标准方法:

<?php

// Session starten
session_start();

use PayPalCheckoutSdk\Core\PayPalHttpClient;
use PayPalCheckoutSdk\Core\SandboxEnvironment;
use PayPalCheckoutSdk\Orders\OrdersCaptureRequest;

// Konfigurations-Datei einbinden
require_once '../inc/config.inc.php';


# 1: Environment, Client
$environment = new SandboxEnvironment(PAYPAL_CLIENT_ID, PAYPAL_SECRET);
$client = new PayPalHttpClient($environment);


# 2 Capture
$request = new OrdersCaptureRequest($_GET['orderId']);
$request->prefer('return=representation');

try 
    $response = $client->execute($request);
    $response = array('id' => $response->result->id);
    $response = json_encode($response);
    return $response;  // value of return: "id":"2KY036458M157715J"
catch (HttpException $ex) 
    echo $ex->statusCode;
    print_r($ex->getMessage());

在 01_cart.php 中,智能按钮会根据需要呈现,但单击“PayPal”只会导致错误消息,例如update_client_config_error 等

我认为从我的角度理解这两个脚本如何协同工作存在问题。

提前感谢您的提示和帮助(我已经连续解决这个问题 4 天了,我一直在努力通过所有 PayPal 帮助,但在互联网上没有找到关于这个特定问题的任何信息)。

【问题讨论】:

试试这个链接:developer.paypal.com/docs/checkout/reference/server-integration/… 【参考方案1】:

/httpdocs/01_payPalCheckout.php 路径不好

它必须是可以在您的网络浏览器中加载的

可以在 HTML href 中使用的东西,例如 &lt;a href="/01payPalCheckout.php"&gt;&lt;/a&gt;

在您的浏览器中测试加载 01payPalCheckout.php,确保它正在执行并返回正确的 JSON,然后修复您的客户端代码以指向将在获取时返回该 JSON 的正确路径

【讨论】:

我将 json_encode 添加到 01_payPalCheckout.php 并获得了正确的 JSON 代码(在我看来这是正确的代码) - 我编辑了我的问题以显示生成的 JSON 代码! 不完全是,它正在返回 result.id 并且您的 javascript 只读取 id ...你的意思是我应该只打印 01_payPalCheckout.php (print($result_id)) 中的 id 吗? 不,我的意思是它需要位于对象中的 id,而不是 result -> id 你能不能更明确一点,并给出一个代码示例?谢谢!

以上是关于如何将 PayPal 智能支付按钮与 PHP V2 的 REST API SDK 结合起来?的主要内容,如果未能解决你的问题,请参考以下文章

Paypal Smart Buttons V2 和 IPN - 如何将智能按钮中的字段与 IPN 匹配

PayPal智能支付按钮与服务器端REST API集成

PayPal 智能支付按钮:如何更改语言

PayPal 智能支付按钮 - 请求数量

使用旧状态的 PayPal 智能支付按钮

paypal智能支付按钮显示问题