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

Xero Webhook验证失败:点击Intent to Receive无法返回200 OK

解决Xero Webhook Intent to Receive验证失败问题

以下是针对性的修复步骤,帮你通过验证并正常接收Webhook:

  • 确认Webhook密钥完全匹配
    确保代码中XERO_WEBHOOK_KEY的值和Xero后台配置的Webhook密钥完全一致,包括大小写、特殊字符和空格,复制时避免多粘或少粘内容。建议用环境变量存储密钥,不要硬编码在代码里。

  • 修正请求头的获取方式(针对Rails等框架)
    部分Web框架会将HTTP请求头转换为特定格式,比如Rails会把x-xero-signature转为HTTP_X_XERO_SIGNATURE。如果直接用小写头名获取,可能拿到nil导致验证失败,要改成对应框架的正确获取方式:

    signature = request.headers['HTTP_X_XERO_SIGNATURE'] # Rails环境下的正确写法
    
  • 修复请求体读取后的重置问题
    request.body.read会一次性清空请求体内容,后续若需解析JSON会出错,同时要保证计算HMAC时的payload和Xero发送的完全一致,读取后要重置指针:

    payload = request.body.read
    request.body.rewind # 重置请求体指针,方便后续处理
    
  • 调整HBase64编码方式
    Base64.encode64会自动添加换行符,而Xero的签名是无换行的Base64字符串,改用Base64.strict_encode64生成标准格式的编码,无需额外strip():

    calculated_hmac = Base64.strict_encode64(OpenSSL::HMAC.digest('sha256', key, payload))
    
  • 优化验证逻辑的异常处理
    把异常处理范围调整到合适位置,避免无关逻辑被错误捕获,同时增加签名存在性检查:

    def ensuring_security?
      key = ENV['XERO_WEBHOOK_KEY']
      payload = request.body.read
      request.body.rewind
    
      calculated_hmac = Base64.strict_encode64(OpenSSL::HMAC.digest('sha256', key, payload))
      signature = request.headers['HTTP_X_XERO_SIGNATURE']
    
      return false unless signature
      calculated_hmac == signature
    rescue OpenSSL::OpenSSLError, StandardError => e
      false
    end
    
  • 单独测试Intent请求场景
    Xero的Intent to Receive请求发送的是空JSON payload({}),你可以本地模拟:用空字符串作为payload,用自己的密钥计算HMAC,对比Xero发送的签名是否一致,验证计算逻辑的正确性。

验证通过后,确保端点在验证成功时返回200 OK,失败时返回403 Forbidden,即可完成Intent验证,后续就能正常接收Contacts和Invoices的Webhook更新。

内容的提问来源于stack exchange,提问作者Muhammad Junaid Iqbal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 00:45:35