ruby-on-rails - 为 PayPal 创建 IPN URL

标签 ruby-on-rails paypal paypal-ipn

我使用 paypal recurring gem 设置了 PayPal。我需要帮助了解如何实现 PayPal IPN。

任何帮助将不胜感激,因为这是我项目的最后一步。我需要设置 IPN,以便当用户从他们的 PayPal 帐户取消/暂停计费时,它将显示为已从我的数据库中取消。

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

订阅.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

订阅 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

路线:

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

支付通知 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

通知 Controller :

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

最佳答案

你需要修正你的路线。

应该是:

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

关于ruby-on-rails - 为 PayPal 创建 IPN URL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23916610/

相关文章:

ruby-on-rails - 有没有办法用元标记做 If IE8 检查?

paypal - 如何从 Adaptive Payment API 调用中获取送货地址?

php - 使用 HTTPS 的 Paypal IPN 验证回传

ruby-on-rails - 通过 users_controller.rb 中的代码修改用户的数据库

ruby-on-rails - Paperclip 2.3.5 到 3.3.1 导致 url 与路径不同

ruby-on-rails - 打包 html 模板、javascript 和 css 以供多个平台使用

Paypal:不同国家/地区的账单和送货地址?

php - 在 PHP 代码中集成 PayPal

php - paypal 付款在 magento 中不可见结帐页面

php - Paypal IPN : certificate verify failed