В октябре 2017 года у Яндекс.Кассы появились новый платёжный протокол и третья версия API. Мы уже рассказывали о том, как и почему к этому пришли, а сейчас напомним ключевые причины перейти на него для тех, кто этого ещё не сделал.

1. Подключение платежей стало реально быстрым


На новом API оно происходит в 5-10 раз быстрее, чем раньше, и теперь среднестатистический разработчик может подключить платежи к своему (ну, или не совсем) сайту или приложению за один рабочий день, а не за пять, как было раньше. Речь, конечно, о той части работы, когда всё согласовано, заявки одобрены и ключи доступа получены. Но на это тоже достаточно дня.

А для тех, кто продаёт в соцсетях, работает выставление счетов на почту, смской или просто ссылкой, которую можно отправить в личные сообщения.

2. Экономятся силы разработчиков и админов


Для сопровождения старой версии нужно позаботиться о разных мелких вещах — выделить под работу с API статический IP-адрес, раз в год менять сертификаты. А ещё в старой версии нет поддержки SNI-режима HTTPS, который сейчас бесплатно (или почти бесплатно) входит в услугу «хостинг с HTTPS» у многих хостинг-провайдеров

Для возвратов, подтверждения, отмены или повтора платежей картой используется протокол MWS (Merchant Web Services). С помощью MWS магазин может совершать возвраты, подтверждать и отменять отложенные платежи, а также повторять платежи банковской картой (если плательщик на это согласился). В старой версии API для работы с MWS магазину нужно было получить от удостоверяющего центра Яндекс.Денег сертификат X.509, с помощью которого магазин формировал запросы к Яндекс.Кассе. Сейчас всё это идет из коробки — вы просто получаете ключи доступа и внедряете нужные платёжные методы.

В общем, из процесса интеграции пропало много лишних вещей, с которыми приходилось разбираться своими силами и тратить на это время разработчиков и админов.

3. Только REST и ничего лишнего


Мы переписали всё в REST-стиле — теперь протокол понятно построен и предсказуемо себя ведёт. В копилку прошлых сложностей — почти у каждого платёжного метода был собственный синтаксис, сценарий и процесс, через который приходилось пройти при установке, настройке и проведении платежей. Новый протокол избавился от «детских болезней», соответствует стандартам — которые, в том числе, задают международные платежные лидеры.

Давайте для сравнения посмотрим на старый и новый методы возврата платежа.

Раньше нужно было сформировать документ-распоряжение на исполнение операции по стандарту XML 1.0, сформировать криптопакет формата PKCS#7 с цифровой подписью, но без цепочек сертификации, компрессии данных и шифрования. После этого формировался POST-запрос по HTTP/1.1 с телом криптопакета или во вложении через MIME-тип application/pkcs-mime. Дальше дело за малым — передать восемь входных параметров и, в принципе, всё готово.

Итого, HTTP-запрос:
POST /webservice/mws/api/returnPayment HTTP/1.1
Content-Type: application/pkcs7-mime
Content-Length: 906

——-BEGIN PKCS7——-
MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCA
JIAEgbE8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI/Pg0KPG1h
a2VEZXBvc2l0aW9uUmVzcG9uc2UgY2xpZW50T3JkZXJJZD0iMTI5MTExNjIzNDUy
OCIgc3RhdHVzPSIwIi6789Jvcj0iMCIgcHJvY2Vzc2VkRFQ9IjIwMTAtMTEtMzBU
MTE6MjM6NTQuNjI0WiIgYmFsYW5jZT0iNTQxNDYuNzMiIC8+DQoAAAAAAAAxggF8
MIIBeAIBATB3MGoxCzAJBgNVBAYTAlJVMQ8wDQYDVQQIEwZSdXNzaWExFjAUBgNV
BAcTDVN0LlBldGVyc2J1cmcxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5
IEx0ZDEPMA0GA1UEAxMGc2VydmVyAgkAy2xbdQckXjIwCQYFKw4DAhoFAKBdMBgG
CSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTEwMTEzMDEx
MjM1NVowIwYJKoZIhvcNAQkEMRYEFEYNh8glwqIXGR/n6oYrApa8DaO5MA0GCSqG
SIb3DQEBAQUABIGAHlgGsYK30RXWBvuQao0V73KIPQE1A6BCg7Y6Iag/xlmZ3rBB
kFpszF/O2fB+t84pCHfV15ErZQEkAqIotkEYEgA3hAddEW5+RWUzp+3npHpW5OY7
h3niP5Pj+r0P8EDgHe2j0Zb3dzj2mbwOshZD+FP1IcR8AmiTV3u35C6KAEsAAAAA
AAA=
——-END PKCS7——-


