Not receiving paypal notifications through active merchant - ruby-on-rails

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

Related

Active Merchant paypal recurring payments

I am using Active Merchant gem to handle payments through the site. But now i want to make these payments recurring, on a monthly basis. Is there a way using active merchant or?
subscription_controller.rb
class SubscriptionsController < ApplicationController
def new
#home_page = true
#white = true
#subscription = Subscription.new(token: params[:token])
if !logged_in?
redirect_to signup_url
end
end
def create
#subscription = Subscription.new(subscription_params)
#subscription.remote_ip = request.remote_ip
#subscription.user_id = current_user.id
if #subscription.save
if #subscription.purchase
#subscription.send_thank_you_email
redirect_to thankyou_path
else
raise ActiveRecord::Rollback
flash[:notice] = "It seems something went wrong with the paypal transaction. Please check that your credit card is valid and has credit in it and try again."
redirect_to :back
end
else
flash[:notice] = "Something went wrong with marking your purchase as complete. Please contact support to check it out."
redirect_to :back
end
end
def purchase
response = GATEWAY.setup_purchase(999,
ip: request.remote_ip,
return_url: new_subscription_url,
cancel_return_url: root_url,
currency: "USD",
items: [{name: "Order", description: "Recurring payment for ******", quantity: "1", amount: 999}]
)
redirect_to GATEWAY.redirect_url_for(response.token)
end
def thank_you
#home_page = true
#white = true
end
private
def subscription_params
params.require(:subscription).permit(:token)
end
end
subscription.rb model
def purchase
response = GATEWAY.purchase(999, express_purchase_options)
response.success?
end
def token=(token)
self[:token] = token
if new_record? && !token.blank?
# you can dump details var if you need more info from buyer
details = GATEWAY.details_for(token)
puts details.params["PayerInfo"]["PayerName"].inspect
self.payer_id = details.payer_id
self.first_name = details.params["PayerInfo"]["PayerName"]["FirstName"]
self.last_name = details.params["PayerInfo"]["PayerName"]["LastName"]
end
end
# send thank you email
def send_thank_you_email
UserMailer.thank_you(self).deliver_now
end
private
def express_purchase_options
{
:ip => remote_ip,
:token => token,
:payer_id => payer_id
}
end
production.rb environment
config.after_initialize do
ActiveMerchant::Billing::Base.mode = :production
::GATEWAY = ActiveMerchant::Billing::PaypalExpressGateway.new(
:login => ENV['PAYPAL_LOGIN'],
:password => ENV['PAYPAL_PASSWORD'],
:signature => ENV['PAYPAL_SIGNATURE']
)
end
I think ActiveMerchant used to have something like this:
subscription = PAYPAL_EXPRESS_GATEWAY.recurring(#subscription.price_in_cents, nil,
:description => 'blah',
:start_date => Date.tomorrow,
:period => 'Year',
:frequency => 1,
:amount => price,
:currency => 'USD'
)
See this answer Does ActiveMerchant support Subscription Based transaction
Also see this: https://github.com/activemerchant/active_merchant/blob/master/lib/active_merchant/billing/gateways/paypal_express.rb
https://github.com/activemerchant/active_merchant/blob/master/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb

How to send email to user after payment is done with paypal

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

How to use Rhodes without Rhosync or RhoConnect?

I know we can sync data using rhodes without Rhosync or Rhoconnect by using direct web service, but I'm here little bit confuse where to place that code for webservice call and how do we initialize it. Can anyone help me with small example?
Thanks in Advance.
I got it and it works for me.
class ProductController < Rho::RhoController
include BrowserHelper
# GET /product
def index
response = Rho::AsyncHttp.get(:url => "example.com/products.json",
:headers => {"Content-Type" => "application/json"})
#result = response["body"]
render :back => '/app'
end
# GET /product/{1}
def show
id =#params['id']
response = Rho::AsyncHttp.get(:url => "example.com/products/"+ id +".json",
:headers => {"Content-Type" => "application/json"})
#result = response["body"]
end
# GET /product/new
def new
#product = product.new
render :action => :new, :back => url_for(:action => :index)
end
# GET /product/{1}/edit
def edit
id =#params['product_id'].to_s
response = Rho::AsyncHttp.get(:url => "example.com/products/#{id}.json",
:headers => {"Content-Type" => "application/json"})
#result = response["body"]
end
# POST /product/create
def create
name = #params['product']['name']
price = #params['product']['price']
body = '{"product" : {"name" : "'+ name +'","price" :"'+ price +'" } }'
#result = Rho::AsyncHttp.post(:url => "example.com/products.json",
:body => body, :http_command => "POST", :headers => {"Content-Type" => "application/json"})
redirect :action => :index
end
# POST /product/{1}/update
def update
name=#params['product']['name']
price=#params['product']['price']
body = '{"product" : {"name" : "' + name + '","price" :"' + price + '" } }'
id = #params["product_id"].to_s
response = Rho::AsyncHttp.post(:url => "example.com/products/#{id}.json",
:body => body, :http_command => "PUT",:headers => {"Content-Type" => "application/json"})
redirect :action => :index
end
# POST /product/{1}/delete
def delete
id = #params["product_id"].to_s
response = Rho::AsyncHttp.post(:url => "example.com/products/#{id}.json",
:http_command => "DELETE",
:headers => {"Content-Type" => "application/json"})
redirect :action => :index
end
end
Most easy form of http server request is next:
Rho::AsyncHttp.get(
:url => "http://www.example.com",
:callback => (url_for :action => :httpget_callback)
)
where httpget_callback is name of the controller callback method.
See more details at official Rhodes docs.

