Sending POST data and Redirecting to external website from a view

1,199 views
Skip to first unread message

M Godshall

unread,
May 29, 2009, 12:52:34 PM5/29/09
to Django users
Based on everything that I've read on the subject the last few days,
it sounds like it's impossible to redirect a user to an external url
with POST data. If that's the case, I really need some help figuring
out a secure solution to the following scenario:

My client wants to use the secure payment form provided by their
payment provider's website. Here's how the process should work:

1. User submits form with basic information (no personal data) on
client site
2. Client site validates the data from the form
3. Add sensitive account credentials to data (id and pin so the
payment provider can identify my client's account)
4. Send user to payment provider's secure https website with basic
information and client account credentials
5. User fills out payment information on payment provider's website

The documentation only shows examples of sending this data (client id
and pin) as hidden fields in a form, posting directly to the
provider's url, but they don't recommend that approach for production
environments for obvious security reasons. Unfortunately, their
documentation and tech support don't offer any secure alternatives, so
hopefully the Django community will be able to offer better insight.

I explored urllib/urllib2, but I couldn't figure out a way to direct
the user to the payment providers secure web page along with the data
mentioned above. I'm certainly not an expert with these tools, so if
you're aware of a solution please point me in the right direction.

As a point of reference, the following code will give you an idea of
what I'm trying to accomplish:

def select_payment(request):
if request.method == 'POST':
form = PaymentForm(request.POST)
if form.is_valid():
values = {...} #cleaned form data, add client id and pin
data = urllib.urlencode(values)
url = 'https://www.xxx.com' #payment providers website

#Idea 1
full_url = url + '?' + data
return HttpResponseRedirect(full_url) #Successfully redirects
with data, but exposes client data in url. Not good.

#Idea 2
response = urllib2.urlopen(url, data)
the_page = response.read()
return HttpResponse(the_page) #This actually shows the form from
the payment provider's website with the data I sent, but it shows it
in my client's url. Instead, I need to send the user to the payment
provider's website with this data so they can fill out the form on a
secure page. This seems like it should be possible since I can post
data to the url and get a response this way.

else:
form = PaymentForm()
return render_to_response('payments.html', {'form': form},
context_instance=RequestContext(request))

If I can't find a way to make this work, I'll have to setup an SSL
certificate for my client and have them host the form, but I'd really
like to avoid this if possible. A big thanks to everyone from the
Django irc who has helped me with this already. Hopefully I'll find
some closure soon.

Tom Evans

unread,
May 29, 2009, 3:11:20 PM5/29/09
to django...@googlegroups.com

I'm not sure I understand completely, so correct me if I'm wrong, but it
seems like you want to avoid the obvious way of doing this, by writing
out a form on an SSL protected page, and having the user submit it, or
auto submitting it, and you want to avoid this to avoid having to get an
SSL certificate?

If you think about it, this is impossible. You have the extra secret
information, and it is the user who must present this extra information
to the payment processor. Without having your own SSL certificate, there
would be no way to securely get that information to the user. Finally,
users are not impressed by commerce sites who don't do the checkout
process over SSL, so its worth doing just to 'get the padlock'.

Is there service provided by the payment processor for you to pass the
data to the payment processor over a back channel, exchange for a token,
and then redirect the user to their site with said token? Otherwise, you
have to certificate up. Sorry.

Cheers

Tom

M Godshall

unread,
May 29, 2009, 3:57:47 PM5/29/09
to Django users
This particular client is non-profit and they have a minimal budget
for this, so they requested that I use the payment provider's form
since it already has an SSL certificate. I realize getting a SSL
certificate and hosting the checkout process on the client's website
makes the most sense, but I'm trying to make this work the way they
asked me to do it before going in that direction. The only
information a user provides on the client's website is what event they
are giving money toward, so the actual checkout is done on the payment
provider's website. I'll look into the token suggestion you gave, but
my hopes are pretty low at this point. Thanks for taking the time to
reply.

Lacrima

unread,
May 30, 2009, 11:31:09 AM5/30/09
to Django users
Hello!

This is impossible to redirect a user to external site with post.
urllib and urllib2 can only help to fetch data, but not to redirect a
user.
So if you do not use ssl, you have to use hidden fields where you
should specify id and pin.

You can make payments much secure using hash algorithms. But your
payment provider must provide corresponding API.

I had near your problem in one project... And below is what have been
done.
First, a user fills in a form with general order information. Then,
this form is validated in my view. After that user is redirected to
order confirmation page on my site. Among submitted general order
information this page includes "Checkout" button and two hidden fields
(action url of the form is set to payment provider site). One hidden
field is all order info encoded with base64 function, and other field
is signature, which is a hash of secret key + order info. When the
user clicks "Checkout" he is sent to payment provider site. Then the
server decodes order info and checks signature. If that is ok, the
user fills payment info ... and so on...
This will protect from tampering data.

With regards,
Max.
(sorry if my English isn't very proper)
Reply all
Reply to author
Forward
0 new messages