Интеграция API платежных намерений Stripe и завершение платежного процесса

Stripe Checkout предоставляет простой способ принимать платежи от пользователей. Он предоставляет предварительно созданную страницу оформления заказа и возможность добавить логотип или изменить тему на цвет вашего бренда. Но Checkout не дает полного контроля.

Например, вы не можете подтвердить платеж на своем сервере приложений; вместо этого подтверждение выполняется на самом интерфейсе. Вы не можете создать индивидуальный поток платежей только из Stripe Checkout. Вам нужно будет использовать API платежных намерений. В этом руководстве вы узнаете, как интегрировать API платежных намерений в интерфейс React.js и серверную часть Node.js.

Прежде всего, возьмите свои ключи API с панели управления Stripe. Создайте учетную запись на Stripe и посетите их панель управления (в тестовом режиме), чтобы получить «публичный ключ» и «секретный ключ». Вы можете использовать тестовые ключи без активации/подтверждения своего бизнес-аккаунта.

Платежный поток

Весь процесс оплаты состоит из двух частей: предоплата и оплата. Прежде чем позволить пользователю инициировать платеж, мы собираемся собрать его данные и предпочтительные способы оплаты. Затем предложите им выбрать способ завершения платежа.

Давайте разберем это дальше:

Предоплата

  1. Пользователь регистрируется в вашем веб-приложении. Пользователь одновременно также регистрируется на Stripe как «клиент».
  2. Пользователя спрашивают о предпочтительных способах оплаты. Детали хранятся на Stripe (прикрепляются к клиенту).
  3. Перед оплатой пользователю показывается список его сохраненных способов оплаты (из Stripe). Они выбирают один, чтобы продолжить.

Оплата

Отсюда существует обратная связь между интерфейсом (приложение React) и сервером (приложение Node). Вот примерно как это происходит:

  1. React инициирует процесс, отправив запрос POST на ваш сервер, содержащий id выбранного способа оплаты (и дополнительную информацию).
  2. Node использует API платежных намерений Stripe для создания платежного намерения путем предоставления amount, currency, способа оплаты id, клиента id, description и других сведений.
  3. После того, как намерение создано, вы можете сохранить детали в своей собственной базе данных, если это необходимо. Вся информация о транзакциях хранится в Stripe, и к ней можно получить доступ через их API, но если у вас есть конкретные варианты использования, вы можете хранить детали намерений в своей собственной базе данных. Объект намерения, созданный Stripe, отправляется обратно в качестве ответа.
  4. Используя секрет клиента платежного намерения (не путать с секретом клиента Stripe API), полученный из бэкенда, react сгенерирует форму проверки платежа. Пользователь вводит CVV/CVC для подтверждения платежа.
  5. React отправляет POST-запрос подтверждения намерения с соответствующими деталями для подтверждения платежа.
  6. Node использует API платежных намерений Stripe для подтверждения намерения и отправляет объект подтверждения в ответ. Этот объект подтверждения содержит поле next_action, которое сообщает внешнему интерфейсу, завершен ли поток или есть ожидающие действия.
  7. React использует поле next_action в ответе, чтобы решить, завершить процесс или продолжить. В последнем случае Stripe предоставляет метод handleCardAction() для выполнения любых необходимых действий (например, поток 3DS).
  8. Как только действие выполнено, API подтверждения намерения вызывается снова, и тот же процесс следует до тех пор, пока не останется next_action. (Шаги 6, 7, 8 в цикле)
  9. Если на каком-либо из вышеперечисленных шагов возникает ошибка, можно выполнить соответствующую обработку ошибок, чтобы сообщить пользователю, что пошло не так. Если нет, транзакция выполнена успешно, и пользователю может быть показан пользовательский интерфейс успеха.

Настроить

Я буду держать учебник в основном сосредоточенным на интеграции платежей и опуская что-либо еще, например, запросы на добавление пользователей, получение цены или обновление статуса платежа. Я предполагаю, что вы уже настроили приложение React и Node.

Приложение Node

Установите Stripe из npm (кроме других необходимых зависимостей, таких как экспресс или bcrypt). Вы можете пройти это руководство о том, как настроить систему аутентификации на NodeJS. Кроме того, получите ключи API (доступный для публикации и секретный ключ) и сохраните их, желательно, в файле .env или в файле конфигурации.

npm install stripe

Приложение React

