#ruby-on-rails #stripe-payments
#ruby-on-rails #stripe-платежи
Вопрос:
Я создаю приложение Rails, используя бета-версию Stripe Checkout. Для этого я создаю Stripe::Checkout::Session
на сервере, использую redirectToCheckout
во внешнем интерфейсе, а затем жду, когда придет webhook с типом, checkout_beta.session_succeeded
сообщающим мне, что платеж был выполнен. Это работает нормально, но:
Для каждого платежа Stripe создает нового клиента, а это не то, чего я хочу. Если существующий клиент платит второй раз, Stripe не следует создавать нового клиента, новый платеж должен быть привязан к существующему клиенту.
Как я могу установить идентификатор клиента перед перенаправлением на оформление заказа?
Вот мой код Ruby controller:
# app/controllers/payments_controller.rb
def new
@session = Stripe::Checkout::Session.create(
success_url: "https://shop.example.test/success",
cancel_url: "https://shop.example.test/cancelled",
payment_method_types: ["card"],
line_items: cart_items.map do |cart_item|
{
name: cart_item.name,
quantity: 1,
amount: cart_item.name.price.cents,
currency: 'eur'
}
end,
customer_email: current_user.email
)
end
HTML код (с использованием Slim):
# app/views/payments/new.html.slim
= content_tag :div, nil, data: {
controller: 'stripe',
stripe_public_key: ENV['STRIPE_PUBLIC_KEY'],
stripe_session_id: @session.id }
Код JavaScript (использующий Stimulus.js ):
// app/javascripts/controllers/stripe_controller.js
import { Controller } from 'stimulus'
export default class extends Controller {
connect() {
this.stripe = window.Stripe(this.data.get('public-key'), {
betas: ['checkout_beta_4']
})
this.stripe.redirectToCheckout({
paymentIntentId: this.data.get('session-id')
}).then((result) => {
console.log(result)
})
}
}
Код Ruby webhook (с использованием драгоценного камня stripe_event):
# config/initializer/stripe.rb
Stripe.api_key = Rails.configuration.x.stripe.private_key
Stripe.api_version = '2019-02-19; checkout_sessions_beta=v4'
StripeEvent.signing_secret = Rails.configuration.x.stripe.webhook_secret
class RecordSessions
def call(event)
session = event.data.object
Payment.create!(
stripe_charge_token: session.payment_intent
)
end
end
StripeEvent.configure do |events|
events.subscribe 'checkout_beta.session_succeeded', RecordSessions.new
end
Комментарии:
1. Прямо сейчас это невозможно, по замыслу сеанс всегда создает нового клиента, но это, вероятно, изменится очень скоро, когда бета-версия продвинется вперед и Stripe добавит новые функции.
Ответ №1:
API Stripe::Checkout::Session.create
позволяет добавлять customer
ключ, который ссылается на идентификатор клиента Stripe. Таким образом, платеж добавляется к вашему существующему клиенту.
Вы можете указать существующий объект Customer для Checkout, который будет использоваться при совершении разовых платежей или подписок. Если вы это сделаете, все объекты Stripe, созданные Checkout, будут связаны с этим клиентом.
session = Stripe::Checkout::Session.create( customer: 'cus_123', payment_method_types: ['card'], line_items: [{ name: 'T-shirt', description: 'Comfortable cotton t-shirt', images: ['https://example.com/t-shirt.png'], amount: 500, currency: 'eur', quantity: 1, }], success_url: 'https://example.com/success', cancel_url: 'https://example.com/cancel', )
Смотрите: https://stripe.com/docs/payments/checkout/server#using-existing-customers