Quantcast
Channel: Vimタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 5608

RailsでPayjpを使った購入機能を実装する

$
0
0

こんばんは!
某フリマサイト開発でpayjpでAPIを使ったクレジットカード購入機能を実装したので備忘録

完成形

demo

demo

参考

Rails で Payjp を使って決済システムを導入する
https://qiita.com/hirotakasasaki/items/794c920016ac7c33da74
Pay.jpを使用してクレジットカード登録削除機能の実装をしてみた
https://qiita.com/wrtenniss/items/75dc631778506f8bce16
【Rails】payjpを使用した決済機能を実装する①〜クレジットカードの登録編〜
https://qiita.com/dice9494/items/4aa04da1056d1f15919e
Railsで単発決済システム(Pay.jp)を実装
https://qiita.com/nobu0717/items/52b744350ef24047e1c1

payjpAPIの使い方は上記の記事を確認頂ければ丁寧に書いてくれてますので割愛

躓いたところ

環境変数どこに書くの?

秘密鍵や公開鍵をコードに直張りはセキュリティの都合上よろしくないので、
Payjp.api_key = ENV['PAYJP_PRIVATE_KEY']
こんなふうにコード書いて.bash_profileへ記述します

ターミナル
$ vim ~/.bash_profile
.bash_profile
//まず「i」押下して入力モードにしましょう
export PAYJP_ACCESS_KEY='sk_test_*************'
export PAYJP_PUBLIC_KEY='pk_test_*************'
//escキー=> : => w => qの順で.bash_profileから抜けます
ターミナル
//環境変数が設定できているか確認
$printenv

exportコマンドで定義した環境変数を確認する時はprintenvコマンド使いましょう。環境変数名=値と出力されればokです

これどこに書くの?

