[JAVA] Introduction de pay.jp

Comment installer Pay.jp

Il s'agit d'un service d'agence de paiement par carte de crédit et peut être introduit avec une simple API ouverte.

Why

La quantité de code est très petite, et vous pouvez facilement soumettre un formulaire avec Javascript, donc je vais le présenter (je l'omettrai)

Créer une application

Terminal


% cd ~/projects(comme vous voulez)
% rails _6.0.0_ new payjp_practice -d mysql
% cd payjp_practice
% rails db:create

Création de modèle de commande

Terminal


% rails g model order

Créer une table de commandes

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

N'oubliez pas!

Terminal


% rails db:migrate

Validation

app/models/order.rb


class Order < ApplicationRecord
  validates :price, presence: true
end

routage

config/routes.rb


Rails.application.routes.draw do
  root to: 'orders#index'
  resources :orders, only:[:create]
end

contrôleur des commandes

Terminal


% rails g controller orders

app/controllers/orders_controller.rb


class OrdersController < ApplicationController

  def index
  end

  def create
  end

end

Créer une vue

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, "Somme d'argent" %>
    <%= f.text_field :price, class:"price", placeholder:"Exemple)2000" %>
  </div>
  <%= f.submit "achat" ,class:"button" %>
<% end %>

Description CSS

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;
}

Édition du contrôleur

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

Modèle partiel

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'>
<%#réduction%>

Voir la description

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, "Somme d'argent" %>
    <%= f.text_field :price, class:"price", placeholder:"Exemple)2000" %>
  </div>
  <div class='form-wrap'>
    <%= f.label :number,  "numéro de carte" %>
    <%= f.text_field :number, class:"number", placeholder:"numéro de carte(Caractères alphanumériques demi-largeur)", maxlength:"16" %>
  </div>
  <div class='form-wrap'>
    <%= f.label :cvc ,"CVC" %>
    <%= f.text_field :cvc, class:"cvc", placeholder:"Numéro à 4 ou 3 chiffres au dos de la carte", maxlength:"3" %>
  </div>
  <div class='form-wrap'>
    <p>date d'expiration</p>
    <div class='input-expiration-date-wrap'>
      <%= f.text_field :exp_month, class:"exp_month", placeholder:"Exemple)3" %>
      <p>Mois</p>
      <%= f.text_field :exp_year, class:"exp_year", placeholder:"Exemple)24" %>
      <p>Année</p>
    </div>
  </div>
  <%= f.submit "achat" ,class:"button" %>
<% end %>

supprimer les turbolinks et ajouter du code

java:app/views/layouts/application.html.erb


<%#réduction%>
    <%= stylesheet_link_tag 'application', media: 'all'  %>
    <%= javascript_pack_tag 'application' %>
<%#réduction%>

app/javascript/packs/application.js


//réduction
require("@rails/ujs").start()
// require("turbolinks").start() //Commenter
require("@rails/activestorage").start()
require("channels")
//réduction

Lire payjp.js

java:app/views/layouts/application.html.erb


<%#réduction%>
    <%= 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' %>
<%#réduction%>

Prêt à tokeniser

app/javascript/packs/application.js


//réduction
require("@rails/ujs").start()
// require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
require("../card")
//réduction

Tir d'événement

app/javascript/card.js


const pay = () => {
  const form = document.getElementById("charge-form");
  form.addEventListener("submit", (e) => {
    e.preventDefault();
    console.log("Événement déclenché lors de la soumission du formulaire")
  });
};

window.addEventListener("load", pay);

Paramètre de clé publique

app/javascript/card.js


const pay = () => {
  Payjp.setPublicKey("pk_test_******************"); // PAY.Clé publique de test JP
  const form = document.getElementById("charge-form");
  form.addEventListener("submit", (e) => {
    e.preventDefault();
    console.log("Événement déclenché lors de la soumission du formulaire")
  });
};

window.addEventListener("load", pay);

Obtenir des informations sur le formulaire

app/javascript/card.js


const pay = () => {
  Payjp.setPublicKey("pk_test_******************"); // PAY.Clé publique de test JP
  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);

Tokenisation des informations de la carte

app/javascript/card.js


const pay = () => {
  Payjp.setPublicKey("pk_test_******************"); // PAY.Clé publique de test JP
  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);

Vérifions en saisissant une fois les informations de la carte de test préparées par pay.jp!

Numéro de carte 4242424242424242 (16 chiffres) CVC 123 Date d'expiration Futur à partir de l'enregistrement (25/04, etc.)

