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:
luisramos0
2020-01-28 12:10:03 +00:00
parent 47916f823f
commit 404e7c1f37
3 changed files with 34 additions and 18 deletions

View File

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

View File

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

View File

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