Архитектура оформления заказа в интернет-магазине Rest API

stripe-payments #checkout #rest #webshop

#stripe-платежи #Оформить покупку #rest #интернет-магазин

Вопрос:

Я создаю страницу оформления заказа в интернет-магазине, и я застрял с одной проблемой — как я могу быть уверен, что пользователь действительно заплатил?

Стек: Quarkus Angular

Я интегрировал способ оплаты Stripe на своей странице оформления заказа. Каждый раз, когда открывается страница оформления заказа, я получаю намерение Stripe от серверной части. Затем, после того, как пользователь ввел информацию о карте и нажал «Оплатить», я получаю во внешнем интерфейсе ответ от stripe: «ок, пользователь заплатил!», Затем я вызываю ОБЩЕДОСТУПНУЮ конечную точку на моем сервере (из внешнего интерфейса) и говорю: «ок, пользователь заплатил, подтвердитепорядок.

Как я могу быть уверен, что клиент действительно заплатил? Он мог бы просто позвонить на мою конечную точку ОБЩЕДОСТУПНОГО сервера и подтвердить заказ, и я бы не знал, что оплата stripe на самом деле никогда не происходила.

Я предполагаю, что, может быть, я могу позвонить на сервер stripe и спросить: «Эй, был ли на самом деле платеж, выполненный с этим намерением stripe»?

Какова наилучшая практика здесь, как я должен реализовать часть подтверждения заказа?

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

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

Ответ №1:

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

Вы можете обратиться к https://stripe.com/docs/payments/accept-a-payment?platform=webamp;ui=elements#web-post-payment к каким событиям прислушиваться.

Вы также можете более подробно ознакомиться с webhooks здесь: https://stripe.com/docs/webhooks

Ответ №2:

Когда вы используете Stripe API, вы можете запустить сеанс оформления заказа. Когда вы запустите его, он вернет объект для этого сеанса. В этом объекте вы можете получить доступ к идентификатору оформления заказа

Сначала вы запускаете сеанс оформления заказа следующим образом

 curl https://api.stripe.com/v1/checkout/sessions 
  -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: 
  -d success_url="https://example.com/success" 
  -d cancel_url="https://example.com/cancel" 
  -d "payment_method_types[0]"=card 
  -d "line_items[0][price]"=price_H5ggYwtDq4fbrJ 
  -d "line_items[0][quantity]"=2 
  -d mode=payment
 

После этого вы получите результат, аналогичный

 {
  "id": "cs_test_EHNhgisbBCZj4HfTaFiSyoLPLYr1qNPmHeVmZw0BRNDVRYWeAppSFrMt",
  "object": "checkout.session",
  "after_expiration": null,
  "allow_promotion_codes": null,
  "amount_subtotal": null,
  "amount_total": null,
  "automatic_tax": {
    "enabled": false,
    "status": null
  },
  "billing_address_collection": null,
  "cancel_url": "https://example.com/cancel",
  "client_reference_id": null,
  "consent": null,
  "consent_collection": null,
  "currency": null,
  "customer": null,
  "customer_details": null,
  "customer_email": null,
  "expires_at": 1634799676,
  "livemode": false,
  "locale": null,
  "metadata": {},
  "mode": "payment",
  "payment_intent": "pi_1Dpavq2eZvKYlo2Co0uGctWr",
  "payment_method_options": {},
  "payment_method_types": [
    "card"
  ],
  "payment_status": "unpaid",
  "phone_number_collection": {
    "enabled": false
  },
  "recovered_from": null,
  "setup_intent": null,
  "shipping": null,
  "shipping_address_collection": null,
  "submit_type": null,
  "subscription": null,
  "success_url": "https://example.com/success",
  "total_details": null,
  "url": "https://checkout.stripe.com/pay/..."
}
 

Два наиболее важных атрибута в этом объекте

  • ID
  • url

Идентификатор является уникальным идентификатором сеанса, и вы должны перенаправить пользователя на URL для оплаты.

После оплаты вы можете просмотреть сеанс оформления заказа и проверить статус

 curl https://api.stripe.com/v1/checkout/sessions/cs_test_EHNhgisbBCZj4HfTaFiSyoLPLYr1qNPmHeVmZw0BRNDVRYWeAppSFrMt 
  -u sk_test_4eC39HqLyjWDarjtT1zdp7dc:
 

В результате этого примера ответа

 {
  "id": "cs_test_EHNhgisbBCZj4HfTaFiSyoLPLYr1qNPmHeVmZw0BRNDVRYWeAppSFrMt",
  "object": "checkout.session",
  "after_expiration": null,
  "allow_promotion_codes": null,
  "amount_subtotal": null,
  "amount_total": null,
  "automatic_tax": {
    "enabled": false,
    "status": null
  },
  "billing_address_collection": null,
  "cancel_url": "https://example.com/cancel",
  "client_reference_id": null,
  "consent": null,
  "consent_collection": null,
  "currency": null,
  "customer": null,
  "customer_details": null,
  "customer_email": null,
  "expires_at": 1634799676,
  "livemode": false,
  "locale": null,
  "metadata": {},
  "mode": "payment",
  "payment_intent": "pi_1Dpavq2eZvKYlo2Co0uGctWr",
  "payment_method_options": {},
  "payment_method_types": [
    "card"
  ],
  "payment_status": "unpaid",
  "phone_number_collection": {
    "enabled": false
  },
  "recovered_from": null,
  "setup_intent": null,
  "shipping": null,
  "shipping_address_collection": null,
  "submit_type": null,
  "subscription": null,
  "success_url": "https://example.com/success",
  "total_details": null,
  "url": null
}
 

Как вы можете видеть, у вас есть атрибут payment_status — с его помощью вы можете проверить, действительно ли пользователь заплатил.

В качестве альтернативы вы также можете использовать webhooks, но я предпочитаю мой пример

Удачи!