Inclure la valeur du jeton dans le formulaire

app/javascript/card.js


const pay = () => {
  Payjp.setPublicKey("pk_test_******************"); // PAY.Clé publique de test JP
  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);

Masquer la valeur du jeton

app/javascript/card.js


const pay = () => {
  Payjp.setPublicKey("pk_test_******************"); // PAY.Clé publique de test JP
  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);

Supprimer les informations de carte de crédit

app/javascript/card.js


const pay = () => {
  Payjp.setPublicKey("pk_test_******************"); // PAY.Clé publique de test JP
  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);

Soumettez les informations du formulaire côté serveur

app/javascript/card.js


const pay = () => {
  Payjp.setPublicKey("pk_test_******************"); // PAY.Clé publique de test JP
  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);

Édition de paramètres solide

app/controllers/orders_controller.rb


#réduction

  private

  def order_params
    params.require(:order).permit(:price).merge(token: params[:token])
  end

end

Ajouté au modèle de commande

app/models/order.rb


class Order < ApplicationRecord
  attr_accessor :token
  validates :price, presence: true
end

Présentation de Gem

Gemfile


#réduction
gem 'payjp'

Description du traitement des paiements et refactoring

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_***********"  #Propre PAYE.Ecrire la clé privée du test JP
    Payjp::Charge.create(
      amount: order_params[:price],  #Prix du produit
      card: order_params[:token],    #Jeton de carte
      currency: 'jpy'                 #Type de devise (yen japonais)
    )
  end

end

Validation

app/models/order.rb


class Order < ApplicationRecord
  attr_accessor :token
  validates :price, presence: true
  validates :token, presence: true
end

Variables d'environnement (pour Mac Catalina et versions ultérieures)

Terminal


% vim ~/.zshrc
#Appuyez sur i pour passer en mode insertion et ajoutez ce qui suit. Ne supprimez pas la description existante.
export PAYJP_SECRET_KEY='sk_test_************'
export PAYJP_PUBLIC_KEY='pk_test_************'
#Après l'édition, appuyez sur la touche esc:Tapez wq pour enregistrer et quitter

Terminal


#Édité.Rechargez zshrc pour utiliser les variables d'environnement ajoutées
% source ~/.zshrc

Invitation des variables d'environnement affectées à la clé privée

app/controllers/orders_controller.rb


#réduction
def pay_item
   Payjp.api_key = ENV["PAYJP_SECRET_KEY"]
   Payjp::Charge.create(
     amount: order_params[:price],
     card: order_params[:token],
     currency:'jpy'
   )
end

Appel de variables d'environnement avec JavaScript

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);
  //réduction

Résumé

Même si c'était facile, il y a peut-être eu beaucoup de descriptions. Cependant, comme il s'agit d'une fonction de paiement relativement simple introduite dans l'API, il peut être bon de la supprimer. Dans la plupart des cas, vous ajouterez des colonnes, etc. dans l'original, il est donc recommandé d'écrire lentement dans l'ordre! c'est tout!

Recommended Posts

Introduction de pay.jp
[Rails] Présentation de PAY.JP
Introduction de milkode
Introduction de Docker - Partie 1--
Introduction de l'authentification des utilisateurs
[Rails] Introduction aux principes de base du dispositif
[Docker] Introduction de l'instruction de base de Docker
[Rails] Introduction de Rubocop par les débutants
De l'introduction à l'utilisation de byebug
Lombok ① Introduction
Introduction (auto-introduction)
[Session d'étude interne] Introduction du "Code lisible"
Production d'applications personnelles 2 Introduction de la police WEB
Introduction de Docker Hub et des commandes Auto-apprentissage ①
Introduction du guide de programmation Java de nouvelle génération (Java 10)
Sortie du livre "Introduction à Java"
[Java] Introduction
Introduction et précautions de Gem Friendly Id
12 du tableau
Introduction (édition)
Introduction de l'environnement de développement de l'ingénieur IDOM (physique)
Introduction et explication de l'utilisation de Font Awesome
Introduction du guide de programmation Java de nouvelle génération (Java 11)
Introduction du guide de programmation Java de nouvelle génération (Java 12)
[Docker] Introduction à docker compose Résumé de base de docker-compose.yml
[Ruby on Rails] Jusqu'à l'introduction de RSpec
Introduction de Rspec et de la localisation japonaise des messages d'erreur
[Introduction à Java] Bases de l'arithmétique Java (pour les débutants)