mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-20 04:59:16 +00:00
72 lines
2.7 KiB
Ruby
72 lines
2.7 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# Here we clone (or find a clone of)
|
|
# - 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
|
|
#
|
|
# This is required when using the Stripe Payment Intents API:
|
|
# - the customer and payment methods are stored in the platform account
|
|
# so that they can be re-used across multiple sellers
|
|
# - when a card needs to be charged, we need to clone (or find the clone)
|
|
# in the seller's stripe account
|
|
#
|
|
# To avoid creating a new clone of the card/customer each time the card is charged or
|
|
# authorized (e.g. for SCA), we attach metadata { clone: true } to the card the first time we
|
|
# clone it and look for a card with the same fingerprint (hash of the card number) and
|
|
# that metadata key to avoid cloning it multiple times.
|
|
|
|
require 'stripe/credit_card_clone_finder'
|
|
|
|
module Stripe
|
|
class CreditCardCloner
|
|
def initialize(card, stripe_account)
|
|
@card = card
|
|
@stripe_account = stripe_account
|
|
end
|
|
|
|
def find_or_clone
|
|
cloned_card = Stripe::CreditCardCloneFinder.new(@card, @stripe_account).find_cloned_card
|
|
cloned_card || clone
|
|
end
|
|
|
|
private
|
|
|
|
def clone
|
|
new_payment_method = clone_payment_method
|
|
|
|
# If no customer is given, it will clone the payment method only
|
|
return [nil, new_payment_method.id] if @card.gateway_customer_profile_id.blank?
|
|
|
|
new_customer = Stripe::Customer.create({ email: @card.user.email },
|
|
stripe_account: @stripe_account)
|
|
attach_payment_method_to_customer(new_payment_method.id,
|
|
new_customer.id)
|
|
|
|
add_metadata_to_payment_method(new_payment_method.id)
|
|
|
|
[new_customer.id, new_payment_method.id]
|
|
end
|
|
|
|
def clone_payment_method
|
|
platform_acct_payment_method_id = @card.gateway_payment_profile_id
|
|
customer_id = @card.gateway_customer_profile_id
|
|
|
|
Stripe::PaymentMethod.create({ customer: customer_id,
|
|
payment_method: platform_acct_payment_method_id },
|
|
stripe_account: @stripe_account)
|
|
end
|
|
|
|
def attach_payment_method_to_customer(payment_method_id, customer_id)
|
|
Stripe::PaymentMethod.attach(payment_method_id,
|
|
{ customer: customer_id },
|
|
stripe_account: @stripe_account)
|
|
end
|
|
|
|
def add_metadata_to_payment_method(payment_method_id)
|
|
Stripe::PaymentMethod.update(payment_method_id,
|
|
{ metadata: { "ofn-clone": true } },
|
|
stripe_account: @stripe_account)
|
|
end
|
|
end
|
|
end
|