Первое шифрование
Итак нам нужно зашифровать запрос.
Ключи необходимые для шифрования запроса: https://nanokassa.ru/integration/documentation/publichnye-rsa-klyuchi/
Итак нам нужно зашифровать вот такой запрос:
{ "kassaid": "123456", "kassatoken": "12345678912345678912345678912345", "cms": "ss7-7.3.0.209", "check_send_type": "email", "products_arr": [{ "name_tovar": "\u041a\u0430\u0440\u0442\u043e\u043d\u043d\u0430\u044f \u043a\u043e\u0440\u043e\u0431\u043a\u0430 2, 11112", "price_piece_bez_skidki": 7744, "skidka": 1297, "kolvo": 2, "price_piece": 7095, "summa": 14191, "stavka_nds": 6, "priznak_sposoba_rascheta": 4, "priznak_predmeta_rascheta": 1, "priznak_agenta": "none", "phone_oper_perevoda": "", "operation_plat_agenta": "", "phone_oper_priem_plat": "", "name_oper_perevoda": "", "address_oper_perevoda": "", "inn_oper_perevoda": "", "phone_postavshika": "", "name_postavshika": "", "discount": { "type": "amount", "value": 12.97 } }, { "name_tovar": "\u0423\u043f\u0430\u043a\u043e\u0432\u043a\u0430", "price_piece_bez_skidki": 155, "skidka": 26, "kolvo": 2, "price_piece": 142, "summa": 284, "stavka_nds": 6, "priznak_sposoba_rascheta": 4, "priznak_predmeta_rascheta": 4, "priznak_agenta": "none", "phone_oper_perevoda": "", "operation_plat_agenta": "", "phone_oper_priem_plat": "", "name_oper_perevoda": "", "address_oper_perevoda": "", "inn_oper_perevoda": "", "phone_postavshika": "", "name_postavshika": "", "discount": { "type": "amount", "value": 0.26 } }, { "name_tovar": "\u041a\u0430\u0440\u0442\u043e\u043d\u043d\u0430\u044f \u043a\u043e\u0440\u043e\u0431\u043a\u0430 2, 11112", "price_piece_bez_skidki": 2277, "skidka": 191, "kolvo": 1, "price_piece": 2086, "summa": 2086, "stavka_nds": 6, "priznak_sposoba_rascheta": 4, "priznak_predmeta_rascheta": 1, "priznak_agenta": "none", "phone_oper_perevoda": "", "operation_plat_agenta": "", "phone_oper_priem_plat": "", "name_oper_perevoda": "", "address_oper_perevoda": "", "inn_oper_perevoda": "", "phone_postavshika": "", "name_postavshika": "", "discount": { "type": "amount", "value": 1.91 } }, { "name_tovar": "\u0414\u043e\u0441\u0442\u0430\u0432\u043a\u0430: PickPoint", "price_piece": 30000, "summa": 30000, "kolvo": 1, "stavka_nds": 6, "priznak_sposoba_rascheta": 4, "priznak_predmeta_rascheta": 1, "priznak_agenta": "none", "phone_oper_perevoda": "", "operation_plat_agenta": "", "phone_oper_priem_plat": "", "name_oper_perevoda": "", "address_oper_perevoda": "", "inn_oper_perevoda": "", "phone_postavshika": "", "name_postavshika": "", "deliveryposition": "yes" }], "oplata_arr": { "rezhim_nalog": "2", "money_nal": 0, "money_electro": 46561, "money_predoplata": 0, "money_postoplata": 0, "money_vstrecha": 0, "kassir_inn": "", "kassir_fio": "", "client_email": "[email protected]", "client_phone": "123" }, "itog_arr": { "priznak_rascheta": 1, "itog_cheka": 46561 }
Итак вот этот большой запрос после шифрования должен превратиться вот в такой небольшой запрос:
{ "ab":"GYBhagdYGWgahjGDHASgdjhas...ASDGd", "de":"GYBhagdYGWgahjGDHASgdjhas...ASDGd", "kassaid":"123456", "kassatoken":"3212312312312", "check_type":"standart", "rid":"2020_123456789abc123456789123456789abc" "test":"1" }
Разберем, что здесь что.
Переменные kassaid и kassatoken - данные для авторизации.
В переменной test мы прописываем, тестовый это запрос или «боевой». Внимание! Не забывайте его указывать! Потому, что если вы его не указали, мы автоматически считаем его тестовым и не проведем через онлайн кассы. (Возможные значения: 0; 1) (1 -запрос тестовый, 0 - запрос боевой). Этот объект придется еще раз указывать - поэтому не забывайте о нем. Зато они будут видны в личном кабинете nanokassa.ru
В переменной ab находится ключ для дешифровки пакета de. Объект ab зашифрован с помощью шифрования RSA.
В переменной de находится основной пакет с данными. Объект de зашифрован с помощью AES256-CTR. Ключ каждый раз разный. Ключ можно узнать только расшифровав пакет ab (RSA)
В переменной check_type находится параметр типа чека. Если это чек прихода или возврата, поставьте параметр standart. Если это чек коррекции - то параметр должен быть равен korrcheck.
В переменной rid находится параметр уникальный параметр Request-ID. Он не обязателен. Подробнее про него можете прочитать тут.
Вот функции (на php) (с учетом, что установлен openssl), чтобы грамотно вам зашифровать пакеты для первого шифрования. (request показан обобщенно). Для шифрования aes256-ctr используется функция openssl_encrypt.
$request = '{ "kassaid": "123456", "kassatoken": "3212312312312", "cms":"xxx", ... "card_amount": 3934 }'; $IVdata = random_bytes(16); $pw = random_bytes(32); $mk = 'xxx'; // hmac контроль в формате base64 $dataAES = openssl_encrypt($request, "aes-256-ctr", $pw, OPENSSL_RAW_DATA, $IVdata); $hmac = hash_hmac('sha512', $IVdata.$dataAES, base64_decode($mk), true); $returnDataDE = base64_encode($hmac.$IVdata.$dataAES);
То есть строение пакета de должно быть таким. 64 байта hmac, 16 байт IVDATA, и остальные байты самого пакета.
Теперь перейдем к пакету ab.
Вот функции (на php) (с учетом, что установлен openssl), чтобы грамотно вам зашифровать пакеты для первого шифрования. (pubkey показан обобщенно). Для шифрования RSA используется функция openssl_public_encrypt.
$pubkey = "-----BEGIN PUBLIC KEY----- HASGDHJASGDASDSAGD .... SADGHASDHASJGDAHJS== -----END PUBLIC KEY-----"; openssl_public_encrypt($pw, $ab_rsa, $pubkey, OPENSSL_PKCS1_OAEP_PADDING) $ab = base64_encode ($ab_rsa); $returnDataAB = $ab;
Теперь мы можем уже понять, как получить вот такой пакет.
{ "ab":"GYBhagdYGWgahjGDHASgdjhas...ASDGd", "de":"GYBhagdYGWgahjGDHASgdjhas...ASDGd", "kassaid":"123456", "kassatoken":"3212312312312", "check_type":"standart", "test":"1" }
Перейдем ко второму шифрованию.