You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PHP中集成PayPal标准结账?弹窗出现后消失

PayPal标准结账PHP集成弹窗秒关问题修复

问题描述

我参考PayPal官方文档将Node.js版本的标准结账代码转换为PHP代码,集成到PHP网站后,点击PayPal按钮时,弹窗出现后立即消失。以下是当前使用的代码及修复方案:


index.php(修复后)

<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://www.paypal.com/sdk/js?client-id=你的PayPal客户端ID"></script>
</head>
<body>
  <div id="paypal-button-container"></div>

  <script>
    paypal.Buttons({
      createOrder: function(data, actions) {
        return fetch('create-paypal-order.php', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            amount: '10.00'
          })
        }).then(function(response) {
          if (!response.ok) throw new Error('创建订单请求失败');
          return response.json();
        }).then(function(order) {
          return order.id;
        }).catch(function(err) {
          console.error('创建订单出错:', err);
          alert('创建订单失败,请稍后重试');
        });
      },
      onApprove: function(data, actions) {
        return fetch('capture-paypal-order.php', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            orderID: data.orderID
          })
        }).then(function(response) {
          if (!response.ok) throw new Error('捕获订单请求失败');
          return response.json();
        }).then(function(details) {
          alert('交易完成,感谢 ' + details.payer.name.given_name);
          // TODO: 执行支付后的后续操作
        }).catch(function(err) {
          console.error('捕获订单出错:', err);
          alert('交易处理失败,请稍后重试');
        });
      },
      onError: function(err) {
        console.error('PayPal按钮错误:', err);
        alert('支付出现错误,请稍后重试');
      }
    }).render('#paypal-button-container');
  </script>
</body>
</html>

create-paypal-order.php(修复后)

<?php
$clientId = '你的PayPal客户端ID';
$clientSecret = '你的PayPal客户端密钥';

// 接收前端发送的JSON数据
$input = json_decode(file_get_contents('php://input'), true);
$amount = isset($input['amount']) ? $input['amount'] : '10.00';
$currency = 'USD';

// 获取PayPal访问令牌
$authString = base64_encode($clientId . ':' . $clientSecret);
$apiUrl = 'https://api.paypal.com/v1/oauth2/token';
$apiHeaders = [
    'Accept: application/json',
    'Accept-Language: en_US',
    'Authorization: Basic ' . $authString
];
$apiData = 'grant_type=client_credentials';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiUrl);
curl_setopt($ch, CURLOPT_HTTPHEADER, $apiHeaders);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $apiData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// 确保cacert.pem路径正确,使用绝对路径避免错误
curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . '/lib/cacert.pem');

$response = curl_exec($ch);
if ($response === false) {
    http_response_code(500);
    echo json_encode(['error' => curl_error($ch)]);
    curl_close($ch);
    exit;
}
curl_close($ch);

$authResult = json_decode($response, true);
if (!isset($authResult['access_token'])) {
    http_response_code(401);
    echo json_encode(['error' => '获取访问令牌失败']);
    exit;
}
$accessToken = $authResult['access_token'];

// 创建PayPal订单
$apiUrl = 'https://api.paypal.com/v2/checkout/orders';
$apiHeaders = [
    'Content-Type: application/json',
    'Authorization: Bearer ' . $accessToken
];
$apiData = json_encode([
    'intent' => 'CAPTURE',
    'purchase_units' => [
        [
            'amount' => [
                'currency_code' => $currency,
                'value' => $amount
            ]
        ]
    ]
]);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiUrl);
curl_setopt($ch, CURLOPT_HTTPHEADER, $apiHeaders);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $apiData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . '/lib/cacert.pem');

$response = curl_exec($ch);
if ($response === false) {
    http_response_code(500);
    echo json_encode(['error' => curl_error($ch)]);
    curl_close($ch);
    exit;
}
curl_close($ch);

$order = json_decode($response, true);
if (!isset($order['id'])) {
    http_response_code(400);
    echo json_encode(['error' => '创建订单失败', 'details' => $order]);
    exit;
}

// 返回JSON格式的订单ID,匹配前端解析要求
echo json_encode(['id' => $order['id']]);
?>

capture-paypal-order.php(修复后)

<?php
$clientId = '你的PayPal客户端ID';
$clientSecret = '你的PayPal客户端密钥';

// 接收前端发送的订单ID
$input = json_decode(file_get_contents('php://input'), true);
$orderID = isset($input['orderID']) ? $input['orderID'] : '';
if (empty($orderID)) {
    http_response_code(400);
    echo json_encode(['error' => '缺少订单ID']);
    exit;
}

// 获取PayPal访问令牌
$authString = base64_encode($clientId . ':' . $clientSecret);
$apiUrl = 'https://api.paypal.com/v1/oauth2/token';
$apiHeaders = [
    'Accept: application/json',
    'Accept-Language: en_US',
    'Authorization: Basic ' . $authString
];
$apiData = 'grant_type=client_credentials';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiUrl);
curl_setopt($ch, CURLOPT_HTTPHEADER, $apiHeaders);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $apiData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . '/lib/cacert.pem');

$response = curl_exec($ch);
if ($response === false) {
    http_response_code(500);
    echo json_encode(['error' => curl_error($ch)]);
    curl_close($ch);
    exit;
}
curl_close($ch);

$authResult = json_decode($response, true);
if (!isset($authResult['access_token'])) {
    http_response_code(401);
    echo json_encode(['error' => '获取访问令牌失败']);
    exit;
}
$accessToken = $authResult['access_token'];

// 捕获PayPal订单
$apiUrl = "https://api.paypal.com/v2/checkout/orders/$orderID/capture";
$apiHeaders = [
    'Content-Type: application/json',
    'Authorization: Bearer ' . $accessToken
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiUrl);
curl_setopt($ch, CURLOPT_HTTPHEADER, $apiHeaders);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . '/lib/cacert.pem');

$response = curl_exec($ch);
if ($response === false) {
    http_response_code(500);
    echo json_encode(['error' => curl_error($ch)]);
    curl_close($ch);
    exit;
}
curl_close($ch);

$orderData = json_decode($response, true);
echo json_encode($orderData);
?>

核心修复说明

  1. 前端请求路径修正:fetch URL添加.php后缀,确保服务器能正确解析请求
  2. 响应格式统一:后端所有接口返回JSON格式数据,避免前端解析纯文本报错导致弹窗关闭
  3. 变量名错误修复:统一capture-paypal-order.php中的变量名,解决授权失败问题
  4. 数据接收方式调整:改用file_get_contents('php://input')接收前端JSON数据,替代无法解析JSON的$_POST
  5. 错误处理增强:前后端添加明确的错误捕获和提示,避免静默失败
  6. SSL安全优化:移除CURLOPT_SSL_VERIFYPEER = false的不安全设置,使用绝对路径确保证书文件可访问

内容的提问来源于stack exchange,提问作者Meraqp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 19:12:02