mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-04-05 07:19:14 +00:00
Make credit card cloner clone the payment method even if the customer is not given
This makes the payments without saving card work again in the frontoffice as well as the payments taken by the seller in the backoffice
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Here we clone
|
||||
# - a card (card_*) or payment_method (pm_*) stored in a customer in a platform account
|
||||
# - a card (card_*) or payment_method (pm_*) stored (in a customer) in a platform account
|
||||
# into
|
||||
# - a payment method (pm_*) in a new customer in a connected account
|
||||
# - a payment method (pm_*) (in a new customer) in a connected account
|
||||
#
|
||||
# This is required when using the Stripe Payment Intents API:
|
||||
# - the customer and payment methods are stored in the platform account
|
||||
@@ -18,13 +18,11 @@
|
||||
module Stripe
|
||||
class CreditCardCloner
|
||||
def clone(credit_card, connected_account_id)
|
||||
# No need to clone the card if there's no customer, i.e., it's a card for one time usage
|
||||
if credit_card.gateway_customer_profile_id.blank?
|
||||
return nil, credit_card.gateway_payment_profile_id
|
||||
end
|
||||
|
||||
new_payment_method = clone_payment_method(credit_card, connected_account_id)
|
||||
|
||||
# If no customer is given, it will clone the payment method only
|
||||
return nil, new_payment_method.id if credit_card.gateway_customer_profile_id.blank?
|
||||
|
||||
new_customer = Stripe::Customer.create({ email: credit_card.user.email },
|
||||
stripe_account: connected_account_id)
|
||||
attach_payment_method_to_customer(new_payment_method.id,
|
||||
|
||||
@@ -28,17 +28,13 @@ module Stripe
|
||||
before do
|
||||
allow(Stripe).to receive(:api_key) { "sk_test_12345" }
|
||||
|
||||
stub_request(:post, "https://api.stripe.com/v1/payment_methods")
|
||||
.with(body: { customer: customer_id, payment_method: payment_method_id},
|
||||
headers: { 'Stripe-Account' => stripe_account_id })
|
||||
.to_return(payment_method_response_mock)
|
||||
|
||||
stub_request(:post, "https://api.stripe.com/v1/customers")
|
||||
.with(body: { email: credit_card.user.email },
|
||||
headers: { 'Stripe-Account' => stripe_account_id })
|
||||
.to_return(customer_response_mock)
|
||||
|
||||
stub_request(:post, "https://api.stripe.com/v1/payment_methods/#{new_payment_method_id}/attach")
|
||||
stub_request(:post,
|
||||
"https://api.stripe.com/v1/payment_methods/#{new_payment_method_id}/attach")
|
||||
.with(body: { customer: new_customer_id },
|
||||
headers: { 'Stripe-Account' => stripe_account_id })
|
||||
.to_return(payment_method_response_mock)
|
||||
@@ -47,24 +43,36 @@ module Stripe
|
||||
end
|
||||
|
||||
context "when called with a card without a customer (one time usage card)" do
|
||||
it "returns a nil customer and the given payment id" do
|
||||
before do
|
||||
stub_request(:post, "https://api.stripe.com/v1/payment_methods")
|
||||
.with(body: { payment_method: payment_method_id },
|
||||
headers: { 'Stripe-Account' => stripe_account_id })
|
||||
.to_return(payment_method_response_mock)
|
||||
end
|
||||
|
||||
it "clones the payment method only" do
|
||||
customer_id, payment_method_id = cloner.clone(credit_card, stripe_account_id)
|
||||
|
||||
expect(payment_method_id).to eq new_payment_method_id
|
||||
expect(customer_id).to eq nil
|
||||
expect(payment_method_id).to eq payment_method_id
|
||||
end
|
||||
end
|
||||
|
||||
context "when called with a valid customer and payment_method" do
|
||||
before do
|
||||
stub_request(:post, "https://api.stripe.com/v1/payment_methods")
|
||||
.with(body: { customer: customer_id, payment_method: payment_method_id },
|
||||
headers: { 'Stripe-Account' => stripe_account_id })
|
||||
.to_return(payment_method_response_mock)
|
||||
|
||||
credit_card.update_attribute :gateway_customer_profile_id, customer_id
|
||||
end
|
||||
|
||||
it "clones the card successefully" do
|
||||
it "clones both the payment method and the customer" do
|
||||
customer_id, payment_method_id = cloner.clone(credit_card, stripe_account_id)
|
||||
|
||||
expect(customer_id).to eq new_customer_id
|
||||
expect(payment_method_id).to eq new_payment_method_id
|
||||
expect(customer_id).to eq new_customer_id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -75,10 +75,20 @@ describe "checking out an order with a Stripe SCA payment method", type: :reques
|
||||
end
|
||||
|
||||
context "when the user submits a new card and doesn't request that the card is saved for later" do
|
||||
let(:hubs_payment_method_response_mock) do
|
||||
{ status: 200, body: JSON.generate(id: hubs_stripe_payment_method) }
|
||||
end
|
||||
|
||||
before do
|
||||
# Clones the payment method to the hub's stripe account
|
||||
stub_request(:post, "https://api.stripe.com/v1/payment_methods")
|
||||
.with(body: { payment_method: stripe_payment_method },
|
||||
headers: { 'Stripe-Account' => 'abc123' })
|
||||
.to_return(hubs_payment_method_response_mock)
|
||||
|
||||
# Charges the card
|
||||
stub_request(:post, "https://api.stripe.com/v1/payment_intents")
|
||||
.with(basic_auth: ["sk_test_12345", ""], body: /#{stripe_payment_method}.*#{order.number}/)
|
||||
.with(basic_auth: ["sk_test_12345", ""], body: /#{hubs_stripe_payment_method}.*#{order.number}/)
|
||||
.to_return(payment_intent_response_mock)
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user