mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-27 01:43:22 +00:00
Adding request specs for case when using an existing card stored by Stripe for payment
This commit is contained in:
@@ -210,8 +210,8 @@ class CheckoutController < Spree::CheckoutController
|
||||
existing_card_id = params[:order].delete(:existing_card)
|
||||
if existing_card_id.present?
|
||||
credit_card = Spree::CreditCard.find(existing_card_id)
|
||||
if credit_card.user_id != spree_current_user.id || credit_card.user_id.blank?
|
||||
raise Core::GatewayError.new Spree.t(:invalid_credit_card)
|
||||
if credit_card.try(:user_id).blank? || credit_card.user_id != spree_current_user.try(:id)
|
||||
raise Spree::Core::GatewayError.new I18n.t(:invalid_credit_card)
|
||||
end
|
||||
|
||||
# Not currently supported but maybe we should add it...?
|
||||
|
||||
@@ -93,9 +93,9 @@ module Spree
|
||||
end
|
||||
|
||||
def create_payment_profile
|
||||
return unless source.is_a?(CreditCard) &&
|
||||
(source.number || source.gateway_payment_profile_id) &&
|
||||
source.gateway_customer_profile_id.nil?
|
||||
return unless source.is_a?(CreditCard)
|
||||
return unless source.number || source.gateway_payment_profile_id
|
||||
return unless source.gateway_customer_profile_id.nil?
|
||||
payment_method.create_profile(self)
|
||||
rescue ActiveMerchant::ConnectionError => e
|
||||
gateway_error e
|
||||
|
||||
@@ -2,11 +2,12 @@ require 'spec_helper'
|
||||
|
||||
describe "Submitting Stripe Connect charge requests", type: :request do
|
||||
include ShopWorkflow
|
||||
include AuthenticationWorkflow
|
||||
|
||||
let!(:order_cycle) { create(:simple_order_cycle) }
|
||||
let!(:enterprise) { create(:distributor_enterprise) }
|
||||
let!(:exchange) { create(:exchange, order_cycle: order_cycle, sender: order_cycle.coordinator, receiver: enterprise, incoming: false, pickup_time: "Monday")}
|
||||
let!(:shipping_method) { create(:free_shipping_method, distributors: [enterprise]) }
|
||||
let!(:shipping_method) { create(:shipping_method, calculator: Spree::Calculator::FlatRate.new(preferred_amount: 0), distributors: [enterprise]) }
|
||||
let!(:payment_method) { create(:payment_method, type: "Spree::Gateway::StripeConnect", distributors: [enterprise]) }
|
||||
let!(:stripe_account) { create(:stripe_account, enterprise: enterprise) }
|
||||
let!(:line_item) { create(:line_item, price: 12.34) }
|
||||
@@ -25,38 +26,84 @@ describe "Submitting Stripe Connect charge requests", type: :request do
|
||||
order.update_attributes(distributor_id: enterprise.id, order_cycle_id: order_cycle.id)
|
||||
order.reload.update_totals
|
||||
set_order order
|
||||
|
||||
# Storing the card against the user
|
||||
stub_request(:post, "https://sk_test_123456:@api.stripe.com/v1/customers")
|
||||
.with(:body => { card: token, email: order.email})
|
||||
.to_return(status: 200, body: JSON.generate({ id: "cus_A123", default_card: "card_XyZ456", sources: { data: [{id: "1"}] } }), headers: {})
|
||||
|
||||
stub_request(:post, "https://api.stripe.com/v1/tokens")
|
||||
.with(:body => { card: "card_XyZ456", customer: "cus_A123"})
|
||||
.to_return(status: 200, body: JSON.generate({id: "tok_123"}), headers: {})
|
||||
|
||||
stub_request(:post, "https://sk_test_123456:@api.stripe.com/v1/charges")
|
||||
.with(:body => {"amount"=>"1234", "card"=>{"exp_month"=>"10", "exp_year"=>"2025"}, "currency"=>"aud", "description"=>"Spree Order ID: #{order.number}", "payment_user_agent"=>"Stripe/v1 ActiveMerchantBindings/1.63.0"})
|
||||
.to_return(body: JSON.generate(charge_response_mock))
|
||||
end
|
||||
|
||||
context "when the charge request is accepted" do
|
||||
let(:charge_response_mock) { { id: "ch_1234", object: "charge", amount: 2000} }
|
||||
context "when a new card is submitted" do
|
||||
before do
|
||||
# Saves the card against the user
|
||||
stub_request(:post, "https://sk_test_123456:@api.stripe.com/v1/customers")
|
||||
.with(:body => { card: token, email: order.email})
|
||||
.to_return(status: 200, body: JSON.generate({ id: "cus_A123", default_card: "card_XyZ456", sources: { data: [{id: "1"}] } }), headers: {})
|
||||
|
||||
it "should process the payment" do
|
||||
put update_checkout_path, params
|
||||
expect(response).to redirect_to(spree.order_path(order))
|
||||
expect(order.payments.completed.count).to be 1
|
||||
# Requests a token from the newly saved card
|
||||
stub_request(:post, "https://api.stripe.com/v1/tokens")
|
||||
.with(:body => { card: "card_XyZ456", customer: "cus_A123"})
|
||||
.to_return(status: 200, body: JSON.generate({id: "newtoken_123"}), headers: {})
|
||||
|
||||
# Charges the card
|
||||
stub_request(:post, "https://sk_test_123456:@api.stripe.com/v1/charges")
|
||||
.with(:body => {"amount"=>"1234", "card"=>"newtoken_123", "currency"=>"aud", "description"=>"Spree Order ID: #{order.number}", "payment_user_agent"=>"Stripe/v1 ActiveMerchantBindings/1.63.0"})
|
||||
.to_return(body: JSON.generate(charge_response_mock))
|
||||
end
|
||||
|
||||
context "and the charge request is accepted" do
|
||||
let(:charge_response_mock) { { id: "ch_1234", object: "charge", amount: 2000} }
|
||||
|
||||
it "should process the payment, and stores the card/customer details" do
|
||||
put update_checkout_path, params
|
||||
expect(response).to redirect_to(spree.order_path(order))
|
||||
expect(order.payments.completed.count).to be 1
|
||||
card = order.payments.completed.first.source
|
||||
expect(card.gateway_customer_profile_id).to eq "cus_A123"
|
||||
expect(card.gateway_payment_profile_id).to eq "card_XyZ456"
|
||||
end
|
||||
end
|
||||
|
||||
context "when the charge request returns an error message" do
|
||||
let(:charge_response_mock) { { error: { message: "Bup-bow..."} } }
|
||||
|
||||
it "should not process the payment" do
|
||||
put update_checkout_path, params
|
||||
expect(response).to render_template(:edit)
|
||||
expect(order.payments.completed.count).to be 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when the charge request returns an error message" do
|
||||
let(:charge_response_mock) { { error: { message: "Bup-bow..."} } }
|
||||
context "when an existing card is submitted" do
|
||||
let(:credit_card) { create(:credit_card,
|
||||
payment_method_id: payment_method.id,
|
||||
user_id: order.user_id,
|
||||
gateway_payment_profile_id: "card_AbC123",
|
||||
gateway_customer_profile_id: "cus_Z456",
|
||||
month: 11, year: 2026) }
|
||||
|
||||
it "should not process the payment" do
|
||||
put update_checkout_path, params
|
||||
expect(response).to render_template(:edit)
|
||||
expect(order.payments.completed.count).to be 0
|
||||
before do
|
||||
params[:order][:existing_card] = credit_card.id
|
||||
quick_login_as(order.user)
|
||||
|
||||
# Requests a token
|
||||
stub_request(:post, "https://api.stripe.com/v1/tokens")
|
||||
.with(:body => {"card"=>"card_AbC123", "customer"=>"cus_Z456"})
|
||||
.to_return(status: 200, body: JSON.generate({id: "newtoken_123"}), headers: {})
|
||||
|
||||
# Charges the card
|
||||
stub_request(:post, "https://sk_test_123456:@api.stripe.com/v1/charges")
|
||||
.with(:body => {"amount"=>"1234", "card"=>"newtoken_123", "currency"=>"aud", "description"=>"Spree Order ID: #{order.number}", "payment_user_agent"=>"Stripe/v1 ActiveMerchantBindings/1.63.0"})
|
||||
.to_return(body: JSON.generate(charge_response_mock))
|
||||
end
|
||||
|
||||
context "and the charge request is accepted" do
|
||||
let(:charge_response_mock) { { id: "ch_1234", object: "charge", amount: 2000} }
|
||||
|
||||
it "should process the payment, and keep the profile ids" do
|
||||
put update_checkout_path, params
|
||||
expect(response).to redirect_to(spree.order_path(order))
|
||||
expect(order.payments.completed.count).to be 1
|
||||
card = order.payments.completed.first.source
|
||||
expect(card.gateway_customer_profile_id).to eq "cus_Z456"
|
||||
expect(card.gateway_payment_profile_id).to eq "card_AbC123"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user