Creating an IPN URL for PayPal

I have a PayPal setup using paypal return gem. I need help understanding how to implement PayPal IPN.

Any help would be greatly appreciated, as this is the last step for my project. I need to configure IPN so that users cancel / suspend billing from their PayPal account, which will appear as canceled from my database.

Paypal_payment.rb:

def initialize(subscription) @subscription = subscription end def checkout_details process :checkout_details end def checkout_url(options) process(:checkout, options).checkout_url end def make_recurring process :request_payment process :create_recurring_profile, period: :monthly, frequency: 1, start_at: Time.zone.now end def suspend process :suspend, :profile_id => @subscription.paypal_recurring_profile_token end def reactivate process :reactivate, :profile_id => @subscription.paypal_recurring_profile_token end private def process(action, options = {}) options = options.reverse_merge( token: @subscription.paypal_payment_token, payer_id: @subscription.paypal_customer_token, description: @subscription.plan.name, amount: @subscription.plan.price, ipn_url: "http://mydomain.com/paypal/ipn", currency: "USD" ) response = PayPal::Recurring.new(options).send(action) raise response.errors.inspect if response.errors.present? response end end 

Subscription.rb:

  belongs_to :plan belongs_to :subscription belongs_to :user validates_presence_of :plan_id validates_presence_of :email attr_accessor :stripe_card_token, :paypal_payment_token def expires_at self.updated_at + plan.duration.days end def save_with_payment if valid? if paypal_payment_token.present? save_with_paypal_payment else save_with_stripe_payment end end end def paypal PaypalPayment.new(self) end def save_with_paypal_payment response = paypal.make_recurring self.paypal_recurring_profile_token = response.profile_id save! end def save_with_stripe_payment customer = Stripe::Customer.create(description: email, plan: plan_id, card: stripe_card_token) self.stripe_customer_token = customer.id save! rescue Stripe::InvalidRequestError => e logger.error "Stripe error while creating customer: #{e.message}" errors.add :base, "There was a problem with your credit card." false end def payment_provided? stripe_card_token.present? || paypal_payment_token.present? end def suspend_paypal paypal.suspend save end def reactivate_paypal paypal.reactivate save end def update_card(subscriber, card_info) token = Stripe::Token.create( card: { number: card_info[:number], exp_month: card_info[:exp_month], exp_year: card_info[:exp_year], cvc: card_info[:cvc] } ) customer = Stripe::Customer.retrieve(user.subscription.stripe_customer_token) card = customer.cards.create(card: token.id) card.save customer.default_card = card.id customer.save rescue Stripe::InvalidRequestError => e logger.error "Stripe error while updating card info: #{e.message}" errors.add :base, "#{e.message}" false end end 

Subscription Controller:

  def new plan = Plan.find(params[:plan_id]) @subscription = plan.subscriptions.build if params[:PayerID] @subscription.paypal_customer_token = params[:PayerID] @subscription.paypal_payment_token = params[:token] @subscription.email = @subscription.paypal.checkout_details.email end end def create @subscription = Subscription.new(params[:subscription]) if @subscription.save_with_payment redirect_to @subscription, :notice => "Thank you for subscribing!" else render :new end end def show @subscription = Subscription.find(params[:id]) end def paypal_checkout plan = Plan.find(params[:plan_id]) subscription = plan.subscriptions.build redirect_to subscription.paypal.checkout_url( return_url: new_subscription_url(:plan_id => plan.id), cancel_url: root_url ) end def updatesubscription @user = current_user @customer = Stripe::Customer.retrieve(@user.subscription.stripe_customer_token) if @user.subscription.plan_id == 12 @customer.update_subscription(:plan => "1", :prorate => true) current_user.subscription.update_attributes(:plan_id => 1) flash.alert = 'Your subscription has been changed to monthly!' redirect_to root_url elsif @user.subscription.plan_id == 1 @customer.update_subscription(:plan => "12", :prorate => true) current_user.subscription.update_attributes(:plan_id => 12) current_user.save! flash.alert = 'Your subscription has been changed to annually!' redirect_to root_url end end def cancelsubscription @user = current_user @customer = Stripe::Customer.retrieve(@user.subscription.stripe_customer_token) @customer.cancel_subscription() current_user.subscription.update_attributes(:cancelled => 1) current_user.save! flash.alert = 'Your subscription has been cancelled successfully!' redirect_to root_url end def showcard @user = current_user Stripe::Customer.retrieve(@user.subscription.stripe_customer_token).cards.all() end def suspend @user = current_user @user.subscription.suspend_paypal current_user.subscription.update_attributes(:cancelled => 1) flash.alert = 'Billing has been suspended!' redirect_to root_url end def reactivate @user = current_user @user.subscription.reactivate_paypal current_user.subscription.update_attributes(:cancelled => nil) flash.alert = 'Billing has been activated!' redirect_to root_url end def edit_card @user = current_user end def update_card @user = current_user card_info = { name: params[:name], number: params[:number], exp_month: params[:date][:month], exp_year: params[:date][:year], cvc: params[:cvc] } if @user.subscription.update_card(@subscriber, card_info) flash.alert = 'Saved. Your card information has been updated.' redirect_to root_url else flash.alert = 'Stripe reported an error while updating your card. Please try again.' redirect_to root_url end end end 

routes:

  post "paypal/ipn" => "notifications#create" 

Payment Notification Controller:

 def index redirect_to root_url end def create PaymentNotification.create!(:params => params, :status => params[:payment_status], :transaction_id => params[:txn_id]) render :nothing => true end end 

Notification Controller:

  def create query = params query[:cmd] = "_notify-validate" if(response.body == "VERIFIED") Rails.logger.debug params.inspect "Notification is valid" end end end 
+6
source share
3 answers

You need to fix your routes.

It should be:

  match '/paypal/ipn' => 'notifications#create', :via => [:get, :post], :as => 'notifications_create' 
0
source

The PayPal developer site has an IPN testing tool. You can specify its callback URL and send call samples. You must first register in order to use it.

0
source

So, you only have a problem - is it getting IPN to run in your test account .. ?? When you use the simulator, does everything work as expected?

For IPN to work in the sandbox, all you have to do is make sure that it is included in the profile of the sandbox seller’s account. You can log in to your sandbox account at http://sandbox.paypal.com in the same way as in real time. After you go there, go to the profile and then to the IPN settings so that you can enable it and set the corresponding URL.

0
source

Source: https://habr.com/ru/post/969989/


All Articles