LoginSignup
7
8

More than 3 years have passed since last update.

[Rails]Pay.jpを利用したクレジット決済機能実装 ③ ~クレジットカード詳細表示・削除~

Last updated at Posted at 2020-04-29

はじめに

例によって、某プログラミングスクールの最終課題である、フリマアプリのクローンサイト作成において、購入機能実装時にPay.jpを利用したので、健忘録としてここに記す。
今回は「クレジットカード詳細表示・削除」の実装に取り掛かります。

バージョン情報

ruby '2.5.1'
Rails '5.2.4.2'

実装の流れ

  1. 実装の準備・APIの導入
  2. モデルの作成・クレジットカード登録
  3. クレジットカード詳細表示・削除 ← 今回の実装内容
  4. クレジットカード購入(決済)機能

前提条件として

今回の実装機能のダイジェスト

クレジットカード詳細表示から削除はこんな感じ

Image from Gyazo

  • クレジットカード詳細表示画面上で、登録クレジット会社のロゴ画像、カード番号末尾4桁、有効期限が表示される。
  • 削除ボタンを押すと、登録情報が削除される

前置きはこれくらいで、いよいよ実装!

いよいよ実装! まずはコントローラーの記載

まずはコントローラーの記載を行います。
詳細表示機能はshowアクションで、削除機能はdestroyアクションで定義します。

controllers/credit_cards_controller.rb
  require "payjp" # PAYJPとやり取りするために、payjpをロード

  def new
    # 前回のnewアクションに追記
    # すでにクレジットカード登録されている場合は、showアクションにリダイレクト
    @card = CreditCard.where(user_id: current_user.id)
    redirect_to credit_card_path(current_user.id) if @card.exists?
  end

  # ここのcreateメソッドは前回と同じ
  def create
    Payjp.api_key = Rails.application.credentials.dig(:payjp, :PAYJP_SECRET_KEY)

    if params["payjp_token"].blank?
      redirect_to action: "new", alert: "クレジットカードを登録できませんでした。"
    else
      customer = Payjp::Customer.create(
        email: current_user.email,
        card: params["payjp_token"],
        metadata: {user_id: current_user.id}
      )
      @card = CreditCard.new(user_id: current_user.id, customer_id: customer.id, card_id: customer.default_card)
      if @card.save
      else
        redirect_to action: "create"
      end
    end
  end

  def show
    # ログイン中のユーザーのクレジットカード登録の有無を判断
    @card = CreditCard.find_by(user_id: current_user.id)
    if @card.blank?
      # 未登録なら新規登録画面に
      redirect_to action: "new" 
    else
      # 前前回credentials.yml.encに記載したAPI秘密鍵を呼び出します。
      Payjp.api_key = Rails.application.credentials.dig(:payjp, :PAYJP_SECRET_KEY)
      # ログインユーザーのクレジットカード情報からPay.jpに登録されているカスタマー情報を引き出す
      customer = Payjp::Customer.retrieve(@card.customer_id)
      # カスタマー情報からカードの情報を引き出す
      @customer_card = customer.cards.retrieve(@card.card_id)

      ##カードのアイコン表示のための定義づけ
      @card_brand = @customer_card.brand
      case @card_brand
      when "Visa"
        # 例えば、Pay.jpからとってきたカード情報の、ブランドが"Visa"だった場合は返り値として
        # (画像として登録されている)Visa.pngを返す
        @card_src = "visa.png"
      when "JCB"
        @card_src = "jcb.png"
      when "MasterCard"
        @card_src = "master.png"
      when "American Express"
        @card_src = "amex.png"
      when "Diners Club"
        @card_src = "diners.png"
      when "Discover"
        @card_src = "discover.png"
      end

      #  viewの記述を簡略化
      ## 有効期限'月'を定義
      @exp_month = @customer_card.exp_month.to_s
      ## 有効期限'年'を定義
      @exp_year = @customer_card.exp_year.to_s.slice(2,3)
    end
  end

  def destroy
    # ログイン中のユーザーのクレジットカード登録の有無を判断
    @card = CreditCard.find_by(user_id: current_user.id)
    if @card.blank?
      # 未登録なら新規登録画面に
      redirect_to action: "new"
    else
      # 前前回credentials.yml.encに記載したAPI秘密鍵を呼び出します。
      Payjp.api_key = Rails.application.credentials.dig(:payjp, :PAYJP_SECRET_KEY)
      # ログインユーザーのクレジットカード情報からPay.jpに登録されているカスタマー情報を引き出す
      customer = Payjp::Customer.retrieve(@card.customer_id)
      # そのカスタマー情報を消す
      customer.delete
      @card.delete
      # 削除が完了しているか判断
      if @card.destroy
      # 削除完了していればdestroyのビューに移行
      # destroyビューを作るのが面倒であれば、flashメッセージを入れてトップページやマイページに飛ばしてもOK

      else
        # 削除されなかった場合flashメッセージを表示させて、showのビューに移行
        redirect_to credit_card_path(current_user.id), alert: "削除できませんでした。"
      end
    end
  end

