学生向けプログラミング入門 | 無料

学生向けにプログラミングを無料で解説。Java、C++、Ruby、PHP、データベース、Ruby on Rails, Python, Django

Rails7.1 | 民泊予約アプリ作成 | 39 | クレジットカード決済

↓↓クリックして頂けると励みになります。



38 | Stripe Connect】 << 【ホーム】 >> 【40 | 予約確認メール



Stripeの設定を今までやりましたが、実際に登録したクレジットカードで決済できるように実装していきます。


「app\controllers\reservations_controller.rb」ファイルの記述を更新します。


1.6行目の「create()」メソッドの記述を以下のように更新します。

  def create
    room = Room.find(params[:room_id])

    if current_user == room.user
      flash[:alert] = "オーナーが予約することはできません。"
    elsif current_user.stripe_id.blank?
      flash[:alert] = "予約する前にクレジットカードを登録する必要があります。"
      return redirect_to settings_payment_path
    else

        start_date = Date.parse(reservation_params[:start_date])
        end_date = Date.parse(reservation_params[:end_date])
        days = (end_date - start_date).to_i
        if days == 0
          flash[:alert] = "宿泊日数が1泊以上でなければ予約することはできません。"
        else

          @reservation = current_user.reservations.build(reservation_params)
          @reservation.room = room
          @reservation.price = room.price
          @reservation.total = room.price * days
          #@reservation.save

          charge(room, @reservation)
          flash[:notice] = "予約が完了しました。"
        end
      end
      redirect_to room
  end



2.58行目に「charge()」メソッドを追加します。

    def charge(room, reservation)
      host_amount = (reservation.total * 0.8).to_i # 売上の80%がホストに入る
      if !reservation.user.stripe_id.blank?
        customer = Stripe::Customer.retrieve(reservation.user.stripe_id)
        charge = Stripe::Charge.create(
          :customer => customer.id,
          :amount => reservation.total,
          :description => room.listing_name,
          :currency => "jpy",
          transfer_data: {
            amount: host_amount, 
            destination: room.user.merchant_id, # ホストのストライプID
          },
        )
  
        if charge
          flash[:notice] = "お支払い手続きが完了し、ご予約されました。"
        else
          flash[:notice] = "お支払い手続きができません。予約ができませんでした。"
        end
      end
      rescue Stripe::CardError => e
        reservation.declined!
        flash[:alert] = e.message
    end



app\controllers\reservations_controller.rb

class ReservationsController < ApplicationController
    
  before_action :authenticate_user!
  before_action :set_reservation, only: [:approve]

  def create
    room = Room.find(params[:room_id])

    if current_user == room.user
      flash[:alert] = "オーナーが予約することはできません。"
    elsif current_user.stripe_id.blank?
      flash[:alert] = "予約する前にクレジットカードを登録する必要があります。"
      return redirect_to settings_payment_path
    else

        start_date = Date.parse(reservation_params[:start_date])
        end_date = Date.parse(reservation_params[:end_date])
        days = (end_date - start_date).to_i
        if days == 0
          flash[:alert] = "宿泊日数が1泊以上でなければ予約することはできません。"
        else

          @reservation = current_user.reservations.build(reservation_params)
          @reservation.room = room
          @reservation.price = room.price
          @reservation.total = room.price * days
          #@reservation.save

          charge(room, @reservation)
          flash[:notice] = "予約が完了しました。"
        end
      end
      redirect_to room
  end

  def your_trips
    @trips = current_user.reservations.order(start_date: :asc).page(params[:page]).per(5)
  end

  def your_reservations
    @rooms = current_user.rooms
  end

  def approve
    @reservation.Approved!
    redirect_to your_reservations_path
  end    

  private
  def reservation_params
      params.require(:reservation).permit(:start_date, :end_date)
  end
  
  def set_reservation
    @reservation = Reservation.find(params[:id])
  end

  def charge(room, reservation)
    host_amount = (reservation.total * 0.8).to_i # 売上の80%がホストに入る
    if !reservation.user.stripe_id.blank?
      customer = Stripe::Customer.retrieve(reservation.user.stripe_id)
      charge = Stripe::Charge.create(
        :customer => customer.id,
        :amount => reservation.total,
        :description => room.listing_name,
        :currency => "jpy",
        transfer_data: {
          amount: host_amount, 
          destination: room.user.merchant_id, # ホストのストライプID
        },
      )

      if charge
        flash[:notice] = "お支払い手続きが完了し、ご予約されました。"
      else
        flash[:notice] = "お支払い手続きができません。予約ができませんでした。"
      end
    end
    
    rescue Stripe::CardError => e
      reservation.declined!
      flash[:alert] = e.message
  end

