diff --git a/lib/active_merchant/billing/gateways/stripe_payment_intents_decorator.rb b/lib/active_merchant/billing/gateways/stripe_payment_intents_decorator.rb index 711589f0cc..eb29ca560a 100644 --- a/lib/active_merchant/billing/gateways/stripe_payment_intents_decorator.rb +++ b/lib/active_merchant/billing/gateways/stripe_payment_intents_decorator.rb @@ -38,9 +38,9 @@ ActiveMerchant::Billing::StripePaymentIntentsGateway.class_eval do end # Note: Not all payment methods are currently supported by the - # {Payment Methods API}[https://stripe.com/docs/payments/payment-methods] - # Current implementation will create - # a PaymentMethod object if the method is a token or credit card + # {Payment Methods API}[https://stripe.com/docs/payments/payment-methods] + # Current implementation will create a PaymentMethod object if the method is a token + # or credit card # All other types will default to legacy Stripe store def store(payment_method, options = {}) params = {} @@ -48,27 +48,15 @@ ActiveMerchant::Billing::StripePaymentIntentsGateway.class_eval do # If customer option is provided, create a payment method and attach to customer id # Otherwise, create a customer, then attach - # if payment_method.is_a?(StripePaymentToken) || - # payment_method.is_a?(ActiveMerchant::Billing::CreditCard) - add_payment_method_token(params, payment_method, options) - if options[:customer] - customer_id = options[:customer] - else - post[:validate] = options[:validate] unless options[:validate].nil? - post[:description] = options[:description] if options[:description] - post[:email] = options[:email] if options[:email] - customer = commit(:post, 'customers', post, options) - customer_id = customer.params['id'] + result = add_payment_method_token(params, payment_method, options) + return result if result.is_a?(ActiveMerchant::Billing::Response) - # return the stripe response if expected customer id is not present - return customer if customer_id.nil? - end - commit(:post, - "payment_methods/#{params[:payment_method]}/attach", - { customer: customer_id }, options) - # else - # super(payment, options) - # end + customer_id = options[:customer] || customer(post, payment_method, options).params['id'] + options = format_idempotency_key(options, 'attach') + attach_parameters = { customer: customer_id } + attach_parameters[:validate] = options[:validate] unless options[:validate].nil? + + commit(:post, "payment_methods/#{params[:payment_method]}/attach", attach_parameters, options) end private diff --git a/spec/support/request/stripe_stubs.rb b/spec/support/request/stripe_stubs.rb index 9a10c9830a..524233cffc 100644 --- a/spec/support/request/stripe_stubs.rb +++ b/spec/support/request/stripe_stubs.rb @@ -44,7 +44,7 @@ module StripeStubs # Stubs the customers call to both the main stripe account and the connected account def stub_customers_post_request(email:, response: {}, stripe_account_header: false) stub = stub_request(:post, "https://api.stripe.com/v1/customers") - .with(body: { email: }) + .with(body: { expand: ["sources"], email: }) stub = stub.with(headers: { 'Stripe-Account' => 'abc123' }) if stripe_account_header stub.to_return(customers_response_mock(response)) end diff --git a/spec/system/consumer/checkout/payment_spec.rb b/spec/system/consumer/checkout/payment_spec.rb index 970c9a09c8..0646e40185 100644 --- a/spec/system/consumer/checkout/payment_spec.rb +++ b/spec/system/consumer/checkout/payment_spec.rb @@ -250,6 +250,25 @@ describe "As a consumer, I want to checkout my order" do click_on "Next - Order summary" proceed_to_summary end + + context "when saving card" do + it "selects Stripe SCA and proceeds to the summary step" do + stub_customers_post_request(email: order.user.email) + stub_payment_method_attach_request + + choose pay_method.to_s + fill_out_card_details + check "Save card for future use" + + click_on "Next - Order summary" + proceed_to_summary + + # Verify card has been saved with correct stripe IDs + user_credit_card = order.reload.user.credit_cards.first + expect(user_credit_card.gateway_payment_profile_id).to eq "pm_123" + expect(user_credit_card.gateway_customer_profile_id).to eq "cus_A123" + end + end end end