現在プログラミング学習中で、これはメモしたいと思ったものを、自分用に分かりやすく残しておきます。
(前回投稿した内容の続きというか別ルートみたいな感じになります。)
【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
メソッドを使用して、引っ付ける!