问题
I'm building a Rails application using Stripe Checkout Beta. For this, I'm creating a Stripe::Checkout::Session
on the server, use redirectToCheckout
on the frontend and then wait for the webhook coming in with the type checkout_beta.session_succeeded
telling me that the payment was fulfilled. This works fine, but:
For every payment, Stripe creates a new customer - which is not what I want. If an existing customer pays a second time, Stripe should not create a new customer, the new payment should be linked to the existing customer.
How can I set the customer id before I redirect to Checkout?
Here is my Ruby controller code:
# 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
The HTML code (using 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 }
The JavaScript code (using 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)
})
}
}
The Ruby webhook code (using the gem 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:
The API of Stripe::Checkout::Session.create
allows to add a customer
key which references to a Stripe customer id. This way the payment is added to your existing customer.
You may specify an existing Customer object for Checkout to use when making one-time payments or subscriptions. If you do so, any Stripe objects that Checkout creates are associated with that Customer.
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', )
See: https://stripe.com/docs/payments/checkout/server#using-existing-customers
来源:https://stackoverflow.com/questions/55165793/stripe-checkout-beta-avoid-creating-new-customer-for-every-payment