Конечно, да, скажете вы. Но не было бы этой статьи, если бы не было вопроса.
Так же эта статья будет вам полезна, если вы используете эквайринг от Тинькофф.
Немного предыстории. Какое-то время назад на одном из своих проектов я поменял онлайн-эквайринг на Тинькофф и уже после отладки начали всплывать странные ошибки с оплатой: хэш-подпись запроса считалась неверно. Причем, только на реальных платежах, что еще больше омрачало ситуацию.
Проблема оказалась в поле Data json-объекта, который приходит от банка в нотификации платежа. В одних случаях оно приходит как Data, а в других DATA (в верхнем регистре).
О проблеме я сообщил в поддержку Тинькофф и тут началось интересное. Поддержка утверждает, что регистр ключей в JSON не играет никакой роли:
Валерий, здравствуйте, JSON не является регистрозависимым. С его точки зрения DATA и Data это одно и тоже. Корень проблемы тут в вашем программном обеспечении, которое как раз регистрозависимое.
К сожалению, доказать обратное техническим специалистам Тинькофф не удалось. Найти упоминание регистрозависимости JSON в спецификации - еще более сложная задача (нашли), поэтому я поступил так, как делаю всегда: пишу код и проверяю как он работает.
Поскольку JSON сам по себе ничего не значит, а всегда обрабатывается каким-либо языком программирования, можно легко узнать, как те или иные языки относятся к ключам в разном регистре в JSON.
JavaScript - как самый популярный
Когда говорят про JSON, самым популярным языком, его использующим, является JS.
const json = JSON.parse('{"Data":1,"DATA":2}');
console.log(json, json.Data); // {Data: 1, DATA: 2} 1
Как видим, регистр ключей играет роль. Два разных ключа с разными значениями. И если в документации указан ключ Data, то DATA не подойдет, увы.
PHP - когда нет JS
Возможно будет разница между массивом и объектом?
<?php
$json = json_decode('{"Data":1,"DATA":2}', true);
var_dump($json);
// array (size=2)
// 'Data' => int 1
// 'DATA' => int 2
$json = json_decode('{"Data":1,"DATA":2}', false);
var_dump($json);
// object(stdClass)[253]
// public 'Data' => int 1
// public 'DATA' => int 2
Ситуация аналогичная. Ключи в разном регистре - это разные ключи. Преобразование в массив или в объект роли не играет.
Go - язык со строгой типизацией
Все же JS и PHP позволяют много вольностей. Возможно компилируемый язык со строгой типизацией будет вести себя иначе?
var data map[string]interface{}
json.Unmarshal([]byte("{\"Data\":1,\"DATA\":2}"), &data)
fmt.Println(data) // map[DATA:2 Data:1]
И снова ключи в разном регистре - это разные ключи. Мы получили map с двумя разными ключами и значениями.
C# - включаемая регистронезависимость
В комментариях выложили пример кода для C#
Поведение либо как у других языков, либо можно включить регистронезависимость и ловить ошибки при наложении свойств (хотя в случае одного свойства и правда не будет разницы).
Заключение
Если вы все еще сомневаетесь, является ли JSON регистрозависимым, просто попробуйте аналогичный код в своем языке программирования.
Я не встречал языка, в котором JSON был бы регистронезависимым. Если вы такой знаете - сообщите, будет интересно.
P.S. Я уверен, что разработчики Тинькофф тоже читают хабр. Обратите пожалуйста внимание на проблему. У вас на проде случайным образом меняется регистр ключа Data в нотификации платежа.
UPD 19.04.22 14:50
Спасибо @Busla за найденное упоминание регистрозависимости в спецификации.