Shopify Payments Apps: New Verification Rejection Codes and Merchant Messages — What Developers Need to Know

Shopify Payments Apps: New Verification Rejection Codes and Merchant Messages — What Developers Need to Know

Table of Contents

  1. Key Highlights:
  2. Introduction
  3. What changed in verificationSessionReject
  4. How the new reason codes map to real-world provider responses
  5. Practical examples and use cases
  6. Implementing verificationSessionReject: a step-by-step guide
  7. Localization best practices for merchantMessage
  8. UI considerations for merchant-facing rejections
  9. Security, privacy, and compliance considerations
  10. Testing: how to validate your implementation
  11. Observability: metrics and dashboards to run
  12. Mapping logic: examples for popular payment providers
  13. Operational playbook and support flow
  14. Migration and backward compatibility
  15. Example integration patterns and code snippets
  16. Common pitfalls and how to avoid them
  17. Operational examples: how to triage a sudden spike in rejections
  18. Governance: policies for merchantMessage content
  19. Where this fits in the broader payments architecture
  20. Next steps for payments app developers
  21. FAQ

Key Highlights:

  • The Payments Apps API's verificationSessionReject mutation now includes two precise rejection reason codes — RESOURCE_NOT_FOUND and RESOURCE_INVALID — plus an optional merchantMessage field for localized, merchant-facing explanations.
  • These additions let payment apps report provider-specific failures with greater accuracy, improve merchant UX, and simplify error mapping, logging, and operational triage.

Introduction

Verification failures interrupt checkout flows and merchant operations. When a payment method cannot be confirmed, merchants need clear, actionable information: is the payment method missing at the provider, is the token invalid for this use case, or is something else wrong? Shopify's update to the Payments Apps API refines how verification rejections are reported. Two new enum values in VerificationSessionStateReason provide greater specificity about why a verification failed, and an optional merchantMessage lets apps deliver a localized explanation directly to merchants.

This change affects payments app developers, integrators, and platform engineers who handle GraphQL verification mutations, map provider errors, and design merchant-facing error handling. The following analysis explains what changed, why it matters, and how to implement these fields responsibly, with examples, best practices, testing guidance, and operational recommendations.

What changed in verificationSessionReject

The verificationSessionReject mutation now accepts more granular reasons and an optional message field intended for the merchant.

Key API updates

  • Two new enum values added to VerificationSessionStateReason:
    • RESOURCE_NOT_FOUND: The payment method cannot be located in the payment provider's system.
    • RESOURCE_INVALID: The payment token is not valid for this use case (for example, it belongs to a different customer or was issued for another payment flow).
  • A new optional input field merchantMessage on VerificationSessionRejectionReasonInput: a custom, localized string the payments app can supply to explain the rejection to the merchant.

Why these fields matter

  • Precise diagnosis: Apps can distinguish between a missing resource and an invalid token, reducing ambiguous error states.
  • Better merchant UX: merchantMessage enables concise, localized guidance at the point of failure.
  • Operational clarity: Logs and metrics enriched with the new codes make troubleshooting and reconciliation more efficient.

These additions are especially relevant to apps that act as intermediaries between merchants and external payment providers (Stripe, Adyen, PayPal, etc.), and to teams that maintain verification flows (saving cards, verifying payment methods, or tokenizing alternative payment methods).

How the new reason codes map to real-world provider responses

Different payment providers present failures differently. Mapping provider-specific error responses to these standardized enum values reduces ambiguity and ensures consistent merchant messaging.

RESOURCE_NOT_FOUND

  • Typical provider signals:
    • HTTP 404 responses for missing payment method endpoints.
    • Error codes like "payment_method_not_found" or "card_not_found".
    • A lookup attempt for a token or payment method ID returns empty.
  • Real-world scenario:
    • Merchant attempts to charge a saved card, the app looks up the card ID at the provider, and the provider returns 404 because the card was deleted or never existed under that token. Use RESOURCE_NOT_FOUND.

RESOURCE_INVALID

  • Typical provider signals:
    • Error codes indicating token misuse, ownership mismatch, or wrong token type (e.g., one-time token used for recurring charge).
    • Explicit messages such as "token invalid for this operation", "payment_method does not belong to customer", or "card must be re-authenticated".
  • Real-world scenario:
    • A merchant attempts to verify a payment token that was generated for a different customer or for a different merchant account. The provider rejects the request citing token-to-customer mismatch. Use RESOURCE_INVALID.

