Identify when Shop Pay email does not match logged in email

We have a store that requires customers to be logged in and approved in order to make purchases. We are experiencing an issue with the express Shop Pay checkout option. If a customer pays with Shop Pay that is connected to a different email than they are logged in as, the order will be attributed to the email on the Shop Pay account, thus creating a new customer account in Shopify. This is an issue because orders and rewards will be attributed to the wrong account.

Unfortunately, disabling Shop Pay in the store is not an option. In an attempt to fix this, I tried implementing a Checkout Validation function that will check if the customer email on the cart has the specific tags that determines if a customer is verified or not.

The issue is that the checkout function always validates the logged in customer email, rather than the email Shop Pay is actually applying.

For example, if I’m logged into my approved account as approved@email.com (which is the account we actually want the order to be attached to) and my Shop Pay account express checkout puts in shoppay@email.com (the wrong email), I want the Checkout Validation function to read the wrong email and prevent the order. But it is reading the approved email every time.

Is there a way for a checkout validation function to read the email Shop Pay is ACTUALLY putting in? Or is there another function that will allow us to prevent orders being attributed to the wrong customer email?

query CartValidationsGenerateRunInput {
  buyerJourney {
    step
  }
  cart {
    buyerIdentity {
      email
      customer {
        hasAnyTag(tags: ["approved"])
      }
    }
  }
}
import { BuyerJourneyStep } from "../generated/api";

/**
 * @typedef {import("../generated/api").CartValidationsGenerateRunInput} CartValidationsGenerateRunInput
 * @typedef {import("../generated/api").CartValidationsGenerateRunResult} CartValidationsGenerateRunResult
 */

/**
 * @param {CartValidationsGenerateRunInput} input
 * @returns {CartValidationsGenerateRunResult}
 */
export function cartValidationsGenerateRun(input) {
  const step = input.buyerJourney.step;
  const customer = input.cart?.buyerIdentity?.customer;
  const email = input.cart?.buyerIdentity?.email;
  const isApproved = customer?.hasAnyTag;

  if (step === BuyerJourneyStep.CartInteraction || !email) {
    return { operations: [] };
  }

  if (!isApproved) {
    return {
      operations: [
        {
          validationAdd: {
            errors: [
              {
                message:
                  `Your email address (${email}) is not approved to place orders. If you're using Shop Pay, ensure it's connected to your approved account email, or select a different payment method.`,
                target: "$.cart.buyerIdentity.email",
              },
            ],
          },
        },
      ],
    };
  }

  return { operations: [] };
}

@jc_lk the core issue here is that during Shop Pay express checkout, the email is resolved from the Shop Pay account before your validation function can intercept it, so by the time the function runs it’s already reading the logged-in customer rather than the Shop Pay email being applied.

One approach worth trying is adding the PAYMENT_CUSTOMIZATION step check instead of relying solely on CartInteraction. Also, you can try querying purchasingCompany or checking at THANK_YOU step to catch the mismatch post-checkout and trigger a correction flow via webhook.

The more reliable workaround we’ve seen is handling this on the orders/create webhook side — when an order comes in, check if the email matches an approved customer tag, and if not, flag it for manual review or auto-cancel. Not ideal but it’s more dependable than trying to intercept Shop Pay mid-flow since Shopify doesn’t currently expose the Shop Pay email to validation functions before it’s applied.