python-redsys icon indicating copy to clipboard operation
python-redsys copied to clipboard

Error 431 using Flask (render_template)

Open blackhold opened this issue 6 years ago • 0 comments

I share the problem that I had some days ago, finally I solved! :) I tried to contact with redsys support and told me that they don't offer support of 3rd code... so then here you have the solution of my problem:

The function prepare_request from Client, returns values as binary b'string', if you send it directly to template when using Flask and render_template, the variable of hidden fields converts b'string' to HTML b'string' to avoid that before passing variables to render_template you have to convert them to unicode (or string)

     _redsys = {
     "Ds_MerchantParameters":_redsys2.get("Ds_MerchantParameters").decode('utf-8'),        
     "Ds_SignatureVersion":_redsys2.get("Ds_SignatureVersion"),
     "Ds_Signature":_redsys2.get("Ds_Signature").decode('utf-8')
     }

I will send to render_template the variable called _redsys

Here you have the example code using python3.5 + flask + render_template + boostrap

Add to file views.py

from decimal import Decimal as D, ROUND_HALF_UP
from redsys import currencies, languages, transactions
from redsys.client import RedirectClient

@app2.route('/order')
def order():
    _error = "0"
    form = ""

    _data = {'url' : 'https://sis-t.redsys.es:25443/sis/realizarPago' }

    secret_key = u'XXX'
    sandbox = True
    client = RedirectClient(secret_key, sandbox)
    request = client.create_request()
    request.merchant_code = u'XXX'
    request.terminal = u'1'
    request.transaction_type = transactions.STANDARD_PAYMENT
    request.currency = currencies.EUR
    request.order = u'000000001'
    # The amount must be defined as decimal and pre-formated with only two decimals
    request.amount = D('10.56489').quantize(D('.01'), ROUND_HALF_UP)
    request.merchant_data = 'merchant data for tracking purpose like order_id, session_key, ...'
    request.merchant_name = "your company name"
    request.titular = "customer name"
    request.product_description = "product description"
    request.merchant_url = "https://sis-t.redsys.es:25443/sis/realizarPago"
    _redsys2 = client.prepare_request(request)

    _redsys = {
    "Ds_MerchantParameters":_redsys2.get("Ds_MerchantParameters").decode('utf-8'),
    "Ds_SignatureVersion":_redsys2.get("Ds_SignatureVersion"),
    "Ds_Signature":_redsys2.get("Ds_Signature").decode('utf-8')
    }

    return render_template('pages/order.html', form=form, error=_error, data=_data, redsys=_redsys)

Then in template file pages/order.html:

<form action="{{ data['url'] }}" method="post" role="form">
    <input type="hidden" name="Ds_SignatureVersion" value="{{ redsys['Ds_SignatureVersion'] }}"/>
    <input type="hidden" name="Ds_MerchantParameters" value="{{ redsys['Ds_MerchantParameters'] }}"/>
     <input type="hidden" name="Ds_Signature" value="{{ redsys['Ds_Signature'] }}"/>
     <button type="submit" class="btn btn-default">Submit Button</button>
     <button type="reset" class="btn btn-default">Reset Button</button>
</form>

Take care to install using pip3 install the missing modules

I wish it could be helpful to someone some day :)

Thanks you much!

blackhold avatar Nov 28 '18 14:11 blackhold