连接中断时Braintree订阅因处理器拒绝创建失败的追踪方法
解决Braintree订阅创建失败(超时/处理器拒绝)的状态追踪问题
一、处理网络超时场景
网络超时触发catch块时,Braintree服务器可能已接收并处理了订阅请求,只是客户端未收到响应。此时不能仅记录异常,需补充后续校验逻辑:
- 在catch块中,将未确认状态的订阅ID存入本地数据库(比如新建
pending_subscriptions表) - 用定时任务(如Cron)周期性调用Braintree的
subscription()->find($sid)接口,查询这些订阅的实际状态,直到获取明确结果
修改catch块示例:
catch(Exception $ex) { $result["error"] = BT_EXCEPTION_OCCURRED_WHILE_SUBSCRIBING_PLAN; $result["ex"] = $ex; // 记录当前及后续未处理的订阅ID到待查询队列 $pendingSids = array_slice($arrIds, $i); // 假设存在将ID存入数据库的函数 $this->savePendingSubscriptions($pendingSids); }
二、处理Processor Declines Error场景
这类错误会返回$response->success = false,但Braintree不会主动触发默认Webhook,需主动处理:
- 解析
$response->errors获取具体拒绝原因,同时将订阅失败状态写入本地数据库,不依赖Webhook - 若要通过Webhook接收事件,需在Braintree控制台开启
subscription_charged_unsuccessfully或subscription_went_past_due事件——处理器拒绝首次扣款时,订阅通常会进入逾期状态,触发对应Webhook
修改失败分支逻辑,补充错误详情:
else { // Subscription creation failed $tmp = array(); $tmp["sid"] = $arrIds[$i]; $tmp["error"] = BT_FAILED_TO_SUBSCRIBE_PLAN; // 记录处理器返回的具体错误信息 $tmp["processor_errors"] = $response->errors->deepAll(); $tmp["response"] = $response; $result["result"][] = $tmp; // 写入本地订阅状态表,标记为失败 $this->updateSubscriptionStatus($arrIds[$i], 'failed', $tmp["processor_errors"]); }
三、优化Webhook事件处理
确保Webhook接收器覆盖以下关键事件,更新本地订阅状态:
subscription_charged_successfully:扣款成功subscription_charged_unsuccessfully:扣款失败(含处理器拒绝)subscription_went_past_due:订阅逾期subscription_canceled:订阅取消subscription_created:订阅创建成功(即使首次扣款失败,订阅可能已生成)
四、保障订阅ID幂等性
你已手动指定id参数,需额外确保:
- 同一订阅ID不重复调用创建接口
- 本地数据库中订阅ID唯一,避免状态混淆
内容的提问来源于stack exchange,提问作者Flanker
相关产品推荐
相关产品推荐