Это единственные пакеты, связанные с Stripe, которые вам нужны. Я также установил множество других пакетов для создания пользовательского интерфейса (страна-штат-город, реакция-оплата-вводы), форматирования даты и времени (дата-fns) и выполнения запросов (аксиос). Не стесняйтесь использовать все, что плавает в вашей лодке.

npm install @stripe/react-stripe-js @stripe/stripe-js

Предварительная оплата

Резюме:

  1. Создайте пользователя и клиента Stripe.
  2. Разрешить пользователю добавлять способ оплаты.
  3. Регистрация пользователя

Внешний интерфейс

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

Я создал простую форму регистрации. Вы можете найти полный код в репозитории GitHub, ссылка на который находится в конце статьи. Далее мы создадим API для связи этой формы.

Бэкенд

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

const stripe = require(“stripe”)(require(“./config.json”).stripeSecretKey);

Затем в API регистрации пользователей используйте stripe.customers.create({ }) для создания клиента Stripe (в то же время создайте запись пользователя в своей собственной базе данных). Возвращенный объект содержит клиента id, который вы должны сохранить в своей базе данных для пользователя. Список всех параметров для создания пользователя вы можете найти в справочнике по API здесь.

Если вы перейдете на панель инструментов Stripe, вы увидите только что добавленные данные пользователя. На следующем шаге мы даем пользователю возможность добавить способ оплаты.

2. Добавить способ оплаты

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

Примечание. мы не будем хранить информацию о способах оплаты в нашей собственной базе данных. Все хранится в Stripe и извлекается через API Stripe. Для получения дополнительной информации о способах оплаты вы можете ознакомиться с этим руководством.

Внешний интерфейс

Я использовала ) и country-state-city для создания пользовательского интерфейса. Вы можете создать его по своему усмотрению, нам просто нужна форма, в которой пользователь может добавить детали, связанные со своим способом оплаты.

Изменить. Оглядываясь назад, отправка данных карты на серверную часть и последующее создание способа оплаты, вероятно, не лучший способ сделать это. Лучшая альтернатива — сначала создать способ оплаты на внешнем интерфейсе, получить способ оплаты id, отправить этот id на серверную часть и привязать этот метод к вашему клиенту Stripe в серверной части.

Чтобы получить данные карты во внешнем интерфейсе, вы должны использовать CardElement, предоставленный Stripe. Вы можете найти обновленный код в репозитории GitHub.

Я отредактировал AddPayMethod.js и API прикрепления способа оплаты, чтобы отразить это изменение, и прокомментировал предыдущий код для обеспечения прозрачности.

Бэкенд

Получите данные из внешнего интерфейса и вызовите attachMethod() API Stripe, который привяжет этот способ оплаты к предоставленному клиенту id. Здесь я жестко закодировал клиента Id (пользователя, которого мы создали выше). Вам нужно будет получить идентификатор клиента вашего пользователя в соответствии с вашей настройкой. В случае успеха вы можете просмотреть способ оплаты, прикрепленный к пользователю, на панели инструментов Stripe.

Оплата

Теперь, когда клиент и способы оплаты готовы. Пришло время произвести оплату. Но сначала несколько слов о платежных намерениях.

Назначение платежа

Для создания пользовательских асинхронных потоков платежей Stripe предоставляет набор API для создания и подтверждения платежных намерений. Эти API помогают обрабатывать динамические платежи (например, аутентификацию 3D Secure) и отслеживать статус платежа.

Из документации Stripe:

«Построение интеграции с API платежных намерений включает в себя два действия: создание и подтверждение платежного намерения. Каждый PaymentIntent обычно соотносится с одной корзиной покупок или сеансом клиента в вашем приложении. PaymentIntent инкапсулирует сведения о транзакции, такие как поддерживаемые способы оплаты, сумма для сбора и желаемая валюта».

Намерение создается в тот момент, когда пользователь нажимает кнопку оплаты. Он содержит всю необходимую информацию о транзакции, такую ​​как способ оплаты, сумма платежа, валюта, клиент Stripe id и описание. Stripe использует объект намерения для отображения пользовательского интерфейса для сбора информации о карте, обработки любых дополнительных действий и, наконец, подтверждения. Для получения подробной информации о намерениях и их различных этапах вы можете ознакомиться с этими документами Stripe: платежные намерения и намерения.

Продолжаем процесс. Теперь мы позволим пользователю начать процесс оплаты.

