現在プログラミング学習中で、これはメモしたいと思ったものを、自分用に分かりやすく残しておきます。
(前回投稿した内容の続きというか別ルートみたいな感じになります。)
【Rails】PAYJPでトークン生成時のエラー解決
PAYJPを導入してトークンを生成したが、決済が成功しない...
テスト用のカード情報を入力して、購入ボタンを押したら、

のように表示されました。
前回の内容に記述しておりますので割愛しますが、
トークン生成のJavaScriptの記述中にconsole.log()を書いてstatusを確認したところ、200と出ており、トークン生成に成功していることは確認が取れております。
(トークンがいない?? そんなはずはない!!!)
現状把握
エラーの原因を探るために、binding.pryを使用して、paramsの中身を確認したところ、
pry(#<OrdersController>)> params
=> <ActionController::Parameters {"authenticity_token"=>"uRxJ+Ho4c2vi4Pc8MrK/s7UhNbujnVBDt7qjJ11pFpeHWDMltGl3eu/ls94DaALSPNfIpoMtUd4aeOcs4Z8Y4w==", "item_order"=>{"postal_code"=>"555-0000", "prefecture_id"=>"9", "city"=>"市区町村", "block_number"=>"番地", "building_name"=>"建物名", "phone_number"=>"09012345678"}, "token"=>"tok_3b5890d13fb07a96a6cf2fa832e0", "controller"=>"orders", "action"=>"create", "id"=>"3"} permitted: false>
後半部分を見ると分かりますが、
"token"=>"tok_3b5890d13fb07a96a6cf2fa832e0"
tokenはしっかりparamsの中に入っていました!!!
トークンはしっかり生成されているのです!
では次に、コントローラーの現状を見てみましょう。
def order_params
params.require(:item_order).permit(:token, :postal_code, :prefecture_id, :city, :block_number, :building_name, :phone_number).merge(item_id: @item[:id], user_id: current_user.id)
end
def set_item
@item = Item.find(params[:id])
end
def pay_item
Payjp.api_key = ENV["PAYJP_SECRET_KEY"]
Payjp::Charge.create(
amount: @item.selling_price,
card: order_params[:token],
currency:'jpy'
)
end
現状の記述としては、
paramsに入っている:item_orderの中の:tokenをorder_params[:token]として受け取っている。
ということになります。
では、もう一度binding.pryで今度はorder_paramsと入力して確認してみましょう。
pry(#<OrdersController>)> order_params
=> <ActionController::Parameters {"postal_code"=>"555-0000", "prefecture_id"=>"9", "city"=>"市区町村", "block_number"=>"番地", "building_name"=>"建物名", "phone_number"=>"09012345678", "item_id"=>3, "user_id"=>3} permitted: true>"building_name"=>"建物名", "phone_number"=>"09012345678"} permitted: false>
tokenがいない!!!!!!!
params.require(:item_order).permit(:token, ~~~~)
このように、requireとpermitで書いているのになんで???
解決
bindng.pryで確認したところ、tokenが生成されているのは確認できたので、生成されたトークンの移動の仕方に問題がありました。
現在tokenが生成されている場所は、item_orderの外であり、paramsの直下なので、
そもそものtokenの場所が違ったということです。
binding.pryで、試しにparams[:token]と入力してみますと、
pry(#<OrdersController>)> params[:token]
=> "tok_14078502197e031107d18bb7e428"
と出ます。
なので、このように記述する必要があったということです。
def order_params
params.require(:item_order).permit(:postal_code, :prefecture_id, :city, :block_number, :building_name, :phone_number).merge(item_id: @item[:id], user_id: current_user.id, token: params[:token])
end
少し長いですが、mergeメソッドの中にtokenを記述しています。
item_orderの中にではなく、order_paramsに引っ付けるための記述です。
こうすることで、order_paramsに引っ付けることができたので、記述を変更した後にbinding.pryで確認してみますと、
pry(#<OrdersController>)> order_params
=> <ActionController::Parameters {"postal_code"=>"333-0000", "prefecture_id"=>"13", "city"=>"市区町村", "block_number"=>"番地", "building_name"=>"建物名", "phone_number"=>"09012345678", "item_id"=>3, "user_id"=>3, "token"=>"tok_14078502197e031107d18bb7e428"} permitted: true>
これでバッチリです☆
order_params[:token]で受け取れるようになり、決済も無事成功しました!!!
まとめ
tokenの居場所をしっかり理解する!
mergeメソッドを使用して、引っ付ける!