Skip to Content

Сценарий: тестирование 3-D Secure

В боевом контуре челлендж 3-D Secure включается индивидуально — по эквайеру, типу интеграции и фрод-правилам. Полагаться на то, что он будет или что его не будет, нельзя: интеграция должна одинаково работать в обоих режимах. Песочница даёт это проверить — 3-D Secure переключается настройкой проекта card_3ds_enabled (v2.65.0).

Где переключается. На карточке проекта в Admin UI песочницы, по умолчанию включён. Если доступа в Admin UI нет — попросите администраторов sandbox переключить настройку для вашего проекта. Настройка проектная: поля запроса, которое снимало бы челлендж на отдельный платёж, в протоколе нет.

Что настройка меняет, а что нет

Сценарий3-D Secure включён3-D Secure снят
Оплата картой через платёжную формуАдрес из ответа ведёт на форму реквизитов, за ней страница подтвержденияТот же адрес и та же форма, страница подтверждения пропущена: платёж проводится сразу после отправки реквизитов
Списание по карточному контракту (custom form, только XML)В ответе есть блок AuthorizationInfo со ссылкой на страницу подтверждения 3-D SecureПлатёж проводится синхронно в самом CreateInvoice: блока AuthorizationInfo нет, AuthorizationType — SKIP, статусы инвойса уже несут исход
СБП и SberPayЧелленджа нет по устройству протоколаТо же — настройка их не затрагивает
Зарезервированные окончания карты 0001–0005РаботаютРаботают так же: это эмуляция отказа эквайера, к 3-D Secure она отношения не имеет

Чем сценарии отличаются в запросе: платёжная форма — <UndefinedBankCardCustomer> без блока CustomerContractInfo, в JSON "type": "undefined_bank_card"; списание по контракту — тот же CreateInvoice с CustomerContractInfo/MerchantContractID.

Состав ответа меняется ровно в одном сценарии — списание по контракту. У оплаты через платёжную форму разница видна только плательщику (на один экран меньше), а партнёру приходят тот же ответ и то же платёжное уведомление. Проверка вида «пришёл AuthorizationUrl — значит челлендж включён» неверна: для платёжной формы адрес приходит всегда.

Кейс 1 — платёжная форма: ответ одинаковый в обоих режимах

  1. Создайте карточный инвойс без блока контракта — как в сценарии «карта».
  2. Перейдите по AuthorizationUrl (XML) или authorization.url (JSON) — откроется форма реквизитов; тестовая карта 4111 1111 1111 1111.
  3. Настройка включена: после отправки реквизитов открывается страница подтверждения, она принимает любые 4 цифры. Настройка снята: сразу итоговый экран, страницы подтверждения нет.
  4. Сверьте ответ CreateInvoice и платёжное уведомление в обоих прогонах — они совпадают.

Автотест, который считает редиректы на платёжной странице или ждёт экран подтверждения, сломается при смене настройки. Привязывайтесь к коллбеку и к статусу из GetInvoice, а не к числу экранов.

Кейс 2 — списание по контракту: исход приходит в ответе

Контракт привязывается заранее — шаг 1 сценария «привязка карты». Дальше обычный CreateInvoice с <CustomerContractInfo>, и вот здесь ответ зависит от настройки.

