#node.js #stripe-payments #subscription #3d-secure #trail
Вопрос:
- Стек: Nodejs/Vue/Полоса
- ПРИМЕЧАНИЕ: Логика работает для стандартной карты (4242424242424242), когда пробной версии не существует, работают даже 3D-карты.
- Эта карта используется для этого теста: 4000002500003155
Всем привет, так что название в значительной степени говорит обо всем, у меня проблема с картами 3d secure, когда пробная версия заканчивается.
Шаги для воспроизведения: Узел(СЕРВЕР):
- создать клиента
const customer = await this.getInstance().customers.create({ email: userData.email, name: userData.fullname, });
- создать подписку
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, });
- возврат данных на сторону КЛИЕНТА
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, };
Со стороны КЛИНИКИ:
- Получение ответа:
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;
- В зависимости от типа намерения:
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 }, }); }
- Подтверждение запускает режим 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. Большое вам спасибо, я протестировал оба сценария, и все в точности так, как вы объяснили!