0

I'm using Stripe API using Flask. I'm wondering how I can pass an arguments when switching the page as I do using redirect(url_for('')).

For example,

@app.route('/charge', methods=['POST'])
def charge():

    amount= #Amount in cents

    customer = stripe.Customer.create(
        email='[email protected]',
        source=request.form['stripeToken']
        )

    charge = stripe.Charge.create(
         customer=customer.id,
         amount=amount,
         currency='usd',
         description='Test'
         )

When I finished inputting card info, the page is switched to other page and create token. Now I want to get the amount of the money from the previous page as an argument. But I don't know how to do it when using Stripe API.

Usually, I can do it like this answer does redirect while passing arguments

How can I do this?

I tried the first guy's way but it didn't work.

The previous page is like this On this page, users will input their card info using Stripe checkout window and after inputting, it redirect to charge page.

@app.route('/checkout', methods=['GET'])
def checkout():
    item_id = request.args['item_id']
    item = Item.query.filter_by(id=item_id).first()
    return redirect(url_for('charge', item_id=item_id), code=307)
    return render_template('checkout.html', title='Check Out',key=stripe_keys['publishable_key'], item=item)

When I entered this page, this error message appeared on the page:

Bad Request
The browser (or proxy) sent a request that this server could not understand

1 Answer 1

2

The solutions are the followings:

from flask import Flask, request 

@app.route('/previouspage/', methods=['GET'])
def previous_page():
   item = Item.query.filter_by(id=item_id).first()
   redirect(url_for('charge', amount=item.price), code=307)


@app.route('/charge/<amount>', methods=['GET', 'POST'])
def charge(amount):

    customer = stripe.Customer.create(
        email='[email protected]',
        source=request.form['stripeToken']
        )

    charge = stripe.Charge.create(
        customer=customer.id,
        amount=amount,
        currency='usd',
        description='Test'
        )

But the more correct way to avoid passing path variables in URls is to use query strings instead (eg. charge?amount=10.0). Like this:

@app.route('/previouspage/', methods=['GET'])
def previous_page():
    item = Item.query.filter_by(id=item_id).first()
    return redirect(url_for('charge', amount=item.price), code=307)


@app.route('/charge', methods=['GET', 'POST'])
def charge():
    amount = request.args.get('amount')
    customer = stripe.Customer.create(
            email='[email protected]',
            source=request.form['stripeToken']
            )

    charge = stripe.Charge.create(
        customer=customer.id,
        amount=amount,
        currency='usd',
        description='Test'
    )

Keep in mind that both approaches are not that safe because someone can change the price in url. So even better you should pass only the Item ID and fetch the item in /charge. Like this:

@app.route('/previouspage/', methods=['GET'])
def previous_page():
    return redirect(url_for('charge', item_id=item_id), code=307)


@app.route('/charge', methods=['GET', 'POST'])
def charge():
    amount = request.args.get('item_id')
    item = Item.query.filter_by(id=item_id).first()
    if not item:
        return '....some kind of error'

    customer = stripe.Customer.create(
            email='[email protected]',
            source=request.form['stripeToken']
            )

    charge = stripe.Charge.create(
        customer=customer.id,
        amount=item.price,
        currency='usd',
        description='Test'
    )
Sign up to request clarification or add additional context in comments.

7 Comments

Actually what I want to pass isn't part of form so I cannot do this.
what kind of data you want to pass? JSON? even if it's json you can do request.get_json()
It's not form. It's just on of the columns in a datatable and set as a variable. like on the previous page, item = Item.query.filter_by(id=item_id).first() Item is defined like this and one of the column representing the price. I want to get it from the specific item
So usually I can pass a variable using url_for.
First the redirect url_for will return 302 and will move to GET. So what you need is this redirect(url_for('charge', amount=item.price), code=307). updating also the code
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.