Резюме:

  1. Получить и перечислить ранее сохраненные способы оплаты для текущего пользователя.
  2. Предложите пользователю выбрать способ оплаты (или добавить его). Когда пользователь выбирает метод, вызовите API создания намерения (/payment/create), чтобы создать и вернуть объект платежного намерения.
  3. Используя объект намерения, создайте форму проверки платежа, чтобы пользователь мог ввести CVV/CVC для подтверждения платежа.
  4. Список способов оплаты

Внешний интерфейс

Бэкенд

listPaymentMethods() API Stripe извлекает все способы оплаты, привязанные к данному идентификатору клиента. Опять же, для простоты я жестко закодировал клиента id. Вам придется найти клиента id пользователя по-своему.

Обратите внимание, что каждый способ оплаты имеет уникальный id, который используется для идентификации метода при последующих обменах.

2. Пользователь выбирает способ оплаты

Внешний интерфейс

Когда пользователь выбирает метод, на NodeJs отправляется запрос POST со способом оплаты id и дополнительной информацией, такой как продукт id, которую вы можете использовать для получения суммы платежа из своей базы данных. Объект платежного намерения создается и возвращается API, который содержит всю информацию о платеже, включая сумму. Вам необходимо сохранить это платежное намерение. React будет использовать данные paymentIntent и paymentMethod для дальнейшей обработки платежа.

Бэкенд

Опять же, как вы получите клиента Stripe id, зависит от вас. Кроме того, получите сумму, за которую пользователь хочет заплатить. Затем мы используем paymentIntents.create({}) API для создания платежного намерения. Для ключа подтверждения_метода установлено значение вручную, что обеспечивает дополнительную защиту от мошенничества, предоставляя дополнительный шаг проверки при оплате. Подробнее об этом можно прочитать здесь.

При необходимости вы можете добавить запись об этой платежной сессии в свою базу данных. Объект платежного намерения отправляется в качестве ответа. Этот объект содержит все детали транзакции.

3. Создайте форму оформления заказа

Далее вы создадите форму оформления заказа и запросите CVV/CVC выбранной карты, а затем подтвердите платеж. Вам не нужно, чтобы пользователь вводил другие данные карты, поскольку они уже сохранены и доступны из поля payment_method объекта намерения.

Внешний интерфейс

Я постарался сделать код максимально кратким и убрать большую часть JSX. Вы можете найти полный код в репозитории GitHub (PaymentForm.js). Используя ранее полученные объекты paymentMethod и paymentIntent, вы можете визуализировать большую часть карты. Используйте утилиты, предоставленные @stripe/react-stripe-js и @stripe/stripe-js, для создания остальной части пользовательского интерфейса и функциональности.

Stripe использует CardCvcElement для сбора CVC/CVV пользователя, а затем проверяет его с помощью метода stripe.createToken(). В случае успеха вызовите API подтверждения намерения (/payment/confirm) с полями paymentIntent и paymentMethod.

Когда API вернет успешное завершение, передайте возвращенный JSON функцииhandleServerResponse(). Эта функция проверяет, нужно ли выполнить дальнейшие действия (next_action field), а затем вызывает другую функцию handleAction()с тем же JSON.

Затем функция handleAction выполняет любое требуемое действие (например, открывает поток 3D-безопасности) и после завершения указанного действия снова вызывает API POST/payment/confirm. Этот процесс выполняется в цикле до тех пор, пока не останется next_action для обработки.

Бэкэнд

Просто используйте идентификатор платежного намерения и идентификатор платежного метода, чтобы подтвердить намерение с помощью stripe.paymentIntents.confirm(). После успешного подтверждения обновите статус платежа в собственной базе для закрытия. В ответ отправьте обратно объект ответа подтверждения, который содержит поле next_action, которое React использует, чтобы решить, следует ли завершить транзакцию или обработать действие.

Заключение

Ну вот. Теперь вы успешно интегрировали API платежных намерений Stripe и завершили платежный процесс, включая безопасность 3DS. Я пропустил здесь большую часть запросов и обращений к вашим собственным базам данных.

Например, я везде жестко запрограммировал customer_id. Фактический метод будет зависеть от того, как настроена ваша система. Вам решать, какие детали всего процесса вы хотите сохранить в своей базе данных.

Все сохраняется в Stripe и может быть получено с помощью их API. Я бы рекомендовал не хранить данные о способе оплаты (сохраненные карты) и использовать API-интерфейсы Stripe для их извлечения.

Вы можете найти весь код здесь:



Надеюсь, это было полезно. Удачи в разработке!