TH's Notes
  • Home
  • Categories
  • Tags
  • Archives

依照簽署方案進行收費

假設我們現在想為網站開發收費機制, 使用者註冊後會立刻索取第一個月的服務費用, 之後每過一個月, 系統都會自動向客戶的信用卡帳戶請款。 下面將以 Stripe 金流服務為例, 敘述如何在 Rails 中實作這項功能。

設定 Plans

請先在 Stripe Plans 新增一個 ID 為 base 的收費方案,如下

新增 customer_token

然後在 Rails 的 users table 裡面, 新增 customer_token 欄位,如下

db/schema.rb:

create_table "users", force: true do |t|
  t.string   "full_name"
  t.string   "email"
  t.string   "password_digest"
  t.string   "slug"
  t.string   "token"
  t.boolean  "admin"
  t.string   "customer_token"   # 新增 customer_token
  t.boolean  "active",          default: true
  t.datetime "created_at"
  t.datetime "updated_at"
end

設定 Stripe API Key

在 config/initializers/stripe.rb, 裡面設定 Stripe 的 API Key

config/initializers/stripe.rb:

Stripe.api_key = ENV['STRIPE_SECRET_KEY']

產生 Stripe customer

在處理註冊的服務 裡面, 產生 Stripe customer, 並將 customer token 儲存下來

app/services/user_signup.rb:

class UserSignup

  attr_reader :error_message

  def initialize(user)
    @user = user
  end

  def sign_up(stripe_token)
    if @user.valid?
      # 產生 Stripe customer
      customer = StripeWrapper::Customer.create(
        :user => @user,
        :card => stripe_token,
        :description => "Sign up for #{@user.email}"
      )
      if customer.successful?
        # 儲存 customer token
        @user.customer_token = customer.customer_token
        @user.save
        AppMailer.delay.send_welcome_email(@user)
        @status = :success
        self
      else
        @status = :failed
        @error_message = customer.error_message
        self
      end
    else
      @status = :failed
      @error_message = "Invalid user information. Please check the errors below."
      self
    end
  end

  def successful?
    @status == :success
  end

end


class UserSignup

  attr_reader :error_message

  def initialize(user)
    @user = user
  end

  def sign_up(stripe_token)
    if @user.valid?
      # 產生 Stripe customer
      customer = StripeWrapper::Customer.create(
        :user => @user,
        :card => stripe_token,
        :description => "Sign up for #{@user.email}"
      )
      if customer.successful?
        @user.save
        AppMailer.delay.send_welcome_email(@user)
        @status = :success
        self
      else
        @status = :failed
        @error_message = customer.error_message
        self
      end
    else
      @status = :failed
      @error_message = "Invalid user information. Please check the errors below."
      self
    end
  end

  def successful?
    @status == :success
  end

end

StripeWrapper 定義了產生 Stripe customer 的動作, 並且將預設方案設為 base

app/models/stripe_wrapper.rb:

module StripeWrapper
  class Customer
    attr_reader :response, :error_message

    def initialize(options = {})
      @response = options[:response]
      @error_message= options[:error_message]
    end

    def self.create(options = {})
      begin
        response = Stripe::Customer.create(
          :card => options[:card],
          :plan => options[:plan] || "base", # 預設為 base 方案
          :email => options[:user].email
        )
        new(response: response)
      rescue Stripe::CardError => e
        new(error_message: e.message)
      end
    end

    def successful?
      response.present?
    end

    def customer_token
      response.id
    end
  end
end
Comments
comments powered by Disqus

  • « 使用 Service Objects 編寫註冊服務
  • 查看交易記錄的後台功能 »

Published

Feb 6, 2015

Category

Web

Tags

  • rails 63
  • stripe 4
  • Powered by Pelican. Theme: Elegant by Talha Mansoor