Ambiguous or mixed cases

  • Providers sometimes return vague errors. If the provider response cannot be reliably classified as missing vs invalid, prefer conservative handling: choose the code that best matches likely merchant action (often RESOURCE_INVALID), include a clear merchantMessage, and log provider details for follow-up.

Practical examples and use cases

Below are concrete scenarios showing when each code should be used and examples for merchantMessage content.

Scenario A — Deleted stored card

  • Situation: Merchant attempts to re-use a token for a stored card; provider returns 404.
  • Reason: RESOURCE_NOT_FOUND
  • merchantMessage: "Saved card not found at the payment provider. Ask the customer to re-enter their card details or re-save the payment method."

Scenario B — Token generated for different customer

  • Situation: A token created during checkout for customer A is presented during an order for customer B.
  • Reason: RESOURCE_INVALID
  • merchantMessage: "The payment information appears linked to a different customer. Ask the customer to re-enter their payment details."

Scenario C — Token intended for single-use only

  • Situation: The stored payment token is a single-use token; the provider refuses reuse.
  • Reason: RESOURCE_INVALID
  • merchantMessage: "This payment token can only be used once. Request a new payment method from the customer."

Scenario D — Provider-side outage or sync lag

  • Situation: Provider temporarily cannot resolve the resource (intermittent 404-like error).
  • Reason: when transient, treat as RESOURCE_NOT_FOUND but add guidance about retry
  • merchantMessage: "Payment provider could not locate the method right now. Try again in a few minutes or ask the customer to re-add the payment method."

Scenario E — Fraud or token revocation by provider

  • Situation: Provider marks token invalid due to suspected fraud or revoked credentials.
  • Reason: RESOURCE_INVALID
  • merchantMessage: "Payment method was declined by the payment provider. Re-request payment details from the customer or contact the payment provider."

These examples show how combining reason codes with a clear merchant message yields a better path forward than an opaque "verification failed" state.

Implementing verificationSessionReject: a step-by-step guide

This section walks through the lifecycle of mapping a provider error to the new verificationSessionReject input and sending the mutation.

  1. Capture and normalize provider error
  • Parse the provider response for status codes, numeric error codes, and textual messages.
  • Normalize to a structured object with fields like type, code, status, message, and whether the error is transient.
  1. Map normalized error to VerificationSessionStateReason
  • Maintain a mapping layer from provider codes to Shopify enums:
    • 404 / payment_method_not_found -> RESOURCE_NOT_FOUND
    • token_owner_mismatch / token_invalid_for_operation -> RESOURCE_INVALID
  • If mapping is uncertain, prefer RESOURCE_INVALID and record provider details.
  1. Compose merchantMessage
  • Build a concise, non-technical message that guides the merchant.
  • Localize the message according to the shop's locale settings.
  • Do not include provider internal IDs or sensitive tokens.
  1. Call verificationSessionReject via GraphQL
  • Include the standardized enum and merchantMessage in the rejection reason.

Sample GraphQL mutation

mutation RejectVerification($sessionId: ID!, $reason: VerificationSessionRejectionReasonInput!) {
  verificationSessionReject(id: $sessionId, reason: $reason) {
    verificationSession {
      id
      state
      stateReason {
        code
        merchantMessage
      }
    }
    userErrors {
      field
      message
    }
  }
}

Example variables for RESOURCE_NOT_FOUND

{
  "sessionId": "gid://shopify/PaymentVerificationSession/12345",
  "reason": {
    "code": "RESOURCE_NOT_FOUND",
    "merchantMessage": "Saved payment method not found at the payment provider. Ask the customer to re-enter their payment method."
  }
}

Example variables for RESOURCE_INVALID

{
  "sessionId": "gid://shopify/PaymentVerificationSession/67890",
  "reason": {
    "code": "RESOURCE_INVALID",
    "merchantMessage": "The supplied payment token is invalid for this action. Request a new payment method from the customer."
  }
}
  1. Handle response and update application state
  • On success, update your internal verification state and present any merchantMessage in the merchant UI.
  • On errors or userErrors from Shopify, log and surface actionable items to the development or ops team.
  1. Logging and auditing
  • Persist provider response, the mapping decision, the chosen enum, and merchantMessage for audits and troubleshooting.
  • Mask any sensitive data stored for logs per PCI and privacy rules.

