5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【フリマアプリ】PAY.JPでのクレジットカード決済機能について(第3回) 〜運用編(購入)〜

Last updated at Posted at 2020-05-05

 某スクールにおいて、チーム開発で、フリーマーケットアプリを作成中であり、使用した技術について公開しています。
※初学者のため、ミスや認識違いが多々あると思いますがご了承ください。

フリマアプリにおいて、PAY.JPを用いたクレジットカード決済機能を実装しました!!

前回記事 

今回の記事は運用編(購入)となります。

それでは、実際にPAY.JPを用いてクレジットカード機能を用いた購入ができるように実装して行きたいと思います。

##カード情報表示

825ca2a1a52d58d1bdafec6ab3d0b05f.png

「購入する」ボタンをクリックしたら、cardsコントローラーのshowアクションに遷移します。

0b757cba1d9c27d344feafefe81b6d41.png

遷移先の「購入確認画面」です。ご覧のように、カードの情報が記載されているため、showコントローラーではユーザーに紐づいたカード情報を取得してくる必要があります。

では、showコントローラーを確認してみます。

cards_controller
class CardsController < ApplicationController
  require 'payjp'

  before_action :set_item, only:[:show,:pay]
  before_action :take_card, only:[:show,:pay]
  before_action :set_api_key

  def show 
      if @card.blank?
        #登録された情報がない場合にカード登録画面に移動
        flash[:alert] = '購入前にカード登録してください'
        redirect_to cards_path and return
      else
        #保管した顧客IDでpayjpから情報取得
        set_customer
        #保管したカードIDでpayjpから情報取得、カード情報表示のためインスタンス変数に代入
        set_card_information
      end
      if current_user.address == nil
          flash[:alert] = '購入前に住所登録してください'
          redirect_to new_address_path
      end
  end

private

  def set_item
    @item = Item.find(params[:id])
    @address = Address.find_by(user_id:current_user.id)
  end

  def set_api_key
    Payjp.api_key = Rails.application.credentials[:payjp][:PAYJP_PRIVATE_KEY]
    binding.pry
  end

  def set_customer
    @customer = Payjp::Customer.retrieve(@card.customer_id)
  end

  def set_card_information
    @card_information = @customer.cards.retrieve(@card.card_id)
  end

  def take_card
    @card = Card.find_by(user_id: current_user.id)
  end
  
end

解説します。
まずは before_action :set_item が実行されます。これは、商品と配送先住所を引っ張ってくるためで、クレジットカード決済とは直接関係はありません。

次に before_action :take_card が実行されます。
cardsテーブルから現在のユーザーに紐づくレコードを変数@cardに格納します。(payjp側に保存してる顧客データーではありません。)

def show 
 if @card.blank?
   #登録された情報がない場合にカード登録画面に移動
    flash[:alert] = '購入前にカード登録してください'
    redirect_to cards_path and return
 else

登録しているカード情報がなければ、カード新規登録画面へ遷移します。
「and return」は直接関係ないので、後ほど番外で説明します。

else
  #保管した顧客IDでpayjpから情報取得
  set_customer
  #保管したカードIDでpayjpから情報取得、カード情報表示のためインスタンス変数に代入
  set_card_information

カードが登録されている場合は、set_customerメソッドが呼び出されます。

 def set_customer
  @customer = Payjp::Customer.retrieve(@card.customer_id)
 end

@cardcustomer_idを元に、Payjpから顧客データーを取得して、変数@customerに格納します。

次に set_card_informationメソッドが呼び出されます。

def set_card_information
 @card_information = @customer.cards.retrieve(@card.card_id)
end

@customerに紐づく、クレジットカード情報を取得して 変数@card_informationに格納します。

これにより、クレジットカードの情報を表示することができます。ちなみに、カード情報を表示するhaml部分は以下の通りです。

-# カード番号
= "**** **** **** " + @card_information.last4
-# 有効期限
 - exp_month = @card_information.exp_month.to_s
 - exp_year = @card_information.exp_year.to_s.slice(2,3)
 = exp_month + " / " + exp_year

Payjp側でlast4というキーに下4桁を格納してくれています。

##クレジットカードを用いて購入する

「購入する」をクリックしたら、cardsコントローラーのpayアクションへと遷移するようにリンクをはっています

cardsコントローラーのpayアクションを見てみます。

cards_controller.rb
class CardsController < ApplicationController
  require 'payjp'

  before_action :set_item, only: [:show,:pay]
  before_action :take_card, only:[:show,:pay]
  before_action :set_api_key
  def pay
    @item.update(buyer_id: current_user.id)
    # 現在のユーザーを購入者に登録
    Payjp::Charge.create(
    :amount => @item.price, 
    :customer => @card.customer_id, 
    :currency => 'jpy', #日本円
   )
    redirect_to item_purchase_index_path(@item.id)
  # 購入確認画面に遷移
  end

private

  def set_item
    @item = Item.find(params[:id])
    @address = Address.find_by(user_id:current_user.id)
  end

  def set_api_key
    Payjp.api_key = Rails.application.credentials[:payjp][:PAYJP_PRIVATE_KEY]
    binding.pry
  end

  def take_card
    @card = Card.find_by(user_id: current_user.id)
  end
  
end

解説します。
before_action :set_item で 購入しようとしているItemが@itemに、ユーザーの配送先が@addressに格納されています。クレジットカード購入機能と直接は関係ありません。

before_action :take_card
before_action :set_api_key
については、showアクションの時と同じです。

def pay
  @item.update(buyer_id: current_user.id)

現在のユーザーを購入者に登録として、buyer_idカラムに格納します。クレジットカード購入機能と直接は関係ありません。

Payjp::Charge.create(
    :amount => @item.price, 
    :customer => @card.customer_id, 
    :currency => 'jpy', #日本円
   )

商品の値段や、@cardに紐づく顧客データーを元に、payjp側で決済してくれます。

無事に決済が完了したら、以下のようにpayjp側に反映されます。

115df87f9fd9a7dc1c048027314869b4.png

以上でクレジットカードを用いた購入機能が実装できました。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?