end



振込先の登録をしないとお部屋の登録ができないようにします。


記述追加 app\controllers\rooms_controller.rb(19行目)

    if !current_user.is_active_host
      return redirect_to settings_payout_path, alert: "振込口座の登録を先に行ってください。"
    end    



app\controllers\rooms_controller.rb

class RoomsController < ApplicationController

  protect_from_forgery except: [:upload_photo]

  before_action :set_room, except: [:index, :new, :create]
  before_action :authenticate_user!, except: [:show]
  before_action :is_authorised, only: [:listing, :pricing, :photo_upload, :delete_photo, :amenities, :location, :update]

  def index
     @rooms = Room.all
  end

  def new
    @room = current_user.rooms.build
  end

  def create

    if !current_user.is_active_host
      return redirect_to settings_payout_path, alert: "振込口座の登録を先に行ってください。"
    end    
    
    @room = current_user.rooms.build(room_params)
    if @room.save
      redirect_to listing_room_path(@room), notice: "保存しました。"
    else
      flash[:alert] = "問題が発生しました。"
      render :new
    end
  end

  def show
    @photos = @room.photos
    @i = 0
    @guest_reviews = @room.guest_reviews

  end

  def listing
  end

  def pricing
  end

  def description
  end

  def photo_upload
  end

  def amenities
  end

  def location
  end

  def update

    new_params = room_params
    new_params = room_params.merge(active: true) if is_ready_room

    if @room.update(new_params)
      flash[:notice] = "保存しました。"
    else
      flash[:alert] = "問題が発生しました。"
    end
    redirect_back(fallback_location: request.referer)
  end

  def upload_photo
    @room.photos.attach(params[:file])
    render json: { success: true }
  end

  def delete_photo
    @image = ActiveStorage::Attachment.find(params[:photo_id])
    @image.purge
    redirect_to photo_upload_room_path(@room)
  end

  # 予約 開始日のAJAX処理
  def preload
    today = Date.today
    reservations = @room.reservations.where("start_date >= ? OR end_date >= ?", today, today)

    render json: reservations
  end

  # 予約 終了日のAJAX処理
  def preview
    start_date = Date.parse(params[:start_date])
    end_date = Date.parse(params[:end_date])

    output = {
      conflict: is_conflict(start_date, end_date, @room)
    }

    render json: output
  end

  private
  def set_room
    @room = Room.find(params[:id])
  end

  def room_params
    params.require(:room).permit(:home_type, :room_type, :accommodate, :bed_room, :bath_room, :listing_name, :summary, :address, :latitude, :longitude, :is_tv, :is_kitchen, :is_air, :is_heating, :is_internet, :price, :active, :description)
  end

  def is_authorised
    redirect_to root_path, alert: "権限がありません。" unless current_user.id == @room.user_id
  end
  
  def is_ready_room
    !@room.active && !@room.price.blank? && !@room.listing_name.blank? && !@room.photos.blank? && !@room.address.blank?
  end

  # 予約 プライベートメソッド
  def is_conflict(start_date, end_date, room)
    check = room.reservations.where("? < start_date AND end_date < ?", start_date, end_date)
    check.size > 0? true : false
  end

end



先に口座登録していないと部屋を登録することが出来なくなっています。
ブラウザ確認
http://localhost:3000/rooms/new

先に振込口座登録
先に振込口座登録



クレジットカードを登録しないと予約ができないようになっています。

先にクレジットカード登録
先にクレジットカード登録



予約すると登録したクレジットカードで決済されます。

決済完了
決済完了



ストライプでテスト決済が確認できます。
ストライプのダッシュボードページで「payments」を選択し、テスト決済を確認します。

決済確認
決済確認

支払いの詳細をみると売上の80%が送金されるようになっています。

売上の80%を送金
売上の80%を送金



38 | Stripe Connect】 << 【ホーム】 >> 【40 | 予約確認メール




↓↓クリックして頂けると励みになります。

YAE C5 CLINIC(札幌美容クリニック)

関連記事(外部サイト)