И сам запрос на возврат платежа:
<returnPaymentRequest
clientOrderId="46890"
requestDT="2011-07-02T20:38:00.000Z"
invoiceId="2000000433"
shopId="6689"
amount="10.00"
currency="643"
cause="Пользователь отказался принять заказ"
/>

В новой версии API возврат платежа на Python выглядит так:
refund = Refund.create({
    "amount": {
        "value": "2.00",
        "currency": "RUB"
    },
    "payment_id": "21741269-000d-50be-b000-0486ffbf45b0"
})

Вернётся понятный JSON, который можно разобрать чем угодно за минимальное время:
{
    "id": "216742f7-0016-50be-b000-078a43a63ae4",
    "status": "succeeded",
    "amount": {
      "value": "2.00",
      "currency": "RUB"
    },
    "created_at": "2017-10-04T19:27:51.407Z",
    "payment_id": "21746789-000f-50be-b000-0486ffbf45b0"
  }

Красота.

4. Поддержка разных языков и технологий


Ещё у нового API есть SDK для мобильных устройств, PHP, Python и Node.js. Чем бы ни занимались ваши бэкенд-ребята (ну, кроме совсем уж экзотических случаев), платежи через Кассу подключаются быстро. Если человек активно пишет на Python дольше пары месяцев — он справится с интеграцией.

В прошлом году мы выпустили библиотеку для мобильных приложений на iOS и Android. С её помощью платёжные формы встраиваются в приложение и выглядят как его часть (и никаких WebView). Пользователи смогут оплатить заказ банковской картой, из кошелька в Яндекс.Деньгах, через Google Pay, Apple Pay или Сбербанк Онлайн.

Внедряется тоже просто — отдайте инструкцию вашему разработчику и скоро увидите, как стало прекрасно. Подробнее о том, как мобильный SDK увеличивает уровень счастья у вас и у пользователей ваших мобильных приложений, мы уже писали в нашем хабраблоге.

5. Регулярные платежи без шаманства


Сразу после установки и настройки заработают платежи картой с предавторизацией средств — они встроены в API по умолчанию.
Рекуррентные платежи (и картой, и из кошелька) тоже есть: нужно согласовать их со службой безопасности, но так было и в старом протоколе. Если при рекуррентном платеже используется карта с обязательным 3D-Secure, то новый API сначала вернёт ссылку на него.
В общем, всё стало проще — здесь тоже не нужно выполнять длинные ритуалы с MWS, получением сертификатов и всеми остальными криптоужасами.

6. Автоматические уведомления о смене статуса платежа


Раньше приходилось вручную проверять статус каждого платежа, а теперь, если он изменился, разработчику автоматически упадёт уведомление.
В API v3 встроены четыре вида автоматических уведомлений о статусе платежей:
  1. «Ожидает подтверждения мерчантом после оплаты»,
  2. «Оплачен»,
  3. «Отменён или произошла ошибка при платеже»,
  4. «Платеж возвращен».

На старом протоколе для этого приходилось писать сложный MWS-метод listOrders, который показывал перечень и свойства заказов. 12 параметров, сложная логика отправки запроса и интригующая возможность получить ответ в формате CSV:

