IPN and LCN payloads with special characters(Example :- UTF-8) are failing HMAC validations.
For example below is the part of a IPN notification triggered from twoChekout backend to a webhook hosted on a nodejs service.
{"GIFT_ORDER":"0","SALEDATE":"2026-07-10 19:34:27","PAYMENTDATE":"2026-07-10 19:34:32","REFNO":"275794946","REFNOEXT":"","SHOPPER_REFERENCE_NUMBER":"","ORDERNO":"1828","ORDERSTATUS":"PAYMENT_AUTHORIZED","PAYMETHOD":"Visa/MasterCard","PAYMETHOD_CODE":"CCVISAMC","FIRSTNAME":"John","LASTNAME":"Doe","COMPANY":"cisco","REGISTRATIONNUMBER":"","FISCALCODE":"","TAX_OFFICE":"","CBANKNAME":"","CBANKACCOUNT":"","ADDRESS1":"R. Álvaro Coutinho 14","ADDRESS2":"","CITY":"Lisboa","STATE":"Lisboa","ZIPCODE":"1150-025","COUNTRY":"Portugal","COUNTRY_CODE":"pt","PHONE":"","FAX":"","CUSTOMEREMAIL":"sud.int.japanipn@wbxlab.us","FIRSTNAME_D":"John","LASTNAME_D":"Doe","COMPANY_D":"cisco","ADDRESS1_D":"R. Álvaro Coutinho 14","ADDRESS2_D":"","CITY_D":"Lisboa","STATE_D":"Lisboa","ZIPCODE_D":"1150-025","COUNTRY_D":"Portugal","COUNTRY_D_CODE":"pt","PHONE_D":
fix :- replacing val.length.toString() to Buffer.byteLength(val, 'utf8').toString() would help calculating right length and matching the hash. Buffer.byteLength(val, 'utf8').toString() covers regular characters as well.
IPN and LCN payloads with special characters(Example :- UTF-8) are failing HMAC validations.
For example below is the part of a IPN notification triggered from twoChekout backend to a webhook hosted on a nodejs service.
Here as Address fields contain UTF-8 chars like Álvaro, https://github.com/2Checkout/2checkout-node-sdk/blob/808291b0f5ca6e114aa2d85ef929ff53fec396a6/lib/ipn.js#L79 calculates
val.length.toString() + val.toString()which considers Á as length 1, but hash calculated from backend 2checkout(probably PHP) considers as 2.fix :- replacing val.length.toString() to Buffer.byteLength(val, 'utf8').toString() would help calculating right length and matching the hash. Buffer.byteLength(val, 'utf8').toString() covers regular characters as well.