Обновление платежей Stripe для SCA с использованием модели повторяющегося биллинга

В настоящее время я перехожу свое приложение с использования Stripe Charges API на использование Stripe PaymentIntents API, чтобы соответствовать правилам SCA. Мое приложение представляет собой службу подписки с повторяющейся моделью выставления счетов, поэтому я обычно следил за примерами "Членство в спортзале" в документации по миграции, а также просматривал другие соответствующие документы и ссылки.

Я использую Stripe Elements во внешнем интерфейсе, чтобы фиксировать платежные реквизиты и т. Д. В настраиваемой форме, а затем отправляю на свой сервер с токеном оплаты Stripe для дальнейшей обработки (синхронно). Обновления внешнего интерфейса достаточно просты, и у меня нет проблем с ними, но я немного запутался в обновлениях внутреннего интерфейса.

Все примеры кода, которые я могу найти в документации (обычно потрясающей), показывают, как преобразовать Charge звонки в PaymentIntent вызывает, например, этот старый вызов Charge:

Map<String, Object> chargeParams = new HashMap<String, Object>();
chargeParams.put("amount", 1099);
chargeParams.put("currency", "eur");
chargeParams.put("source", request.token_id);
Charge.create(chargeParams);

... становится этим с помощью API-интерфейса PaymentIntents:

Map<String, Object> createPaymentIntentParams = new HashMap<String, Object>();
createPaymentIntentParams.put("currency", "eur");
createPaymentIntentParams.put("amount", 1099);
createPaymentIntentParams.put("confirm", true);
createPaymentIntentParams.put("confirmation_method", "manual");
createPaymentIntentParams.put("payment_method", request.paymentMethodId);
intent = PaymentIntent.create(createPaymentIntentParams);

Поэтому, если от клиента требуется дополнительная авторизация (как указано в PaymentIntent status), запрос будет отправлен обратно клиенту, а Stripe SDK обработает дополнительные меры безопасности.

Но мое приложение не использует Chargeзвонит таким образом. Обычно это выглядит так:

Map<String, Object> srchOpts = new HashMap<>();
srchOpts.put("email", userEmail);   

List<Customer> matchingCustomers = Customer.list(srchOpts).getData();
Customer customer = null;
Subscription subscription = null;

if ( matchingCustomers.isEmpty() ){
    Map<String, Object> params = new HashMap<String, Object>();
    params.put("email", userEmail);
    params.put("source", stripeToken);
    customer = Customer.create(params); // potential SCA rejection ??
}
else if (matchingCustomers.size() == 1) {
    customer = matchingCustomers.get(0);
    Map<String, Object> params = new HashMap<String, Object>();
    params.put("source", stripeToken);
    PaymentSourceCollection paymentSources = customer.getSources();
    paymentSources.create(params); // potential SCA rejection ??
}

Map<String, Object> item = new HashMap<String, Object>();
item.put("plan", planId);

Map<String, Object> items = new HashMap<String, Object>();
items.put("0", item);

Map<String, Object> params = new HashMap<String, Object>();
params.put("items", items);

params.put("customer", customer.getId());
subscription = Subscription.create(params); // potential SCA rejection ??

Новые Customer создание, новое PaymentSource создание и новое Subscription вызовы создания, которые подлежат отклонению SCA, в какой момент мне придется возвращаться заказчику для дальнейшей аутентификации?

Если да, то как мне проверить, необходимо ли это с помощью вызовов Customer и PaymentSource, и как получить требуемый секретный токен клиента для отправки обратно во внешний интерфейс? Объект подписки предоставляет доступ кSetupIntent объект, имеющий статус и секрет клиента, так что я должен их проверить и использовать?

Любые ссылки на соответствующие документы с примерами были бы очень полезны.

1 ответ

Решение

SCA требуется только тогда, когда вы пытаетесь произвести платеж. После того, как вы собрали платежные реквизиты своего клиента (и при желании сохранили их как нового клиента), вы просите Stripe завершить платеж. Затем Stripe свяжется с банком клиента и спросит, можно ли произвести платеж или требуется дополнительная аутентификация.

Если банк говорит, что ничего лишнего не требуется, платеж проходит успешно и все в порядке.

Если банк заявляет, что требуется проверка 3DS, вам нужно будет пропустить своего клиента через поток 3DS, который, по сути, является этапом 2FA, чтобы гарантировать, что лицо, запрашивающее платеж, также является держателем карты.

Если ваш клиент все еще находится в "сеансе" (например, все еще находится на вашем сайте), вы должны передать только что созданный секрет клиента PaymentIntent в свой интерфейс и использовать Stripe.js для завершения шага 2FA и аутентификации платежа.

Если ваш клиент находится вне сеанса (например, это повторяющаяся подписка, и они не находятся на вашем сайте), вам нужно будет отправить своему клиенту электронное письмо, чтобы вернуть его на свой сайт для выполнения шага 3DS (или вы можете использовать Stripe's размещенная страница счета-фактуры).

В вашем случае, когда вы создаете подписку (при условии, что вы не используете пробные периоды), Stripe создаст счет-фактуру с автоматически созданным прикрепленным PaymentIntent. Вы можете получить доступ к этому счету черезlatest_invoiceпараметр в подписке. Если требуется этап 3DS, в PaymentIntent будетrequires_action status, что означает, что вам нужно вернуть вашего клиента в рабочее состояние для завершения платежа.

В этом случае Stripe автоматически отправит вашему пользователю электронное письмо с размещенной страницей счета, чтобы он мог завершить платеж. Без размещенной на хосте страницы счета-фактуры вам придется создать свою собственную реализацию, чтобы вернуть пользователя "в рабочее состояние".

Вам не нужно будет использовать 3DS при создании Customer или PaymentMethod, только когда вы действительно пытаетесь перевести средства из одного места в другое.

Другие вопросы по тегам