如何在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); ?>
核心修复说明
- 前端请求路径修正:fetch URL添加
.php后缀,确保服务器能正确解析请求 - 响应格式统一:后端所有接口返回JSON格式数据,避免前端解析纯文本报错导致弹窗关闭
- 变量名错误修复:统一
capture-paypal-order.php中的变量名,解决授权失败问题 - 数据接收方式调整:改用
file_get_contents('php://input')接收前端JSON数据,替代无法解析JSON的$_POST - 错误处理增强:前后端添加明确的错误捕获和提示,避免静默失败
- SSL安全优化:移除
CURLOPT_SSL_VERIFYPEER = false的不安全设置,使用绝对路径确保证书文件可访问
内容的提问来源于stack exchange,提问作者Meraqp
相关产品推荐
相关产品推荐

