[RUBY] [Rails] Implémentez la fonction d'achat de produits avec une carte de crédit enregistrée auprès de PAY.JP

introduction

Nous avons introduit PAY.JP pour effectuer des paiements par carte de crédit avec une application personnelle. Il est décrit comme un mémorandum concernant la mise en œuvre de la fonction.

Article précédent Mettre en œuvre la fonction d'enregistrement / suppression de carte de crédit dans PAY.JP

Conditions préalables

Nous avons créé un modèle de carte et un contrôleur de carte pour enregistrer les informations de la carte jusqu'à la dernière fois. Cette fois, nous allons créer un nouveau modèle d'achat et un nouveau contrôleur et effectuer le processus d'achat.

procédure

  1. Créez un modèle
  2. Créer un tableau
  3. Création d'un contrôleur

Créer un modèle

Cette fois, nous allons créer un modèle de commande.

class Order < ApplicationRecord
  belongs_to :user
  has_many :products, through: :order_details
  has_many :order_details, dependent: :destroy
  belongs_to :card
  belongs_to :address

  enum postage: {burden: 0, free: 1}
  enum status: {payé: 0,Préparation à la livraison: 1,Livré: 2}

  def add_items(cart)
    cart.line_items.target.each do |item|
      item.cart_id = nil
      line_items << item
    end
  end
end

Depuis que j'ai créé le site EC, j'ai défini la méthode d'instance, etc. parce qu'elle implémente la fonction de panier, etc., mais cette fois je l'omettrai parce que je me concentre sur la fonction d'achat. Donc, une ligne de appartient_to: card est la partie que vous souhaitez utiliser.

Créer une table

Créez le fichier de migration comme suit.


class CreateOrders < ActiveRecord::Migration[5.2]
  def change
    create_table :orders do |t|
      t.references :user, foreign_key: true
      t.references :address, foreign_key: true
      t.references :card, foreign_key: true
      t.references :product, foreign_key: true
      t.integer :quantity, null: false
      t.integer :status, default: 0, null: false
      t.integer :postage, default: 0, null: false
      t.integer :price, null: false
      t.timestamps
    end
  end
end

La carte est installée en tant que clé externe.

Créer un contrôleur

Nous allons créer un contrôleur de commande. Cette fois, nous utiliserons deux actions, new et create.


class OrdersController < ApplicationController
  before_action :set_cart
  before_action :user_signed_in
  before_action :set_user
  before_action :set_card
  before_action :set_address

  require "payjp"

  #Écran de saisie de commande
  def new
    @line_items = current_cart.line_items
    @cart = current_cart
    if @cart.line_items.empty?
      redirect_to current_cart, notice: "Le panier est vide"
      return
    end
    if @card.present?
      customer = Payjp::Customer.retrieve(@card.customer_id)
      default_card_information = customer.cards.retrieve(@card.card_id)
      @card_info = customer.cards.retrieve(@card.card_id)
      @exp_month = default_card_information.exp_month.to_s
      @exp_year = default_card_information.exp_year.to_s.slice(2,3)
      customer_card = customer.cards.retrieve(@card.card_id)
      @card_brand = customer_card.brand
      case @card_brand
      when "Visa"
        @card_src = "icon_visa.png "
      when "JCB"
        @card_src = "icon_jcb.png "
      when "MasterCard"
        @card_src = "icon_mastercard.png "
      when "American Express"
        @card_src = "icon_amex.png "
      when "Diners Club"
        @card_src = "icon_diners.png "
      when "Discover"
        @card_src = "icon_discover.png "
      end
      @order = Order.new
    end
  end

  #Enregistrer une commande
  def create
    unless user_signed_in?
      redirect_to cart_path(@current_cart), notice: "Veuillez vous connecter"
      return
    end
    @purchaseByCard = Payjp::Charge.create(
    amount: @cart.total_price,
    customer: @card.customer_id,
    currency: 'jpy',
    card: params['payjpToken']
    )
    @order = Order.new(order_params)
    @order.add_items(current_cart)
    if @purchaseByCard.save && @order.save!
      OrderDetail.create_items(@order, @cart.line_items)
      flash[:notice] = 'La commande est terminée. Vous pouvez consulter l'historique des commandes sur Ma page.'
      redirect_to root_path
    else
      flash[:alert] = "La commande n'a pas pu être enregistrée"
      redirect_to action: :new
    end
  end

  private
  def order_params
    params.permit(:user_id, :address_id, :card_id, :quantity, :price)
  end

  def set_user
    @user = current_user
  end

  def set_cart
    @cart = current_cart
  end

  def set_card
    @card = Card.find_by(user_id: current_user.id)
  end

  def set_address
    @address = Address.find_by(user_id: current_user.id)
  end

  def user_signed_in
    unless user_signed_in?
      redirect_to cart_path(@cart.id), alert: "Vous devez vous connecter pour procéder au paiement"
    end
  end