3-D Secure включён — ответ отправляет плательщика на подтверждение
<Response> <CreateInvoiceResponse> <BankCardCustomer> <MerchantCustomerId>client_id</MerchantCustomerId> </BankCardCustomer> <InvoiceInfo> <CustomerPrice amount="20.00" currency="RUB" includingVAT="true" /> <InvoiceStatus>WaitPaymentConfirmation</InvoiceStatus> <PaymentStatus>NOT_PAID</PaymentStatus> <AuthorizationType>AUTH_PAGE</AuthorizationType> <IsAuthorized>false</IsAuthorized> <InvoiceID>3c8d95c6-0006-0062-6727-4ea756dba332</InvoiceID> <MerchantOrderID>order_126</MerchantOrderID> </InvoiceInfo> <BillingInfo> <BillingChannel>BankRtp</BillingChannel> </BillingInfo> <CustomerContractInfo> <ContractID>1c6495bb-0002-005f-f54e-d286731d55b9</ContractID> <AuthorizationType>SKIP</AuthorizationType> <ExpirationTimeUtc>27.04.2028 21:00:06</ExpirationTimeUtc> <MerchantContractID>1234567890</MerchantContractID> </CustomerContractInfo> <AuthorizationInfo> <AuthorizationUrl>https://pay-sandbox.digitalspb.com/checkout/a038a5ce-c580-4ff1-b480-e364b21a7474/pin?last4=4444</AuthorizationUrl> </AuthorizationInfo> </CreateInvoiceResponse> <ResultCode>0</ResultCode> <ResultDescription>OK</ResultDescription> </Response>
3-D Secure снят — исход уже в ответе, редиректить некуда
<Response> <CreateInvoiceResponse> <BankCardCustomer> <MerchantCustomerId>client_id</MerchantCustomerId> </BankCardCustomer> <InvoiceInfo> <CustomerPrice amount="20.00" currency="RUB" includingVAT="true" /> <InvoiceStatus>Processed</InvoiceStatus> <PaymentStatus>PAID</PaymentStatus> <AuthorizationType>SKIP</AuthorizationType> <IsAuthorized>true</IsAuthorized> <InvoiceID>4d9e95c6-0006-0062-6727-4ea756dba333</InvoiceID> <MerchantOrderID>order_127</MerchantOrderID> </InvoiceInfo> <BillingInfo> <BillingChannel>BankRtp</BillingChannel> </BillingInfo> <CustomerContractInfo> <ContractID>1c6495bb-0002-005f-f54e-d286731d55b9</ContractID> <AuthorizationType>SKIP</AuthorizationType> <ExpirationTimeUtc>27.04.2028 21:00:06</ExpirationTimeUtc> <MerchantContractID>1234567890</MerchantContractID> </CustomerContractInfo> </CreateInvoiceResponse> <ResultCode>0</ResultCode> <ResultDescription>OK</ResultDescription> </Response>

Что должен уметь код, разбирающий этот ответ:

  • не считать AuthorizationInfo обязательным — при снятом челлендже блока нет, и обращение к нему по индексу упадёт;
  • брать исход из InvoiceStatus / PaymentStatus, а не из факта редиректа: со снятым челленджем инвойс приходит уже Processed / PAID;
  • не путать два AuthorizationType: у CustomerContractInfo он SKIP в обоих режимах (это про контракт, PIN-подтверждения у карточного контракта нет), а у InvoiceInfo он AUTH_PAGE с челленджем и SKIP без него.

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

Кейс 3 — отказ эквайера при снятом челлендже

Зарезервированные окончания карты работают независимо от 3-D Secure. Привяжите контракт картой с окончанием 0001–0005 (см. Ошибки карты) и спишите по нему при снятой настройке: отказ придёт в том же ответе CreateInvoice — InvoiceStatus Cancelled, PaymentStatus NOT_PAID. С включённым челленджем тот же отказ виден только после прохождения страницы подтверждения. Это и есть главный выигрыш режима без 3-D Secure для тестов: негативный сценарий проверяется одним запросом, без браузера.

Кейс 4 — СБП настройка не затрагивает

Челленджа у СБП нет по устройству протокола, поэтому сценарий «СБП» в обоих режимах идёт одинаково. Если СБП-платёж повёл себя иначе после переключения настройки — дело не в 3-D Secure.

Чек-лист

  1. Кейс 1 прогнан в обоих режимах, ответ и коллбек совпали.
  2. Кейс 2 прогнан в обоих режимах, парсер пережил ответ без AuthorizationInfo.
  3. Исход берётся из статусов и коллбека, а не из наличия AuthorizationUrl.
  4. Кейс 3 прогнан: отказ по зарезервированному окончанию виден в обоих режимах.
  5. Перед выходом в прод выяснено, включён ли челлендж у вашего эквайера — но код рассчитан на оба варианта.