status=0;error=0;processedDT=2011-08-02T14:46:58.096+03:00;orderCount=2
shopId;shopName;articleId;articleName;invoiceId;orderNumber;paymentSystemOrderNumber;customerNumber;createdDatetime;paid;orderSumAmount;
orderSumCurrencyPaycash;orderSumBankPaycash;paidSumAmount;paidSumCurrencyPaycash;paidSumBankPaycash;receivedSumAmount;receivedSumCurrencyPaycash;
receivedSumBankPaycash;shopSumAmount;shopSumCurrencyPaycash;shopSumBankPaycash;paymentDatetime;paymentAuthorizationTime;payerCode;payerAddress;payeeCode;
paymentSystemDatetime;avisoReceivedDatetime;avisoStatus;paymentType;agentId;uniLabel;environment
1;"Ваш магазин";2;"Шапка-ушанка";2000024717776;"2011.08.02 09:07:32";483512879684006008;97881;2011-08-02T08:07:59.148+03:00;true;10.15;643;1003;10.15;643;
1003;10.15;643;1003;10.15;643;1003;2011-08-02T08:07:59.684+03:00;483512879684006008;41003476047679;192.168.1.127;41003131475668;2011-08-02T08:07:59.684+03:00;
2011-08-02T08:07:59.660+03:00;1000;AC;200002;1cd12967-0001-5000-8000-000000034fd8;Live
1;"Ваш магазин";2;"Шапка-ушанка";2000024717780;2000024717780;483512937773006008;770367;2011-08-02T08:08:57.175+03:00;true;10.00;643;1003;10.00;643;
1003;10.00;643;1003;10.00;643;1003;2011-08-02T08:08:57.773+03:00;483512937773006008;41003494819180;192.168.1.127;41003131475668;2011-08-02T08:08:57.773+03:00;
2011-08-02T08:08:57.730+03:00;1000;AC;200002;1cd129a4-0001-5000-8000-000000034fe1;Live

В новой версии так. Запрос:
curl https://payment.yandex.net/api/v3/payments/{payment_id} \ -u <Идентификатор магазина>:<Секретный ключ>
Ответ: 
{
  "id": "22312f66-000f-5100-8000-18db351245c7",
  "status": "waiting_for_capture",
  "paid": true,
  "amount": {
    "value": "2.00",
    "currency": "RUB"
  },
  "created_at": "2018-07-18T10:51:18.139Z",
  "description": "Заказ №72",
  "expires_at": "2018-07-25T10:52:00.233Z",
  "metadata": {},
  "payment_method": {
    "type": "bank_card",
    "id": "22ebbf66-000f-5000-8000-18db351245c7",
    "saved": false,
    "card": {
      "first6": "555555",
      "last4": "4444",
      "card_type": "MasterCard"
    },
    "title": "Bank card *4444"
  },
  "test": false
}

7. Сразу понятно, в какой момент возникла ошибка


Если платеж не прошел, то вместо «что-то пошло не так» новый API в явном виде даст понять, почему так вышло — например, на карте кончились деньги или пользователь хотел расплатиться через Сбербанк Онлайн, но он не подключен.
Изредка могут возникать кратковременные «что-то пошло не так» — мы, конечно, с ними боремся (лид-редактор Наташа в этом месте кивает мне и показывает большой палец), но предсказать различия в маппинге ошибок у разных банков или неожиданное поведение софта иногда невозможно. Даже нам.
В общем, если платёж отменен, то из ответа API сразу будет понятно, из-за чего:
{
  "id": "22379b7b-000f-5000-9030-1a603a795739",
  "status": "canceled",
  "paid": false,
  "amount": {
    "value": "2.00",
    "currency": "RUB"
  },
  "created_at": "2018-05-23T15:24:43.812Z",
  "metadata": {},
  "payment_method": {
    "type": "bank_card",
    "id": "22977a7b-000f-5000-9000-1a603a795129",
    "saved": false
  },
  "recipient": {
    "account_id": "100001",
    "gateway_id": "1000001"
  },
  "test": false,
  "cancellation_details": {
    "party": "payment_network",
    "reason": "payment_method_restricted"
  }
}

8. Всё можно проверить, прежде чем начать


Чтобы получить тестовые ключи и посмотреть, как всё работает, нужно зарегистрироваться в личном кабинете Яндекс.Кассы — для этого нужны логин на Яндексе и ИНН компании. В анкете выберите самостоятельную регистрацию — через минуту будет создан тестовый контур и вы сможете проверить, как ходят платежи.

