ПОЛОСА — Создание подписки с пробной версией, реализация одноразовой аутентификации не выполняется для карт 3D secure после окончания пробной версии

#node.js #stripe-payments #subscription #3d-secure #trail

Вопрос:

  • Стек: Nodejs/Vue/Полоса
  • ПРИМЕЧАНИЕ: Логика работает для стандартной карты (4242424242424242), когда пробной версии не существует, работают даже 3D-карты.
  • Эта карта используется для этого теста: 4000002500003155

https://stripe.com/docs/testing#regulatory-cards

Всем привет, так что название в значительной степени говорит обо всем, у меня проблема с картами 3d secure, когда пробная версия заканчивается.

Шаги для воспроизведения: Узел(СЕРВЕР):

  1. создать клиента
 const customer = await this.getInstance().customers.create({
      email: userData.email,
      name: userData.fullname,
    });
 
  1. создать подписку
 const subscription = await this.getInstance().subscriptions.create({
   customer,
   items: [
     {
       price: priceId,
     },
   ],
   off_session: true,
   promotion_code,
   payment_behavior: 'default_incomplete',
   expand: ['latest_invoice.payment_intent', 'pending_setup_intent'],
   metadata,
   trial_from_plan: true,
});
 
  1. возврат данных на сторону КЛИЕНТА
  const invoice = subscription.latest_invoice as Stripe.Invoice;
 const intentType = subscription.pending_setup_intent ? 'setup' : 'payment';
 const intent = intentType === 'payment'
        ? (invoice.payment_intent as Stripe.PaymentIntent)
        : (subscription.pending_setup_intent as Stripe.SetupIntent);
 const formattedSubscription = pick(subscription,['cancel_at_period_end','cancel_at','canceled_at']);
    
 return {
      intentType,
      ...pick(intent, ['id', 'client_secret', 'status']),
      ...formattedSubscription,
    };
 

Со стороны КЛИНИКИ:

  1. Получение ответа:
  const response = await this.$pricesService.buyPlan(this.selectedPlan.id, {
          fullname: this.nameOnTheCard,
          email: this.email,
          hash: this.couponApplied?.hash,
        });
        if (response.error) {
          throw new Error(response.error);
        }
 
  const { intentSecret, intentID, intentType, ...restOfBuyResponse } = response;
 
  1. В зависимости от типа намерения:
  if (intentType === 'payment') {
          stripeResponse = await StripeInstance.confirmCardPayment(intentSecret, {
            payment_method: { card: this.$refs.cardElement.$refs.element._element },
          });
        } else {
          stripeResponse = await StripeInstance.confirmCardSetup(intentSecret, {
            payment_method: { card: this.$refs.cardElement.$refs.element._element },
          });
        }
 
  1. Подтверждение запускает режим 3d Secure, и после его подтверждения оплачивается счет на 0 долларов.

Все работает так, как должно, до этого следующего момента.

Чтобы как можно быстрее протестировать режим отслеживания, я создал API для удаления пробной версии из подписки

  const subscription = await this.getInstance().subscriptions.update(subscriptionId, {
      trial_end: 'now',
    });
 

После этого счет просрочен, подписка не выполнена (с переключением на ожидание).
Я заметил, что метод default_payment_method отсутствует, поэтому я даже вернул способ оплаты с намерением настройки с внешнего интерфейса и прикрепил к клиенту даже настройки счета.
Но независимо от того, что я изменил, новый счет и намерение оплаты никогда не использовали эту информацию.

Является ли это ожидаемым поведением из-за каких-то правил или я что-то упускаю?

Счет-фактура

///////////
Подписки
////////////
Мероприятия

Ответ №1:

По умолчанию как создание, так и обновление подписки считается запросом на сеанс, и, следовательно, карта требует аутентификации.

Если это сделано исключительно в целях тестирования, вы можете включить off_session=true .

  const subscription = await this.getInstance().subscriptions.update(subscriptionId, {
    trial_end: 'now',
    off_session : true
 });
 

Если вы позволите пробной версии подписки завершиться и продвигаться естественным образом (без вызова API для обновления подписки), вы увидите, что 3DS запрашиваться не будет (с использованием карты, заканчивающейся на 3155).

Вы можете попробовать это, создав подписку с trial_end настройкой на ближайшее возможное время. Вы можете сделать вызов API для завершения и оплаты счета, если не хотите ждать 1 час, пока это будет сделано автоматически.

 const subscription = await stripe.subscriptions.create({
  customer: 'cus_FfkjLYmWcepurw',
  items: [
    {price: 'price_1JXgRCJQtHgRImA7fDIHY4B2'},
  ],
  trial_end : 1634536700
});
 

Комментарии:

1. Большое вам спасибо, я протестировал оба сценария, и все в точности так, как вы объяснили!