Получить статус заряда Stripe из использованного исходного токена - Node + MongoDB - PullRequest
0 голосов
/ 21 сентября 2018

Допустим, мой пользователь отправляет токен кредитной карты на мой сервер для совершения покупки.Затем я сохраняю этот токен в корзине моего пользователя, и в последовательности я его заряжаю.

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

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

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

Каждый раз, когда мой сервер перезагружается,некоторые процессы запускаются для проверки целостности базы данных (кстати, я использую MongoDB), и один из этих процессов пытается взимать плату за все пользовательские корзины (с уже сгенерированными токенами карт), которые были оставлены в состоянии «ожидающий платеж»,Если жетон карты еще не был заряжен, все работает хорошо, но если он уже был заряжен, я просто не знаю, была ли заряд успешным или нет, поэтому я не могу обновить свою корзину до согласованного состояния.

Я могу получить токен карты, используя "stripe.tokens.retrieve (token) .then (..."), но я просто знаю, использовался он или нет. Я должен найти способ узнать, был ли онзаряжен, и если это удалось.

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

Кто-нибудь знает, как решить эту проблему, или какую-либо лучшую логику для обеспечения согласованности платежей в реализации платежей MongoDB?

1 Ответ

0 голосов
/ 24 сентября 2018

Как прокомментировал @karllekko, это ответ на мой вопрос:

"Вы можете создать и сохранить уникальный идентификатор в начале попытки извлечения корзины и использовать его в качестве ключа идемпотентности при созданииЗапрос на оплату: stripe.com/docs/api#idempotent_requests Затем, если у вас возникнет сбой, вы можете безопасно повторить запрос, и если вы используете тот же ключ, он не создаст дублирующийся платеж (вы просто получите исходный ответ) "

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

Это запрос, который позволяет избежать дублирования платежей и всегдадает один и тот же ответ, успешный или нет, для одного и того же токена карты, и дает возможностьукажите в корзине моего пользователя:

stripe.charges.create(
        {
          amount: amount,
          currency: 'usd',
          source: token
        },
        {
          idempotency_key: token
        }
      ).then(
        res => resolve(res),// Proceed to a success card/order state and allow products/services to be accessed by user. If an attempt of make duplicate payments using the same card-token happens, you'll receive the same success response and will be able to proceed to the same success card/order state.
        err => reject({e: err, m: 'PAYMENT_ERROR', i: 'STRIPE_CHARGE_ERROR'})// An error occurred with the original charge request, so you'll have to rollback to the pre-checkout cart state. Even if you couldn't get the original error response, using an idempotency key will give you the exactly same error response in this step when you retry the charge attempt for this same card-token, so you know you have to rollback.
      )

Спасибо, @karllekko!

...