Localization best practices for merchantMessage

merchantMessage is intended for merchants, not end customers. Messages should be short, clear, and localized. Consider these practices:

  • Use the shop's primary locale or locales configured in Shopify. Query the shop's locale via the Admin API if necessary.
  • Maintain translation files for each supported locale rather than concatenating messages on the fly.
  • Keep messages under a brief character limit (e.g., 200 characters) to avoid UI overflow.
  • Avoid platform or provider-specific jargon. Replace codes like "RESOURCE_NOT_FOUND" with an actionable sentence.
  • Provide a single actionable suggestion: re-enter card, contact provider, or retry in a few minutes.
  • Where relevant, include localized links (help center, support contact) that open in the merchant's preferred language.

Examples of merchantMessage variants

  • English: "Saved card not found. Ask the customer to re-enter their card details or save a new payment method."
  • Spanish: "No se encontró la tarjeta guardada. Solicite al cliente que vuelva a ingresar los datos o guarde un nuevo método de pago."
  • French: "Carte enregistrée no trouvée. Demandez au client de saisir à nouveau ses coordonnées ou d'enregistrer un nouveau moyen de paiement."

Keep messages generic enough to avoid exposing provider error internals but specific enough to guide next steps.

UI considerations for merchant-facing rejections

How merchants see and act on merchantMessage defines how useful this field is. Design merchant UI elements around clarity and action.

Placement

  • Present merchantMessage inline with the verification status on the relevant order or payment method page.
  • Include a status badge (e.g., "Verification rejected: Reason") with a short message and a "Next steps" area.

Action buttons

  • Offer a primary action tailored to the message:
    • "Request new payment details"
    • "Retry verification" (if transient)
    • "Contact payment provider"
  • Provide a secondary "Details" link that shows sanitized provider logs for admins or ops teams.

Role-based visibility

  • Only show merchantMessage to user roles that need it (store owner, support staff). Avoid exposing it to customers.

Audit trail

  • Attach the rejection reason and merchantMessage to the order timeline or payment history so staff can see when and why verification was rejected.

Accessibility

  • Ensure messages are readable by screen readers and follow contrast and semantic HTML best practices.

Security, privacy, and compliance considerations

merchantMessage should be merchant-friendly and must never expose sensitive data. Adhere to these rules.

Avoid sensitive details

  • Never include full payment tokens, card numbers, CVV, provider API keys, or any PII in merchantMessage.
  • Do not embed provider error payloads directly in merchant-facing strings.

Limit what you log

  • Logs should retain enough context for debugging but must mask or truncate tokens, PANs, and CVVs.
  • Follow PCI DSS guidance for logging payment-related data.

Data retention and GDPR

  • Treat verification failure records as operational data; purge or anonymize according to your retention policies and legal obligations.
  • For EU merchants, allow data subject requests to remove personal data used in debug logs.

Rate limiting and retries

  • Avoid automated repeated verification attempts that could trigger provider rate limits or fraud detection.
  • Use exponential backoff for retries and qualify retries only for transient errors.

Least privilege

  • When calling providers' APIs, use scoped credentials limited to required operations. Rotate credentials periodically and handle secrets securely.

Transport security

  • Use TLS for all provider and Shopify API calls. Validate certificates and monitor for weak ciphers.

Testing: how to validate your implementation

Robust testing reduces surprises in production. Cover these layers:

Unit tests

  • Build unit tests for the mapping layer that converts provider error payloads into VerificationSessionStateReason and merchantMessage.
  • Include tests for unknown or newly introduced provider codes.

Integration tests

  • Simulate provider responses across a variety of error codes and validate the GraphQL mutation payloads your app sends.
  • Test merchantMessage localization by changing shop locales and verifying translations render correctly.

End-to-end tests

  • Run test flows that exercise the verificationSessionReject mutation and confirm the merchant UI displays merchantMessage and state updates correctly in the Shopify admin.

