Сценарий: тестирование 3-D Secure
В боевом контуре челлендж 3-D Secure включается индивидуально — по эквайеру, типу интеграции и фрод-правилам. Полагаться на то, что он будет или что его не будет, нельзя: интеграция должна одинаково работать в обоих режимах. Песочница даёт это проверить — 3-D Secure переключается настройкой проекта card_3ds_enabled (v2.65.0).
Sandbox
Где переключается. На карточке проекта в 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 — платёжная форма: ответ одинаковый в обоих режимах
- Создайте карточный инвойс без блока контракта — как в сценарии «карта».
- Перейдите по
AuthorizationUrl(XML) илиauthorization.(JSON) — откроется форма реквизитов; тестовая картаurl 4111 1111 1111 1111. - Настройка включена: после отправки реквизитов открывается страница подтверждения, она принимает любые 4 цифры. Настройка снята: сразу итоговый экран, страницы подтверждения нет.
- Сверьте ответ
CreateInvoiceи платёжное уведомление в обоих прогонах — они совпадают.
Автотест, который считает редиректы на платёжной странице или ждёт экран подтверждения, сломается при смене настройки. Привязывайтесь к коллбеку и к статусу из GetInvoice, а не к числу экранов.
Кейс 2 — списание по контракту: исход приходит в ответе
Контракт привязывается заранее — шаг 1 сценария «привязка карты». Дальше обычный CreateInvoice с <CustomerContractInfo>, и вот здесь ответ зависит от настройки.
Sandbox
<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><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 прогнан в обоих режимах, ответ и коллбек совпали.
- Кейс 2 прогнан в обоих режимах, парсер пережил ответ без
AuthorizationInfo. - Исход берётся из статусов и коллбека, а не из наличия
AuthorizationUrl. - Кейс 3 прогнан: отказ по зарезервированному окончанию виден в обоих режимах.
- Перед выходом в прод выяснено, включён ли челлендж у вашего эквайера — но код рассчитан на оба варианта.