使用python-redsys实现POST跳转至Redsys支付系统遇阻求助
解决Redsys支付跳转问题
问题根源
你遇到的SIS0431错误,是因为args中的Ds_MerchantParameters和Ds_Signature是bytes类型,直接传递给表单会导致Redsys无法正确解析JSON参数;而GET方式被拒绝是因为Redsys明确要求使用POST请求提交支付参数。
解决方案步骤
1. 修正视图中的参数类型
生成args后,将bytes类型的参数解码为UTF-8字符串,避免JSON解析错误:
@login_required def redsys_start(request): secret_key = DS_SECRET_KEY client = RedirectClient(secret_key) parameters = { "merchant_code": DS_MERCHANT_MERCHANTCODE, "terminal": DS_MERCHANT_TERMINAL, "transaction_type": STANDARD_PAYMENT, "currency": EUR, # 注意:生产环境必须生成唯一订单号,不能用固定值 "order": "000000001", "amount": D("10.56489").quantize(D(".01"), ROUND_HALF_UP), "merchant_data": "test merchant data", "merchant_name": "Example Commerce", "titular": "Example Ltd.", "product_description": "Products of Example Commerce", "merchant_url": reverse('front:shop_cart_payment_callback'), } args = client.prepare_request(parameters) # 将bytes参数解码为字符串 args['Ds_MerchantParameters'] = args['Ds_MerchantParameters'].decode('utf-8') args['Ds_Signature'] = args['Ds_Signature'].decode('utf-8') context = {'args': args, 'BANK_PAIEMENT_URL': BANK_PAIEMENT_URL} # 返回包含自动提交表单的模板 return render(request, 'redsys_payment_form.html', context)
2. 创建自动提交的支付表单模板
新建redsys_payment_form.html模板,通过POST方式自动将参数提交到Redsys支付端点:
<!DOCTYPE html> <html> <head> <title>跳转至支付页面...</title> <script type="text/javascript"> // 页面加载后自动提交表单 window.onload = function() { document.getElementById('redsys-form').submit(); }; </script> </head> <body> <p>正在跳转至支付页面,请稍候...</p> <form id="redsys-form" method="POST" action="{{ BANK_PAIEMENT_URL }}"> {% csrf_token %} <input type="hidden" name="Ds_SignatureVersion" value="{{ args.Ds_SignatureVersion }}"> <input type="hidden" name="Ds_MerchantParameters" value="{{ args.Ds_MerchantParameters }}"> <input type="hidden" name="Ds_Signature" value="{{ args.Ds_Signature }}"> <!-- 备用手动提交按钮 --> <button type="submit">如果未自动跳转,请点击此处</button> </form> </body> </html>
3. 关键注意事项
- 订单号
order必须唯一,生产环境建议用自增ID或UUID生成,避免重复提交报错。 - 确保
BANK_PAIEMENT_URL使用对应环境的Redsys地址(测试/生产环境地址不同)。 - 回调视图
shop_cart_payment_callback需处理Redsys的POST请求,用client.create_response()验证签名,逻辑参考官方文档。
内容的提问来源于stack exchange,提问作者Ahima
相关产品推荐
相关产品推荐

