Solved

Possible to restrict payment methods via customer email?

Kronos9326
Excursionist
15 1 0

Is it possible to detect a customers email address at checkout, and then restrict the payment methods that are available to them?

 

ie. Email address = joe@blow.com then remove all but paypal

Accepted Solution (1)
playwright-mike
Shopify Partner
72 18 33

This is an accepted solution.

You can achieve this by creating a new Payment Method script in the Script Editor.

 

  1. Be sure you have the Script Editor app installed
  2. Create a new Payment Method script
  3. Choose a "Blank template"
  4. Paste this script into the code area
  5. Customize the top of the script to include the emails to search for and the payment methods to hide

When customizing the script, be sure to put the payment methods in lowercase letters. So "Shopify Payments" should be written as "shopify payments".

You should be able test your script in the Script Editor or preview the script in your checkout.

 

HIDE_GATEWAYS_FOR_CUSTOMER_EMAILS = [
  {
    customer_email_match_type: :include,
    customer_emails: ["joe@blow.com", "jill@example.com"],
    gateway_match_type: :exact,
    gateway_names: ["shopify payments", "bank deposit"],
  },
]

# ================================ Script Code (do not edit) ================================
# ================================================================
# CustomerEmailSelector
#
# Finds whether the supplied customer matching email.
# ================================================================
class CustomerEmailSelector
  def initialize(match_type, emails)
    @comparator = match_type == :include ? 'any?' : 'none?'
    @emails = emails.map { |email| email.downcase.strip }
  end

  def match?(customer)
    customer_email = customer.email.downcase
    @emails.include? customer_email
  end
end

# ================================================================
# GatewayNameSelector
#
# Finds whether the supplied gateway name matches any of the
# entered names.
# ================================================================
class GatewayNameSelector
  def initialize(match_type, gateway_names)
    @comparator = match_type == :exact ? '==' : 'include?'
    @gateway_names = gateway_names.map { |name| name.downcase.strip }
  end

  def match?(payment_gateway)
    @gateway_names.any? { |name| payment_gateway.name.downcase.strip.send(@comparator, name) }
  end
end

# ================================================================
# HideGatewaysForCustomerEmailsCampaign
#
# If we have a matching customer, the entered gateway(s) will be
# hidden.
# ================================================================
class HideGatewaysForCustomerEmailsCampaign
  def initialize(campaigns)
    @campaigns = campaigns
  end

  def run(cart, payment_gateways)
    return if cart.customer.nil?

    @campaigns.each do |campaign|
      customer_email_selector = CustomerEmailSelector.new(
        campaign[:customer_email_match_type],
        campaign[:customer_emails],
      )

      next unless customer_email_selector.match?(cart.customer)

      gateway_name_selector = GatewayNameSelector.new(
        campaign[:gateway_match_type],
        campaign[:gateway_names],
      )
      
      payment_gateways.delete_if do |payment_gateway|
        gateway_name_selector.match?(payment_gateway)
      end
    end
  end
end

CAMPAIGNS = [
  HideGatewaysForCustomerEmailsCampaign.new(HIDE_GATEWAYS_FOR_CUSTOMER_EMAILS),
]

CAMPAIGNS.each do |campaign|
  campaign.run(Input.cart, Input.payment_gateways)
end

Output.payment_gateways = Input.payment_gateways

 

 

Let me know if that was helpful for you!

Matthew

Playwright | Create Shopify Scripts without writing code | https://playwrightapp.com
- Was my reply helpful? Please Like and Accept Solution.

View solution in original post

Replies 2 (2)

WhiteWater_Web
Shopify Expert
456 17 42

Hi there - this is possible if you are on Shopify Plus. 

Let us know if you need a hand.

Cheers!

WhiteWater Web

A certified Shopify Partner and Expert, WhiteWater Web (WWW) is a premium digital solutions company specializing in advanced Shopify Dev, Usability/Design, and Online Strategy. WWW has been working with the Shopify platform since 2006.
info@whitewatersolutions.com
playwright-mike
Shopify Partner
72 18 33

This is an accepted solution.

You can achieve this by creating a new Payment Method script in the Script Editor.

 

  1. Be sure you have the Script Editor app installed
  2. Create a new Payment Method script
  3. Choose a "Blank template"
  4. Paste this script into the code area
  5. Customize the top of the script to include the emails to search for and the payment methods to hide

When customizing the script, be sure to put the payment methods in lowercase letters. So "Shopify Payments" should be written as "shopify payments".

You should be able test your script in the Script Editor or preview the script in your checkout.

 

HIDE_GATEWAYS_FOR_CUSTOMER_EMAILS = [
  {
    customer_email_match_type: :include,
    customer_emails: ["joe@blow.com", "jill@example.com"],
    gateway_match_type: :exact,
    gateway_names: ["shopify payments", "bank deposit"],
  },
]

# ================================ Script Code (do not edit) ================================
# ================================================================
# CustomerEmailSelector
#
# Finds whether the supplied customer matching email.
# ================================================================
class CustomerEmailSelector
  def initialize(match_type, emails)
    @comparator = match_type == :include ? 'any?' : 'none?'
    @emails = emails.map { |email| email.downcase.strip }
  end

  def match?(customer)
    customer_email = customer.email.downcase
    @emails.include? customer_email
  end
end

# ================================================================
# GatewayNameSelector
#
# Finds whether the supplied gateway name matches any of the
# entered names.
# ================================================================
class GatewayNameSelector
  def initialize(match_type, gateway_names)
    @comparator = match_type == :exact ? '==' : 'include?'
    @gateway_names = gateway_names.map { |name| name.downcase.strip }
  end

  def match?(payment_gateway)
    @gateway_names.any? { |name| payment_gateway.name.downcase.strip.send(@comparator, name) }
  end
end

# ================================================================
# HideGatewaysForCustomerEmailsCampaign
#
# If we have a matching customer, the entered gateway(s) will be
# hidden.
# ================================================================
class HideGatewaysForCustomerEmailsCampaign
  def initialize(campaigns)
    @campaigns = campaigns
  end

  def run(cart, payment_gateways)
    return if cart.customer.nil?

    @campaigns.each do |campaign|
      customer_email_selector = CustomerEmailSelector.new(
        campaign[:customer_email_match_type],
        campaign[:customer_emails],
      )

      next unless customer_email_selector.match?(cart.customer)

      gateway_name_selector = GatewayNameSelector.new(
        campaign[:gateway_match_type],
        campaign[:gateway_names],
      )
      
      payment_gateways.delete_if do |payment_gateway|
        gateway_name_selector.match?(payment_gateway)
      end
    end
  end
end

CAMPAIGNS = [
  HideGatewaysForCustomerEmailsCampaign.new(HIDE_GATEWAYS_FOR_CUSTOMER_EMAILS),
]

CAMPAIGNS.each do |campaign|
  campaign.run(Input.cart, Input.payment_gateways)
end

Output.payment_gateways = Input.payment_gateways

 

 

Let me know if that was helpful for you!

Matthew

Playwright | Create Shopify Scripts without writing code | https://playwrightapp.com
- Was my reply helpful? Please Like and Accept Solution.