end

La nouvelle action prend la forme d'une page de confirmation d'achat. Si l'utilisateur ne s'est pas enregistré, la page de confirmation d'achat ne peut pas être visitée en premier lieu. De plus, il s'agit d'une spécification permettant à l'utilisateur d'enregistrer la carte sur Ma page.

Si vous souhaitez enregistrer votre carte pour la première fois sur la page de confirmation d'achat, vous pouvez apporter la variable d'instance de la nouvelle action du contrôleur de carte créée dans l'article précédent.

L'action de création nécessite les éléments suivants: Le contenu est extrait pour une visualisation facile.


def create
  @purchaseByCard = Payjp::Charge.create(
  amount: @cart.total_price,
  customer: @card.customer_id,
  currency: 'jpy',
  card: params['payjpToken']
  )
  if @purchaseByCard.save
    flash[:notice] = 'La commande est terminée.'
    redirect_to root_path
  else
    flash[:alert] = "La commande n'a pas pu être enregistrée"
    redirect_to action: :new
  end
end

Lorsque l'achat est terminé ci-dessus, les ventes sont également enregistrées dans PAY.JP comme indiqué ci-dessous. alt

Recommended Posts

[Rails] Implémentez la fonction d'achat de produits avec une carte de crédit enregistrée auprès de PAY.JP
[Rails] Implémentez la fonction d'enregistrement / suppression de carte de crédit dans PAY.JP
Introduisons la fonction de carte de crédit en utilisant payjp (préparation)
J'ai essayé d'implémenter la fonction de prévisualisation d'image avec Rails / jQuery
[Retrait des rails] Créez une fonction de retrait simple avec des rails
Créez quand même une fonction de connexion avec Rails
Mettre en œuvre la fonction de catégorie de produit en utilisant l'ascendance ① (Préparation)
Faisons une fonction de recherche avec Rails (ransack)
Implémentons une fonction pour limiter le nombre d'accès à l'API avec SpringBoot + Redis
Utilisation de l'API PAY.JP avec Rails ~ Enregistrement de la carte ~ (payjp.js v2)
Je souhaite implémenter une fonction d'édition des informations produit ~ part1 ~
Une note sur la fonction de départ de Ruby on Rails
[Ruby on Rails] Implémenter la fonction de connexion par add_token_to_users avec l'API
Implémentez la fonction de connexion simplement avec le nom et le mot de passe dans Rails (3)
Implémenter la fonction d'application dans Rails
[Rails] Implémenter la fonction de recherche d'utilisateurs
Rails ~ Comprendre la fonction de message ~
[Rails] Implémenter la fonction de publication d'images
L'histoire du refactoring avec un assistant personnel pour la première fois dans une application Rails
[Rails] Un moyen simple d'implémenter une fonction d'auto-introduction dans votre profil
Implémentez une fonction de recherche affinée pour plusieurs modèles sans gemme Rails5.
Je souhaite ajouter une fonction de navigation avec ruby on rails
J'ai créé une fonction de réponse pour l'extension Rails Tutorial (Partie 1)
J'ai créé une fonction de réponse pour l'extension Rails Tutorial (Partie 5):
[Illustration] Recherche de la somme des pièces avec une fonction récursive [Ruby]
(Ruby on Rails6) Créer une fonction pour modifier le contenu publié
J'ai essayé de créer une fonction de groupe (babillard) avec Rails
[Rails] J'écrirai très attentivement le mécanisme et la méthode d'utilisation de payjp (API) (enregistrement Kureka)