Add authorize action to the stripe_sca gateway and make it fetch the redirect url if provided

Change the purchase action to only capture the alrteady authorized payment intent
This commit is contained in:
luisramos0
2020-02-07 11:26:08 +00:00
committed by Luis Ramos
parent e3ffe8fe6b
commit 4b3b4e00ff

View File

@@ -32,9 +32,41 @@ module Spree
# NOTE: the name of this method is determined by Spree::Payment::Processing
def purchase(money, creditcard, gateway_options)
provider.purchase(*options_for_purchase_or_auth(money, creditcard, gateway_options))
payment_intent_id = payment_intent(creditcard, gateway_options)
unless payment_intent_id
return failed_activemerchant_billing_response("No Pending Payment Found")
end
payment_intent_response = Stripe::PaymentIntent.retrieve(payment_intent_id,
stripe_account: stripe_account_id)
if payment_intent_response.last_payment_error.present?
return failed_activemerchant_billing_response(payment_intent_response.
last_payment_error.
message)
end
if payment_intent_response.status != 'requires_capture'
return failed_activemerchant_billing_response("Invalid PaymentIntent status.")
end
options = basic_options(gateway_options)
options[:customer] = creditcard.gateway_customer_profile_id
provider.capture(money, payment_intent_id, options)
rescue Stripe::StripeError => e
failed_activemerchant_billing_response(e.message)
end
# NOTE: the name of this method is determined by Spree::Payment::Processing
def authorize(money, creditcard, gateway_options)
authorize_response = provider.authorize(*options_for_authorize(money,
creditcard,
gateway_options))
if url = url_for_authorization(authorize_response)
authorize_response.cvv_result['message'] = url if authorize_response.cvv_result.present?
end
authorize_response
rescue Stripe::StripeError => e
# This will be an error caused by generating a stripe token
failed_activemerchant_billing_response(e.message)
end
@@ -65,11 +97,17 @@ module Spree
options.merge(login: Stripe.api_key)
end
def options_for_purchase_or_auth(money, creditcard, gateway_options)
def basic_options(gateway_options)
options = {}
options[:description] = "Spree Order ID: #{gateway_options[:order_id]}"
options[:currency] = gateway_options[:currency]
options[:stripe_account] = stripe_account_id
options
end
def options_for_authorize(money, creditcard, gateway_options)
options = basic_options(gateway_options)
options[:return_url] = full_checkout_path
customer_id, payment_method_id = Stripe::CreditCardCloner.new.clone(creditcard,
stripe_account_id)
@@ -77,6 +115,23 @@ module Spree
[money, payment_method_id, options]
end
def url_for_authorization(response)
next_action = response.params["next_source_action"]
return unless response.params["status"] == "requires_source_action" &&
next_action.present? &&
next_action["type"] == "authorize_with_url"
next_action["authorize_with_url"]["url"]
end
def payment_intent(creditcard, gateway_options)
order_number = gateway_options[:order_id].split('-').first
payment = Spree::Order.find_by_number(order_number).payments.merge(creditcard.payments).last
return unless payment
payment.response_code
end
def failed_activemerchant_billing_response(error_message)
ActiveMerchant::Billing::Response.new(false, error_message)
end
@@ -86,6 +141,16 @@ module Spree
errors.add(:stripe_account_owner, I18n.t(:error_required))
end
def full_checkout_path
URI.join(url_helpers.root_url, url_helpers.checkout_path).to_s
end
def url_helpers
# This is how we can get the helpers with a usable root_url outside the controllers
Rails.application.routes.default_url_options = ActionMailer::Base.default_url_options
Rails.application.routes.url_helpers
end
end
end
end