{"id":3069,"date":"2026-09-25T13:40:49","date_gmt":"2026-09-25T03:40:49","guid":{"rendered":"https:\/\/www.gpayments.com\/blog\/?p=3069"},"modified":"2026-09-25T13:44:55","modified_gmt":"2026-09-25T03:44:55","slug":"app-based-3ds-challenge-flow","status":"publish","type":"post","link":"https:\/\/www.gpayments.com\/blog\/article\/app-based-3ds-challenge-flow\/","title":{"rendered":"How the SDK and ACS interact during an app-based 3DS challenge"},"content":{"rendered":"\n<p style=\"text-align: left;\">An app-based 3DS challenge looks simple from the outside. The cardholder taps, a screen appears, they enter a code, the payment completes. Underneath, the screen they see is the product of a negotiation that runs across four separate messages, and if any party populates its part incorrectly the SDK will abandon the challenge outright.<\/p>\n<p style=\"text-align: left;\">Most integration problems in app-based 3DS trace back to a misunderstanding of which component decides what. Here is the division of labour.<\/p>\n<h2 style=\"text-align: left;\"><strong>The device declares what it can render<\/strong><\/h2>\n<p style=\"text-align: left;\">Before anything else, the 3DS Server must tell the issuer what the cardholder&#8217;s device is capable of displaying. It does this in the authentication request through a data element describing all the user interfaces the SDK supports and the options for rendering challenge screens.<\/p>\n<p style=\"text-align: left;\">One point catches teams out. Neither the requestor app nor the 3DS Server can change or select the values in that element. It describes what the SDK supports, not what anyone would prefer. In versions 2.1.0 and 2.2.0 the SDK is required to support all the possible device rendering options, so the element is effectively a statement of fact rather than a configuration choice.<\/p>\n<h2 style=\"text-align: left;\"><strong>The ACS decides the method and the template<\/strong><\/h2>\n<p style=\"text-align: left;\">Having assessed risk and concluded that a challenge is needed, the ACS makes two decisions and communicates both in the authentication response.<\/p>\n<p style=\"text-align: left;\">The first is the authentication method it will use. The second is the initial interface and template it will require the SDK to present to the cardholder. These are separate elements because they answer separate questions: how the cardholder will be verified, and what they will look at while it happens.<\/p>\n<p style=\"text-align: left;\">Both are required elements in the authentication response when a challenge is being requested.<\/p>\n<h2 style=\"text-align: left;\"><strong>Five templates, and the choice is constrained<\/strong><\/h2>\n<p style=\"text-align: left;\">Here is the part worth committing to memory, because it governs what you can actually build.<\/p>\n<p style=\"text-align: left;\">The SDK offers four native templates: text entry, single select, multi select, and out-of-band. There is also an HTML template. The ACS indicates which interface it intends to use, and then selects a specific template for the challenge itself.<\/p>\n<p style=\"text-align: left;\">The constraint is that the selection must be consistent. If the ACS has indicated it will use the native interface, it should select one of the four native templates. If it has indicated the HTML interface, it should select the HTML template. Mixing the two is a defect rather than a creative choice.<\/p>\n<p style=\"text-align: left;\">The template identifier is mandatory in every challenge response for the app-based flow, because the SDK needs to know what to draw at each step.<\/p>\n<h2 style=\"text-align: left;\"><strong>The element that silently aborts your challenge<\/strong><\/h2>\n<p style=\"text-align: left;\">This is the single most useful thing in this article for anyone debugging an app integration.<\/p>\n<p style=\"text-align: left;\">The UI data elements are specified as optional in the general data element table. In practice they are not. The ACS must provide all the required UI data elements for the template it has chosen, and if it does not, the SDK will abort the challenge and return an error message indicating that a mandatory data element is missing.<\/p>\n<p style=\"text-align: left;\">EMVCo has flagged one specific case where this bites. The challenge information label is mandatory, but it is missing from certain figures in earlier specification bulletins, which has led implementers to omit it. The guidance is to supply either a meaningful label or, failing that, a string containing a single space character. Supplying nothing ends the challenge.<\/p>\n<p style=\"text-align: left;\">If your app-based challenges are failing immediately with a missing mandatory element, this is the first place to look.<\/p>\n<h2 style=\"text-align: left;\"><strong>The final response is deliberately different<\/strong><\/h2>\n<p style=\"text-align: left;\">During the challenge, the ACS supplies UI elements to the SDK for display. In the final challenge response, it signals the end of the challenge and the transaction outcome instead. Because the challenge is over, there is no interface left to draw, so the final response carries no UI-related elements at all, including no template identifier.<\/p>\n<p style=\"text-align: left;\">An integration that expects a consistent message shape across every challenge response will break on the last one. The difference is intentional.<\/p>\n<h2 style=\"text-align: left;\"><strong>HTML templates have hard constraints<\/strong><\/h2>\n<p style=\"text-align: left;\">If the ACS uses the HTML template, it must include specific URLs in its HTML for the actions the cardholder can take: one for submitting data input, and one for the button that switches to an out-of-band authentication app. The SDK monitors URL changes to retrieve the cardholder&#8217;s response as query parameters.<\/p>\n<p style=\"text-align: left;\">Two constraints matter.<\/p>\n<p style=\"text-align: left;\">If the cardholder submits without entering a value, the SDK still retrieves a form, with the parameter names present but empty. That is a normal condition, and it is also what happens where the screen has a button but no entry field, such as a completion button in an out-of-band flow. Only a completely blank query string is treated as malformed HTML with no action-bound button, at which point the SDK sends an error message.<\/p>\n<p style=\"text-align: left;\">More importantly, the ACS must not include any externally referenced CSS or any JavaScript in its HTML. The SDK will block execution as a security measure, the page will be unusable, and the cardholder will not be able to complete the challenge. Design your HTML templates as self-contained, script-free documents or they will not work.<\/p>\n<h2 style=\"text-align: left;\"><strong>Scrolling and screen real estate<\/strong><\/h2>\n<p style=\"text-align: left;\">Where the interface is larger than the device screen, the SDK supports scrolling, and this applies to both native and HTML templates. The SDK supports vertical and horizontal scrolling for HTML and at minimum vertical scrolling for native templates.<\/p>\n<p style=\"text-align: left;\">EMVCo&#8217;s recommendation is to keep the header zone anchored at the top rather than allowing it to scroll, so the cardholder can always see the transaction context and reach the cancel button. That is a small design decision with a direct bearing on trust: a cardholder who cannot see what they are approving, or cannot find a way out, is a cardholder who abandons.<\/p>\n<h2 style=\"text-align: left;\"><strong>Where the outcome is reported<\/strong><\/h2>\n<p style=\"text-align: left;\">When the challenge completes, the ACS reports the authentication result in the results message, including both the authentication method used and the rendering type. Both are mandatory there.<\/p>\n<p style=\"text-align: left;\">That matters for analytics more than for the flow. If you want to know which challenge methods and which templates correlate with completion in your own traffic, the data is already arriving in the results message. Most implementations discard it.<\/p>\n<h2 style=\"text-align: left;\"><strong>Frequently Asked Questions<\/strong><\/h2>\n<p style=\"text-align: left;\"><strong>Can the merchant choose which challenge template the cardholder sees?<\/strong><\/p>\n<p style=\"text-align: left;\">No. The requestor app and 3DS Server cannot change or select the device rendering options, and the ACS chooses the method and template. The merchant&#8217;s influence is indirect, through the quality of the data it supplies for risk assessment and through the SDK it integrates.<\/p>\n<p style=\"text-align: left;\"><strong>Why does our challenge abort immediately with a missing data element error?<\/strong><\/p>\n<p style=\"text-align: left;\">Almost always because the ACS has not supplied every UI element the chosen template requires. The elements are marked optional in the general table but are required in practice, and the SDK aborts when one is absent. The challenge information label is the most common omission.<\/p>\n<p style=\"text-align: left;\"><strong>Can the ACS use JavaScript in an HTML challenge template?<\/strong><\/p>\n<p style=\"text-align: left;\">No. The ACS must not include any externally referenced CSS or any JavaScript. The SDK blocks execution as a security measure, which leaves the page unusable and the challenge uncompletable.<\/p>\n<p style=\"text-align: left;\"><strong>Why does the last challenge response look different from the others?<\/strong><\/p>\n<p style=\"text-align: left;\">Because the challenge has finished and there is nothing left to display. The final response signals the end of the challenge and the outcome, and deliberately omits the UI-related elements that appear in earlier responses, including the template identifier.<\/p>\n<p style=\"text-align: left;\"><strong>Integrating an app-based challenge?<\/strong> <a href=\"https:\/\/www.gpayments.com\/solutions\/acquiring\/#:~:text=Mobile%20Fraud%20Prevention%20with%20Unmatched%20Security%20and%20User%20Experience%20using\">ActiveSDK<\/a> is the GPayments mobile 3DS SDK, and <a href=\"https:\/\/www.gpayments.com\/solutions\/issuing\/\">ActiveAccess<\/a> is the GPayments Access Control Server. <a href=\"https:\/\/www.gpayments.com\/contact\/\">Speak with a 3DS specialist<\/a> about app-based challenge implementation.<\/p>\n\n\n","protected":false},"excerpt":{"rendered":"<p>An app-based 3DS challenge looks simple from the outside. The cardholder taps, a screen appears, they enter a code, the payment completes. Underneath, the screen they see is the product of a negotiation that runs across four separate messages, and if any party populates its part incorrectly the SDK will abandon the challenge outright. Most [&hellip;]<\/p>\n","protected":false},"author":13,"featured_media":3071,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"footnotes":""},"categories":[2],"tags":[19,37,109],"class_list":["post-3069","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-article","tag-3d-secure","tag-acs","tag-sdk"],"aioseo_notices":[],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gpayments.com\/blog\/wp-json\/wp\/v2\/posts\/3069","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gpayments.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gpayments.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gpayments.com\/blog\/wp-json\/wp\/v2\/users\/13"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gpayments.com\/blog\/wp-json\/wp\/v2\/comments?post=3069"}],"version-history":[{"count":3,"href":"https:\/\/www.gpayments.com\/blog\/wp-json\/wp\/v2\/posts\/3069\/revisions"}],"predecessor-version":[{"id":3073,"href":"https:\/\/www.gpayments.com\/blog\/wp-json\/wp\/v2\/posts\/3069\/revisions\/3073"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gpayments.com\/blog\/wp-json\/wp\/v2\/media\/3071"}],"wp:attachment":[{"href":"https:\/\/www.gpayments.com\/blog\/wp-json\/wp\/v2\/media?parent=3069"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gpayments.com\/blog\/wp-json\/wp\/v2\/categories?post=3069"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gpayments.com\/blog\/wp-json\/wp\/v2\/tags?post=3069"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}