前回の記事の続きです。
Payjp(Pay.jp)から既に顧客IDとカードIDを取得済みでの購入を想定しています。
##前提条件
・devise/hamlが導入済みでログインができている
・payjpのアカウントが既に取得できていて、ユーザーとカードの登録が完了しており、cardテーブルに以下の情報が登録されている
user_id ... UserテーブルのID
customer_id ... payjpの顧客ID
card_id ... payjpのデフォルトカードID
顧客IDとデフォルトカードIDは以下の画面で顧客ごとに確認できます。
##1.コントローラーを作成しよう
コントローラとビュー(indexとdone)を作成するため、下記コマンドを実行します。
$ rails g controller buyers index done
コントローラーの中身を編集
class BuyersController < ApplicationController
require 'payjp'#Payjpの読み込み
before_action :set_card, :set_item
def index
if @card.blank?
#登録された情報がない場合にカード登録画面に移動
redirect_to new_card_path
else
Payjp.api_key = Rails.application.credentials[:PAYJP_PRIVATE_KEY]
#保管した顧客IDでpayjpから情報取得
customer = Payjp::Customer.retrieve(@card.customer_id)
#カード情報表示のためインスタンス変数に代入
@default_card_information = customer.cards.retrieve(@card.card_id)
end
end
def pay
Payjp.api_key = Rails.application.credentials[:PAYJP_PRIVATE_KEY]
Payjp::Charge.create(
:amount => @item.price, #支払金額を引っ張ってくる
:customer => @card.customer_id, #顧客ID
:currency => 'jpy', #日本円
)
redirect_to done_item_buyers_path #完了画面に移動
end
def done
end
private
def set_card
@card = Card.find_by(user_id: current_user.id)
end
def set_item
@item = Item.find(params[:item_id])
end
end
set_card , set_itemの記述で、cardとitemの情報をもってきます
今回は、先ほど作成したindexから、form_tag内のaction: 'pay'で、controller内のpayを発動
##2.購入画面と完了画面を作成しよう
購入画面
%h2.buy-content__title
購入内容の確認
.buy-content__item
.buy-content__item__inner
.buy-item-main
.buy-item-image
= image_tag "#{@item.images[0].url}", size: '64x64', class: 'buydetails-contet__image'
.buy-item-detail
.buy-item-name
= @item.name
%p.buy-price
= "¥#{@item.price.to_s}"
%span.shipping-free (税込) 送料込み
.buy-content__item
%form.buy-form
.buy-price-table
.buy-price-table__left
支払金額
.buy-price-table__right
= "¥#{@item.price.to_s}"
.buy-content__user-info
.buy-content__user-info__inner
%h3 支払方法
.user-info-update
= link_to "変更する", "#", calss:"update-btn"
.user-info-text
- if @default_card_information.blank?
%br /
- else
= "**** **** **** " + "#{@default_card_information.last4}"
%br
- 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
%br
.buy-content__user-info
.buy-content__user-info__inner
%h3 配送先
.user-info-update
= link_to "変更する","#", calss:"update-btn"
.user-info-text
〒111-1111
%br
大阪府大阪市北区〇〇1-11
%br
山田太郎
= form_tag(action: :pay, method: :post) do
%button.buy-button{type:"submit"} 購入する
*exp_monthはカードの期限月、exp_yearは期限年、last4はカードの下4桁を取得
PAYJP カードオブジェクト
完了画面
%h1.buy-content__attention
%i.far.fa-clock
発送をお待ちください
%h2.buy-content__attention__title
購入が完了しました
.buy-content__item
.buy-content__item__inner
.buy-item-main
.buy-item-image
= image_tag "#{@item.images[0].url}", size: '64x64', class: 'buydetails-contet__image'
.buy-item-detail
.buy-item-name
= @item.name
%p.buy-price
%span
= "¥#{@item.price.to_s}"
%span
.shipping-free (税込) 送料込み
.buy-content__item
%form.buy-form
.buy-price-table
.buy-price-table__left
支払金額
.buy-price-table__right
= "¥#{@item.price.to_s}"
.buy-content__user-info__submit
= link_to "トップページへ戻る", root_path, class: 'buy-content__user-info__submit__button'
ルーティング設定ですが、商品詳細ページからitem_idを引き継ぎたかったので、下記のようにしました
resources :items do
resources :buyers, only: [:index] do
collection do
get 'done', to: 'buyers#done'
post 'pay', to: 'buyers#pay'
end
end
end
##購入の確認
購入が完了するとPayjpが以下の様に変わります
##参考
https://qiita.com/takachan_coding/items/d21c0d2621368c9b0d9b
https://qiita.com/Ikuy_h/items/7232ba32e0b728ff77aa