How to Configure Step-Up Verification
This guide explains how to set up Step-Up Verification in Commerce. Step-Up Verification adds an extra identity check before a customer can carry out a sensitive change on their account: on top of their password, the customer must enter a short one-time code to prove they are the real account owner before the change is accepted.
The same identity check protects more than one change. Today it is used when a customer changes the email address or the phone number on their account. You can turn the check on or off — and adjust how it behaves — for each of these separately.
1. Overview
An attacker who gets into a customer's session does not usually stop there. The first thing worth changing is the email address or phone number on the account, because those are the channels password resets and one-time codes are sent to. Step-Up Verification makes that change cost more than a borrowed session, and it makes sure the real owner hears about it.
Each protected change has its own name in the settings, so you can configure them independently:
email-change— the identity check before the account's primary email address is changed.phone-change— the identity check before the phone number on the profile is changed.
What this feature does:
Asks for two things, not one. The customer's password and a one-time code. A live session on its own is not enough.
Sends the code to the customer's own contact. The code always goes to the phone number or email address already saved on the account — never to the new address or number the customer is trying to set.
Will not reuse the channel they signed in with. A customer who signed in with a text-message code cannot receive the identity code by text message as well; the second check has to be genuinely separate.
Ties the code to the exact new value. A code approved for one email address cannot be used to set a different one.
Tells the storefront what is missing. The storefront does not need to know in advance whether the check is on; it asks, and the response lists which of the two factors is still needed.
Announces the change and lets the customer undo it. Once the change completes, the previous email address or phone number receives a message with a one-click undo link. Completing a change the customer asked for costs them nothing else — their password and their signed-in sessions keep working. Using the undo link is what disables the password.
Settings used in this guide
Which changes are protected, delivery channels, how long the check stays valid
VERIFICATION_TOKEN_CONF
Dynamic Settings, section 142
Code lifetime, wrong-guess limit, resend waiting time
OTP_PURPOSE_SETTINGS
Dynamic Settings, section 141
Routing the email change endpoints to their protected variants
EMAIL_CHANGE_VIEW, EMAIL_SET_PRIMARY_VIEW
Environment Variables, entries 94 and 95
How long a completed change can be undone
SECURE_EMAIL_CHANGE_REVOKE_WINDOW_DAYS, SECURE_PHONE_CHANGE_REVOKE_WINDOW_DAYS
Dynamic Settings, sections 143 and 144
The dynamic settings are documented in Dynamic Settings, and the environment variables in Environment Variables.
The SMS gateway must be configured and working before the check can be used on the text-message channel: see the SMS_GATEWAY and SMS_GATEWAYS entries in Dynamic Settings.
2. Setup
2.1. Turning the check on with VERIFICATION_TOKEN_CONF
Nothing is protected until you switch it on for a specific change.
Log in to Omnitron using your own credentials.

Go to Sales Channels → Sales Channel Settings → Dynamic Settings.

Type VERIFICATION_TOKEN_CONF in the search box and click it in the list.
Enter the configuration on the edit screen, then save. The configuration has one shared section named
defaultwhose values apply everywhere, plus one section per protected change. A value set inside a change's own section overrides the shared value.
Example configuration:
In this example the email change check is on and sends the code to the customer's current email address, and they have 15 minutes to finish the change afterwards. The phone number change check is on as well, with both channels available and the default 10-minute window.
The keys you can set in each section:
enabled
Whether the identity check is required for this change.
allowed_channels
Which delivery methods the customer may choose from — sms, email, or both.
token_ttl_seconds
How long the completed check stays valid, in seconds. In practice, how long the customer has to finish the change after entering the code.
For the accepted values and defaults, see section 142 of Dynamic Settings.
Turning the check on inside the default section does not turn it on for any change. To require it, set enabled inside that change's own section — for example inside email-change.
Think twice before restricting a change to a single channel. The check refuses the channel the customer's current session signed in with, so if email-change allows only sms, every customer who signed in with a text-message code is locked out of changing their email address. Leaving both channels available avoids this.
2.2. Adjusting the code itself
How long a code is valid, how many wrong guesses are allowed, and how soon a new code can be requested come from a separate setting, OTP_PURPOSE_SETTINGS, using the same names for the protected changes. On the same Dynamic Settings screen, search for it and save a value such as:
Here an email change allows three wrong guesses instead of five, the code expires after 5 minutes, and a new code cannot be requested more often than once a minute. See section 141 of Dynamic Settings for every field and its fallback.
2.3. Enabling the protected email change flow
For an email change, turning the purpose on is only half of the setup — the endpoints also have to be routed to their protected variants. Add these two environment variables to the Commerce service in ACC:
The first applies the identity check to the change request. The second sends the notice with the undo link described in section 4 once the change completes.
A phone number change needs neither variable: enabling phone-change is enough, because the profile endpoint carries the check itself.
A partial setup fails quietly rather than loudly, so check all three switches together:
EMAIL_CHANGE_VIEWset but theemail-changepurpose disabled — the change still succeeds on the password alone, with no code ever requested.The purpose enabled but
EMAIL_SET_PRIMARY_VIEWunset — the change is protected, but no notice or undo link is ever sent, so a customer whose account was taken over has nothing to click.
See entries 94 and 95 of Environment Variables for the full description of both.
2.4. Setting how long a change can be undone
Two settings decide how long the undo link keeps working. Both default to 7 days.
On the same Dynamic Settings screen, type SECURE_EMAIL_CHANGE_REVOKE_WINDOW_DAYS in the search box and click it in the list.

