[RUBY] Create an EC site using stripe! (Account creation)

Petit promotion

https://www.code-sell.net/ We have created a service that allows you to sell your code! If you have code you don't need, please use it. By the way, I am using the stripe described in this article.

at first

https://qiita.com/UTOG/items/6a00135a5114a70727c3 It is a continuation of.

Last time I made a purchase function. This time I will create a stripe account (Standard and Custom). However, I said that I would do it from the new registration function of devise last time, but if that is the case, the article will be too long (normally troublesome ...) and I will not make any unusual settings, so I will assume that devise is installed.

Refer to the article below for how to install devise. No Twitter authentication or email authentication function is required. [* Rails *] How to use devise (rails6 version)

When creating a standard account Reference article

Standard Both the form and the dashboard are of the type prepared by stripe. For details, please see the previous article, but if you briefly introduce the features

merit

It's very easy to implement, you don't have to create a form or submission system, and if something goes wrong, it's your responsibility.

Demerit

However, the design of the form and dashboard cannot be changed, and the feeling of "I'm using stripe!" Comes out very much. There is a feeling that one service is not complete.

Start creating

gemfile


gem 'omniauth-stripe-connect'

Don't forget the bundle

rails g migration AddStripeAccountToUsers access_code:string publishable_key:string uid:string

Add access_code, publishable_key and uid to your user model. In particular, uid is an important column that connects stripe accounts and apps. Next, set the callback.

devise.rb


Devise.setup do |config|
・ ・ ・
  config.omniauth :stripe_connect,
    ENV["CLIENT_ID"],
    ENV["SECRET_KEY"],
    scode: 'read_write',
    stripe_landing: 'login'
・ ・ ・
end

Next, set the stripe_connect method to be called after registration.

omniauth_callbacks_controller.rb


def stripe_connect
  auth_data = request.env["omniauth.auth"]
  @user = current_user
  if @user.persisted?
    @user.access_code = auth_data.credentials.token
    @user.publishable_key = auth_data.info.stripe_publishable_key
    @user.uid = auth_data.uid
    @user.save

    sign_in_and_redirect @user, event: :authentication
    flash[:notice] = 'Stripe Account Created And Connected' if is_navigational_format?
   else
     session["devise.stripe_connect_data"] = request.env["omniauth.auth"]
     redirect_to root_path
   end
end

Set stripe_url in helper. If I write it directly in views, it doesn't work.

application_helper.rb


module ApplicationHelper
  def stripe_url
   "https://connect.stripe.com/oauth/authorize?response_type=code&client_id=#{ENV["CLIENT_ID"]}&scope=read_write"
  end    
end

This is the link to register. Please do it wherever you like. I recommend putting it around the profile edit screen.

slim:edit.html.slim


  = link_to "to register", stripe_url

If you write in erb

erb:edit.html.erb


  <%= link_to "to register", stripe_url %>

that's all. It's that easy! However, since you do not have to create the form and submission system yourself, you cannot change the design.

custom The form, submission system, and dashboard are all self-made. Feeling that only API is used I would like you to see the previous article for the same details.

merit

You can change forms and dashboards without feeling stripes, complete with one service

Demerit

It's hard to implement, you have to create all the forms and dashboards, it's your responsibility if something goes wrong

Start creating

rails g migration AddStripeAccountToUsers access_code:string publishable_key:string uid:string

Add access_code, publishable_key and uid to your user model. In particular, uid is an important column that connects stripe accounts and apps.

rails g controller accounts

accounts_controller.rb


