ruby-on-rails - 如何取消 Paypal 订阅?

标签 ruby-on-rails ruby paypal subscription paypal-subscriptions

我终于想通了如何使用本教程实现 PayPal 定期计费。 http://railscasts.com/episodes/289-paypal-recurring-billing

一切正常,但是如何取消订阅....

下面是我写的所有代码,我还添加了一些评论/问题

错误

app/controllers/subscriptions_controller.rb:27:in `show'

Couldn't find Subscription with id=cancel_account

请帮助 rails 新手。 :)

Controller

class SubscriptionsController < ApplicationController

  def new
    plan = Plan.find(params[:plan_id])
    @subscription = plan.subscriptions.build
    @subscription.user_id = current_user.id
    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 destroy
    @subscription = current_user.subscription
    @previous_plan = @subscription.plan

    if @subscription.cancel_recurring
      flash[:success] = 'Subscription Canceled.'
    end
    redirect_to some_path
  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

end

模型

class Subscription < ActiveRecord::Base
  attr_accessible :paypal_customer_token, :paypal_recurring_profile_token, 
                  :plan_id, :user_id, :email, :paypal_payment_token

  attr_accessor :paypal_payment_token

  belongs_to :plan
  belongs_to :user

  validates_presence_of :plan_id
  validates_presence_of :email
  validates_presence_of :user_id

  def save_with_payment
    if valid?
      if paypal_payment_token.present?
       save_with_paypal_payment
    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 payment_provided?
    paypal_payment_token.present?
  end

end

class PaypalPayment
  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 + 1.month
  end

  def cancel_recurring
    response = ppr.cancel_subscription(at_date_end: true) #Needs a end period field in
    self.current_date_end_at = Time.at(response.current_date_end)
    self.plan_id = plan.id
    self.status = "canceled"
    return self.save
  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.to_i,
      currency: "USD"
    )
    response = PayPal::Recurring.new(options).send(action)
    raise response.errors.inspect if response.errors.present?
    response
  end
end

观点

<%= form_for @subscription do |f| %>

  <%= f.hidden_field :plan_id %>
  <%= f.hidden_field :user_id %>
  <%= f.hidden_field :paypal_customer_token %>
  <%= f.hidden_field :paypal_payment_token %>

  <% unless @subscription.payment_provided? %>
  <div class="field">
    <%= radio_button_tag :pay_with, :paypal %>
    <%= label_tag :pay_with_paypal do %>
      <%= image_tag "paypal.png" %>
    <% end %>
  </div>
  <% end %>


*** WHAT WOULD BE THE LINK TO CANCEL THE SUBSCRIPTION ***

    <%= link_to image_tag("https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif"),
    paypal_checkout_path(plan_id: @subscription.plan_id) %>

    <%= link_to "Cancel Subscription", cancel_account_subscriptions_path(plan_id: 
    @subscription.plan_id) %>



  <div id="billing_fields">
    <div class="field">
      <%= f.label :email %>
      <%= f.text_field :email %>

    </div>
    <% if @subscription.payment_provided? %>
      Payment has been provided. Click "Subscribe" to complete the subscription.
    <% end %>
    <div class="actions">
      <%= f.submit "Subscribe" %>
    </div>
  </div>
<% end %>

路线

App::Application.routes.draw do

  resources :subscriptions do
    collection do
      delete :cancel_account
    end
  end

  get 'paypal/checkout', to: 'subscriptions#paypal_checkout'

end

最佳答案

要销毁用户的 Paypal 订阅,您应该在订阅模型中创建一个销毁操作。

订阅 Controller .rb

  def destroy
    @subscription = current_user.subscription
    @previous_plan = @subscription.plan

    if @subscription.cancel_recurring
      flash[:success] = 'Subscription Canceled.'
    end
    redirect_to some_path
  end

在您的模型中获取当前用户并取消他们的订阅。如果用户按月订阅但在 30 天内的 2 天内取消,则他们的帐户订阅应在 at_end_date 期限之前有效(请注意)。

  def cancel_recurring
    response = ppr.cancel_subscription(at_date_end: true) #Needs a end period field in
    self.current_date_end_at = Time.at(response.current_date_end)
    self.plan_id = plan.id
    self.status = "canceled"
    return self.save
  end

路线.rb

resources :subscriptions do
 collection do
   delete :cancel_account
 end
end

在您看来,您会像这样迭代计划

<% @plans.each do |plan| %>
  <%= link_to "Cancel Account", cancel_account_subscriptions_path(@subscription, plan_id: plan.id), method: :delete %>
<% end %>

关于ruby-on-rails - 如何取消 Paypal 订阅?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19918253/

相关文章:

php - Paypal - Zend_Http_Client_Adapter_Curl - 如何打开 CURLOPT_VERBOSE

paypal - 沙盒 paypal- 灯箱不加载

ruby-on-rails - 要检查的 RSpec 测试(Rails 模型 : validates :something, :inclusion => 来自其他 activeRecord 的列表)

angularjs - Paypal api oauth

ruby-on-rails - 如何干净地更新 Rails 4 中的 HABTM 关联列表?

ruby 强制对实数进行整数除法

ruby-on-rails - 是否有内置方法从数据库中获取单个 ActiveRecord 属性(忽略内存中的值)?

ruby - 如何编写一个方法来计算 ruby​​ 中字符串中最常见的子字符串?

ruby-on-rails - 我在 Rails 中使用 Figaro gem 时遇到错误

ruby-on-rails - Rails 3.2.13/Devise 2.2.3 : Method "authenticate_scope!" throws error: wrong number of arguments (1 for 0)