Staging provider

  • Use providers' sandbox or test environments to simulate 404-like missing resources and token mismatch scenarios.
  • If the provider lacks specific error codes in test mode, inject synthetic responses or use a mock provider to simulate exact behaviors.

Monitoring and alerting

  • Track the rate of verification rejections by reason code.
  • Alert on unexpected spikes in RESOURCE_NOT_FOUND or RESOURCE_INVALID that could indicate provider outages or systemic regressions.

Manual QA checklist

  • Confirm merchantMessage strings are concise and actionable.
  • Verify messages are localized and displayed in the appropriate language.
  • Ensure no PII or sensitive tokens appear in merchant-facing text or logs.

Observability: metrics and dashboards to run

Instrument rejection flows to gain operational insight and to measure merchant impact.

Essential metrics

  • Rejection count per reason (RESOURCE_NOT_FOUND, RESOURCE_INVALID, other).
  • Rejection rate per verification attempt (rejections / total verifications).
  • Time-to-resolution for rejections (median and P95).
  • Retried verifications success rate after rejection.
  • Rejections per merchant (to detect misconfiguration or merchant-specific issues).

Dashboards

  • Trend chart of rejection rates over time segmented by reason code and provider.
  • Heatmap of rejections per region and per shop locale.
  • Correlation view linking provider errors to rejection codes.

Alerts

  • High-volume spike in RESOURCE_NOT_FOUND → potential provider degradation.
  • Rising trend in RESOURCE_INVALID → possible tokenization issues or integration regression.
  • Persistent rejections for a single merchant → targeted support outreach.

Logging schema

  • For each rejection, log: timestamp, shop_id, verification_session_id, provider_response_summary (sanitized), chosen_reason_code, merchantMessage, and developer_reason_classification.
  • Store a trace ID to tie together provider request, GraphQL call, and merchant UI event.

Mapping logic: examples for popular payment providers

Provide mapping examples for common providers to reduce ambiguity.

Stripe

  • Provider signal: 404 when retrieving PaymentMethod by ID → RESOURCE_NOT_FOUND
  • Provider signal: "resource_missing" / "No such payment_method" → RESOURCE_NOT_FOUND
  • Provider signal: "payment_method_unactivated" or "token_already_used" (single-use token) → RESOURCE_INVALID

Adyen

  • Provider signal: PSP-level response codes referencing "unknownShopper" or "paymentMethodNotFound" → RESOURCE_NOT_FOUND
  • Provider signal: signature mismatch or stored shopperReference mismatch → RESOURCE_INVALID

PayPal

  • Provider signal: resource not found error when fetching vaulted instrument → RESOURCE_NOT_FOUND
  • Provider signal: instrument invalid for merchant account or billing agreement not matching → RESOURCE_INVALID

Generic mapping table (conceptual)

  • 404 / not found status → RESOURCE_NOT_FOUND
  • Ownership mismatch, token expired for use case, type mismatch → RESOURCE_INVALID
  • Timeout or transient network errors → treat outside as a transient error and consider retry; if provider returns not found due to sync issues, log as RESOURCE_NOT_FOUND but mark as transient in your internal metadata.

Keep your mapping layer externalized and configurable, so you can update mappings quickly when providers change error codes.

Operational playbook and support flow

Design operating procedures around rejected verifications so merchants and support teams resolve issues efficiently.

Triage rules

  • If RESOURCE_NOT_FOUND and re-check within X minutes succeeds, auto-correct and notify merchant that verification completed.
  • If RESOURCE_INVALID, generate a support ticket with sanitized provider details for manual follow-up if merchant cannot resolve.

Customer support scripts

  • RESOURCE_NOT_FOUND: "Our system could not find the saved payment method at the payment provider. Please ask your customer to re-enter their payment details or add a new payment method."
  • RESOURCE_INVALID: "The payment method appears invalid for this transaction. Please request a new payment method. If you believe this is incorrect, contact support with this verification reference."

Escalation

  • For repeated failures across many merchants, escalate to provider support with reproducible steps, sanitized logs, timestamps, and trace IDs.

SLA expectations

  • Define internal SLAs for investigating payment verification rejections (e.g., initial triage within 1 hour, plan for remediation within 24–72 hours depending on impact).