class AccountsController < ApplicationController
    before_action :authenticate_user!
    def new
    end

    def create
      user = current_user
      data = Stripe::Account.create(
        type: "custom",
        country: "JP",
        email: user.email,
        requested_capabilities: ['card_payments', 'transfers'],
        business_type: 'individual',
        individual: {
            first_name_kana: params[:first_name_kana],
            first_name_kanji: params[:first_name_kanji],
            last_name_kana: params[:last_name_kana],
            last_name_kanji: params[:last_name_kanji],
            gender: params[:gender],
            email: user.email,
            dob: {
                day: params[:"day(3i)"].to_i,
                month: params[:"day(2i)"].to_i,
                year: params[:"day(1i)"].to_i,
            },
            address_kanji: {
                country: "JP",
                postal_code: params[:postal_code],
                state: params[:state],
                city: params[:city],
                town: params[:town],
                line1: params[:line1],
                line2: params[:line2],
            },
            address_kana: {
                line1: params[:line1],
            },
        },
        tos_acceptance: {
            date: Time.now.to_i,
            ip: request.remote_ip,
        },
        external_account: {
          object: "bank_account",
          country: "JP",
          currency: 'jpy',
          account_holder_name: params[:account_holder_name],
          account_holder_type: 'individual',
          routing_number: params[:routing_number],
          account_number: params[:account_number],
        },
      )
      user.update(uid: data.id)
      redirect_to "/accounts/top", notice: 'I saved it.'
    rescue Stripe::CardError => e
      flash[:alert] = "An error has occurred.{e.message}"
      render :top
  
    # Invalid parameters were supplied to Stripe's API
    rescue Stripe::InvalidRequestError => e
      flash[:alert] = "An error has occurred (InvalidRequestError)#{e.message}"
      render :top
  
    # Authentication with Stripe's API failed(maybe you changed API keys recently)
    rescue Stripe::AuthenticationError => e
      flash[:alert] = "An error has occurred (AuthenticationError)#{e.message}"
      render :top
  
    # Network communication with Stripe failed
    rescue Stripe::APIConnectionError => e
      flash[:alert] = "An error has occurred (APIConnectionError)#{e.message}"
      render :top
  
    # Display a very generic error to the user, and maybe send yourself an email
    rescue Stripe::StripeError => e
      flash[:alert] = "An error has occurred (StripeError)#{e.message}"
      render :top
  
    #When an error occurs other than stripe related
    rescue => e
      flash[:alert] = "An error has occurred#{e.message}"
      render :top
    end

    def update
        user = current_user
        data = Stripe::Account.update(
            current_user.stripe_user_id,
            email: user.email,
            requested_capabilities: ['card_payments', 'transfers'],
            business_type: 'individual',
            individual: {
                first_name_kana: params[:first_name_kana],
                first_name_kanji: params[:first_name_kanji],
                last_name_kana: params[:last_name_kana],
                last_name_kanji: params[:last_name_kanji],
                gender: params[:gender],
                email: user.email,
                dob: {
                    day: params[:"day(3i)"].to_i,
                    month: params[:"day(2i)"].to_i,
                    year: params[:"day(1i)"].to_i,
                },
                address_kanji: {
                    country: "JP",
                    postal_code: params[:postal_code],
                    state: params[:state],
                    city: params[:city],
                    town: params[:town],
                    line1: params[:line1],
                    line2: params[:line2],
                },
                address_kana: {
                    line1: params[:line1],
                },
            },
          external_account: {
            object: "bank_account",
            country: "JP",
            currency: 'jpy',
            account_holder_name: params[:account_holder_name],
            account_holder_type: 'individual',
            routing_number: params[:routing_number],
            account_number: params[:account_number],
          },
        )
        redirect_to "/accounts/top", notice: 'it changed.'
    rescue Stripe::CardError => e
      flash[:alert] = "An error has occurred.{e.message}"
      render :top

    # Invalid parameters were supplied to Stripe's API
    rescue Stripe::InvalidRequestError => e
      flash[:alert] = "An error has occurred (InvalidRequestError)#{e.message}"
      render :top

    # Authentication with Stripe's API failed(maybe you changed API keys recently)
    rescue Stripe::AuthenticationError => e
      flash[:alert] = "An error has occurred (AuthenticationError)#{e.message}"
      render :top

    # Network communication with Stripe failed
    rescue Stripe::APIConnectionError => e
      flash[:alert] = "Error occurred (APIConnectionError)#{e.message}"
      render :top

    # Display a very generic error to the user, and maybe send yourself an email
    rescue Stripe::StripeError => e
      flash[:alert] = "An error has occurred (StripeError)#{e.message}"
      render :top

    #When an error occurs other than stripe related
    rescue => e
      flash[:alert] = "An error has occurred#{e.message}"
      render :top
    end
