diff --git a/src/core/lib/PaymentPinVerification.mjs b/src/core/lib/PaymentPinVerification.mjs index d2c699fc..33c419f4 100644 --- a/src/core/lib/PaymentPinVerification.mjs +++ b/src/core/lib/PaymentPinVerification.mjs @@ -168,21 +168,30 @@ function verifyIbm3624Pin(pvkHex, decimalizationTable, pinValidationData, padCha } /** - * Decimalizes a PVV candidate using the common numeric-first rule. + * Decimalizes a PVV candidate using the standard two-pass rule: + * pass 1 collects decimal digits (0-9); pass 2 maps A=0 B=1 C=2 D=3 E=4 F=5. * * @param {string} hex * @returns {string} */ function decimalizePvv(hex) { + const upper = hex.toUpperCase(); let out = ""; - for (const ch of hex.toUpperCase()) { + + for (const ch of upper) { if (/\d/.test(ch)) { out += ch; - } else { - out += String((ch.charCodeAt(0) - "A".charCodeAt(0)) % 10); + if (out.length >= 4) return out.substring(0, 4); } - if (out.length >= 4) return out.substring(0, 4); } + + for (const ch of upper) { + if (/[A-F]/.test(ch)) { + out += String(ch.charCodeAt(0) - "A".charCodeAt(0)); + if (out.length >= 4) return out.substring(0, 4); + } + } + return out.substring(0, 4); } diff --git a/src/core/operations/VerifyVISAPVV.mjs b/src/core/operations/VerifyVISAPVV.mjs index 01b6b49c..2fd381d6 100644 --- a/src/core/operations/VerifyVISAPVV.mjs +++ b/src/core/operations/VerifyVISAPVV.mjs @@ -23,7 +23,7 @@ class VerifyVISAPVV extends Operation { this.testDataSamples = [ { name: "VISA PVV verify sample", - input: "6077", + input: "6776", args: ["0123456789ABCDEFFEDCBA9876543210", "5432101234567890", 1, "1234", true] } ]; diff --git a/tests/operations/tests/Payment.mjs b/tests/operations/tests/Payment.mjs index bbf66cf6..a2abcfb6 100644 --- a/tests/operations/tests/Payment.mjs +++ b/tests/operations/tests/Payment.mjs @@ -812,7 +812,7 @@ TestRegister.addTests([ pin: "1234", pvvInput: "1012345678911234", encryptedPvvInputHex: "6A77E65CFE349D60", - pvv: "6077" + pvv: "6776" }, null, 4), recipeConfig: [ { @@ -823,7 +823,7 @@ TestRegister.addTests([ }, { name: "VISA PVV Verify: known sample", - input: "6077", + input: "6776", expectedOutput: JSON.stringify({ pinVerificationKeyHex: "0123456789ABCDEFFEDCBA9876543210", pan: "5432101234567890", @@ -831,8 +831,8 @@ TestRegister.addTests([ pin: "1234", pvvInput: "1012345678911234", encryptedPvvInputHex: "6A77E65CFE349D60", - pvv: "6077", - expectedPvv: "6077", + pvv: "6776", + expectedPvv: "6776", valid: true }, null, 4), recipeConfig: [ @@ -913,8 +913,8 @@ TestRegister.addTests([ pin: "1234", pvvInput: "1012345678911234", encryptedPvvInputHex: "6A77E65CFE349D60", - pvv: "6077", - expectedPvv: "6077", + pvv: "6776", + expectedPvv: "6776", valid: true }, null, 4), recipeConfig: [