Documentation for merchants

  • Publish knowledge base articles that explain common rejection reasons and steps they can take.
  • Include screenshots and sample messages so merchant staff know what to do when they see these errors in the Shopify admin.

Migration and backward compatibility

Adopt these new fields in a controlled manner to avoid regression.

Version awareness

  • The new input field is associated with a specific Payments Apps API version (documentation references around 2026-04). Confirm the version your app uses before relying on merchantMessage to appear in merchant UI.

Graceful fallback

  • If merchantMessage or a new enum value is not supported by the API version in use, send a default rejection with an older enum and rely on internal notifications to the merchant. For example, fallback to a generic "VERIFICATION_FAILED" code while logging the intended merchant message and sending a merchant email.

Feature toggles

  • Roll out support for merchantMessage behind a feature toggle. Monitor for unexpected behaviors in staging and pilot shops before full production release.

Testing compatibility

  • For shops on older API versions, simulate how the shop will display messages and ensure no UI breaks occur when fields are absent or when receiving unexpected enum values.

Deprecation path

  • Keep an eye on Shopify announcements for deprecation timelines. Avoid hardcoding behavior that assumes these new fields will be available forever without verifying API versioning.

Example integration patterns and code snippets

Below are patterns that reduce coupling and centralize logic for mapping, localization, and API calls.

Central mapping module (pseudocode) /* mapProviderErrorToShopifyReason(providerResponse) { if (providerResponse.status == 404 || providerResponse.code == 'payment_method_not_found') { return 'RESOURCE_NOT_FOUND'; } if (providerResponse.code in ['token_invalid', 'owner_mismatch', 'single_use_token']) { return 'RESOURCE_INVALID'; } return 'UNKNOWN'; } */

Localized message generator (pseudocode) /* getMerchantMessage(reason, locale) { const messages = { en: { RESOURCE_NOT_FOUND: 'Saved payment method not found at the payment provider. Ask the customer to re-enter their card details.', RESOURCE_INVALID: 'The payment information is not valid for this action. Request a new payment method from the customer.' }, es: { RESOURCE_NOT_FOUND: 'No se encontró el método de pago guardado. Solicite al cliente que vuelva a ingresar los datos.', RESOURCE_INVALID: 'La información de pago no es válida para esta acción. Solicite un nuevo método de pago al cliente.' } }; return messages[locale]?.[reason] || messages['en'][reason]; } */

GraphQL call wrapper (pseudocode) /* async rejectVerification(sessionId, providerResponse, shopLocale) { const reasonCode = mapProviderErrorToShopifyReason(providerResponse); const merchantMessage = getMerchantMessage(reasonCode, shopLocale); const variables = { sessionId, reason: { code: reasonCode, merchantMessage } }; return callShopifyGraphQL('verificationSessionReject', variables); } */

These patterns centralize logic and make it easy to update mapping or messaging without touching the GraphQL invocation layer.

Common pitfalls and how to avoid them

Pitfall: Exposing provider internals to merchants

  • Avoid including raw error codes, API paths, or provider request IDs in merchantMessage. Keep merchant-facing text actionable and non-technical.

Pitfall: Overly long merchantMessage

  • Long messages truncate in some UI contexts. Keep messages short and include a "Details" link for admins if more context is necessary.

Pitfall: Treating transient provider errors as permanent

  • Classify transient network or provider timeouts separately and provide a retry path rather than immediate rejection to RESOURCE_NOT_FOUND.

Pitfall: Not localizing messages

  • Sending English-only merchantMessage to merchants in other locales provides worse UX. Build localization into the flow from the start.

Pitfall: Hardcoding mappings

  • Providers change error codes. Make mapping configurable and external, so you can update mappings quickly when providers change behavior.

Operational examples: how to triage a sudden spike in rejections

Scenario: Overnight spike in RESOURCE_NOT_FOUND across multiple shops using the same provider.

Immediate steps

  1. Verify provider status dashboard for outages.
  2. Cross-check provider API latency and error rates.
  3. Identify common factors (all shops using provider X, same region, or same tokenization method).
  4. If provider outage confirmed, set merchant-facing status banner and escalate to provider support.
  5. For affected merchants, advise a retry window and provide staff scripts.