(例によって、フラッシュメッセージをしれっと入れてます)
参考にした記事: 【Rails】flashメッセージを使用して簡易メッセージを表示させる詳しい方法と解説

変更、追記内容としては

  • newメソッドにクレジットカード登録済みの際にshowアクションに移るように定義
  • (詳細表示機能として)showメソッドの定義。その際に
    • viewで表示するクレジットカードのブランド画像を定義
    • viewで表示するクレジットカード情報の有効期限の年と月を定義
  • (削除機能として)destroyメソッドを定義

です。

ついでにルーティングも設定しておく

config/routes.rb
Rails.application.routes.draw do

# したの方に追記 :show, :destroyを追加で記述
  resources :credit_cards, only: [:new, :create, :show, :destroy] do
  end
end

これでパスが生成されたので、該当リンクに貼り付けます。

続いて、ビューの記載

ちなみに部分テンプレートを使用してます(ファイル名を参照!)。

showビューの記載

views/credit_cards/show/_show.html.haml
.show
  .show__frame
    .show__frame__title
      登録クレジットカード情報
    .credit_card__list
      .credit_card__list__title
        クレジットカード一覧
      .credit_card__list__frame
        .credit_card_info
          .credit_card_info__brand
            # showメソッドで定義した@card_srcを呼び出し
            # 画像をcardsというフォルダを作り、入れておく
            = image_tag "cards/#{@card_src}", class: "credit_card_info__brand__img", alt: @card_brand
          .credit_card_info__numbers
            .number
              # Pay.jpから取得したカード番号の末尾4桁を取得
              = "**** **** **** " + @customer_card.last4
            .expiration_date
              .expiration_date__title
                有効期限
              .expiration_date__info
                # showメソッドで定義した有効期限の年と月を取得
                = @exp_month + " / " + @exp_year
        .destroy__function
          .destroy__function__link
            # 削除ボタンを作成、押すとdestroyメソッドが働くように
            = link_to credit_card_path, method: :delete, class: "destroy__function__link__btn" do 
              削除する
      .payment-details
        = link_to "支払い方法について >", "", class: "payment-details__btn"

(SCSSはお好みで、、、)
表示例としてはこんな感じ
Image from Gyazo

(お好みで実装)destroyビューの記載

views/credit_cards/destroy/_destroy.html.haml
.destoroy
  .destoroy__frame
    .destoroy__frame__message
      削除が完了しました。
    %ul.destoroy__frame__btns
      %li.credit_card_new_link
        = link_to "クレジットカード新規登録", new_credit_card_path, class: "credit_card_new_link__btn"
      %li.my_page_link
        = link_to "マイページに戻る", users_path(current_user.id), class: "my_page_link__btn"

特に言うことはありません、、、、
クレジット新規登録(newアクションへのパス)をつけておけば、編集機能っぽくなるのかな?

表示例としてはこんな感じ
Image from Gyazo

クレジットカード詳細表示・削除機能 実装完了!!

最後に

以上でクレジットカードの詳細表示・削除機能の実装は完成です!
前回の新規登録機能よりかは難易度が下がったのではないでしょうか。

次回は、「クレジットカード購入(決済)機能」の実装を行います。

参考リンク

7
8
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
7
8