end

There is no time to explain each one. To put it horribly briefly, Stripe :: Account.create is creating a stripe account. There are various items (name, gender, address, account number, etc.) and I will enter them with the parameters sent in the form I will make. Stripe :: Account.update updates your account. The mechanism is the same

Next, we will create views.

slim:accounts/top.html.slim


- if current_user.uid
  = render "edit"
- else
  = render "new"

This is divided into new creation and update depending on whether or not there is a uid. There seems to be a better way ...

slim:_new.html.slim


= form_with url: accounts_path, local: true do |f|
  = render "form", f:f

slim:_edit.html.slim


= form_with url: update_accounts_path(current_user.uid), local: true, method: :patch  do |f|
   = render "form", f:f

slim:_form.html.slim


  = f.text_field :first_name_kanji, placeholder: "Name (first name / kanji)"
  = f.text_field :last_name_kanji, placeholder: "Name (surname / kanji)"
  = f.text_field :first_name_kana, placeholder: "Name (name / kana)"
  = f.text_field :last_name_kana, placeholder: "Name (surname / kana)"
  = f.label :Birthday
  = f.date_select :day, class: "sign_field", include_blank: true, :start_year => 1900, :end_year => Date.today.year
  = f.label :sex
  = f.select :gender, {"male": "male", "Female": "female"}, include_blank: true
  = f.text_field :state, placeholder: "Prefectures"
  = f.text_field :postal_code, placeholder: "Postal code"
  = f.text_field :city, placeholder: "City / ward / town"
  = f.text_field :town, placeholder: "Chome"
  = f.text_field :line1, placeholder: "address"
  = f.text_field :line2, placeholder: "Building (optional)"
  = f.label :Name (Katakana)
  = f.text_field :account_holder_name, placeholder: "Yamada Taro"
  |Arrange in the order of bank code, branch code
  br
  |Please enter as a 7-character sequence
  = f.number_field :routing_number, placeholder: "1234567"
.sign_plase
  = f.label :account number
  = f.number_field :account_number
.actions
  = f.submit "Save"

Finally, write the route.

routes.rb


get "accounts/top"
resources :accounts, only: [:new, :create, :update, :edit]

This should work ...

At the end

After all custom account is difficult (; ∀;). Since the standard account is easy to implement and easy to lose, if you want to try it, you may try standard account for the time being (I did that too). Even so, I remember having a lot of trouble creating a custom account. I had a hard time wanting to pay only for the custom account creation part of this article. I don't have any information at all. Well, it's okay if this helps someone who is stumbling on stripe account creation.

Also, I don't like or comment on this series at all. If you like it, please LGTM. It will be motivation.

Recommended Posts

Create an EC site using stripe! (Account creation)
Create an EC site with Rails5 ⑤ ~ Customer model ~
Create an EC site with Rails 5 ⑩ ~ Create an order function ~
Create an EC site with Rails5 ⑦ ~ Address, Genre model ~
Create an EC site with Rails 5 ⑨ ~ Create a cart function ~
Create an EC site with Rails5 ④ ~ Header and footer ~
Create an EC site with Rails5 ⑥ ~ seed data input ~
Create an EC site with Rails5 ② ~ Bootstrap4 settings, Controller / action definition ~
Create an app catalog site using CLI for Microsoft 365 with Docker
Create an EC site with Rails5 ③-Set model associations and other things-
Let's make a shopping site using stripe! (Purchase)
Creating an EC site with Rails5 ①-App configuration, various gem preparation, Model / Routing creation-
Deploy laravel using docker on EC2 on AWS ① (Create EC2 instance)
[Docker] Build an Apache container on EC2 using dockerfile