Longer-term steps

  • Create runbook entries that include provider contact details, typical remediation steps, and sample merchantMessage texts for incidence communication.
  • Implement rate-limiting and queuing to avoid further load on the provider while attempting retries.

Scenario: Rising RESOURCE_INVALID for a subset of merchants

Immediate steps

  1. Inspect logs for token ownership mismatches or recent changes in tokenization flows (recent SDK updates, for example).
  2. Reproduce with test accounts and tokens; confirm mapping logic.
  3. Contact support for affected merchants with verification session traces and sanitized provider payloads.

Longer-term steps

  • Roll back or patch recent SDK changes producing incorrect token types.
  • Communicate with merchants about any required action (e.g., re-saving payment methods).

Governance: policies for merchantMessage content

Set standards for what merchantMessage can and cannot contain:

Allowed content

  • Brief explanation of what happened.
  • One clear action step.
  • Non-sensitive, high-level provider guidance like "re-enter payment details" or "contact provider."

Forbidden content

  • Any raw tokens, PANs, CVVs, or unmasked card numbers.
  • Provider internal stack traces or debug dumps.
  • Billing or legal statements that could be interpreted as acceptance of liability.

Approval and QA

  • Maintain a centralized source of truth for merchantMessage templates and translations.
  • Require QA sign-off for new or revised templates, particularly for non-English languages.

Where this fits in the broader payments architecture

Verification is one step in payments lifecycle: tokenization → verification → authorization → capture → settlement. Clear, actionable verification failure reasons reduce friction downstream by preventing failed authorizations or unnecessary disputes.

Improved reason codes help:

  • Reduce false declines and repeated merchant actions (retries, refunds).
  • Enable better reconciliation between merchant records and provider records.
  • Provide clearer evidence for dispute resolution when provider-side resource mismatches occur.

Integrators that use Shopify as the orchestration layer for multiple providers benefit most: consistent reason codes and merchant messages provide a uniform experience regardless of provider idiosyncrasies.

Next steps for payments app developers

  • Update mapping logic to classify provider error responses into RESOURCE_NOT_FOUND and RESOURCE_INVALID where appropriate.
  • Add merchantMessage generation and localization to your verification rejection workflow.
  • Implement comprehensive logging and dashboards to monitor the new reason codes.
  • Test end-to-end in provider sandbox and Shopify staging environments.
  • Draft merchant-facing documentation and support scripts that reflect the new, more specific failure modes.

Adopt these updates incrementally and instrument the rollout to measure impact on merchant support volume and verification success rates.

FAQ

Q: What exactly should merchantMessage contain? A: A short, localized sentence that explains the rejection and gives a single, clear next action (e.g., re-enter card, retry later, contact provider). Avoid technical details, provider IDs, or PII.

Q: When should I use RESOURCE_NOT_FOUND vs RESOURCE_INVALID? A: Use RESOURCE_NOT_FOUND when the provider explicitly indicates the payment method or token cannot be located (e.g., HTTP 404 or "not found" errors). Use RESOURCE_INVALID when the provider indicates the token is not valid for the requested operation (ownership mismatch, single-use vs reusable token mismatch, invalid token type).

Q: What if my provider returns an ambiguous error? A: If the provider response is ambiguous, examine context (status codes, operation type). If still unclear, choose the enum that leads to the safest merchant action (usually RESOURCE_INVALID when you want the merchant to re-collect payment details) and log the provider response for follow-up. Consider adding a polite retry suggestion in merchantMessage.

Q: Can merchantMessage include links or HTML? A: merchantMessage should be plain text and localized. If you need to provide links or richer UI, implement them in the merchant admin UI tied to the verification state, not inside merchantMessage itself.

Q: Are there size limits or formatting rules for merchantMessage? A: The input is a string; keep it concise to avoid UI truncation. Follow Shopify API docs for exact length limits on the input object and validate in your code. Keep messages under a practical limit (e.g., 200 characters) and test across admin interfaces.

Q: Will older Shopify API versions accept these new enums and merchantMessage? A: Behavior depends on the API version the shop or app calls. If the version in use predates the change, merchantMessage may be ignored or enums unrecognized. Implement graceful fallback logic for backward compatibility and verify behavior against the API version you target.

