如何取消Paypal订阅?

时间:2013-11-11 23:45:28

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

我终于想出了如何使用本教程实现PayPal Recurring Billing。 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

1 个答案:

答案 0 :(得分:3)

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

Subscription_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

的routes.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 %>