LoginSignup
1
0

More than 3 years have passed since last update.

PayjpのCustomer作成とdefault_cardの設定

Posted at

はじめに

Payjpの決済方法の記事はたくさんありますが、default_card設定方法はなかったので書かせていただきます。
トークン化については他の方が書かれているので、javascriptの記述は割愛します。

開発環境

ruby 2.6.5
Rails 6.0.3.3

参考

説明不足なところはこちらで補ってください。

リファレンス:
https://pay.jp/docs/api/#customer-%E9%A1%A7%E5%AE%A2
https://pay.jp/docs/customer

Cardモデル

自分の場合はCardモデルで下記のカラムを保存しています。

id user_id card_token customer_token
integer tok_~ cus_~

Customer作成

Customer作成にはcard_token(tok_~)が必要になります。
javascriptで受け取ったtokenをコントローラーに渡して、下記の記述をします。

cards_controller.rb
def create
    # card_tokenが正しいか確認
    if params[:card_token] == nil
      redirect_to new_user_card_path
      return
    end
    # ユーザーのcustomer_tokenが存在する場合
    if Card.find_by(user_id: current_user.id)
      card = current_user.card
      customer = Payjp::Customer.retrieve(card[0][:customer_token])
      customer.cards.create(
        card: params[:card_token]
      )
    else
    # ユーザーがcustomer_tokenが存在していない場合 
    customer = Payjp::Customer.create(
      description: "test",
      card: params[:card_token],)
    end
    # cardテーブルに保存
    card = Card.new(
      user_id: current_user.id,
      card_token: params[:card_token],
      customer_token: customer.id)
end

Customer情報取得

配列@cardsを定義して、customer_tokenをもとにcard情報を入れます

card.controller.rb
cards = Card.where(user_id: current_user.id)
      @cards = []
      cards.each do |card|
        @customer = Payjp::Customer.retrieve(card.customer_token)
        @cards << @customer.cards
      end

ユーザーにカードを選択してもらい、引数「i」で選択されたindexを受け取れるようにフォームを作成します。
ビューで@cardsに対してeach_with_indexで下記の記述でカード情報を表示させられます。

select.html.erb

<%= form_with url: set_default_card_path, method: :post, local: true do |f| %>
 <% @cards.each_with_index do |card, i| %>
   <%=f.radio_button :selected, :"#{i}" ,id: "check_card", checked: (card.data[i] [:id] == @customer[:default_card])  %>
   <%= "**** **** **** #{ + card.data[i][:last4]}" %> 
   <%= "#{card.data[i][:exp_year]}#{+ card.data[i][:exp_month]}月" %>
 <% end %>
 <%= f.submit "次へ進む" %>
<% end %>

default_cardの設定方法

select.html.erbのform_withの中でradio_buttonを使い、params[:selected]に#{i}の値を受け取っています。
@customerの[:default_card]に代入して、@customer.saveで完了します。
※@customer.saveをしないと更新されません。

cards_controller
def set_default_card
 cards = Card.where(user_id: current_user.id)
      @cards = []
      cards.each do |card|
        @customer = Payjp::Customer.retrieve(card.customer_token)
        @cards << @customer.cards
      end
 @customer = Payjp::Customer.retrieve(card.customer_token)
 index = params[:selected].to_i
    @customer[:default_card] = @cards[0].data[index][:id]
    @customer.save
end

念のため

  • customerを作成していない場合、card_token(tok_~)があれば、Payjp::Charge.createができます。
  • customerを作成した場合、cardのid(car_~)、もしくはcustomerのid(cus_~)があればPayjp::Charge.createができます。
  • customerのidを渡した場合はcustomerのdefault_cardが使われます。 (指定しない場合は最後に登録したカードがdefault_cardになります。)

最後に

もっと簡便な記述もあるかも知れませんが、これで実装することはできます。
あとは、各々アレンジしてください。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0