You need to enable JavaScript to run this app. Python中Razorpay webhook支付回调签名验证失败如何解决
优惠活动
大模型
产品
解决方案
定价
更多

Python中Razorpay webhook支付回调签名验证失败如何解决

Razorpay webhook签名验证失败问题解决方案

核心问题原因

Razorpay的webhook签名是基于发送的原始未修改请求载荷生成,你之前的错误全部来自载荷处理环节:

  1. 使用json.dumps处理request.json/request.data时,会重新排序JSON键、修改空格/分隔符格式,生成的内容和Razorpay发送的原始载荷不一致,直接导致签名校验失败
  2. request.data本身是bytes类型,直接传入json.dumps会触发类型不兼容的序列化错误
  3. 你最后用request.data.decode('utf-8')传入验证得到None属于正常结果:Razorpay官方SDK的verify_webhook_signature方法验证通过时无返回值,只有验证失败才会抛出SignatureVerificationError异常,你误以为None是错误,实际此时已经校验通过。

正确实现代码

import razorpay
# 以下以Flask框架为例,其他框架仅需调整原始请求体的获取方式即可
from flask import request

# 需和Razorpay webhook配置页填写的密钥完全一致,注意无多余空格、大小写匹配
WEBHOOK_SECRET = "abc"
# 你的Razorpay商户认证信息
RAZORPAY_KEY = "xyz"
RAZORPAY_SECRET = "pqr"

client = razorpay.Client(auth=(RAZORPAY_KEY, RAZORPAY_SECRET))

def handle_razorpay_webhook():
    # 获取请求头中的签名
    webhook_signature = request.headers.get('X-Razorpay-Signature')
    if not webhook_signature:
        return {"status": "error", "msg": "缺少签名头"}, 400
    
    try:
        # 直接传入解码后的原始请求体,不要做任何JSON序列化/格式化操作
        client.utility.verify_webhook_signature(
            request.data.decode('utf-8'),
            webhook_signature,
            WEBHOOK_SECRET
        )
        # 校验通过,此处编写你的业务逻辑,例如修改订单状态、触发发货流程等
        print("签名验证通过,支付状态有效")
        return {"status": "success"}, 200
    except razorpay.errors.SignatureVerificationError:
        # 校验失败,直接拦截非法请求
        print("签名验证失败,请求非法")
        return {"status": "error", "msg": "签名验证失败"}, 403

其他注意事项

  • 若使用Django框架,原始请求体用request.body.decode('utf-8')获取即可,逻辑完全一致
  • 绝对不要对原始请求体做任何修改、格式化、重新序列化操作,必须直接使用Razorpay发送的原始字符串内容
  • 若校验仍然失败,优先核对webhook密钥是否和后台配置完全一致,不要复制到多余的空格、换行符

内容的提问来源于stack exchange,提问作者Jasmine

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 23:45:07