I have used gem "active_paypal_adaptive_payment" also set the payment options
def checkout
recipients = [recipientarray]
response = gateway.setup_purchase(
:return_url => url_for(:action => 'action', :only_path => false),
:cancel_url => url_for(:action => 'action', :only_path => false),
:ipn_notification_url => url_for(:action => 'notify_action', :only_path => false),
:receiver_list => recipients
)
# For redirecting the customer to the actual paypal site to finish the payment.
redirect_to (gateway.redirect_url_for(response["payKey"]))
end
It is redirecting to the paypal payment page..
This is the page
In payment summary it does not displaying any item name , price, etc..
can any one suggest how to configure it . Please help
Thanks
You may want to try using the "ActiveMerchant" gem instead - it's updated by Shofify and we've got it to do exactly what you're looking for.
Problem
The way to get PayPal to list the items is to use the ExpressCheckout version (I think you're just setting up a peer-to-peer payment), and then pass the items in a hash array. We use a cart, but you may have something else.
The trick with paypal epxress is that you have to get all the totals to add up properly. As you will see in the code I post, we are just using a static shipping value for now (we're still developing this current project), but you can omit shipping if you don't need it.
Solution
I can only vouch for ActiveMerchant, because that's the only code I've got, but here is what we do:
Routes
#config/routes.rb
get 'checkout/paypal' => 'orders#paypal_express', :as => 'checkout'
get 'checkout/paypal/go' => 'orders#create_payment', :as => 'go_paypal'
Orders Controller
#controllers/orders_controller.rb
class OrdersController < ApplicationController
#Paypal Express
def paypal_express
response = EXPRESS_GATEWAY.setup_purchase(total,
:items => cart_session.build_order, #this is where you create the hash of items
:subtotal => subtotal,
:shipping => 50,
:handling => 0,
:tax => 0,
:return_url => url_for(:action => 'create_payment'),
:cancel_return_url => url_for(:controller => 'cart', :action => 'index')
)
redirect_to EXPRESS_GATEWAY.redirect_url_for(response.token)
end
#some other stuff is here....
end
Build Items
#models/cart_session.rb (we use this with a cart)
#Build Hash For ActiveMerchant
def build_order
#Take cart objects & add them to items hash
products = cart_contents
#order = []
products.each do |product|
#order << {name: product[0].name, quantity: product[1]["qty"], amount: (product[0].price * 100).to_i }
end
return #order
end
end
Related
I'm trying to send an email to the client when he successfully makes a transaction using paypal.
I've already manage to send the custom email parameter to paypal in a custom parameter they provide.
What I have right now
My product model:
class Product < ActiveRecord::Base
# This defines the paypal url for a given product sale
def paypal_url(return_url, cancel_return, useremail)
values = {
:business => 'your_business_email#example.com',
:cmd => '_xclick',
:upload => 1,
:return => return_url,
:rm => 2,
:cancel_return => cancel_return,
:custom => useremail
}
values.merge!({
"amount" => unit_price,
"item_name" => name,
"item_number" => id,
"quantity" => '1'
})
# For test transactions use this URL
"https://www.sandbox.paypal.com/cgi-bin/webscr?" + values.to_query
end
has_many :payment_notifications
end
here, I'm passing a parameter for the :custom object which I have it hardcoded in the button link_to helper here:
<%= link_to 'checkout', #product.paypal_url(payment_notification_index_url, root_url, 'testing#testing.com') %>
This works perfectly, and I am able to store the custom email in the database:
class PaymentNotificationController < ApplicationController
protect_from_forgery except: [:create]
def create
# #payment = PaymentNotification.create!(params: params, product_id: params[:invoice], status: params[:payment_status], transaction_id: params[:txn_id] )
#payment = PaymentNotification.create!(params: params, product_id: 1, status: params[:payment_status], transaction_id: params[:txn_id], email: params[:custom] )
# render nothing: true
if #payment.status == 'Completed'
PaymentTransactions.success(#payment).deliver_now
redirect_to root_url, notice: 'Success!'
else
redirect_to root_url, notice: 'Error'
end
end
end
Question
How do I get the client to input their email in a field and pass that value into the parameters of the link_to so that paypal return the email so I can store it in the database and send an email to the client?
Thanks
You should not use link_to, but form_tag with method: :get
<%= form_tag (#product.paypal_url(payment_notification_index_url, root_url, :custom)),method: :post do %>
<%= text_field_tag :custom %>
<%= submit_tag 'checkout' %>
<% end %>
This might be more than what you're expecting...but read on.
Before you dive further into the implementation, keep in mind that, you're using the sandbox version of Paypal for testing, and in production, you'd want the paypal_url to return an encrypted url for the user as to avoid tampering of the transaction, such as changing the price (more details at Railscast #143).
Now, realize that any approaches on the client-side via javascript to get the user email field and modify the link will not be secure as the link should be generated from your server after encryption (and you'd need to pass in the user email as part of the call).
So, what can you do? Use ajax to send the request to the server containing the parameters (e.g. return_url, user_email, etc..), and respond in the server with an encrypted link. Then, you can use javascript to replace the link and allow user to click that instead.
As you realize, the implementation above is very general and any answer would not suit your specific case. You should keep the above in mind as you'd be required to do that anyway down the road.
This issue is about: ActiveMerchant + PaypalExpressCheckout + Rails 3.2
I've been trying to build a Paypal Express Checkout on my Rails 3.2 app. Most of the tutorials out there are outdated so I followed a few then read the Paypal Express Checkout integration guide. I've already set up my Sandobx and my paypal informations.
When I try to process the payment by clicking on my "Buy now" link from my view:
<%= link_to image_tag('http://img36.imageshack.us/img36/249/buttonpaypal.png'),
action: 'checkout', controller: 'orders'%>
I am getting the following error:
This transaction is invalid. Please return to the recipient's website to complete
you transaction using their regular checkout flow.
Return to merchant
At this time, we are unable to process your request. Please return to and try
another option.
--- My Controller:
class OrdersController < ApplicationController
include ActiveMerchant::Billing
def checkout
setup_response = ::GATEWAY.setup_purchase(2000,
:ip => request.remote_ip,
:return_url => url_for('confirm'),
:cancel_return_url => url_for(root_path)
)
redirect_to ::GATEWAY.redirect_url_for(setup_response.token)
end
end
--- My Initializer ActiveMerchant.rb:
ActiveMerchant::Billing::Base.mode = :test
::GATEWAY = ActiveMerchant::Billing::PaypalExpressGateway.new(
:login => "I_PUT_MY_EMAIL_HERE",
:password => "I_PUT_MY_PASS_HERE",
:signature => "I_PUT_MY_SIGNATURE_HERE",
:allow_guest_checkout => true
)
--- My routes: routes.rb:
resources :orders do
# Im not sure why 'get :checkout' by itself doesn't work.
get :checkout, :on => :new
get :confirm
get :complete
end
get "pages/index"
This is the gist: https://gist.github.com/11be6cef6a97632343b9
Can anyone point me to a 'recent' tutorial or help me figure out what I am doing wrong here?
The easiest way is to do as follow:
1.) You must create a paypal test account.
2.) Create a Cart Model:
$ rails g model Cart purchased_at:datetime
3.) In your Cart Model Type:
class Cart < ActiveRecord::Base
def paypal_url(return_url)
values = {
# get it form your http://sandbox.paypal.com account
:business => 'ENTER_THE_SELLER_PAYPAL_EMAIL_ADDRESS',
:cmd => '_cart',
:upload => 1,
:return => return_url,
:invoice => id
}
# These values set up the details for the item on paypal.
values.merge!({
# The amount is in cents
"amount_1" => ENTER_AN_AMOUNT_HERE,
"item_name_1" => ENTER_THE_ITEM_NAME_HERE,
"item_number_1" => 1,
"quantity_1" => 1
})
"https://www.sandbox.paypal.com/cgi-bin/webscr?" + values.to_query
end
end
4.) On the appllication_controller.rb file add this
def current_cart
session[:cart_id] ||= Cart.create!.id
#current_cart ||= Cart.find(session[:cart_id])
end
5.) On your the view where you want the checkout button add this:
# 'products_url' is just the url where you would like to redirect
# the user after the transaction
<%= link_to 'Buy with PAYPAL', #cart.paypal_url(products_url) %>
6.) On the controller show action of the view where you want the checkout add this:
def show
...
#cart = current_cart
end
Thats it! This is a PaypalExpressCheckout without a 'real' Cart since I built this Cart without using a Line Item. But you could add a Line Item to it following the Railscast #141 Paypal Basics http://railscasts.com/episodes/141-paypal-basics
There's a recent tutorial here: http://spin.atomicobject.com/2011/10/24/integrating-paypal-express-with-rails-3-1-part-1/.
Given these params:
ex: 1
{:field => 'admin', :id => "1"}
ex: 2
{:field => 'client', :id => "1"}
ex: 3
{:field => 'partner', :id => "1"}
Is it possible, (and how of course) could i dynamically apply this to the User model such as:
controller
#note the field attribute is not a field
#the field attribute I'm trying to set above to what are given in the params hash
def update_user
field = params[:field]
#user = User.find(params[:id])
#user.field = !#user.field
#user.save(false)
render :nothing => true
end
fyi
Why not just send a has with params and update the with update_attributes(params[:user])? Because the users attributes are protected and it's just easier to update a boolean this way.
I would do something like this:
#user = User.where("#{params[:field]} = ?", params[:id]).first if ["admin", "client", "partner"].include?(params[:field])
(The "include?" is a security check to prevent users from choosing some other field you don't want them to)
I currently have three methods which I want to collapse into one:
def send_email(contact,email)
end
def make_call(contact, call)
return link_to "Call", new_contact_call_path(:contact => contact, :call => call, :status => 'called')
end
def make_letter(contact, letter)
return link_to "Letter", new_contact_letter_path(:contact => contact, :letter => letter, :status => 'mailed')
end
I want to collapse the three into one so that I can just pass the Model as one of the parameters and it will still correctly create the path_to. I am trying to do this with the following, but stuck:
def do_event(contact, call_or_email_or_letter)
model_name = call_or_email_or_letter.class.name.tableize.singularize
link_to "#{model_name.camelize}", new_contact_#{model_name}_path(contact, call_or_email_or_letter)"
end
Thanks to the answers here, I have tried the following, which gets me closer:
link_to( "#{model_name.camelize}", send("new_contact_#{model_name}_path",
:contact => contact,
:status => "done",
:model_name => model_name) )
But I can't seem to figure out how to past the #{model_name} when it is an :attribute and then send the value of model_name, not as a string, but referring the object.
I got this to work: -- giving points to Kadada because he got me in the right direction :)
def do_event(contact, call_or_email_or_letter)
model_name = call_or_email_or_letter.class.name.tableize.singularize
link_to( "#{model_name.camelize}", send("new_contact_#{model_name}_path",
:contact => contact,
:status => 'done',
:"#{model_name}" => call_or_email_or_letter ) )
end
Try this:
def do_event(contact, call_or_email_or_letter)
model_name = call_or_email_or_letter.class.name.tableize.singularize
link_to( "#{model_name.camelize}", send("new_contact_#{model_name}_path",
contact, call_or_email_or_letter) )
end
I am currently trying to program my first ajax interface using Rails.
The application currently shows a table populated with list items. The user has to approve or reject each of the list items. I currently have an edit link at the end of each row that shows a form in which I can approve the list item.
I am thinking on using a checkbox instead of the edit link. When the user clicks the checkbox I want to update the database with the status, user name and date/time without leaving this page.
What steps should I follow?
Can I use a checkbox or am I
restricted to buttons?
What xxx_remote helper should I use?
How can I update the checkbox state with the results of the ajax call?
I don't think that a checkbox is the correct control for what you're looking for.
You said you want user's to be able to approve or reject items which means that you have 3 states: unhandled, approved and rejected. A checkbox only supports 2 states: off and on
I would use two links accept and reject and then do it as follows.
In your view:
...
<tr id="item1">
<td>Accept or Reject</td>
<td>
link_to_remote 'accept', :action => :accept, :id => 1, :method => :post
link_to_remote 'reject', :action => :reject, :id => 1, :method => :post
</td>
</tr>
...
In your controller
def accept
item = Item.find(params[:id])
item.accept
respond_to do |want|
want.js {
render :update do |page|
page << "$('item_#{item.id}').cells[0].innerHTML = 'Accepted'"
...include other updates you need to make to your row...
page.visual_effect :highlight, "item_#{item.id}"
end
}
end
end
... similar for reject method ...
This is a comment to solution proposed by Andrew,
I had to write params of link_to_remote function like this
link_to_remote 'reject', :url => {:action => :reject, :id => item.id, :method => :post}
Also, remember to add new actions to your routes.rb if You are using restful resources
i.e.
map.resources :items, :member => {:accept => :post, :reject => :post}