#はじめに
今回 gem payjp
を使用しクレジットカードの登録・削除機能を実装したので
備忘録として書きます
#バージョン情報
ruby '2.5.1'
rails '5.2.4'
mysql2 '5.6系'
#導入済みのgem
gem haml-rails
gem devise
#PAY.JPとは
PAY.JPの重要な機能であるカード情報のトークン化、支払い処理、定期課金を簡単に実装ができる凄い子なのです
※クレジットカード情報を保存する事は禁止されているため
payjpがトークン化(暗号化)してこちらのmysqlに返して保存できるようにしてくれます
今回下記流れを頭に入れておくと実装しやすいかも!
❶フォームにカード情報を入力し送信
❷入力されたカード情報は直接PAY.JPサーバーへ送られ、PAY.JPは一意のトークンを返す
❸サーバーサイドでトークンを受け取り、トークンを使った各種処理を行う(支払い処理、顧客へカードを紐付ける)
#1.PAY.JPへ登録を行う
https://pay.jp/
#APIの確認
今回はテスト秘密鍵とテスト公開鍵を使用します
#payjpのgemを導入
gem payjp
bundle install をお忘れなく
$ bundle install
#payjp.のjsを読み込めるようにする
%script{src: "https://js.pay.jp/", type: "text/javascript"}
を下記のように入れてください
!!!
%html
%head
%meta{content: "text/html; charset=UTF-8", "http-equiv": "Content-Type"}/
%title test
%script{src: "https://js.pay.jp/", type: "text/javascript"}
= csrf_meta_tags
= csp_meta_tag
= stylesheet_link_tag 'application', media: 'all'
= javascript_include_tag 'application'
%body
= yield
#テーブルを作成
rails g model Card user_id:integer customer_id:string card_id:string
テーブルは下記になります
class CreateCards < ActiveRecord::Migration[5.2]
def change
create_table :cards do |t|
t.integer :user_id, null: false
t.string :customer_id, null: false
t.string :card_id, null: false
t.timestamps
end
end
end
マイグレーションをお忘れなく
$ rails db:migrate
#環境変数を設定
テスト秘密鍵とテスト公開鍵を入れます
$ vim ~/.bash_profile
i
で入力できるようにして
自身のテスト秘密鍵とテスト公開鍵を入れてください
export PAYJP_PRIVATE_KEY='sk_test_*****************'
export PAYJP_KEY='pk_test_*****************'
入力できたら esc
⇨ :wp
⇨ ENTER
で保存
最後に環境変数を記述したら必ず下記のコマンドで設定を有効する
$ source ~/.bash_profile
設定できているかは
$printenv
にて確認
PAYJP_PRIVATE_KEY='sk_test_*****************'
PAYJP_KEY='pk_test_*****************'
が入っていればOK!
#環境変数の使用方法
ENV['PAYJP_PRIVATE_KEY']
ENV['PAYJP_KEY']
上記の表示で環境変数として使用ができます!
#routesの設定
resources :cards,only:[:index,:new,:show]do
collection do
#payjpでトークン化を行う
post 'pay', to: 'cards#pay'
#カード削除
post 'delete', to: 'cards#delete'
#カード情報入力
post 'show', to: 'cards#show'
end
end
#Payjpのjavascripts を設定
app/asstes/javascriptsにpay.js
のファイルを作成してください
document.addEventListener(
"DOMContentLoaded", e => {
if (document.getElementById("token_submit") != null) { //token_submitというidがnullの場合、下記コードを実行しない
Payjp.setPublicKey("pk_test_4842a1069943b3e72c287e0b"); //ここに公開鍵を直書き
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
);
#コントローラーを作成
$ rails g controller cards new show
class CardsController < ApplicationController
require "payjp"
def new
#current_user.idでログインしてるユーザーのみ登録ができるようにしてます
card = Card.where(user_id: current_user.id)
#カード登録がまだならshowページへ飛ぶ
redirect_to action: "show" if card.exists?
end
def pay #payjpとCardのデータベース作成
Payjp.api_key = ENV["PAYJP_PRIVATE_KEY"]
if params['payjp-token'].blank?
# paramsの中にjsで作った'payjpTokenが存在するか確かめる
redirect_to action: "new"
else
customer = Payjp::Customer.create(
description: '登録テスト', #なくてもOK
email: current_user.email, #なくてもOK
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"
flash[:notice] = 'クレジットカードの登録が完了しました'
else
redirect_to action: "pay"
flash[:alert] = 'クレジットカード登録に失敗しました'
end
end
end
def delete #PayjpとCardデータベースを削除
card = Card.where(user_id: current_user.id).first
if card.blank?
else
Payjp.api_key = ENV["PAYJP_PRIVATE_KEY"]
customer = Payjp::Customer.retrieve(card.customer_id)
customer.delete
card.delete
end
redirect_to action: "new"
end
def show #Cardのデータpayjpに送り情報を取り出す
card = Card.where(user_id: current_user.id).first
if card.blank?
redirect_to 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
end
#カードの登録画面を作成
.form-wapper
= form_tag(pay_cards_path, method: :post, id: 'charge-form', name: "inputForm") do
.signup-content_text
.form-group.form-group_text
%label.form-group_label カード番号
%span.essential 必須
= text_field_tag "number", "", class: "number", placeholder: "半角数字のみ" ,maxlength: "16", type: "text", id: "card_number"
.form-group.form-group_text.card_label
%label.form-group_label 有効期限
%span.essential 必須
.form-group
.form-flex#form-flex
.birth-group
%select#exp_month{name: "exp_month", type: "text", class: "select-default"}
%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.fa.fa-chevron-down
%span.birth-group__month 月
.birth-group
%select#exp_year{name: "exp_year", type: "text", class: "select-default2"}
%option{value: ""} --
%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
%option{value: "2030"}30
%i.fa.fa-chevron-down.down
%span.birth-group__year 年
.form-group.form-group_text.card_code
%label.form-group_label セキュリティコード
%span.essential3 必須
= text_field_tag "cvc", "", class: "cvc", placeholder: "カード背面3~4桁の番号", maxlength: "4", id: "cvc"
#card_token
.form-group
= submit_tag "追加する", id: "token_submit"
#カード削除画面を作成
.card-group
.card-group__title
%label クレジットカード一覧
%br
= "**** **** **** " + @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
= form_tag(delete_cards_path, method: :post, id: 'charge-form', name: "inputForm") do
%input{ type: "hidden", name: "card_id", value: "" }
%button.btn_delate 削除する
#カード登録ができる確認
http://localhost:3000/card/new にアクセスして登録できるか確認してください
※このときテストカードを使用して登録をしてください!
ができていれば成功です!!!
#もし下記エラーが起きたら
400 Bad Request=不正なパラメーターなどのリクエストエラー
もしくは
Invalid email address provided=(無効なメールアドレスが提供されました)
と出た場合は
a@gmail.com / b@yahoo.co.jp で試してみたら解決します
アドレス a@a などのアドレスが無効と返されているみたいです