9
11

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 5 years have passed since last update.

Pay.jpを用いた購入機能の実装

Posted at

概要

Pay.jpを用いた購入機能の実装を備忘録としてまとめます。
修正点ありましたらご指摘お願いいたします。
Transaction(取り引き)テーブルおよびProduct(商品)テーブルをもとに作っていきます。

前提

  • Pay.jpのアカウント作成済み
  • Pay.jpにてクレジットカード登録機能は実装済み
  • ビューはHamlで記載
  • deviseにてログイン済み

手順

  1. Transactionテーブルを作成(購入済みの場合SOLD OUTを表示させるため)
  2. アソシエーションの設定
  3. Transactionコントローラーを作成
  4. 環境変数の設定
  5. ルーティングの設定
  6. マークアップ:購入内容確認画面
  7. マークアップ:購入完了画面
  8. マークアップ:購入済みの場合SOLD OUTを表示
  9. 購入データの確認

Transactionテーブルを作成

今回は購入済みの場合SOLD OUTを表示させるためにTransactionテーブルを作成します。

$ rails g model Transaction
db/migrate/20200000000000_create_transactions.rb
class CreateTransactions < ActiveRecord::Migration[5.2]
  def change
    create_table :transactions do |t|
      t.references :product, null: false, foreign_key: true
      t.references :user, null: false, foreign_key: true
      t.timestamps
    end
  end
end

マイグレートを実行

$ rails db:migrate

アソシエーションの設定

transaction.rb
class Transaction < ApplicationRecord
  belongs_to :user, optional: true
  belongs_to :product, optional: true
end

Transactionコントローラーを作成

$ rails g controller transactions
transactions_controller.rb
class TransactionsController < ApplicationController
  require 'payjp'
  before_action :set_card, only: [:pay_index, :pay]
  before_action :set_product

  def pay_index
    @top_image = @product.images.first
    @card = @set_card.first
    if @card.blank?
      redirect_to controller: "cards", action: "new"
    else
      Payjp.api_key = ENV["PAYJP_PRIVATE_KEY"]
      customer = Payjp::Customer.retrieve(@card.customer_id)
      @default_card_information = customer.cards.retrieve(@card.card_id)
    end
  end

  def pay
    @card = @set_card.first
    Payjp.api_key = ENV['PAYJP_PRIVATE_KEY']
    Payjp::Charge.create(
    :amount => @product.price,
    :customer => @card.customer_id,
    :currency => 'jpy',
  )
  redirect_to action: 'done', product_id: @product
  end

  def done
    @top_image = @product.images.first
    Transaction.create(product_id: @product.id, user_id: current_user.id)
  end

  private

  def set_card
    @set_card = Card.where(user_id: current_user.id)
  end

  def set_product
    @product = Product.find(params[:product_id])
  end

end

環境変数の設定

コントローラ内のENV["PAYJP_PRIVATE_KEY"]は環境変数でテスト秘密鍵を設定し読み込む。
今回はdotenvとgonを利用する。

dotenv:Railsの環境変数管理
gon:JSにてRailsで定義した環境変数を使用
参考:https://qiita.com/3443/items/44202ff6504210592570#comments

※gonはCard登録機能にて使用したため今回は関係ありません

ルーティングの設定

routes.rb
Rails.application.routes.draw do
  devise_for :users
  root "products#index"
  resources :users, only: [:edit, :update]
  resources :products
  resources :cards, only: [:new, :show, :destroy] do
    collection do
      post 'pay_show', to: 'cards#pay_show'
      post 'pay', to: 'cards#pay'
    end
  end

  ##今回の該当箇所
  resources :transactions, only: [:index] do
    collection do
      get 'pay_index', to: 'transactions#pay_index'
      post 'pay', to: 'transactions#pay'
      get 'done', to: 'transactions#done'
    end
  end

end

マークアップ:購入内容確認画面

Image from Gyazo

pay_index.html.haml
.transaction-pay
  .transaction-pay__content
    %h2.transaction-pay__title 購入内容の確認
    .transaction-pay__item
      .transaction-pay__item-box
        = image_tag @top_image.image.url, alt:"商品画像", class: "transaction-pay__item-image"
      .transaction-pay__item-detail
        %p.transaction-pay__item-detail--name
          = @product.name
        .transaction-pay__item-detail-price
          .transaction-pay__item-detail-price--text.transaction-pay__item-detail-price--text
            = @product.price
          .transaction-pay__item-detail-price--shipping (税込)送料込み
    .transaction-pay__table
      .transaction-pay__table-inner
        .transaction-pay__table-form
          .transaction-pay__table-content
            .transaction-pay__table-pay
              %p.transaction-pay__table-pay--title 支払い金額
            .transaction-pay__table-price
              %p.transaction-pay__table-price--title%p.transaction-pay__table-price--title
                = @product.price
          .transaction-pay__table-way
            %h3 支払い方法
            .transaction-pay__table-register
              - if @default_card_information.blank?
                %i.fas.fa-plus-circle
                %span.icon-register
                = link_to "登録してください", new_card_path
              - else
                = "**** **** **** " + @default_card_information.last4
                - exp_month = @default_card_information.exp_month.to_s
                - exp_year = @default_card_information.exp_year.to_s.slice(2,3)
                = exp_month + " / " + exp_year
          .transaction-pay__table-buy
            = form_tag(action: :pay, method: :post, product_id: @product) do
              %button.transaction-pay__table-buy-button 購入する

マークアップ:購入完了画面

Image from Gyazo

done.html.haml
.transaction-done
  .transaction-done__content
    .transaction-done__text
      購入が完了しました!
    .transaction-done__image
      = image_tag @top_image.image.url, alt:"商品画像", class: "transaction-done__image--img"
    .transaction-done__title
      = @product.name
    .transaction-done__price
      .transaction-done__price--text
        = @product.price
      .transaction-done__price--info
        (送料込み)

マークアップ:購入済みの場合SOLD OUTを表示

Image from Gyazo

show.html.haml
.product-show
  .product-show__main
    .product-show__content
      .product-show__top-content
        .product-show__item-box
          .product-show__item-box--name
            = @product.name
          .product-show__item-box__body
            .product-show__item-box__body--top-img
              = image_tag @top_image.image.url, alt:"トップ画像", class: "product-show__item-top-img"
            .product-show__item-box__body--list
              - @images.each do |image|
                .product-show__item-box__body--sub-img
                  = image_tag image.image.url, alt:"サブ画像", class: "product-show__item-sub-img"
          .product-show__item-box--price
            %span 
            = "#{@product.price}円"
            .product-show__item-box--price-detail
              %span.product-show__item-box--price-detail-text
                (税込)
              %span.product-show__item-box--price-detail-text
                = @product.delivery_charge
          .product-show__item-box--item-detail
            = @product.name
          -# 商品出品者であれば表示させない
          - if user_signed_in? && (current_user.id == @product.user_id)
          - else
            .product-show__transaction
              .product-show__transaction-box
                -# 商品購入済みであればSOLD OUT
                - if @product_id.present?
                  .product-transaction-btn
                    SOLD OUT
                - else
                  = link_to "購入画面に進む", pay_index_transactions_path(product_id: @product), class: "product-transaction-btn"

購入データの確認

購入ができていれば下記のURLにて履歴が確認できます。
https://pay.jp/d/charges

以上です

9
11
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
9
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?