I am using this gem active_paypa_adaptive_payment for payments system on a web page.
preapproval_payment feature is working fine and I have a preapproval_key inside my database.
Now I want execute the agreement with my preaproval_key.
I have been checking cancel_preapproval method and it does work fine.
I dont need go to paypal page with cancel_preapproval method in my cancel_order method in my order controller.i.e.:
preapproval_key = #order.payment.preapproval_key
response = gateway.cancel_preapproval(:preapproval_key => preapproval_key)
respond_to do |format|
if response.ack == "Success"
#order.update_attributes
format.html { redirect_to user_orders_url(current_user), notice: t(".cancel_order_success") }
else
format.html { redirect_to user_orders_url(current_user), alert: t(".cancel_order_wrong") }
end
end
How can I execute the agreement with my preapproval_key for transfer funds from sender account to receiver account?
is it possible this feature for execute the agreement instead cancel the agreement with my preapproval_key?
Thank you very much
The solution is add the field :preapproval_key to the response. Something like, in your action:
def your_action
recipients = [{:email => 'receiver_email',
:amount => some_amount,
:primary => true},
{:email => 'receiver_email',
:amount => recipient_amount,
:primary => false}
]
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
:preapproval_key => "your_preapproval_key_here",
)
respond_to do |format|
if object.update_attributes
format.html { redirect_to root_path, notice: t(".success") }
else
format.html { redirect_to root_path, alert: t(".wrong") }
end
end
end
Note that you must have preapproval_key available. You can save it to your database when you make preapproved payment or you can get it with the api PreapprovalDetails
With this way you can make a pay with a preapproved payment. I recommend you add fields as :fees_payer, :senderEmail, :memo...etc for more details.
Regards!
Related
everyone.
I'm gonna test an active record object destroy failure but I've problems creating a failure situation.
I have a before_filter method called 'require_user_payment_info' which validates the #payment_info object before the delete method is called, so I can't create a 'bad' #payment_info object before the delete method is called.
Here's the require_user_payment_info method:
def require_user_payment_info
#payment_info = credit_card_model.slave.find_by_user_guid(user_guid)
if !#payment_info || #payment_info.user_guid != user_guid
redirect_to(:controller => 'store', :action => 'index') and return false
else
if((#payment_info.card_expires_year.to_i < Date.today.year) ||
((#payment_info.card_expires_month.to_i < Date.today.month) && (#payment_info.card_expires_year.to_i == Date.today.year)))
#payment_info.card_account_public = "" #clear this out so the user is forced to re-enter the credit card number
#payment_info.valid?
flash.now[:error] = t('ui_flash_errors.card_expired_error')
end
end
end
And the actual delete method:
def delete
# required to be called via a delete request
redirect_to :action => 'edit' and return if !request.delete?
if #payment_info.destroy
flash[:notice] = "Delete SUCCESSFUL"
redirect_to :action => 'new'
else
flash[:error] = "Delete failed"
redirect_to :action => 'edit'
end
Any ideas?
This is my solution:
def test_delete
payment_info = Factory.create(:payment_info, :user_guid=>#user.guid, :card_expires_month=>'04',
:card_expires_year=>(Date.today.year+2).to_s, :cardholder_city=>"test city",
:cardholder_state=>'NC', :cardholder_country=>'US', :cardholder_zip=>'27612')
PaymentInfo.any_instance.stubs(:destroy).returns(false)
delete(:delete, {}, #session)
assert_response(:redirect)
assert_equal false, assigns(:payment_info).blank?
assert_redirected_to({:controller=>'account', :action=>'edit'})
assert_equal flash[:error], "There was an error deleting your credit card information. Please try again."
end
I want to sent email to user after transcation done. now paypal is working fine for me, but user is not getting mail notification after transcation done? how to get email notification for user .
Here is my code
This is my controller code
This is my paypal function
def pay
if #order.update order_params
#order.update_attributes(:invoice_id => rand.to_s[2..11])
if current_user.billing_address.blank?
current_user.create_billing_address(#order.billing_address.dup.attributes)
end
if current_user.shipping_address.blank?
current_user.create_shipping_address(#order.shipping_address.dup.attributes)
end
# #cart.calculate_shipping
if #order.total == 0
return redirect_to checkout_thank_you_path
end
# if !params['payment'].present?
# return redirect_to :back, notice: 'Select Payment Gateway!'
# end
# if params['payment']=='paypal'
#order.order_statuses.create(status_type: 1)
item_details=[]
#order.line_items.each do |item|
item_details << {:name => item.title, :quantity => item.quantity, :amount => item.amount.fractional}
end
logger.info item_details.inspect
response = EXPRESS_GATEWAY.setup_purchase(#cart.total.fractional,
:ip => request.remote_ip,
:currency =>"USD",
:items => item_details,
:order_id => #order.invoice_id,
:return_url => checkout_thank_you_url,
:cancel_return_url => cart_url
)
return redirect_to EXPRESS_GATEWAY.redirect_url_for(response.token)
# else
# return redirect_to 'https://www.payumoney.com/'
# end
else
flash[:alert] = 'Billing and shipping address fields are required!'
render :addresses
end
end
This is my thank function for paypal
def thank_you
#order = Order.find(session[:order_id])
details = EXPRESS_GATEWAY.details_for(params[:token])
response = EXPRESS_GATEWAY.purchase(#cart.total.fractional, {
ip: request.remote_ip,
token: params[:token],
payer_id: details.payer_id,
items: #order.line_items.map{|l| {name: l.title, quantity: l.quantity, amount: l.amount.fractional}}
})
if response.success?
# logger.info payment_params.inspect
payment_params = {gateway: 'PayPal Express Checkout', transaction_id: response.params['token'], ip: request.remote_ip, amount: response.params['gross_amount']}
#cart.order.created_at = DateTime.now
#cart.order.status = 'Paid'
#cart.order.save
session.delete :order_id
# OrderMailer.order_confirmation(#order).deliver
# OrderMailer.admin_receipt(#order).deliver
else
redirect_to :cart_checkout, alert: 'Something went wrong. Please try again. If the problem persists, please contact us.'
end
#cart = Cart.new current_or_null_user.id, session[:order_id], session[:currency] # Start a new cart
end
Any help is appreciatable
I want to call create action of controller user_clubs and I did this way:
View Clubs
<button>
<%= link_to "Join Club", user_clubs_path(:user_id => current_user.id, :club_id => #club.id, :join_date => Date.current), :method => :post %>
</button>
Controller user_clubs
def create
#user_club = UserClub.new(user_club_params)
respond_to do |format|
if #user_club.save
format.html { redirect_to #user_club, notice: 'User club was successfully created.' }
format.json { render :show, status: :created, location: #user_club }
else
format.html { render :new }
format.json { render json: #user_club.errors, status: :unprocessable_entity }
end
end
end
def user_club_params
params.require(:user_club).permit(:user_id, :club_id, :join_date) --->**Error here**
end
Error information
app/controllers/user_clubs_controller.rb:75:in user_club_params'
app/controllers/user_clubs_controller.rb:28:increate'
Request
Parameters:
{"_method"=>"post",
"authenticity_token"=>"5Grhb+LIGt9B8XbnEcvg7BZQlDE935KO/aeikZoqxYs=",
"club_id"=>"1",
"join_date"=>"2014-11-17",
"user_id"=>"2"
}
Clubs and UserClubs are different. Club is a model that represents a team of people and user_clubs is the model that represents the many-to-many relationship between Users and Clubs.
First, can someone explain me how the call to user_clubs_path followed by the arguments know that has to go to the action create of user_clubs controller?
In second, the objective problem, why is this an error?
First question
Because of your routes definition, type into a terminal:
rake routes
And you'll see all generated routes and its associated helpers. First column (rake output) references the named helper: user_clubs => user_clubs_path):
Second question
You should add the parameters into user_club key, because you're requiring (by strong_parameters) this "scope" params.require(:user_club):
user_clubs_path(:user_club => {:user_id => current_user.id, :club_id => #club.id, :join_date => Date.current})
You'll receive in the controller:
{
"_method" => "post",
"authenticity_token" => "...",
"user_club" => {
"club_id" => "1",
"join_date"=> "2014-11-17",
"user_id"=> "2"
}
}
The parameters need to be nested under the user_club key. Try this instead:
user_clubs_path(:user_club => {:user_id => current_user.id, :club_id => #club.id, :join_date => Date.current})
I was working on an app in which I need to work with ipn, but it seems it does not work well.
I am trying to get the notification in success action and have specified the correct url in paypal sandbox.
def success
topup = current_user.topups.last
logger.debug "topup -------->"
logger.debug topup.amount.to_i
# raise request
details = EXPRESS_GATEWAY.details_for(topup.express_token)
logger.debug "details ------->"
logger.debug details.payer_id
# raise params[:payer_id]
response = EXPRESS_GATEWAY.purchase(topup.price_in_cents,{
:ip => request.remote_ip,
:token => topup.express_token,
:payer_id => details.payer_id
})
logger.debug "Response starts here --------->"
logger.debug response
if response.success?
amount = topup.amount.to_i
current_user.credits = current_user.credits.to_i + amount
current_user.save!
flash[:success] = "Thank you for the top up"
# #account_history = current_user.account_histories.build
# #account_history.update_attribute(:type => "Top Up", :details => "", :amount => amount, :user_id => current_user.id)
redirect_to current_user
notify = Paypal::Notification.new request.raw_post
logger.info "Notifying --------->"
logger.info notify
logger.info notify.status
logger.info "Notifying 2 --------->"
logger.info notify.acknowledge
logger.debug notify.status
if notify.acknowledge
logger.debug "Notifying --------->"
logger.debug notify.mc_gross
logger.debug notify.txn_id
end
else
redirect_to root_url
end
end
notify.acknowledge does not return anything (it is blank)
After banging my head for quite some time I was able to solve the issue. Posting my solution just in case anyone is stuck in the similar situation :-
One important thing is that IPN sends post data to the IPN listener so make sure you have a route defined for this.
I also had a before_filter :authenticate_user! , because of which I was getting html code 401. Had to skip before filter for notify action.
def pay_with_account
topup = Topup.find(params[:id])
response = EXPRESS_GATEWAY.setup_purchase(topup.price_in_cents,{
:ip => request.remote_ip,
:currency_code => 'GBP',
:return_url => topups_success_url(topup),
:notify_url => topups_notify_url(topup),
:cancel_return_url => topups_cancel_url(topup),
# :allow_guest_checkout => true,
:items => [{:name => "Topup", :quantity => 1,:description => "Top up my account", :amount => topup.price_in_cents}]
})
topup.update_attribute :express_token, response.token
redirect_to EXPRESS_GATEWAY.redirect_url_for(response.token)
end
This is the return url :-
def success
topup = current_user.topups.last
details = EXPRESS_GATEWAY.details_for(topup.express_token)
response = EXPRESS_GATEWAY.purchase(topup.price_in_cents,{
:ip => request.remote_ip,
:currency_code => 'GBP',
:token => topup.express_token,
:payer_id => details.payer_id
})
if response.success?
amount = topup.amount.to_i
current_user.credits = current_user.credits.to_i + amount
current_user.save!
redirect_to user_payments_path(current_user)
flash[:success] = "Your transaction was successfully completed"
else
flash[:error] = "Your transaction could not be compelted"
redirect_to user_payments_path(current_user)
end
end
This is the notify url :-
def notify
notify = Paypal::Notification.new(request.raw_post)
if notify.acknowledge
#account_history = topup.user.account_histories.build
#account_history.update_attributes(:payment_type => "Top up",:status => notify.status, :amount => notify.gross)
if params[:payer_status] == "verified"
#account_history.update_attributes(:details => "Pay Pal #{#account_history.id}")
elsif params[:payer_status] == "unverified"
#account_history.update_attributes(:details => "Credit Card #{#account_history.id}")
end
#account_history.save
end
render :nothing => true
end
routes :-
get "topups/pay_with_account"
get "topups/pay_without_account"
get "topups/success"
get "topups/cancel"
get "topups/notify"
post "topups/notify
I am receiving this error in my log console:
The amount is invalid
I am working in development env, with http://localhost:3000/
I have in my controller:
def pay
pay_request = PaypalAdaptive::Request.new
data = {
"returnUrl" => user_orders_url(current_user),
"requestEnvelope" => {"errorLanguage" => "en_US"},
"currencyCode" => "USD",
"receiverList" =>
{ "receiver" => [
{"receiver"=> [{"email"=>"email1", "amount"=>"10.00", "primary" => true}, {"email"=>"email2", "amount"=>"9.00", "primary" => false}]}
]},
"cancelUrl" => user_orders_url(current_user),
"actionType" => "PAY",
"ipnNotificationUrl" => ipn_notification_user_orders_url(current_user)
}
pay_response = pay_request.pay(data)
if pay_response.success?
# Send user to paypal
redirect_to pay_response.preapproval_paypal_payment_url
else
puts pay_response.errors.first['message']
redirect_to root_url, alert: "Something went wrong. Please contact support."
end
end
What am I doing bad?
Can you test with
"amount"=>10
Or
"amount"=>"10"
The error was fixed:
The error is in "primary" => true and "primary" => false.
I have removed this code and now the controller does works fine.
Thank you very much!