#Payjpとは
シンプルなAPIでクレジットカード決済機能を導入出来る、クレジット決済代行サービスです。
ApplePayに対応していたり、cronを使わず定期課金を組み込むことができたりと便利です!
#実装手順
1.Payjpに登録する。
2.登録後、画面左側にある、「API」をクリックします。テスト用、本番用の鍵が表示されますので本番用のキーを使用します。(テスト環境等ではテスト用を使いましょう)
3.Gemfileに以下を記述する。
Gemfile.
gem 'payjp'
忘れず実行する。
$ bundle install
4.Pay.jpの公式のjavascriptを読み込ませられるようする
application.html.haml
%script{src: "https://js.pay.jp/", type: "text/javascript"}
5.cardsテーブルを作成する
20××××××××××.rb
class CreateCards < ActiveRecord::Migration[5.2]
def change
create_table :cards do |t|
t.references :user ,foreign_key: true, null: false # ログインユーザー
t.string :customer_id, null: false # 顧客ID情報(pay.jpから返ってくるデータ)
t.string :card_id, null: false # カードID情報(pay.jpから返ってくるデータ)
t.timestamps
end
end
end
忘れず実行する。
$ rails db:migrate
6.クレジットカード情報の追加と削除のコントローラを作成する
$ rails g controller cards
コントローラー内は以下を記述する。
app/controllers/cards_controller.rb
class CardController < ApplicationController
before_action :get_user_params, only: [:edit, :confirmation, :show]
before_action :get_payjp_info, only: [:new_create, :create, :delete, :show]
def edit
end
def create
if params['payjp-token'].blank?
redirect_to action: "edit", id: current_user.id
else
customer = Payjp::Customer.create(
email: current_user.email,
card: params['payjp-token'],
metadata: {user_id: current_user.id}
)
@card = Card.new(user_id: current_user.id, customer_id: customer.id, card_id: customer.default_card)
if @card.save
redirect_to action: "show"
else
redirect_to action: "edit", id: current_user.id
end
end
end
def delete
card = current_user.cards.first
if card.present?
customer = Payjp::Customer.retrieve(card.customer_id)
customer.delete
card.delete
end
redirect_to action: "confirmation", id: current_user.id
end
def show
card = current_user.cards.first
if card.present?
customer = Payjp::Customer.retrieve(card.customer_id)
@default_card_information = customer.cards.retrieve(card.card_id)
else
redirect_to action: "confirmation", id: current_user.id
end
end
def confirmation
card = current_user.cards
redirect_to action: "show" if card.exists?
end
private
def get_payjp_info
if Rails.env == 'development'
Payjp.api_key = ENV["PAYJP_PRIVATE_KEY"]
else
Payjp.api_key = Rails.application.credentials.payjp[:PAYJP_PRIVATE_KEY]
end
end
end
7.クレジット情報の、確認と削除、追加のフォームを作成する
####confirmation
クレジットカードを追加するか選択する画面
confirmation.html.haml
.main__content
%section.chapter__container
%h2.chapter__head 支払い方法
.payment__main
.payment__list
.payment__list__content
%h3.sub__head クレジットカード一覧
.add__card
.payment__list__content
= link_to edit_card_path(current_user), class: "red__btn", data: {"turbolinks" => false} do
%i
= icon('fas', 'credit-card', class: "card__icon")
クレジットカードを追加する
.not__regist
%span 支払い方法について
####edit
クレジットカードの新規登録画面
edit.html.haml
.main__content
%section.chapter__container
%h2.chapter__head クレジットカード情報入力
= form_tag('/card', method: :post, action: "create", id: 'charge-form', name: "inputForm", class: "chapter__container__inner") do
.form__main__container
.form__content
%label.payment__card カード番号
%span.require__form 必須
= text_field_tag "number", "", class: "number input__deafult", placeholder: "半角数字のみ" ,maxlength: "16", type: "text", id: "card_number"
.card__list
.card__list__picture
.form__content.top__margin
%label.payment__card 有効期限
%span.require__form 必須
.select__box.top__margin
.select__box__half
%select.select__default#exp_month{name: "exp_month", type: "text"}
%option{value: ""} --
%option{value: "1"}01
%option{value: "2"}02
%option{value: "3"}03
%option{value: "4"}04
%option{value: "5"}05
%option{value: "6"}06
%option{value: "7"}07
%option{value: "8"}08
%option{value: "9"}09
%option{value: "10"}10
%option{value: "11"}11
%option{value: "12"}12
%i
= icon('fas', 'chevron-down')
%span 月
.select__box__half
.icon
%select.select__default#exp_year{name: "exp_year", type: "text"}
%option{value: ""} --
%option{value: "2019"}19
%option{value: "2020"}20
%option{value: "2021"}21
%option{value: "2022"}22
%option{value: "2023"}23
%option{value: "2024"}24
%option{value: "2025"}25
%option{value: "2026"}26
%option{value: "2027"}27
%option{value: "2028"}28
%option{value: "2029"}29
%i
= icon('fas', 'chevron-down')
%span 年
.form__content.top__margin
%label セキュリティーコード
%span.require__form 必須
= text_field_tag "cvc", "", class: "cvc", placeholder: "カード背面4桁もしくは3桁の番号", maxlength: "4", id: "cvc"
.single__code
.single__code__text
%span.form__question ?
%span カードの裏面の番号とは?
#card_token
= submit_tag "追加する", id: "token_submit", class: "top__margin"
####show
DBのCard情報を、payjpに送りcustomer情報を取り出す
show.html.haml
.main__content
%section.chapter__container
%h2.chapter__head 支払い方法
.payment__main
.payment__list
.payment__list__content
%h3.sub__head クレジットカード一覧
.card__payment__list
%form.card__payment__content
.card__list
.card__list__picture
.card__number
= "**** **** **** " + @default_card_information.last4
.expire__date
- 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
= form_tag(delete_credit_card_index_path, method: :post, id: 'charge-form', name: "inputForm") do
%input{ type: "hidden", name: "card_id", value: "" }
%button.delete__button 削除する
.how__not__regist
%span 支払い方法について
8.payjpにデータを送るため、入力されたクレジット情報を参考にし、トークンを作成する
payjp.js
document.addEventListener(
"DOMContentLoaded", e => {
if (document.getElementById("token_submit") != null) { //token_submitというidがnullの場合、下記コードを実行しない
Payjp.setPublicKey("ここに公開鍵を書く");
let btn = document.getElementById("token_submit"); //IDがtoken_submitの場合に取得されます
btn.addEventListener("click", e => { //ボタンが押されたときに作動します
e.preventDefault(); //ボタンを一旦無効化します
let card = {
number: document.getElementById("card_number").value,
cvc: document.getElementById("cvc").value,
exp_month: document.getElementById("exp_month").value,
exp_year: document.getElementById("exp_year").value
}; //入力されたデータを取得します。
Payjp.createToken(card, (status, response) => {
if (status === 200) { //成功した場合
$("#card_number").removeAttr("name");
$("#cvc").removeAttr("name");
$("#exp_month").removeAttr("name");
$("#exp_year").removeAttr("name"); //データを自サーバにpostしないように削除
$("#card_token").append(
$('<input type="hidden" name="payjp-token">').val(response.id)
); //取得したトークンを送信できる状態にします
document.inputForm.submit();
alert("登録が完了しました"); //確認用
} else {
alert("カード情報が正しくありません。"); //確認用
}
});
});
}
},
false
);
9.最後にルーティングを設定する
routes.rb
resources :_card, only: [:create, :show, :edit] do
collection do
post 'delete', to: 'card#delete'
post 'show'
end
member do
get 'confirmation'
end
end