Why
Terminal
% cd ~/projects(as you like)
% rails _6.0.0_ new payjp_practice -d mysql
% cd payjp_practice
% rails db:create
Terminal
% rails g model order
db/migrate/**************_create_orders.rb
class CreateOrders < ActiveRecord::Migration[6.0]
def change
create_table :orders do |t|
t.integer :price ,null: false
t.timestamps
end
end
end
Terminal
% rails db:migrate
app/models/order.rb
class Order < ApplicationRecord
validates :price, presence: true
end
config/routes.rb
Rails.application.routes.draw do
root to: 'orders#index'
resources :orders, only:[:create]
end
Terminal
% rails g controller orders
app/controllers/orders_controller.rb
class OrdersController < ApplicationController
def index
end
def create
end
end
java:app/views/orders/index.html.erb
<%= form_with model: @order, id: 'charge-form', class: 'card-form',local: true do |f| %>
<div class='form-wrap'>
<%= f.label :price, "Amount of money" %>
<%= f.text_field :price, class:"price", placeholder:"Example)2000" %>
</div>
<%= f.submit "Purchase" ,class:"button" %>
<% end %>
app/assets/stylesheets/style.css
.card-form{
width: 500px;
}
.form-wrap{
display: flex;
flex-direction: column;
}
.exp_month{
resize:none;
}
.exp_year{
resize:none;
}
.input-expiration-date-wrap{
display: flex;
}
.button{
margin-top: 30px;
height: 30px;
width: 100px;
}
app/controllers/orders_controller.rb
class OrdersController < ApplicationController
def index
@order = Order.new
end
def create
@order = Order.new(order_params)
if @order.valid?
@order.save
return redirect_to root_path
else
render 'index'
end
end
private
def order_params
params.require(:order).permit(:price)
end
end
java:app/views/orders/index.html.erb
<%= form_with model: @order, id: 'charge-form', class: 'card-form',local: true do |f| %>
<%= render 'layouts/error_messages', model: @order %>
<div class='form-wrap'>
<%#abridgement%>
java:app/views/orders/index.html.erb
<%= form_with model: @order, id: 'charge-form', class: 'card-form',local: true do |f| %>
<%= render 'layouts/error_messages', model: @order %>
<div class='form-wrap'>
<%= f.label :price, "Amount of money" %>
<%= f.text_field :price, class:"price", placeholder:"Example)2000" %>
</div>
<div class='form-wrap'>
<%= f.label :number, "card number" %>
<%= f.text_field :number, class:"number", placeholder:"card number(Half-width alphanumeric characters)", maxlength:"16" %>
</div>
<div class='form-wrap'>
<%= f.label :cvc ,"CVC" %>
<%= f.text_field :cvc, class:"cvc", placeholder:"4-digit or 3-digit number on the back of the card", maxlength:"3" %>
</div>
<div class='form-wrap'>
<p>expiration date</p>
<div class='input-expiration-date-wrap'>
<%= f.text_field :exp_month, class:"exp_month", placeholder:"Example)3" %>
<p>Month</p>
<%= f.text_field :exp_year, class:"exp_year", placeholder:"Example)24" %>
<p>Year</p>
</div>
</div>
<%= f.submit "Purchase" ,class:"button" %>
<% end %>
java:app/views/layouts/application.html.erb
<%#abridgement%>
<%= stylesheet_link_tag 'application', media: 'all' %>
<%= javascript_pack_tag 'application' %>
<%#abridgement%>
app/javascript/packs/application.js
//abridgement
require("@rails/ujs").start()
// require("turbolinks").start() //Comment out
require("@rails/activestorage").start()
require("channels")
//abridgement
java:app/views/layouts/application.html.erb
<%#abridgement%>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<script type="text/javascript" src="https://js.pay.jp/v1/"></script>
<%= stylesheet_link_tag 'application', media: 'all' %>
<%= javascript_pack_tag 'application' %>
<%#abridgement%>
app/javascript/packs/application.js
//abridgement
require("@rails/ujs").start()
// require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
require("../card")
//abridgement
app/javascript/card.js
const pay = () => {
const form = document.getElementById("charge-form");
form.addEventListener("submit", (e) => {
e.preventDefault();
console.log("Event fired when submitting form")
});
};
window.addEventListener("load", pay);
app/javascript/card.js
const pay = () => {
Payjp.setPublicKey("pk_test_******************"); // PAY.JP test public key
const form = document.getElementById("charge-form");
form.addEventListener("submit", (e) => {
e.preventDefault();
console.log("Event fired when submitting form")
});
};
window.addEventListener("load", pay);
app/javascript/card.js
const pay = () => {
Payjp.setPublicKey("pk_test_******************"); // PAY.JP test public key
const form = document.getElementById("charge-form");
form.addEventListener("submit", (e) => {
e.preventDefault();
const formResult = document.getElementById("charge-form");
const formData = new FormData(formResult);
const card = {
number: formData.get("order[number]"),
cvc: formData.get("order[cvc]"),
exp_month: formData.get("order[exp_month]"),
exp_year: `20${formData.get("order[exp_year]")}`,
};
});
};
window.addEventListener("load", pay);
app/javascript/card.js
const pay = () => {
Payjp.setPublicKey("pk_test_******************"); // PAY.JP test public key
const form = document.getElementById("charge-form");
form.addEventListener("submit", (e) => {
e.preventDefault();
const formResult = document.getElementById("charge-form");
const formData = new FormData(formResult);
const card = {
number: formData.get("order[number]"),
cvc: formData.get("order[cvc]"),
exp_month: formData.get("order[exp_month]"),
exp_year: `20${formData.get("order[exp_year]")}`,
};
Payjp.createToken(card, (status, response) => {
if (status == 200) {
const token = response.id;
console.log(token)
}
});
});
};
window.addEventListener("load", pay);
Card number 4242424242424242 (16 digits) CVC 123 Expiration date Future from registration (04/25, etc.)
app/javascript/card.js
const pay = () => {
Payjp.setPublicKey("pk_test_******************"); // PAY.JP test public key
const form = document.getElementById("charge-form");
form.addEventListener("submit", (e) => {
e.preventDefault();
const formResult = document.getElementById("charge-form");
const formData = new FormData(formResult);
const card = {
number: formData.get("order[number]"),
cvc: formData.get("order[cvc]"),
exp_month: formData.get("order[exp_month]"),
exp_year: `20${formData.get("order[exp_year]")}`,
};
Payjp.createToken(card, (status, response) => {
if (status == 200) {
const token = response.id;
const renderDom = document.getElementById("charge-form");
const tokenObj = `<input value=${token} name='token'>`;
renderDom.insertAdjacentHTML("beforeend", tokenObj);
debugger;
}
});
});
};
window.addEventListener("load", pay);
app/javascript/card.js
const pay = () => {
Payjp.setPublicKey("pk_test_******************"); // PAY.JP test public key
const form = document.getElementById("charge-form");
form.addEventListener("submit", (e) => {
e.preventDefault();
const formResult = document.getElementById("charge-form");
const formData = new FormData(formResult);
const card = {
number: formData.get("order[number]"),
cvc: formData.get("order[cvc]"),
exp_month: formData.get("order[exp_month]"),
exp_year: `20${formData.get("order[exp_year]")}`,
};
Payjp.createToken(card, (status, response) => {
if (status == 200) {
const token = response.id;
const renderDom = document.getElementById("charge-form");
const tokenObj = `<input value=${token} name='token' type="hidden"> `;
renderDom.insertAdjacentHTML("beforeend", tokenObj);
debugger;
}
});
});
};
window.addEventListener("load", pay);
app/javascript/card.js
const pay = () => {
Payjp.setPublicKey("pk_test_******************"); // PAY.JP test public key
const form = document.getElementById("charge-form");
form.addEventListener("submit", (e) => {
e.preventDefault();
const formResult = document.getElementById("charge-form");
const formData = new FormData(formResult);
const card = {
number: formData.get("order[number]"),
cvc: formData.get("order[cvc]"),
exp_month: formData.get("order[exp_month]"),
exp_year: `20${formData.get("order[exp_year]")}`,
};
Payjp.createToken(card, (status, response) => {
if (status == 200) {
const token = response.id;
const renderDom = document.getElementById("charge-form");
const tokenObj = `<input value=${token} name='token' type="hidden"> `;
renderDom.insertAdjacentHTML("beforeend", tokenObj);
}
document.getElementById("order_number").removeAttribute("name");
document.getElementById("order_cvc").removeAttribute("name");
document.getElementById("order_exp_month").removeAttribute("name");
document.getElementById("order_exp_year").removeAttribute("name");
});
});
};
window.addEventListener("load", pay);
app/javascript/card.js
const pay = () => {
Payjp.setPublicKey("pk_test_******************"); // PAY.JP test public key
const form = document.getElementById("charge-form");
form.addEventListener("submit", (e) => {
e.preventDefault();
const formResult = document.getElementById("charge-form");
const formData = new FormData(formResult);
const card = {
number: formData.get("order[number]"),
cvc: formData.get("order[cvc]"),
exp_month: formData.get("order[exp_month]"),
exp_year: `20${formData.get("order[exp_year]")}`,
};
Payjp.createToken(card, (status, response) => {
if (status == 200) {
const token = response.id;
const renderDom = document.getElementById("charge-form");
const tokenObj = `<input value=${token} name='token' type="hidden"> `;
renderDom.insertAdjacentHTML("beforeend", tokenObj);
}
document.getElementById("order_number").removeAttribute("name");
document.getElementById("order_cvc").removeAttribute("name");
document.getElementById("order_exp_month").removeAttribute("name");
document.getElementById("order_exp_year").removeAttribute("name");
document.getElementById("charge-form").submit();
});
});
};
window.addEventListener("load", pay);
app/controllers/orders_controller.rb
#abridgement
private
def order_params
params.require(:order).permit(:price).merge(token: params[:token])
end
end
app/models/order.rb
class Order < ApplicationRecord
attr_accessor :token
validates :price, presence: true
end
Gemfile
#abridgement
gem 'payjp'
app/controllers/orders_controller.rb
class OrdersController < ApplicationController
def index
@order = Order.new
end
def create
@order = Order.new(order_params)
if @order.valid?
pay_item
@order.save
return redirect_to root_path
else
render 'index'
end
end
private
def order_params
params.require(:order).permit(:price).merge(token: params[:token])
end
def pay_item
Payjp.api_key = "sk_test_***********" #Own PAY.Write the JP test private key
Payjp::Charge.create(
amount: order_params[:price], #Product price
card: order_params[:token], #Card token
currency: 'jpy' #Currency type (Japanese Yen)
)
end
end
app/models/order.rb
class Order < ApplicationRecord
attr_accessor :token
validates :price, presence: true
validates :token, presence: true
end
Terminal
% vim ~/.zshrc
#Press i to switch to insert mode and add the following. Do not delete the existing description.
export PAYJP_SECRET_KEY='sk_test_************'
export PAYJP_PUBLIC_KEY='pk_test_************'
#After editing, press the esc key:Type wq to save and exit
Terminal
#Edited.Reload zshrc to use the added environment variables
% source ~/.zshrc
app/controllers/orders_controller.rb
#abridgement
def pay_item
Payjp.api_key = ENV["PAYJP_SECRET_KEY"]
Payjp::Charge.create(
amount: order_params[:price],
card: order_params[:token],
currency:'jpy'
)
end
Terminal
% touch config/initializers/webpacker.rb
config/initializers/webpacker.rb
Webpacker::Compiler.env["PAYJP_PUBLIC_KEY"] = ENV["PAYJP_PUBLIC_KEY"]
app/javascript/card.js
const pay = () => {
Payjp.setPublicKey(process.env.PAYJP_PUBLIC_KEY);
//abridgement
Recommended Posts