Update Stripe payment intents decorator

- copied the relevant code from the new Active Merchant version
- Add spec to cover the scenario of saving a card when paying by card
- Fix Stripe stub.

I used stripe stubs for the new scenario because storing a card on
stripe depends on some client side interaction with Stripe. We can't
capture that with VCR.
This commit is contained in:
Gaetan Craig-Riou
2024-02-05 15:21:06 +11:00
parent fad37318b3
commit 62fbaa8a6e
3 changed files with 31 additions and 24 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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