Railsアプリでpayjpをテストでエラーが発生。
解決したいこと
Railsアプリでpayjpを使ってカードの登録を
テストした際にエラーが発生してしまった。
発生している問題・エラー
Failure/Error: customer_id: customer.id,
NoMethodError:
undefined method `id' for {:cards=>{:count=>1, :data=>[{:id=>"car_a96c76b044d7ae21439d7b9840b7", :address_city=>nil, :address_line1=>nil, :address_line2=>nil, :address_state=>nil, :address_zip=>nil, :address_zip_check=>"unchecked", :brand=>"Visa", :country=>nil, :created=>1578830630, :customer=>"cus_ca9d1d98900ec1f2595aebefd9a6", :cvc_check=>"passed", :exp_month=>12, :exp_year=>2020, :fingerprint=>"e1d8225886e3a7211127df751c86787f", :last4=>"4242", :livemode=>false, :metadata=>{}, :name=>nil, :object=>"card"}], :has_more=>false, :object=>"list", :url=>"/v1/customers/cus_ca9d1d98900ec1f2595aebefd9a6/cards"}, :id=>"cus_ca9d1d98900ec1f2595aebefd9a6", :created=>1578830631, :default_card=>"car_a96c76b044d7ae21439d7b9840b7", :description=>nil, :email=>nil, :livemode=>false, :metadata=>{}, :object=>"customer", :subscriptions=>{:count=>0, :data=>[], :has_more=>false, :object=>"list", :url=>"/v1/customers/cus_ca9d1d98900ec1f2595aebefd9a6/subscriptions"}}:Hash
customer_id: customer.id,
該当コード
テスト
context '登録成功' do
let(:user) { create(:user) }
it '適切な情報が存在' do
login(user)
get new_card_path
expect{
allow(Payjp::Customer).to receive(:create).and_return(PayjpMock.customer_information)
post card_path, params: { payjp_token: 'sk_test_c62fade9d045b54cd76d7036',
card_token: 'car_a96c76b044d7ae21439d7b9840b7'}
}.to change{ Card.count }.by(1)
end
end
モック
$(function () {
if (document.URL.match(/card/)) {
var payjp = Payjp(process.env.PAYJP_PUBLIC_KEY);
var elements = payjp.elements();
var numberElement = elements.create('cardNumber', {placeholder: "1111 2222 3333 4444"});
var expiryElement = elements.create('cardExpiry');
var cvcElement = elements.create('cardCvc');
numberElement.mount('#number-form')
expiryElement.mount('#expiry-form')
cvcElement.mount('#cvc-form')
var submit_btn = $("#card_submit");
submit_btn.on('click', function(e){
e.preventDefault();
payjp.createToken(numberElement).then(function (response) {
if (response.error) {
alert(response.error.message)
} else {
$("#card_token").append(
`<input type="hidden" name="payjp_token" value=${response.id}>
<input type="hidden" name="card_token" value=${response.card.id}>`
);
$('#card_form')[0].submit();
$("#card_number").removeAttr("name");
$("#cvc-from").removeAttr("name");
$("#exp_month").removeAttr("name");
$("#exp_year").removeAttr("name");
};
})
});
}
});
コントローラー
class CardsController < ApplicationController
require 'payjp'
before_action :logged_in_user
before_action :exists_card, only:[:new, :create]
def new
card = Card.where(user_id: current_user.id)
end
def create
@user = current_user
Payjp.api_key = Rails.application.credentials[:payjp][:secret_key]
if params[:payjp_token].blank?
redirect_to 'new'
else
customer = Payjp::Customer.create(
description: '登録テスト',
email: current_user.email,
card: params['payjp_token'],
metadata: {user_id: current_user.id}
)
@card = Card.new(
user_id: current_user.id,
customer_id: customer.id,
token_id: customer.default_card
)
if @card.save
flash[:notice] = "カードを登録しました"
redirect_to @user
else
redirect_to 'new'
end
end
end
def destroy
card = Card.find_by(user_id: current_user.id)
if card.blank?
redirect_to user_path(current_user)
else
Payjp.api_key = Rails.application.credentials[:payjp][:secret_key]
customer = Payjp::Customer.retrieve(card.customer_id)
customer.delete
card.delete
end
flash[:notice] = "カード情報を削除しました"
redirect_to user_path(current_user)
end
private
def exists_card
unless current_user.card.blank?
flash[:notice] = "登録できるカードは1枚までです"
redirect_to current_user
end
end
end
0