Skip to main content

Identify Shop users

Shop Pay Wallet and Sign in with Shop identify a buyer with the same value: the Shop user's public ID. Read it from the payment request receipt after checkout, store it on your own customer record, and resolve it again when the same person logs in later.


In this guide, you'll learn how to do the following tasks:

  • Read the Shop user public ID from a payment request receipt.
  • Store the public ID on a customer record in your system.
  • Add Sign in with Shop to your login page and resolve the same public ID.

  • A working Shop Pay Wallet integration. To set one up, refer to Get started with Shop Pay Wallet.
  • Storefront API version 2026-10 or later, or unstable.
  • A Shop app with a client ID and client secret.
  • A login page and a customer database that you control.

Anchor to Step 1: Get the public ID after a paymentStep 1: Get the public ID after a payment

The ShopPayPaymentRequestSessionSubmit mutation returns a receipt for the payment. Request shopUser on the receipt to get the public ID of the Shop user who authorized it:

Mutation

mutation shopPayPaymentRequestSessionSubmit($token: String!, $paymentRequest: ShopPayPaymentRequestInput!, $idempotencyKey: String!) {
shopPayPaymentRequestSessionSubmit(token: $token, paymentRequest: $paymentRequest, idempotencyKey: $idempotencyKey) {
paymentRequestReceipt {
token
processingStatusType
shopUser {
publicId
}
}
userErrors {
field
message
}
}
}

Response

{
"shopPayPaymentRequestSessionSubmit": {
"paymentRequestReceipt": {
"token": "a607823b7ba40ddb4eede13822684b13",
"processingStatusType": "ready",
"shopUser": {
"publicId": "4kQ9mLd2XbVw7NcRp1TgHs6y"
}
},
"userErrors": []
}
}

FieldTypeDescription
publicIdStringThe public ID of the Shop user that authorized the payment request.

shopUser is nullable. It's null when Shopify can't attribute the payment to a Shop user, so complete the order without a Shop user link instead of treating the payment as failed.


Anchor to Step 2: Store the public IDStep 2: Store the public ID

The public ID is a stable identifier for a Shop user. The same person returns the same public ID on every payment and every sign-in, so you can use it as the key that links a Shop user to your own customer record.

After the payment succeeds:

  1. Create or update the customer record in your database, and save the public ID on it.
  2. Start your own session for that customer, such as a signed session cookie.
  3. Continue with your existing order confirmation flow.

Anchor to Step 3: Add Sign in with Shop to your login pageStep 3: Add Sign in with Shop to your login page

Your login page is hosted outside Shopify, so it signs users in with the OpenID Connect authorization code flow, using Shop as the identity provider. Sign in with Shop covers the Shop SDK login feature that renders the button, and Sign in with a third-party identity provider lists every OIDC endpoint.

Redirect the user to https://accounts.shop.app/oauth/authorize with the following query parameters:

ParameterValue
client_idYour Shop app's client ID.
redirect_uriOne of the redirect URLs registered on your Shop app.
response_typecode.
scopeopenid email.
stateA random per-request value that you verify when the user comes back.
code_challengeThe S256 challenge for a per-request PKCE code verifier.
code_challenge_methodS256.

After the user signs in, Shop redirects to your redirect_uri with a code parameter and your state.

Use the right client ID

Use your Shop app's client ID here, not the clientId that you pass to the Shop Pay Wallet JavaScript SDK. The client ID used for Shop Pay Wallet JavaScript SDK will not currently work with the Shop SDK, and so will show an error in the sign in flow if you use it here.


Anchor to Step 4: Exchange the code for an ID tokenStep 4: Exchange the code for an ID token

Exchange the code from your backend, where the client secret stays private:

Token request

curl -X POST https://accounts.shop.app/oauth/token \
-d grant_type=authorization_code \
-d code={code} \
-d redirect_uri={redirect_uri} \
-d code_verifier={code_verifier} \
-d client_id={client_id} \
-d client_secret={client_secret}

The response includes an id_token. Validate it before you trust anything in it:

  1. Verify the signature against the keys at https://accounts.shop.app/auth/jwks.
  2. Check that iss is https://accounts.shop.app, that aud is your client ID, and that exp is in the future.

The sub claim of a validated ID token is the Shop user's public ID, and the email claim is the address on the Shop account.


Anchor to Step 5: Log the user inStep 5: Log the user in

  1. Look up the customer record whose stored public ID matches sub.
  2. If a record exists, then start your session for that customer.
  3. If no record exists, then create one from sub and email.

Because both surfaces return the same value, a buyer who checks out with Shop Pay Wallet first and logs in weeks later lands on one customer record.



Was this page helpful?