payjpアクション
Payjp.api_key=ENV['PAYJP_PRIVATE_KEY']charge=Payjp::Charge.create(amount: 300,#決済金額の事。変数も使えるので後で解説card: params['payjp-token'],currency: 'jpy')

上記コードはフォームに入力したカード情報をトークン化して支払い処理を行う為の処理。APIの定型文です。決済するアクションはitem(productとか)コントローラが振る舞いとしてよろしいでしょう

items_controller.rb
classItemsController<ApplicationControllerdefindex#省略enddefnew#省略enddefcreate#省略enddefpayPayjp.api_key=ENV['PAYJP_PRIVATE_KEY']charge=Payjp::Charge.create(amount: 300,card: params['payjp-token'],currency: 'jpy')endend

決済される金額どうするの?

今のコードでは常に300円の決済しかできません。@itemに格納されているpriceを取り出しましょう

items_controller.rb
classItemsController<ApplicationControllerdefpayPayjp.api_key=ENV['PAYJP_PRIVATE_KEY']charge=Payjp::Charge.create(amount: @item.price,card: params['payjp-token'],currency: 'jpy')endend

これでok!
にはなりません。私はここでピュアRubyの理解が全くできていない事が分かりました。Railsは私のようなRuby知識しょぼ人間でも動いてくれていたんですね...

price for nill:NilClass

スクリーンショット 2019-09-05 1.37.41.png

amount: @item.priceと書いただけでは怒られます
priceって値は@itemの中にnameやtextなどと一緒に格納されています。(語彙力ないので適切な表現でない事をお詫びします)
Railsではハッシュであるparamsを使ってビューからキーと一緒にパラメーターとして送られてきます。params[:キー名]という形で使用できます

items_controller.rb
classItemsController<ApplicationControllerdefpayPayjp.api_key=ENV['PAYJP_PRIVATE_KEY']charge=Payjp::Charge.create(amount: @item.price,card: params['payjp-token'],currency: 'jpy')endprivatedefitem_paramsparams.require(:item).permit(:name,:text,:price,#この辺の他コードは関係ない部分なので省略してます).merge(user_id: current_user.id)endend

item_paramsの中にpriceがいますね。この値をpayアクションに渡してあげればよさそうです

@item = Item.find(params[:id])

itemモデルからfindメソッドでid(キー)を取り出して@itemに格納します。その@itemにはgifでいう所のクロノ・トリガーの画像や商品名、商品説明、価格などが格納されています。その中から価格(price)を取り出してあげれば、その価格をpayjpで決済できますね

controller完成コード

items_controller.rb
classItemsController<ApplicationControllerdefpay@item=Item.find(params[:id])Payjp.api_key=ENV['PAYJP_PRIVATE_KEY']charge=Payjp::Charge.create(amount: @item.price,card: params['payjp-token'],currency: 'jpy')endprivatedefitem_paramsparams.require(:item).permit(:name,:text,:price,#この辺の他コードは関係ない部分なので省略してます).merge(user_id: current_user.id)endend

これでpayjpを使った決済機能の基幹部分が完成しました!
スクリーンショット 2019-09-05 2.11.50.png
payjp側でもちゃんと決済されています

画面遷移ってどうするの?

show.html.haml
=form_tag(action: :pay,method: :post)do%script.payjp-button{:src=>"https://checkout.pay.jp",:type=>"text/javascript","data-text"=>"購入する","data-key"=>"pk_test_**************"}

この二行を表示したいビューに書けばボタンと入力画面(モーダルウィンドウ)が勝手に出現します。ダミーカード番号を入力すれば決済できるのですが、間違っても自分のカード番号は入れないで下さい

カード番号: 4242424242424242※visaカードのテストカード番号
有効期限: 12/20※未来の日付なら何でもok
CVC: 123※3桁なら何でもok
名前: YUI ARAGAKI可愛い娘の名前なら何でもok

ビューはオリジナルでも問題ありません。ただ私はまだそこまで実装できていないのでこの記事には書けません。参考記事にあるのでそちらでご確認お願いします

複数画面の遷移はどうするの?

ここまでのコードではpayアクションはform_tag(action: :pay, method: :post) do ~を埋め込んだビューでしか動きません。私の場合は商品詳細画面〜購入確認画面〜購入完了画面〜ホーム画面と遷移させたかったので
商品詳細画面=>show
購入確認画面=>purchase※ここにform_tagを埋め込んだ
購入完了画面=>done
ルートパスへ戻る
としました

items_controller.rb
classItemsController<ApplicationControllerbefore_action:set_item,only: [:show,:purchase,:pay]#これは繰り返しの記述を避けたいのでprivate以下にset_itemアクションとして記述しbefore_actionで呼び出していますdefindex@items=Item.order('id DESC').limit(4)enddefshowenddefnew@item=Item.new@item.item_images.build@item.build_shippingenddefcreate@item=Item.new(item_params)if@item.saveredirect_toaction: :indexendenddefpurchaseenddefpayPayjp.api_key=ENV['PAYJP_PRIVATE_KEY']charge=Payjp::Charge.create(amount: @item.price,card: params['payjp-token'],currency: 'jpy')redirect_toaction: :doneenddefdoneendprivatedefset_item@item=Item.find(params[:id])enddefitem_paramsparams.require(:item).permit(:name,:text,:price,).merge(user_id: current_user.id)endend

これで後はルーティングを設定すれば3画面遷移ができます

routes.rb
#payjpに必要な箇所だけ抜粋resources:itemsdocollectiondoget'purchase/:id'=>'items#purchase',as: 'purchase'post'pay/:id'=>'items#pay',as: 'pay'#httpメソッドはpostなので注意get'done'=>'items#done',as: 'done'endend

まとめ

Rubyの理解不足でハマっていた部分を除けば難しい事はなく実装できると思います。ただテストコードの書き方が分からずなので、誰かご教授頂きたいです。次は購入したら出品ステータスが取引中や取引完了になって購入できなくなる部分の実装とクレジットカード登録の実装が待っていますので、出力の低い脳みそフルフル回転させていきます!

終わり


Viewing all articles
Browse latest Browse all 5608

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>