Treat pending verification as its own operational state
Source facts: in the documented US ACH setup flow, Stripe uses instant bank verification by default, with manual account entry and microdeposit verification available as a fallback.[2] A SetupIntent requiring microdeposit verification has the requires_action status and a next_action containing verify_with_microdeposits.[2] Editorial recommendation: build recovery around this specific state, rather than showing a generic payment-failed message. The customer's immediate task is to verify the bank account, not to retry a purchase or authorize a different charge. Keep an internal reference to the setup being recovered and show only the relevant account identification in the customer journey. Distinguish waiting for deposits, waiting for customer input and requiring replacement bank details in support guidance. These are proposed operational labels, not additional Stripe API statuses. This article addresses US ACH verification only; it does not describe a PayIn capability, certify an integration or report an executed payment test.
Choose the form from the deposit type, not from a guess
Source facts: Stripe first sends a descriptor-code microdeposit and may fall back to amount-based microdeposits if further verification issues arise.[2] The descriptor route uses one USD 0.01 deposit and a six-character verification string beginning with SM; the documentation's example includes letters, despite its wording of six digits.[2] The amount route uses two non-unique deposits bearing the statement descriptor ACCTVERIFY, and the customer supplies their amounts.[2] The integration must inspect next_action.verify_with_microdeposits.microdeposit_type and submit either descriptor_code or amounts, never both.[2] Editorial recommendation: render one clearly labeled task at a time. For a descriptor deposit, explain that the needed value is in the transaction description, not the one-cent amount. For the amount route, request both deposit amounts and identify the relevant description. Do not copy the source's illustrative object containing both parameters into a real request: its accompanying instruction explicitly says to provide only one route.[2]
Separate the arrival estimate from the verification deadline
Source facts: the deposits take one to two business days to appear on the customer's online statement.[2] The next_action data includes arrival_date and hosted_verification_url, while microdeposit verification has a ten-day timeout.[2] The cited text describes the arrival delay in business days but describes the timeout simply as ten days; it does not establish a detailed timezone or deadline-calculation rule.[2] Editorial recommendation: do not silently convert both periods into the same kind of clock. Present the expected arrival separately from any deadline your implementation can reliably establish. Before arrival, explain what the customer should look for rather than encouraging speculative submissions. After expected arrival, ask the customer to inspect the relevant account's transaction detail before deciding whether recovery is necessary. Avoid promising that a deposit will appear at an exact hour. If the timing information is insufficient to calculate a precise cutoff, acknowledge that limitation and rely on the current setup state rather than displaying an invented countdown.
Preserve attempts by making mismatches actionable
Source facts: Stripe documents limits of ten failed attempts for descriptor-based verification and three for amount-based verification.[2] The payment_method_microdeposit_verification_amounts_mismatch error is synchronous, leaves the status unchanged and reports the remaining attempts in its message.[2] Once the allowed attempts are exceeded, the documented error is payment_method_microdeposit_verification_attempts_exceeded; the status becomes requires_payment_method and last_setup_error is set.[2] Editorial recommendation: distinguish a recoverable mismatch from exhausted attempts in both interface wording and support procedures. After a mismatch, tell the customer to recheck the actual transaction details instead of guessing a new combination. Display remaining attempts only when supported by the actual response or another verified integration field; do not invent a universal counter for both routes. Prevent accidental duplicate submissions while a request is unresolved. A page refresh or another email should not be presented as resetting the processor's allowance. Route an exhausted setup to new bank-detail collection rather than keeping the same entry form open indefinitely.
Recover timeouts and failed deposits through the correct branch
Source facts: payment_method_microdeposit_verification_timeout arrives asynchronously through a webhook when verification is not completed within the required ten-day period; the SetupIntent returns to requires_payment_method with last_setup_error populated.[2] The separate payment_method_microdeposit_failed error can arrive synchronously or asynchronously and also requires new payment method details.[2] Editorial recommendation: do not describe these branches as a simple typo that another code submission can fix. For timeout, explain that the old verification window has ended and guide the customer back through bank-detail collection. For failed deposits, ask the customer to review the bank information in a secure collection flow before proceeding. The cited page establishes the need for new payment method details, but does not prescribe a complete application-level restart architecture.[2] Therefore, decide how to reuse or replace internal setup records only after checking the applicable integration contract. Do not claim that reopening an old link, resending a message or changing a local deadline revives an expired verification.
Make the return journey specific, secure and state-aware
Source facts: when a billing email is supplied, Stripe sends a notification about expected deposit arrival with a link to a hosted verification page.[2] A custom notification can direct customers to the hosted_verification_url in next_action, or an integration can provide its own verification form.[2] Stripe warns not to log the client secret, embed it in URLs or expose it to anyone other than the customer.[2] Editorial recommendation: choose one primary recovery destination and make the message match the active verification type. On return, check the current setup before requesting input: a previously sent reminder may now refer to a completed, expired or otherwise failed setup. Offer the appropriate next step instead of assuming the email's original instructions are still valid. For a custom journey, bind the setup reference to the intended customer and avoid asking support staff to collect bank credentials or full account details through ordinary messages. Keep notification delivery distinct from verification completion in reporting; sending a link is an invitation to act, not evidence that the account is verified.
Close recovery on confirmed setup success, not on payment assumptions
Source facts: successful microdeposit verification returns a SetupIntent with status succeeded and emits setup_intent.succeeded.[2] Failures can appear as direct responses or through setup_intent.setup_failed, so the documented flow is not limited to what the browser sees.[2] Manually linked accounts verified through microdeposits do not provide additional bank data such as balances, ownership and transactions.[2] ACH Direct Debit is also a delayed-notification payment method; verification success is not a report that a later debit has settled.[2] Editorial recommendation: reconcile customer-visible recovery with server-side setup state and stop obsolete reminders after confirmed success. Review separate scenarios for descriptor entry, amount entry, mismatch, exhausted attempts, failed deposits, timeout and a return visit after completion. Measure unresolved setups and recovery outcomes separately from subsequent payment outcomes. These are proposed review cases, not tests performed for this article. The source was reviewed on 2026-09-21; its publication date is unknown, and this review date should not be interpreted as a launch date or a guarantee that the documented behavior will never change.
Sources and dates
Verified on 2026-09-21. Source dates distinguish explicitly stated publication and update dates; an unspecified date does not mean the source was published today. This is public-document research, not a live payment test, security audit or accessibility certification. Vendor facts apply to the cited vendor; proposed workflows are editorial synthesis.
More new articles
Partial authorization leaves a remainder decision, not a paid order →
A valid tax ID is not customer identity verification or a tax decision →
All field guides →