PayPal订阅交易API返回新订阅数据延迟问题求助
PayPal订阅onApprove后调用交易接口返回空,存在10分钟延迟的问题
我正在使用PayPal REST API获取用户订阅后的交易信息。根据PayPal的JS文档,onApprove事件触发时订阅已完成,此时跳转至感谢页并携带Subscription ID,调用订阅交易接口应该能返回数据,但实际初始调用时返回空JSON。
该接口最多需要10分钟才会返回非空交易数据。我的实现逻辑是:在onApprove事件中携带Subscription ID跳转至页面,页面加载时通过PHP cURL调用上述API获取买家邮箱等交易详情,再查询数据库判断该邮箱是否存在,以此决定跳转逻辑。
此逻辑本身可行,但PayPal交易数据返回有大约10分钟的延迟。我不想添加等待延迟,因为PayPal声称onApprove触发时交易已完成,数据应可通过REST API获取。请问:
- 这是PayPal的已知问题吗?
- 如何避免该延迟?
- 延迟时长是否会因用户而异?
我的代码
JS按钮授权流程
<div id="paypal-button-container-P-1UU44524AX8090809MMVRJ3Y"></div> <script src="https://www.paypal.com/sdk/js?client-id=AS-0AbQhD8wSxv0XMvjeRTAUsa-aZtSZm3fSq-qDp_ibhlq9S5XrkgCVDjchICdKS2IZP7IKVo-MTdz7&vault=true&intent=subscription" data-sdk-integration-source="button-factory" data-namespace = "paypal_sdk"></script> <script> paypal_sdk.Buttons({ style: { shape: 'rect', color: 'white', layout: 'vertical', label: 'subscribe' }, createSubscription: function(data, actions) { return actions.subscription.create({ /* Creates the subscription */ plan_id: 'P-1UU44524AX8090809MMVRJ3Y' }); }, onApprove: function(data, actions) { window.location.replace("https://www.my-site.com/create-account/?subscription_id=" + data.subscriptionID); } }).render('#paypal-button-container-P-1UU44524AX8090809MMVRJ3Y'); // Renders the PayPal button </script>
页面加载时的服务端处理
<?php if ( isset( $_GET['subscription_id'] ) && ! empty( $_GET['subscription_id'] ) && is_page( 'create-account' ) ) { /** * Get Access Token */ $ch_auth = curl_init(); curl_setopt($ch_auth, CURLOPT_URL, 'https://api-m.sandbox.paypal.com/v1/oauth2/token'); curl_setopt($ch_auth, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch_auth, CURLOPT_POST, 1); curl_setopt($ch_auth, CURLOPT_POSTFIELDS, "grant_type=client_credentials"); curl_setopt($ch_auth, CURLOPT_USERPWD, 'USR' . ':' . 'PWD'); $headers_auth = array(); $headers_auth[] = 'Content-Type: application/x-www-form-urlencoded'; curl_setopt($ch_auth, CURLOPT_HTTPHEADER, $headers_auth); $result_auth = curl_exec($ch_auth); if (curl_errno($ch_auth)) { echo 'Error:' . curl_error($ch_auth); } curl_close($ch_auth); $auth_arr = json_decode($result_auth); $auth = $auth_arr->access_token; /** * Get Subscription details */ $ch_sub = curl_init(); curl_setopt($ch_sub, CURLOPT_URL, 'https://api-m.sandbox.paypal.com/v1/billing/subscriptions/'.$_GET['subscription_id'].'/transactions?start_time=2022-01-21T07:50:20.940Z&end_time=2022-09-24T07:50:20.940Z'); curl_setopt($ch_sub, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch_sub, CURLOPT_CUSTOMREQUEST, 'GET'); $headers_sub = array(); $headers_sub[] = 'Content-Type: application/json'; $headers_sub[] = 'Authorization: Bearer ' . $auth; curl_setopt($ch_sub, CURLOPT_HTTPHEADER, $headers_sub); $result_sub = curl_exec($ch_sub); if (curl_errno($ch_sub)) { echo 'Error:' . curl_error($ch_sub); } curl_close($ch_sub); $first = end(json_decode($result_sub)->transactions)->payer_name->given_name; $last = end(json_decode($result_sub)->transactions)->payer_name->surname; $mail = end(json_decode($result_sub)->transactions)->payer_email; $exists = email_exists( $mail ); if ( $exists ) { header('Location: '.'https://www.my-site.com/account/?subscription_id=' . $_GET['subscription_id'] . '&account=' . $exists); die(); } }
该逻辑在页面多次刷新(1至100次不等)后才能正常工作。
解决方案
问题核心
onApprove事件仅确认用户完成了订阅授权,订阅状态标记为激活,但交易记录的写入和同步到REST API是异步流程,存在延迟,这是PayPal订阅API的常见现象,沙箱环境延迟更明显。
具体解答
是否为已知问题?
是,这是PayPal后台异步处理导致的同步延迟问题,开发者社区普遍反馈存在该情况,沙箱环境延迟通常比生产环境更长。如何避免延迟?
- 优先调用订阅详情接口:无需依赖交易接口获取买家信息,订阅详情接口(
/v1/billing/subscriptions/{subscription_id})在onApprove触发后即可立即返回买家邮箱、姓名等核心数据,完全避开交易记录的同步延迟。修改PHP代码调用此接口即可。 - 配置Webhooks实时通知:设置PayPal订阅相关Webhook事件(如
BILLING.SUBSCRIPTION.CREATED、PAYMENT.SALE.COMPLETED),当订阅或交易完成时,PayPal主动推送通知到你的服务端,此时再处理后续逻辑,这是最可靠的异步方案。 - 优化轮询逻辑(备选):若必须使用交易接口,可在服务端实现有限次短间隔轮询(如每30秒查询一次,最多10次),替代用户手动刷新,但效率低于前两种方案。
- 延迟时长是否因用户而异?
延迟主要由PayPal后台处理速度和环境(沙箱/生产)决定,与用户无关。沙箱环境延迟可能达10分钟,生产环境通常控制在数分钟内,但极端情况仍可能存在延迟。
代码修改示例
将PHP中获取交易详情的代码替换为调用订阅详情接口:
/** * Get Subscription details (替换原交易接口调用) */ $ch_sub = curl_init(); curl_setopt($ch_sub, CURLOPT_URL, 'https://api-m.sandbox.paypal.com/v1/billing/subscriptions/'.$_GET['subscription_id']); curl_setopt($ch_sub, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch_sub, CURLOPT_CUSTOMREQUEST, 'GET'); $headers_sub = array(); $headers_sub[] = 'Content-Type: application/json'; $headers_sub[] = 'Authorization: Bearer ' . $auth; curl_setopt($ch_sub, CURLOPT_HTTPHEADER, $headers_sub); $result_sub = curl_exec($ch_sub); if (curl_errno($ch_sub)) { echo 'Error:' . curl_error($ch_sub); } curl_close($ch_sub); $sub_data = json_decode($result_sub); $first = $sub_data->payer->name->given_name; $last = $sub_data->payer->name->surname; $mail = $sub_data->payer->email_address;
内容的提问来源于stack exchange,提问作者user3934058
相关产品推荐
相关产品推荐