Q: How should I log provider errors without violating PCI? A: Mask or omit sensitive fields (tokens, PANs, CVV). Store only sanitized identifiers and error codes, timestamps, and trace IDs. Follow PCI DSS and local privacy laws for retention and handling.

Q: Should I retry verification automatically on RESOURCE_NOT_FOUND? A: Not always. If the provider indicated a permanent deletion, retries will not help. If you detect transient conditions (network blips, synchronization lag), implement controlled retries with exponential backoff. Make retry behavior configurable.

Q: How do I measure whether these changes improve merchant outcomes? A: Track metrics such as time-to-resolution, verification success rate after rejection, merchant support contacts related to verification, and conversion impact. Compare pre-rollout and post-rollout baselines.

Q: Who should be notified internally when a shop sees repeated rejections? A: Create alerts routed to your operations or payments team. If multiple merchants are impacted with provider-specific errors, open a provider support ticket and escalate as needed.

Q: Can I include provider error codes in merchantMessage for support staff? A: Avoid doing so for general merchant-facing messages. For admin or support UIs intended only for authorized staff, you can surface sanitized provider error codes and trace IDs in a separate "developer details" area, not in the merchantMessage visible to shop staff at large.

Q: How should I handle localization for a shop with multiple locales? A: Use the shop's primary locale for merchantMessage. If the shop operates multiple locales, detect the user's locale in the admin UI and present localized strings accordingly. Maintain translation files and quality-check all languages.

Q: What happens to verification session state after rejection? A: The verificationSessionReject mutation updates the verification session state on Shopify. Your app should follow the resulting state to determine next steps in your workflow (prompt merchant, log event, or take other actions).

Q: Where can I find more info about the input object and enums? A: Refer to the Shopify Payments Apps API documentation for VerificationSessionRejectionReasonInput and VerificationSessionStateReason in the version you plan to use (look for version tags like 2026-04 in the docs). The docs list exact enum names and field definitions.

Q: Which roles can view merchantMessage? A: Merchant-facing messages should be visible to roles that manage payments (store owners, managers, support agents). Restrict visibility according to your app's role model to avoid leaking operational details to unauthorized users.

Q: How should I approach messaging for non-English markets? A: Invest in professional translations and context-aware phrasing. Do not rely on automatic machine translation for merchantMessage without human review. Localized messages should be tailored to local payment norms and provider behavior.

Q: If I already provide merchant notifications by email, should I still use merchantMessage? A: Use merchantMessage for immediate, contextual guidance within the Shopify admin where verification status appears. Email notifications can complement merchantMessage for follow-up or when merchants are not logged in.

Q: What logging level should I use for mapping decisions? A: Record mapping decisions at INFO level with trace IDs for normal cases and at WARN or ERROR for repeated or high-severity failures. Ensure logs are accessible to authorized engineers and retained per policy.

Q: Are there examples of merchantMessage templates to copy? A: Use the sample messages provided earlier as starting points, then adapt them to your brand voice, supported locales, and the specific operational steps your app supports.

Q: How quickly should I adopt these new fields? A: Prioritize adoption if your app processes stored payment methods, supports recurring billing, or has significant merchant support volume related to verification. Roll out in a staged fashion with monitoring.

Q: Who should own the translation and maintenance of merchantMessage content? A: Product or localization teams should own the message catalog, with engineering responsible for integrating the right strings at runtime. Support and legal should review messages for clarity and compliance.


The new VerificationSessionStateReason values and merchantMessage field add precision and clarity to verification rejection handling. Implement mapping logic, localized merchant messages, robust testing, and comprehensive logging to make the most of these changes and to lower merchant friction when payment verification fails.

POWER your ecommerce with our weekly insights and updates!

Stay aligned on what's happening in the commerce world

Email Address

Handpicked for You

05 June 2026 / Blog

How Shopify Rollouts Lets Merchants Schedule, A/B Test, and Gradually Publish Themes, Checkout, and Customer Accounts
Read more

04 June 2026 / Blog

Shopify Analytics Adds Scatter Plots and Radar Charts to Custom Reports — How Merchants Should Use Them
Read more

02 June 2026 / Blog

Shopify Expands Local Payment Options: MobilePay, TWINT, BLIK and Przelewy24 Rolled Out Across Europe and Beyond
Read more