I am following Ryan Bates' railcast 146 and it is really helpful. However, Im trying to remove the cart object from the process, and just process an order individually. The problem I am having is how to establish the amount which is used twice: once to setup the purchase, and then once to actually execute it. This is what I have resorted to doing, but it exposes the amount in the return_url, which I think is probably bad practice:
class OrdersController < ApplicationController
def express
response = EXPRESS_GATEWAY.setup_purchase(params[:amount],
:ip => request.remote_ip,
:return_url => new_order_url(:amount=>params[:amount]),
:cancel_return_url => root_url
)
redirect_to EXPRESS_GATEWAY.redirect_url_for(response.token)
end
def new
@order = Order.new(:express_token => params[:token], :price_in_cents=>params[:amount])
end
Then in the 开发者_运维技巧view, I add a hidden field with the amount so that when the order is created it has the amount built in (I added a price_in_cents field to the order model). It works fine, but exposing the amount as a param may be a little iffy. Finally, the purchase code looks like this:
def purchase
response = process_purchase
transactions.create!(:action => "purchase", :amount => price_in_cents, :response => response)
cart.update_attribute(:purchased_at, Time.now) if response.success?
response.success?
end
In short, how can I do this without passing around the amount in the params?
Thanks!
Sending the amount in the url is very bad practice - It allows one to change the price and purchase what ever you are selling for the amount he specifies in the URL.
I can see two ways around this issue:
1. You can encrypt the parameters you pass, and decrypt them from the URL. See how to encrypt here
2. You can create a new entity that holds the price of the purchase (or in case you are selling a specific item (since you are not using a cart) - you can pass the id of this item and query for it's price when you need it). Something like this:
class OrdersController < ApplicationController
def express
@product = Product.find(params(:product_id));
response = EXPRESS_GATEWAY.setup_purchase(product.price_in_cents,
:ip => request.remote_ip,
:return_url => new_order_url(product.price_in_cents),
:cancel_return_url => root_url
)
redirect_to EXPRESS_GATEWAY.redirect_url_for(response.token)
end
def new
@product = Product.find(params(:product_id));
@order = Order.new(:express_token => params[:token], :price_in_cents=> @product.price_in_cents)
end
Thanks for your input guys. I ended up storing the amount in the user's session, something like session[:amount]
, and then setting it to nil
as soon as they finish the process. That way its hidden from the user and saves me the trouble of creating new objects or encrypting.
精彩评论