Enter the number of days the undo link should keep working, then save.

Repeat for SECURE_PHONE_CHANGE_REVOKE_WINDOW_DAYS, which does the same for phone number changes.
Choose a period long enough for a customer to notice an unexpected message in their old inbox — or on their old number — and act on it. The link works only once in any case.
3. How the identity check works
When a customer starts a change that is protected:
The storefront sends the change as usual. Because a factor is missing, the request is refused and the response lists what is still needed — the password, the one-time code, or both — along with the delivery methods the customer may choose from.
The customer picks a delivery method. Only the methods you allowed are offered, and the one their session signed in with is already removed from the list.
The code is sent to the phone number or email address already on the account.
The customer enters the code and their password, and the change is accepted.
If the customer needs a new code they can ask for one, but only after the waiting time you set has passed. If they take too long, the code or the completed check expires and they simply start again.
A wrong password does not waste the code. The customer can correct the password and continue with the same code, as long as it has not expired.
The code is tied to the exact value the customer asked for. If they change the new email address or phone number after requesting the code, the code no longer applies and they have to request another one.
3.1. Email change, end to end
An email change has an extra step, because the new address has to be confirmed as well:
The customer asks to change their email address. They enter the new address and their password, and complete the identity check.
A confirmation link is sent to the new address. The change has not taken effect yet.
The change completes when that link is opened. The new address becomes the account's email address, and the previous address receives a message with an undo link.
The customer can undo it. If they did not ask for this change, they open the undo link in the message sent to their old address.
3.2. Phone number change
There is no confirmation step. Once the identity check passes, the new number is saved immediately and the previous number receives a text message with an undo link.
4. The notice and the undo link
The notice sent to the previous email address or phone number is what turns this from a lock into a recovery path. It goes to the channel the change took away, which is the one place an attacker no longer controls.
When a change completes the customer is not disturbed further: the previous address or number receives the notice with a one-click undo link, the change is recorded in the audit log, and that is all. Their password and their signed-in sessions keep working, because this is a change they asked for.
When the undo link is used the change is assumed to have been someone else's, so the password it was made with is no longer trusted:
The previous email address or phone number is restored.
The account's current password is made unusable, so it stops working immediately.
The customer is then sent a password reset link on the restored channel — by email for an email change, by text message for a phone number change — using the same reset flow as the storefront's own "forgot my password". They pick a new password and are back in control.
The notice sent on that channel tells them both things: that the password was disabled, and that a reset link is on its way.
Signed-in sessions are left alone. The unusable password is what stops the attacker from signing in again; anyone already holding a session keeps it until it expires on its own.
For the phone case, the reset link is delivered only if your project ships an sms/account/reset-password.html template. No SMS bodies are provided by the platform, and a missing template is skipped without an error — so the password would be disabled with no way for the customer to set a new one from that message. Confirm that template exists before enabling the phone number check.
The undo link can be used only once, and only within the number of days you set. A phone number change can also no longer be undone if the number has changed again since — a later, legitimate change is never overwritten by an older link.
Wording of the messages
The notices are ordinary templates, editable in Omnitron → Sales Channels → Content Management → Mailing Templates:
Email change, to the previous address
account/email/email_change_old_notice.html
Email change undone
account/email/email_change_revoked_notice.html
Phone change, to the previous number
sms/account/phone-change-old-notice.html
Phone change undone
sms/account/phone-change-revoked-notice.html
Password reset link after an undo
Your existing password reset templates
Each template's available values — including the undo link itself — are listed in E-mail Templates.
Make the undo link easy to find, and keep the text message short enough to arrive in one piece. This link is the customer's only self-service way back after a change they did not make; a message that buries it, or one that gets cut off before it, removes the recovery path even though the feature is working correctly.
The two "undone" messages should also keep their wording about the password being disabled. A customer who reads only that the change was reversed, and then finds their password rejected, has no idea why.
5. Checking your setup
Go through the flow once as a customer would, and confirm each of the following:
Requesting the change without a code is refused, and the response lists the factors that are missing.
The delivery methods offered exclude the channel the test account signed in with.
The code arrives at the account's existing email address or phone number — not at the new value being set.
Changing the new value after requesting the code causes the change to be refused.
The previous address or number receives the notice, and its undo link restores the old value.
After using the undo link, the old password no longer works and a password reset link arrives on the restored channel. For a phone number change, confirm the reset text message actually arrives — that depends on your own
sms/account/reset-password.htmltemplate.Completing a change without using the undo link leaves the customer signed in and their password working.
With the check turned off again, the same change succeeds without a code — so customers are never blocked if you switch it off.
Last updated
Was this helpful?