Rhoconnect webservice login need

I am very new guy in Rhomobile and I want to login a webservice using Rhoconnect can anyone help me how to implement this.
I've tried with in Settings Controler:
def do_login
if #params['username'] and #params['password']
begin
SyncEngine.login(#params['username'], #params['password'], (url_for :action => :login_callback) )
#response['headers']['Wait-Page'] = 'true'
redirect :action => :index
rescue Rho::RhoError => e
#msg = e.message
render :action => :login
end
else
#msg = Rho::RhoError.err_message(Rho::RhoError::ERR_UNATHORIZED) unless #msg && #msg.length > 0
render :action => :login
end
end
Where SyncEngine.login(#params['username'], #params['password']) call the sourecadapter method login; where I'm calling
def login(username, password)
user_info = {:username => username, :password => password }
response = RestClient.get(#base+#params['username']+#params['password'])
result = RestClient.post(:url => "my-webservice" )
#msg=result["body"]
render :action => :index
end
I've tried in:
class Application < Rhoconnect::Base
class << self
def authenticate(username,password,session)
result = RestClient.post(:url => "mywebservice" )
true # do some interesting authentication here...
end
end
But I got nothing..
plz give some idea me; how to solve this
SyncEngine.login call from Rhodes app will call authenticate(username, password, session)
method in application.rb of your RhoConnect app. Then, you can code the authenticate method to call your implementation of user authentication as follows:
def authenticate(username, password, session)
# for example
resp = RestClient.post(:url => "mywebservice", :login => {:username => username, :password => password})
#parse resp as needed and return the result either true or false
# i.e. status contains value true or false in the response body
result = JSON.parse(resp.body)['status']
end
Hope that helps.

How to get gateway response from model into controller - Ruby on Rails

My application uses activemerchant to process payments. I'm using Eway as my payment gateway. I'm storing credit card details with Eway to keep them out of my application database.
I'm using a method store which returns a response with a customer billing id that I can use at a later time to process the order.
http://rdoc.info/github/Shopify/active_merchant/master/ActiveMerchant/Billing/EwayManagedGateway
My main issue is how do I get the response value into my controller so I can save it to the member model.
I've created a simple ruby file to test this all works and it does. I just need to convert this code to work inside my rails app.
require "rubygems"
gem 'activemerchant', '1.15.0'
require 'activemerchant'
ActiveMerchant::Billing::Base.mode = :production
gateway = ActiveMerchant::Billing::EwayManagedGateway.new(
:login => '12345678',
:username => 'mylogin#example.com',
:password => 'mypassword'
)
credit_card = ActiveMerchant::Billing::CreditCard.new(
:type => "visa",
:number => "4444333322221111",
:verification_value => "123",
:month => "11",
:year => "2011",
:first_name => "John",
:last_name => "Citizen"
)
options = {
:order_id => '1230123',
:ip => "127.0.0.1",
:email => 'john.citizen#example.com',
:billing_address => { :title => "Mr.",
:address1 => '123 Sample Street',
:city => 'Sampleville',
:state => 'NSW',
:country => 'AU',
:zip => '2000'
},
:description => 'purchased items'
}
if credit_card.valid?
response = gateway.store(credit_card, options)
if response.success?
puts "Credit Card Stored. #{response.message}"
customer = response.params['CreateCustomerResult']
puts "Customer Id: #{customer}"
else
puts "Error: #{response.message}"
end
else
puts "Error, credit card is not valid. #{credit_card.errors.full_messages.join('. ')}"
end
Here is the relevant code in my order model.
serialize :params
cattr_accessor :gateway
def response=(response)
self.success = response.success?
self.message = response.message
self.params = response.params
self.billing_id = response.params['CreateCustomerResult']
rescue ActiveMerchant::ActiveMerchantError => e
self.success = false
self.message = e.message
self.params = {}
self.billing_id = nil
end
def store
response = Order.gateway.store(credit_card, options)
end
Here is my order controller create code.
def create
#member = current_member
#order_deal = Deal.find(params[:deal_id])
#order = #order_deal.orders.build(params[:order])
#order.member_id = current_member.id
#order.ip_address = request.remote_ip
#deal = #order_deal
if #order.save
if #order.store
render :action => "success"
flash[:notice] = "Successfully processed your order."
else
render :action => "new"
end
else
render :action => 'new'
end
end
So essentially I want to get the
response.params['CreateCustomerResult']
and add it to my member model under
member.billing_id = response.params['CreateCustomerResult]
How can I do this?

Resources