如何解决Xero API删除支付信息时的403 Forbidden错误?
解决Xero API删除Payment时的403 Forbidden错误
核心排查方向
1. 确认OAuth2权限范围
确保你的应用已申请到必要的写入权限:
- 必须包含
accounting.transactions(写入交易权限)和accounting.transactions.read(读取交易权限) - 检查Xero开发者后台的应用权限设置,确认权限级别是Write而非Read Only
- 重新授权租户,确保权限更新后已生效(部分场景下权限变更需要重新授权)
2. 检查Payment删除的前置条件
Xero对删除Payment有严格限制,以下情况无法直接删除:
- Payment已与银行对账记录匹配
- 关联的Invoice已被过账(Posted)
- Payment已被用于其他关联交易(如退款、信用凭证)
如果Payment无法删除,需创建反向退款交易抵消,而非直接删除。
3. 调整操作顺序
你的代码先将Invoice设为VOIDED再删除Payment,可能触发权限限制。正确流程应为:
- 先删除关联的Payment(确保Invoice当前状态为AUTHORISED或DRAFT)
- 再将Invoice更新为VOIDED状态
4. API Explorer无响应的排查
- 确认API Explorer中选择的租户与代码中使用的租户一致
- 检查请求的PaymentID是否属于当前租户,且状态符合删除条件
- 通过浏览器开发者工具查看API Explorer的网络请求详情,获取具体错误信息
代码优化建议
try { if($contract->THIRD_PARTY_SYNC ==1){ $apiInvoicesWithHttpInfoResponse = $apiInstance->getInvoicesWithHttpInfo($xeroTenantId, null, 'InvoiceNumber=="' . $contract->CONTRACT_NO . '"'); $xero_invoice_Response = $apiInvoicesWithHttpInfoResponse[0]->getInvoices()[0]; $apiInstance = self::minuteFlowLimitingProcessing($apiInvoicesWithHttpInfoResponse,$xeroId,$apiInstance); } // 优先处理Payment删除(仅当需要设置为VOIDED时) if($status =='VOIDED' && isset($xero_invoice_Response) && method_exists($xero_invoice_Response, 'getPayments')){ $payments = $xero_invoice_Response->getPayments(); if (!empty($payments)) { $paymentId = $payments[0]->getPaymentID(); $PaymentDelete = new \XeroAPI\XeroPHP\Models\Accounting\PaymentDelete; $deletePayment = $apiInstance->deletePayment($xeroTenantId, $paymentId, $PaymentDelete); } } // 再更新Invoice状态 if ($status == \XeroAPI\XeroPHP\Models\Accounting\Invoice::STATUS_PAID && !empty($filteredPayment)) { $status = \XeroAPI\XeroPHP\Models\Accounting\Invoice::STATUS_AUTHORISED; } elseif ($status == \XeroAPI\XeroPHP\Models\Accounting\Invoice::STATUS_PAID && $xero_invoice_Response ==null) { $status = \XeroAPI\XeroPHP\Models\Accounting\Invoice::STATUS_AUTHORISED; } $xero_invoice->setStatus($status); // 执行Invoice更新操作(原代码可能遗漏此步骤) $apiInstance->updateInvoice($xeroTenantId, $xero_invoice); } catch (\XeroAPI\XeroPHP\ApiException $e) { // 打印详细错误信息定位问题 echo "错误信息: " . $e->getMessage() . "\n"; echo "响应内容: " . $e->getResponseBody() . "\n"; }
额外检查点
- 登录Xero后台,进入设置 > 会计设置 > 高级选项,确认是否开启「允许删除交易」
- 若Payment无法删除,可创建
CreditNote或Overpayment抵消原Payment后,再将Invoice设为VOIDED
内容的提问来源于stack exchange,提问作者jeffery.yang
相关产品推荐
相关产品推荐

