简体   繁体   English

为PayPal创建IPN URL

[英]Creating IPN URL for PayPal

I have PayPal setup using the paypal recurring gem. 我使用paypal重复宝石设置PayPal。 I need help understanding how to implement PayPal IPN. 我需要帮助了解如何实施PayPal IPN。

Any help would be greatly appreciated as this is the last step for my project. 任何帮助将不胜感激,因为这是我的项目的最后一步。 I need to have the IPN setup so that when users cancel/suspend billing from their PayPal account that it will show as cancelled from my database. 我需要设置IPN,以便当用户从其PayPal帐户取消/暂停结算时,它将显示为从我的数据库中取消。

Paypal_payment.rb: 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: 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

Subscriptions 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 Notifications 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

Notifications controller: 通知控制器:

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

In the PayPal developer site there is an IPN test tool. PayPal开发人员站点中,有一个IPN测试工具。 You can provide it your callback URL and send sample calls. 您可以提供回调URL并发送样本调用。 You'll have to register first to use it. 你必须先注册才能使用它。

So you're only problem is getting the IPN's to trigger in your test account..?? 所以你唯一的问题就是让IPN在你的测试账户中触发.. ?? When you use the Simulator does everything work as expected? 当您使用模拟器时,一切都按预期工作吗?

To get IPN working in the sandbox all you need to do is make sure it's enabled in your sandbox seller account profile. 要使IPN在沙箱中工作,您只需确保在沙盒卖家帐户配置文件中启用它即可。 You can login to your sandbox account at http://sandbox.paypal.com just like you would a live account. 您可以在http://sandbox.paypal.com上登录您的沙盒帐户,就像使用真实帐户一样。 Once you're in there go into the profile and then into IPN settings so you can enable it and set the URL accordingly. 进入配置文件后再进入IPN设置,以便启用它并相应地设置URL。

You need to fix your routes. 您需要修复路线。

It should be: 它应该是:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM