[RAILS] Equipé d'une fonction carte utilisant payjp

Equipé d'une fonction carte.

** Utiliser des gemmes ** devise PAY.JP for Ruby Gon gem

Tout d'abord, la fonction d'enregistrement de la carte

Cependant, il semble que la loi interdit aux exploitants de sites de la CE d'avoir des numéros de carte. Par conséquent, ces informations ne peuvent pas être enregistrées dans la base de données. Au lieu de cela, vous devrez enregistrer votre identifiant payjp.

** Flux d'inscription de la carte ** ・ L'utilisateur final entre le numéro de carte, etc. et clique sur Soumettre ・ Les données sont envoyées à payjp et le jeton de carte est retourné. ・ Créer un client (propriétaire) à partir du jeton de carte retourné ・ Enregistrez l'identifiant client et l'identifiant de la carte dans la base de données à partir des informations client créées

Dans mon cas, l'association est

user has_one :card
card belongs_to :user

table de cartes

migrate/***create_cards.rb


      t.references  :user,        foreign_key: true,index:{unique: true}
      t.string      :customer_id, null: false
      t.string      :card_id,     null: false

Maintenant, ajoutons ce qui suit au Gemfile et à l'installation du bundle.

Gemfile


gem 'payjp'
gem 'gon'

** Voici gon ** Un joyau qui vous permet de passer des variables ruby à JQuery (javascript).

** C'est peut-être faux, mais ** je pense que css et JQuery (javascript) peuvent être vus par l'outil de vérification du navigateur. Donc, je pense que c'est une bonne idée d'intégrer la clé directement dans JQuery (javascript). Une clé de test peut convenir, mais vous ne pouvez pas utiliser une clé de test en production. Il existe également un moyen de l'écrire dans credentials.yml, mais comme les clés personnelles sont personnelles, je pense qu'il est souhaitable de les gérer individuellement.

Une fois l'installation terminée, vous pouvez utiliser gon. de application.html.haml Ajouté ci-dessus javascript_include_tag

ruby:app/views/layouts/application.html.haml


= include_gon
= javascript_include_tag 'application'

app/controllers/card_controller.rb


def new
    gon.api_key = ENV["PAYJP_PUBLIC_KEY"]
end

Parce qu'il n'est pas nécessaire de charger les js liés aux cartes sur chaque page Cette fois J'ai écrit ce qui suit directement dans card / new.html.haml.

ruby:app/views/card/new.html.haml


:javascript
  let payjp = Payjp(gon.api_key);

Maintenant que les variables d'environnement sont lues par JQuery, il semble que la clé ne sera pas exposée. Si vous co-développez, enregistrez chaque personne qui en a besoin dans payjp et écrivez-le dans la variable d'environnement.

Puisque la nouvelle action est effectuée ci-dessus, créez un formulaire d'inscription.

javascript:app/views/card/new.html.haml


= form_with url: card_index_path,local:true,id:"cardNew__form" do |f| //card_index_path est le chemin d'accès à l'action de création du contrôleur de carte
    %input#cardNew__form--inputHidden{type:"hidden",name:"payjp-token"}
    #cardNew__form--input
    #cardNew__form--errMessage
    = f.submit "enregistrer",id:"cardNew__form--submit"

%script{src: "https://js.pay.jp/v2/pay.js", type: "text/javascript"}

:javascript //Voici JQuery.

  let payjp = Payjp(gon.api_key); //C'est gon.
  let elements = payjp.elements();
  let cardElement = elements.create('card');

  cardElement.mount('#cardNew__form--input');
//Jusqu'à présent, les champs de saisie préparés par PAYJP ont été créés. Un point de la carte est mignon donc je vais l'utiliser tel quel^^

  $(".cardNew").on("click","#cardNew__form--submit",
    function(e){
      e.preventDefault();
      payjp.createToken(cardElement).then(function(response){ //Ici, envoyez les informations de la carte à payjp et obtenez le jeton de carte.
        if(response.error){
          $('#cardNew__form--errMessage').text(response.error.message);
        }else{
          $("#cardNew__form--inputHidden").attr("value",response.id); //response.id est un jeton de carte. Ici le nom de l'entrée="payjp-token"Donnez la valeur à.
          $("#cardNew__form").submit();
        }
      });
    }
  );

Numéro de carte: 424242424242 ↑ La date d'expiration est dans le futur, et CVC semble être n'importe quoi. Carte de test

Maintenant, appuyez sur Soumettre et le jeton sera envoyé à l'action de création. card_index_path est le chemin d'accès à l'action de création. Si vous ne le voyez pas bien, veuillez l'ajuster avec CSS.

app/controllers/card_controller.rb


  def create
    if params["payjp-token"].blank?
      render :new
    else
      Payjp.api_key = ENV["PAYJP_SECRET_KEY"]
      customer = Payjp::Customer.create( #Ici, créez un client associé au jeton de carte.
        card: params["payjp-token"]
      )
      @card = Card.new(
        user_id: current_user.id,
        customer_id: customer.id, #Ceci est l'identifiant du client.
        card_id: customer.default_card #Il s'agit de l'identifiant de la carte associée au client.
      )
      if @card.save
        redirect_to new_card_path
      else
        render :new
      end
    end
  end

Je pense que vous pouvez enregistrer la carte dans la base de données jusqu'à présent. Si vous souhaitez faciliter les choses, accédez à ici

=form_with url: card_index_path,local:true,id:"new_form" do |f|
    %script{src:"https://checkout.pay.jp/",class:"payjp-button","data-key":"#{@api_key}"}

Copiez et collez la clé de données vide de votre clé publique Créez @ape_key avec un nouveau contrôleur. url est le même que précédemment. id est arbitraire. Je n'ai pas essayé la classe donc je ne sais pas. En ce qui concerne le contrôleur, le nouveau est la spécification gon, donc

@api_key = ENV["PAYJP_PUBLIC_KEY"]

Je pense que ce n'est pas grave si vous le définissez. Il semble envoyer un jeton comme valeur du paramètre payjp-token. Avec cela seul, il semble qu'un écran de saisie de carte de haute qualité soit terminé. C'est incroyable.

Source principale de référence PAY.JP Announcement référence payjp.js v2 Guide payjp.js v2 Créer un client

Blog de référence [Rails] J'ai brièvement résumé la procédure de mise en œuvre de la fonction de paiement en utilisant PAYJP Implémentation de la fonction d'enregistrement et de suppression de carte de crédit avec Payjp (Rails)

Puis payez par carte

Comme un flux

Cliquez pour acheter sur la page de détails du produit Confirmer l'achat sur la page de confirmation d'achat Paiement par carte Créez un identifiant de paiement et qui l'a acheté dans le tableau des paiements Réduisez le champ de stock dans la table des articles et mettez à jour

association

item has_many :payments
payment belogs_to :item

table des paiements

***create_payments.rb


      t.string      :charge_id, null: false
      t.references  :user,      foreign_key: true
      t.references  :item,      foreign_key: true
      t.integer     :quantity,  null: false

haml:views/payments/new.html.haml



= form_with url:item_payments_path,local:true,id:"new_form" do |f|
  = f.number_field :quantity
  = f.submit "Acheter" #J'ai peur de quelque chose, alors j'essaie de ne pas sauter des données telles que le montant d'argent. Seul le nombre d'achats.

payments_controller.rb


  def create
    item = Item.find(params[:item_id])                              #Imbriquez le routage pour inclure l'ID de l'élément.
    item.stock -= params[:quantity].to_i                            #Soustrayez le nombre d'achats du stock d'articles. Tout ce que vous avez à faire est de mettre à jour
    payment = Payment.new(payment_params)
    Payjp.api_key = ENV["PAYJP_SECRET_KEY"] 
    charge = Payjp::Charge.create( #Installez-vous ici.
      amount: item.price.to_i * params[:quantity].to_i,             #Montant du règlement
      customer: Card.find_by(user_id: current_user.id).customer_id, #Client
      currency: 'jpy'                                               #yen japonais
    )
    payment.charge_id = charge.id                                   #J'ai mis l'ID de paiement dans l'instance de paiement que j'ai générée précédemment. Pas besoin de se séparer. comme vous voulez^^
    if payment.save && item.update(stock: item.stock)
      redirect_to root_path
    else
      render "new"
    end
  end

  private
  def payment_params
    params.permit(
      :item_id,
      :quantity,
    ).merge(user_id: current_user.id)
  end

C'est comme ça. Diverses parties ont été omises par souci de clarté. Si vous ne connaissez pas l'imbrication du routage

config/routes.rb


  resources :items do
    resources :payments,only: [:new,:create]
  end

C'est comme ça.

Je pense que cela fonctionnera probablement.

Source principale de référence Guide de l'API payjp.js [Objet de facturation PAY.JP](https://pay.jp/docs/api/#charge%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82 % AF% E3% 83% 88) ↑ Je l'ai omis, mais pour ceux qui veulent afficher les 4 derniers chiffres de la carte ou du VIZA (veuillez utiliser retrieve)

Blog de référence Introduisez un système de paiement utilisant Payjp with Rails

Supprimez la carte enregistrée.

Dans mon cas routage

config/routes.rb


resources :card,only: [:new,:create,:destroy]
card_index POST    /card(.:format)        card#create
new_card   GET     /card/new(.:format)    card#new
card       DELETE  /card/:id(.:format)    card#destroy

J'ai donc changé la vue ci-dessus. Ce qui a changé est de if à else en haut Ce n'est que le jugement de définition de gon de JQuery.

view/card/new.html.haml


  - if current_user.card
    #cardNew__form
      #cardNew__form--type= @card.brand.upcase
      #cardNew__form--num= "**** **** **** #{@card.last4}"
      #cardNew__form--name= @card.name
      =link_to "Supprimer","/card/#{current_user.card.id}"
  - else
    = form_with url: card_index_path,local:true,id:"cardNew__form" do |f|
      %input#cardNew__form--inputHidden{type:"hidden",name:"payjp-token"}
      #cardNew__form--input
      #cardNew__form--errMessage
      = f.submit "enregistrer",id:"cardNew__form--submit"



%script{src: "https://js.pay.jp/v2/pay.js", type: "text/javascript"}

:javascript
  if(typeof gon != 'undefined'){

    const style = {
      base: {
        backgroundColor:'#ffffff',
        '::placeholder': {
          color: '#bbbbbb',
        }
      },
      invalid: {
        color: 'red',
      }
    }

    let payjp = Payjp(gon.api_key);
    let elements = payjp.elements();
    let cardElement = elements.create('card', {style: style});

    cardElement.mount('#cardNew__form--input');

    $(".cardNew").on("click","#cardNew__form--submit",
      function(e){
        e.preventDefault();
        payjp.createToken(cardElement).then(function(response){
          if(response.error){
            $('#cardNew__form--errMessage').text(response.error.message);
          }else{
            $("#cardNew__form--inputHidden").attr("value",response.id);
            $("#cardNew__form").submit();
          }
        });
      }
    );
  }

card_controller.rb


  def new
    if current_user.card
      Payjp.api_key = ENV["PAYJP_SECRET_KEY"]
      customer = Payjp::Customer.retrieve(current_user.card.customer_id)
      @card = customer.cards.retrieve(current_user.card.card_id)
    else
      gon.api_key = ENV["PAYJP_PUBLIC_KEY"]
    end
  end

Recommended Posts

Equipé d'une fonction carte utilisant payjp
Utiliser une imprimante avec Debian 10
Utiliser une webcam avec Raspberry Pi
Créer un décorateur de fonction Python avec Class
Un mémorandum sur l'utilisation de la fonction d'entrée de Python
[Piyopiyokai # 1] Jouons avec Lambda: création d'une fonction Lambda
Évaluez les performances de CNN avec une fonction d'évaluation personnalisée
[Chat De Tornado] Créez un chat en utilisant WebSocket dans Tornado
J'ai essayé d'utiliser la base de données (sqlite3) avec kivy
Histoire de l'utilisation du jeton logiciel de Resona avec 1Password
[Pratique] Créez une application Watson avec Python! # 2 [Fonction de traduction]
[Python] Générer ValueObject avec un constructeur complet à l'aide de classes de données
Créer une fonction pour décrire les polices japonaises avec OpenCV
Enregistrez des tickets avec l'API de Redmine en utilisant des requêtes Python
Je ne peux pas transformer un projet utilisant PyWebView en un exe avec PyInstaller
Créer une application Todo avec Django ⑤ Créer une fonction d'édition de tâches
Utilisez des programmes Python avec le plugin de sortie exec_filter de fluentd
Utilisez des programmes Python avec le plugin de sortie exec de fluentd
Format A4 avec python-pptx
Différencier une fonction à deux variables
Décorer avec un décorateur
J'ai eu une erreur de valeur lors de l'utilisation de JUMAN ++ avec PyKNP
Créons une fonction pour le test paramétré à l'aide d'un objet frame
Créez un bot Mastodon avec une fonction pour répondre automatiquement avec Python
Associez Python Enum à une fonction pour la rendre appelable
Comment imprimer des caractères sous forme de tableau avec la fonction d'impression de Python
Une histoire sur l'installation de matplotlib à l'aide de pip avec une erreur
Pour renvoyer char * dans une fonction de rappel à l'aide de ctypes en Python
Un mémo que j'ai écrit une fonction de base en Python en utilisant la récurrence
Recherche du rapport de circonférence avec une fonction à 3 lignes [méthode Python / Monte Carlo]
[Linux] Ecrire un outil de déploiement à l'aide de rsync avec un script shell
Essayez d'exécuter une fonction écrite en Python à l'aide de Fn Project
Essayez le chiffrement / déchiffrement à l'aide de la clé OpenSSL avec la fonction pow de Python3