When initiating an authentication request to the NDM simulator, if the card is configured for Challenge flow, then the NDM simulator will set the acsURL field to be handled by the NDM Simulator Challenge handler.
The Netcetera Demo Merchant Simulator provides a pre-defined HTML template that is returned when initiating a Challenge Request to the simulated ACS Challenge handler. The challenge screen and the template source are displayed below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | <!DOCTYPE html> < html lang = "en" > < head > < meta charset = "UTF-8" /> < title >NDM Simulator Challenge</ title > </ head > < body style = "margin: 0; padding: 8px;" > < main > < div > < header > < span class = "logo" ></ span > </ header > < div class = "content" > < form id = "mainForm" method = "post" action = "%otpValidationUrl$" > < input id = "threeDSSTransId" type = "text" name = "threeDSSTransId" class = "hidden" value = "%threeDSSTransId$" > < h1 >Challenge Form</ h1 > < div class = "transaction-details" > < ul > < li > < span class = "ui-messages-summary" >Cardholder Account Number: </ span > < span class = "ui-messages-detail" > %acctNumber$ </ span > </ li > < li > < span class = "ui-messages-summary" >Merchant Name: </ span > < span class = "ui-messages-detail" >%merchantName$</ span > </ li > < div id = "purchaseDetails" > < li > < span class = "ui-messages-summary" >Purchase Amount: </ span > < span class = "ui-messages-detail" >%purchaseAmount$</ span > </ li > < li > < span class = "ui-messages-summary" >Purchase Date: </ span > < span class = "ui-messages-detail" >%purchaseDate$</ span > </ li > </ div > </ ul > </ div > < div class = "explainText" >Please enter the sent OTP Code</ div > < dt >< label for = "otp" >Code</ label ></ dt > < dd >< input id = "otp" type = "text" name = "otp" maxlength = "10" onkeyup = "checkOtp()" onblur = "checkOtp()" ></ dd > < footer > < button type = "submit" class = "btn btn-secondary" id = "cancel" name = "challengeCancel" >Cancel</ button > < button type = "submit" class = "btn btn-primary" id = "sendOtp" disabled = "" >Pay</ button > </ footer > </ form > </ div > </ div > </ main > <script> var messageCategory = "%messageCategory$" ; if (messageCategory === "02" ) { document.getElementById( 'purchaseDetails' ).setAttribute( "class" , "hidden" ); } function checkOtp() { var otp = document.getElementById( "otp" ); var submitOtp = document.getElementById( "sendOtp" ); var validInputRegex = /^[a-zA-Z0-9]+$/; submitOtp.disabled = !validInputRegex.test(otp.value); } </script> < style > header { background-color: #458962; color: white; } ul { list-style-type: none; } .ui-messages-summary { font-weight: bold; } .hidden { visibility: hidden; position: absolute; } .logo { padding-top: 2%; background: no-repeat left center url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgd2lkdGg9IjEyM3B4IiBoZWlnaHQ9IjQwcHgiIHZpZXdCb3g9IjAgMCAxMjMgNDAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+DQogICAgPCEtLSBHZW5lcmF0b3I6IFNrZXRjaCA1MS4xICg1NzUwMSkgLSBodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2ggLS0+DQogICAgPHRpdGxlPkdyb3VwPC90aXRsZT4NCiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4NCiAgICA8ZGVmcz48L2RlZnM+DQogICAgPGcgaWQ9IlBhZ2UtMSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+DQogICAgICAgIDxnIGlkPSJHcm91cCIgZmlsbD0iI0ZGRkZGRiI+DQogICAgICAgICAgICA8cGF0aCBkPSJNMTA5LjcyNDAyMSw5LjA4OTE4MTgyIEwxMDQuNTg0NzA2LDkuMDg5MTgxODIgQzEwMS41NzI5NTcsOS4wODkxODE4MiA5OC45NTc5NTY5LDkuODM4Njc2NzcgOTcuMDExNzYxOSwxMS4zNzE2MDYxIEM5NC45NzkxMzIzLDkuODM4Njc2NzcgOTIuMDk4NDUyMSw5LjA4OTE4MTgyIDg4LjI0NTAyODUsOS4wODkxODE4MiBMODMuMTA1NzEzNSw5LjA4OTE4MTgyIEM3Ni41Njg1NjcyLDkuMDg5MTgxODIgNzEuOTAwMzkxNCwxMi42MDI2MTYyIDcxLjkwMDM5MTQsMjAuMDQwMjkyOSBMNzEuOTAwMzkxNCwzNy43NTAyOTI5IEM3MS45MDAzOTE0LDM4LjIxNjk1OTYgNzIuMzY0NDQ1OSwzOC42ODI5MTkyIDcyLjgzMjA0MjgsMzguNjgyOTE5MiBMNzguNDM3NTM3OCwzOC42ODI5MTkyIEM3OC45MDUxMzQ3LDM4LjY4MjkxOTIgNzkuMzcyMDIzMSwzOC4yMTY5NTk2IDc5LjM3MjAyMzEsMzcuNzUwMjkyOSBMNzkuMzcyMDIzMSwyMC41MDYyNTI1IEM3OS4zNzIwMjMxLDE3LjcxMTIwMiA4MC43Njk4NTQ1LDE1Ljg0NjY1NjYgODQuMDM5NDkwMywxNS44NDY2NTY2IEw4Ni44NDI5NDYzLDE1Ljg0NjY1NjYgQzkyLjQ0NTYwNzMsMTUuODQ2NjU2NiA5My4zODAwOTI2LDE3LjI0NTI0MjQgOTMuMzgwMDkyNiwyMS40Mzk1ODU5IEw5My4zODAwOTI2LDM3Ljc1MDI5MjkgQzkzLjM4MDA5MjYsMzguMjE2OTU5NiA5My44NDY5ODExLDM4LjY4MjkxOTIgOTQuMzEzODY5NSwzOC42ODI5MTkyIEw5OS45MTY1MzA1LDM4LjY4MjkxOTIgQzEwMC4zODM0MTksMzguNjgyOTE5MiAxMDAuODUxMDE2LDM4LjIxNjk1OTYgMTAwLjg1MTAxNiwzNy43NTAyOTI5IEwxMDAuODUxMDE2LDIxLjQzOTU4NTkgTDEwMC44NTEwMTYsMjAuNTA2MjUyNSBDMTAwLjg1MTAxNiwxNy43MTEyMDIgMTAyLjI1MjM5LDE1Ljg0NjY1NjYgMTA1LjUxODQ4MywxNS44NDY2NTY2IEwxMDguMzIxOTM5LDE1Ljg0NjY1NjYgQzExMy45MjQ2LDE1Ljg0NjY1NjYgMTE0Ljg1OTA4NSwxNy4yNDUyNDI0IDExNC44NTkwODUsMjEuNDM5NTg1OSBMMTE0Ljg1OTA4NSwzNy43NTAyOTI5IEMxMTQuODU5MDg1LDM4LjIxNjk1OTYgMTE1LjMyNTk3NCwzOC42ODI5MTkyIDExNS43OTI4NjIsMzguNjgyOTE5MiBMMTIxLjM5NjIzMiwzOC42ODI5MTkyIEMxMjEuODQxODY2LDM4LjY4MjkxOTIgMTIyLjMzMDAwOSwzOC4yMTY5NTk2IDEyMi4zMzAwMDksMzcuNzUwMjkyOSBMMTIyLjMzMDAwOSwyMS40Mzk1ODU5IEMxMjIuMzMwMDA5LDEzLjA1MDg5OSAxMTguNTk2MzE4LDkuMDg5MTgxODIgMTA5LjcyNDAyMSw5LjA4OTE4MTgyIiBpZD0iRmlsbC01MCI+PC9wYXRoPg0KICAgICAgICAgICAgPHBhdGggZD0iTTU4LjcwMzEwNjYsMjcuNTgyODI4MyBDNTcuNDIyMTc0NSwzMS4yNzMwMzAzIDU0LjA3MjQ4MDMsMzMuNzUzNDM0MyA1MC4zNjc4Mzc2LDMzLjc1MzQzNDMgQzQ1LjQ2NzI4MDQsMzMuNzUzNDM0MyA0MS40Nzk5NTQxLDI5LjUzMjIyMjIgNDEuNDc5OTU0MSwyNC4zNDM3Mzc0IEM0MS40Nzk5NTQxLDE5LjE1NDU0NTUgNDUuNDY3MjgwNCwxNC45MzMzMzMzIDUwLjM2NzgzNzYsMTQuOTMzMzMzMyBDNTUuMjY4Mzk0OCwxNC45MzMzMzMzIDU5LjI1NTcyMTEsMTkuMTU0NTQ1NSA1OS4yNTU3MjExLDI0LjM0MzczNzQgQzU5LjI1NTcyMTEsMjUuMTI4NTg1OSA1OS4xNTM3LDI1LjkzNjc2NzcgNTguOTUyNDkxNiwyNi43NDM1MzU0IEw1OC45MzEyMzcyLDI2LjgzMDUwNTEgQzU4Ljg4MzA2MDYsMjcuMDE1MDUwNSA1OC44MzI3NTg1LDI3LjE5ODE4MTggNTguNzczOTU0NiwyNy4zNzg0ODQ4IEw1OC43NzM5NTQ2LDI3LjM3OTE5MTkgTDU4LjcwMzEwNjYsMjcuNTgyODI4MyBaIE01OC45NDI1NzI5LDAgTDU4Ljk0MjU3MjksMTEuNDM4OTg5OSBDNTguMjQ0NzE5OSwxMC45MTc4Nzg4IDU3LjQ2OTY0MjcsMTAuNDY0NjQ2NSA1Ni42MzAwOTM3LDEwLjA4Nzc3NzggQzU0Ljg2Mzg1MjcsOS4yOTUxNTE1MiA1Mi44MjkwOTc3LDguODkzNTM1MzUgNTAuNTgxMDkwMiw4Ljg5MzUzNTM1IEM0NS43NTg0NjU4LDguODkzNTM1MzUgNDEuODQyNjk2LDEwLjM0Nzk3OTggMzguOTQxNDY5OCwxMy4yMTU4NTg2IEMzNi4wNzU2Njc2LDE2LjA0ODM4MzggMzQuNjIzMjgzMywxOS45NTI4MjgzIDM0LjYyMzI4MzMsMjQuODIxNzE3MiBDMzQuNjIzMjgzMywyOS4wODYwNjA2IDM2LjEwNDAwNjgsMzIuNjM5MDkwOSAzOS4wMjM2NTM1LDM1LjM4MzIzMjMgQzQxLjk2NDU1NDYsMzguMTQ4NTg1OSA0NS42NDE1NjY1LDM5LjU1MDcwNzEgNDkuOTUxOTU5OCwzOS41NTA3MDcxIEM1Mi41NTI3OTA0LDM5LjU1MDcwNzEgNTQuNzc4MTI2NiwzOS4xNDU1NTU2IDU2LjU2NDkxMzUsMzguMzQ1MTUxNSBDNTcuNTM2OTQ4MywzNy45MDg4ODg5IDU4LjQ2MDA5NzksMzcuMzI2OTY5NyA1OS4zMjAxOTI4LDM2LjYwNzg3ODggTDU5LjMyMDE5MjgsMzguNzAxNTE1MiBMNjUuODQ2MDAzNSwzOC43MDE1MTUyIEw2NS44NDYwMDM1LDAgTDU4Ljk0MjU3MjksMCBaIiBpZD0iRmlsbC00NCI+PC9wYXRoPg0KICAgICAgICAgICAgPHBhdGggZD0iTTE3LjI3OTEyMjQsOS4wODkxODE4MiBMMTEuMjA4MTU2LDkuMDg5MTgxODIgQzQuNjcwMzAxMTUsOS4wODkxODE4MiAwLDEyLjYwMDQ5NDkgMCwyMC4wNDAyOTI5IEwwLDM3Ljc1MSBDMCwzOC4yMTY5NTk2IDAuNDY3NTk2ODk5LDM4LjY4MjkxOTIgMC45MzUxOTM3OTgsMzguNjgyOTE5MiBMNi41Mzg1NjMzMSwzOC42ODI5MTkyIEM3LjAwNTQ1MTczLDM4LjY4MjkxOTIgNy40NzIzNDAxNSwzOC4yMTY5NTk2IDcuNDcyMzQwMTUsMzcuNzUxIEw3LjQ3MjM0MDE1LDIwLjUwNjk1OTYgQzcuNDcyMzQwMTUsMTcuNzEwNDk0OSA4Ljg3MzAwNTQsMTUuODQ2NjU2NiAxMi4xNDE5MzI4LDE1Ljg0NjY1NjYgTDE1Ljg3Nzc0ODYsMTUuODQ2NjU2NiBDMjEuNDgxODI2NiwxNS44NDY2NTY2IDIyLjQxNTYwMzUsMTcuMjQ0NTM1NCAyMi40MTU2MDM1LDIxLjQzODg3ODggTDIyLjQxNTYwMzUsMzcuNzUxIEMyMi40MTU2MDM1LDM4LjIxNjk1OTYgMjIuODgzMjAwNCwzOC42ODI5MTkyIDIzLjM0OTM4MDMsMzguNjgyOTE5MiBMMjguOTU0MTY2OCwzOC42ODI5MTkyIEMyOS4zOTc2NzU0LDM4LjY4MjkxOTIgMjkuODg3MjM1MSwzOC4yMTY5NTk2IDI5Ljg4NzIzNTEsMzcuNzUxIEwyOS44ODcyMzUxLDIxLjQzODg3ODggQzI5Ljg4NzIzNTEsMTMuMDUwODk5IDI2LjE1MjEyNzgsOS4wODkxODE4MiAxNy4yNzkxMjI0LDkuMDg5MTgxODIiIGlkPSJGaWxsLTQ3Ij48L3BhdGg+DQogICAgICAgIDwvZz4NCiAgICA8L2c+DQo8L3N2Zz4='); display: inline-block; background-size: contain; margin: 0 1rem 0 1rem; width: 90px; min-height: 30px; } dd, dt { display: inline-block; font-size: 20px; margin: 24px; } input[type="text"] { border: 1px solid #e4e4e4; border-radius: 2rem; font-weight: 600; padding: .5rem 1rem; line-height: 1; max-width: 100%; text-align: center; width: 10rem; margin-bottom: .25rem; font-size: 15px; } .btn { cursor: pointer; padding: .5rem 2rem; font-weight: 600; line-height: 1; letter-spacing: .05rem; margin-right: .5rem; border: 2px solid #458962; border-radius: 1rem; } .btn-primary { color: #fff; background-color: #458962; } .btn-secondary { background-color: #fff; color: #458962; } footer { font-size: 20px; } button:disabled { background: darkseagreen; border-color: darkseagreen; } .explainText { font-size: 20px; margin-bottom: 10px; } h1 { display: block; font-weight: bold; color: #9a9a9a; } .content { position: absolute; height: auto; } </ style > </ body > </ html > |
The NDM Simulator can be also configured to provide a custom Challenge form. This can be configured via the ds-simulator-config.creq-form.template-location configuration property in the NDM Simulator configuration properties.
In order for the NDM Simulator to properly handle challenge, the customized challenge template must contain the following placeholders:
$ <form method="POST" action="%otpValidationUrl$">
in order for the NDM Simulator to fill the OTP validation URL to a proper endpoint for validating the entered OTP.
$ <input value="%threeDSSTransId$">
in order for the NDM Simulator to fill the 3DS Server Transaction ID and later on when validating the OTP to identify the transaction.
$ <input name="otp">
in order for the NDM Simulator to handle the entered Challenge data.
For handling challenge cancel, the custom challenge template should include additional submit button to the form with name 'challengeCancel', like:
$ <button type="submit" name="challengeCancel">Cancel</button>
Additionally, there is an option to include the following placeholders in the customized template, in order to provide details about the current transaction:
The NDM Simulator will inject values into them retrieved from the current transaction.