Начните подписку для сбора повторяющихся платежей с помощью Stripe

Подписки позволяют вам взимать плату с клиента на повторяющейся основе. Вспомните, что подписка связана с конкретным клиентом и одной или многими повторяющимися ценами, которые определяют интервал выставления счетов. Каждую Подписку можно представить как «двигатель», который генерирует счета-фактуры и собирает платежи на повторяющейся основе.

Существует несколько способов создания Подписок в Stripe. В статье Создание страницы ценообразования SaaS вы узнали, как создать страницу ценообразования. Для справки: если вы используете встраиваемую таблицу цен или ссылки на платежи, вам нужно только вставить эти ссылки, и можно приступать к работе. Однако если вы выберете Stripe Checkout или пользовательскую форму с использованием элемента Payment Element, вам придется написать немного кода.

Здесь мы сосредоточимся на использовании Stripe Checkout для запуска подписки с помощью Ruby on Rails. Пожалуйста, обратитесь к полной документации, чтобы узнать, как интегрироваться с помощью PaymentElement.

Если вы работаете вместе с этой серией, то в вашем приложении уже есть система аутентификации и страница ценообразования. Эта страница ценообразования передает на сервер идентификатор цены для объекта Stripe Price, и мы готовы создать сессию Checkout Session и перенаправить вашего клиента на страницу оформления заказа, размещенную на Stripe.

Интеграция включает в себя один вызов API к Stripe для создания сессии Checkout Session, которая содержит URL, по которому мы перенаправляем клиента. После того, как клиент введет свои платежные данные, мы перенаправим его обратно в наше приложение.

Интеграция

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

С одной стороны, мы можем явно создать клиента и сохранить его ID вместе с аутентифицированным пользователем и связать все будущие вызовы API с этим конкретным клиентом Stripe. С другой стороны, если мы захотим использовать встраиваемую таблицу цен или ссылки на платежи позднее, они создадут для нас клиентов Stripe, и нет никакого способа передать существующего клиента. Для таблицы цен, ссылок на платежи и Stripe Checkout мы можем передать ID нашего аутентифицированного пользователя через свойство client_reference_id, чтобы убедиться, что мы можем связать вновь созданного клиента Stripe с нужным пользователем в нашей базе данных.

Я знаю, что их много, но я рекомендую ознакомиться со всеми аргументами, которые вы можете отправить при вызове API для создания сессии Checkout Session. Ваша бизнес-модель будет диктовать, какие из них вас больше всего волнуют. Например, вы можете захотеть включить автоматический расчет налогов или поддержку кодов купонов.

Используя модель «хороший-лучший-лучший» с единой ценой, это самый простой вызов для создания сеанса SaaS Checkout Session:

session = Stripe::Checkout::Session.create(
  mode: 'subscription',
  line_items: [{
    price: params[:price_id], # The ID of the Price from the custom pricing page
    quantity: 1,
  }],
  success_url: 'http://localhost:3000/thanks',
  cancel_url: 'http://localhost:3000/pricing'
)
Войти в полноэкранный режим Выход из полноэкранного режима

URL успеха (куда перенаправляется клиент после подписки) и URL отмены (если клиент отказывается от покупки, нажав на стрелку назад для отмены) жестко закодированы, поэтому мы передаем только один элемент строки с фиксированным количеством. Обратите внимание, что если вы хотите включить модель ценообразования на одно место, свойство quantity — это то место, где вы можете указать количество мест.

Давайте рассмотрим другой, более реалистичный пример для нашей SaaS-компании:

  1. ассоциирует новую подписку с аутентифицированным пользователем client_reference_id: current_user.id.
  2. динамически создает URL-адреса успеха и отмены с помощью вспомогательных методов маршрутизации Rails
  3. Передает метаданные для сессии и подписки (чтобы упростить автоматизацию в дальнейшем). Таким образом, все веб-крюки о сеансах оформления заказа и подписки будут включать идентификатор для поиска объекта User.
metadata: {
  user_id: current_user.id,
},
subscription_data: {
  metadata: {
    user_id: current_user.id,
  },
},
Вход в полноэкранный режим Выход из полноэкранного режима
  1. Включает промокоды allow_promotion_codes: true,
  2. Собирает налоги
automatic_tax: {
  enabled: true,
},
Войти в полноэкранный режим Выход из полноэкранного режима

Вот как может выглядеть вызов API (я знаю, что это много, но это свидетельствует о мощности и настраиваемости Checkout!)

session = Stripe::Checkout::Session.create(
  mode: 'subscription',
  line_items: [{
    price: params[:price_id],
    quantity: 1,
  }],
  client_reference_id: current_user.id,
  success_url: thanks_checkouts_url, # https://example.com/checkout/thanks
  cancel_url: pricing_url # https://example.com/pricing
  metadata: {
    user_id: current_user.id,
  },
  subscription_data: {
    metadata: {
      user_id: current_user.id,
    },
  },
  allow_promotion_codes: true,
  phone_number_collection: {
    enabled: true,
  },
  automatic_tax: {
    enabled: true,
  },
)
Войти в полноэкранный режим Выйти из полноэкранного режима

В нашем контроллере Checkouts мы обработаем POST-запрос с идентификатором цены, используем его для создания сессии Checkout Session и в конечном итоге перенаправим.

class CheckoutsController < ApplicationController
  # Since we only want to collect payment from authenticated users
  # we ensure they are logged in:
  before_action :authenticate_user!
  def create
    session = Stripe::Checkout::Session.create(
      mode: 'subscription',
      client_reference_id: current_user.id,      
      line_items: [{
        price: params[:price_id],
        quantity: 1,
      }],
      success_url: thanks_checkouts_url, # https://example.com/checkout/thanks
      cancel_url: pricing_url # https://example.com/pricing
      # ...
    )
    redirect_to session.url, allow_other_hosts: true, status: :see_other
  end
end
Вход в полноэкранный режим Выход из полноэкранного режима

Считайте, что каждая сессия оформления заказа эфемерна. Я не храню ничего о сеансе оформления заказа в базе данных, но если бы вы хотели вести учет попыток начать подписку, вы могли бы создать объект CheckoutSession и хранить идентификаторы этих объектов в базе данных.

Возможно, вы заметили свойство subscription у объекта Checkout Session в справке API и задались вопросом, нужно ли хранить этот идентификатор в базе данных при создании Checkout Session. Это свойство subscription будет нулевым до тех пор, пока клиент не пройдет через процесс оформления заказа, поскольку подписка не будет создана до тех пор, пока он не нажмет на кнопку «Подписаться».

Следующие шаги

Обеспечение: как мы узнаем, действительно ли пользователь подписан или нет? В следующей статье этого цикла вы увидите, как обрабатывать типы событий Checkout и Subscription webhook, что является единственным рекомендуемым путем для выполнения заказов и предоставления доступа пользователям.

Об авторе

CJ Avilla (@cjav_dev) — представитель разработчиков в Stripe, разработчик Ruby on Rails и YouTuber. Он любит изучать и преподавать новые языки программирования и веб-фреймворки. Когда он не за компьютером, он проводит время с семьей или катается на велосипеде 🚲.

Оцените статью
devanswers.ru
Добавить комментарий