Когда мы еще не запустили эту возможность, было доступно тестовое окружение, в котором можно попробовать API v3 с помощью REST-клиента Insomnia. Там представлены примеры для оплаты банковской картой, при этом наглядно показано какой запрос отправляется, какой ответ возвращается и что происходит на всех этапах процесса обмена данными.



Для всех этапов интеграции и сопровождения у нас есть пошаговое руководство на русском и английском языках, а ещё подробнейший справочник по API.

В общем, переходите на новый API, если ещё не, или подключайтесь к Яндекс.Кассе — там всё уже готово к вашему визиту.

Комментарии (13)


  1. alexesDev
    24.05.2019 10:27
    +1

    А чудо интерфейс исправили? В котором не видно часть платежей, которые видны из апи и менеджеры руками разводят.


    1. evil_me Автор
      24.05.2019 14:07

      Добрый день. Уточнил у техников, все созданные и оплаченные тестовые платежи видны в личном кабинете Яндекс.Кассы.


  1. donpadlo
    24.05.2019 11:07
    +1

    Там %, сям %. А потом «А почему у вас за наличку дешевле?»


    1. Arnautka
      24.05.2019 12:54

      Действительно, почему?))) а если клиент заказал в подарок? а если получать будет не он? а если наличные у человека раз в неделю бывают (а таких человек много!). Потенциально все эти клиенты пошли в другой магазин, где есть онлайн-оплата, потому что им так в данном случае удобней. И это только самые очевидные случаи, конечно


    1. Andrey_Volk
      24.05.2019 16:36

      Вас никто не заставляет использовать это решение, вроде бы. Как бы, не хотите «там %, сям %» — продавайте сами, вручную :)


      1. donpadlo
        24.05.2019 17:39

        Так так и есть уже. Многие не крупные предприниматели, которым года 3 назад еще было особо без разницы что «по безналу», что за «нал» принимать за товар/услуги, сейчас с большей охотой берут «нал». И доходит до того, что открытым текстом говорят — хочешь дешевле, оплачивай наличкой. Хотя казалось бы по идее шли к «наоборот». Это следствие что «там процентик, сям процентик». Экваринг %, онлайн касса %, банк % и т.д. и т.д. Слишком аппетиты большие у посредников.


  1. Neyury
    24.05.2019 14:01
    +2

    Очень понравился новый API, хотя на практике и не получилось пока воспользоваться, но в дальнейшем планирую.

    Когда стоит ожидать обновление API выплат в таком же стиле?


  1. Codenamed
    24.05.2019 18:36
    +1

    А зачем вы возитесь со всякими там улучшениями API вместо того, чтобы полностью реализовать у себя всю цепочку с онлайн-кассой? Никому не хочется разбираться в зоопарке ваших партнеров и тратить время на интеграцию с теми и с этими.

    Вы планируете сделать сквозное решение с арендой накопителя, так чтобы никакую кассу не видеть никогда и об интеграции с ней тоже не думать? :)


    1. Codenamed
      27.05.2019 17:41

      YaMoneyHelp, раз уж вы тут отвечаете, прокомментируйте пожалуйста разработку собственного решения для полностью «облачных» онлайн-касс.


  1. c3gdlk
    25.05.2019 00:23

    Яндекс касса самый кривой продукт яндекса с которым сталкивался.

    «На Вашем старом аккаунте ошибка, которую мы не можем исправить. Просто заведите новый» — официальный ответ от техподдержки.

    Не юникод символы в запросах на колбеки и прочее. В итоге старая версия работает с кучей костылей, но работает! И желания проверять стабильность новой нет.


    1. YaMoneyHelp
      27.05.2019 12:05

      Здравствуйте, проверим этот ответ поддержки, пожалуйста, подскажите ваш shopID в Яндекс.Кассе.


  1. artemmalko
    26.05.2019 17:10

    Подскажите, как в новой версии API передать return_url для ситуации, когда платеж отменили? Сейчас только 1 url можно передать и он будет на ссылке "в магазин" и до оплаты, и после.


    1. evil_me Автор
      27.05.2019 11:59

      Добрый день!
      Вот здесь даны подробные рекомендации по реализации returl_url.