如何为Rails Pay Gem中的已有用户分配Stripe客户ID
为老用户批量创建Stripe Customer ID(基于Rails Pay Gem)
问题背景
使用Rails Pay Gem时,新用户注册通过User模型的以下配置自动分配Stripe Customer ID:
pay_customer default_payment_processor: :stripe
但现有老用户缺少有效的Stripe客户ID,导致支付时报错。尝试遍历用户分配支付处理器的代码仅关联了本地Pay::Customer记录,并未在Stripe端创建真实客户:
User.find_each do |user| unless user.payment_processor.present? user.set_payment_processor :stripe user.save puts "Created Stripe Customer ID for user: #{user.email}" end end
日志显示,本地Pay::Customer记录虽有processor_id(如cus_XXXXXXXXXXXXXX),但Stripe端不存在该客户,调用u.payment_processor.customer时触发错误:
3.0.0 :011 > u.set_payment_processor :stripe TRANSACTION (0.2ms) BEGIN Pay::Customer Update All (0.7ms) UPDATE "pay_customers" SET "default" = $1 WHERE "pay_customers"."owner_id" = $2 AND "pay_customers"."owner_type" = $3 [["default", false], ["owner_id", 388], ["owner_type", "User"]] Pay::Customer Load (0.4ms) SELECT "pay_customers".* FROM "pay_customers" WHERE "pay_customers"."owner_id" = $1 AND "pay_customers"."owner_type" = $2 AND "pay_customers"."deleted_at" IS NULL AND "pay_customers"."processor" = $3 ORDER BY "pay_customers"."id" ASC LIMIT $4 [["owner_id", 388], ["owner_type", "User"], ["processor", "stripe"], ["LIMIT", 1]] Pay::Customer Exists? (0.2ms) SELECT 1 AS one FROM "pay_customers" WHERE "pay_customers"."processor_id" = $1 AND "pay_customers"."id" != $2 AND "pay_customers"."processor" = $3 LIMIT $4 [["processor_id", "cus_XXXXXXXXXXXXXX"], ["id", 1], ["processor", "stripe"], ["LIMIT", 1]] Pay::Customer Update (0.2ms) UPDATE "pay_customers" SET "default" = $1, "updated_at" = $2 WHERE "pay_customers"."id" = $3 [["default", true], ["updated_at", "2023-08-31 20:18:04.191958"], ["id", 1]] TRANSACTION (0.6ms) COMMIT Pay::Customer Load (0.4ms) SELECT "pay_customers".* FROM "pay_customers" WHERE "pay_customers"."owner_id" = $1 AND "pay_customers"."owner_type" = $2 AND "pay_customers"."default" = $3 AND "pay_customers"."deleted_at" IS NULL LIMIT $4 [["owner_id", 388], ["owner_type", "User"], ["default", true], ["LIMIT", 1]] => #<Pay::Customer:XXXXXXXXXXXXX id: 1, owner_type: "User", owner_id: 388, processor: "stripe", processor_id: "cus_XXXXXXXXXXXXXX", default: true, data: {}, deleted_at: nil, created_at: Mon, 24 Jul 2023 11:19:25.540934000 UTC +00:00, updated_at: Thu, 31 Aug 2023 20:18:04.191958000 UTC +00:00, payment_method_token: nil> 3.0.0 :012 > u.payment_processor.customer /Users/XXXXXX/.rvm/gems/ruby-3.0.0/gems/pay-6.6.1/lib/pay/stripe/billable.rb:66:in `rescue in customer': No such customer: 'cus_XXXXXXXXXXXX' (Pay::Stripe::Error) /Users/XXXXXXXX/.rvm/gems/ruby-3.0.0/gems/stripe-8.5.0/lib/stripe/stripe_client.rb:722:in `handle_error_response': No such customer: 'cus_XXXXXXXXXXXXX' (Stripe::InvalidRequestError) 3.0.0 :013 >
解决方法
方案1:批量创建有效Stripe客户
使用create_payment_processor方法替代set_payment_processor,该方法会同时调用Stripe API创建真实客户,并同步本地记录:
User.find_each do |user| # 检查是否已有有效Stripe客户 unless user.payment_processor&.customer_exists? # 创建Stripe客户并关联到用户 user.create_payment_processor :stripe, email: user.email puts "Created valid Stripe Customer for user: #{user.email}" end end
方案2:修复已存在的无效记录
如果本地已有无效的Pay::Customer记录(如错误生成的cus_ID),先删除无效记录再重新创建:
User.find_each do |user| stripe_customer = user.pay_customers.find_by(processor: "stripe") if stripe_customer # 验证Stripe端是否存在该客户 unless stripe_customer.customer_exists? stripe_customer.destroy user.create_payment_processor :stripe, email: user.email puts "Fixed invalid Stripe Customer for user: #{user.email}" end else # 无记录则直接创建 user.create_payment_processor :stripe, email: user.email puts "Created Stripe Customer for user: #{user.email}" end end
关键说明
create_payment_processor:负责调用Stripe API创建客户,将返回的customer.id保存到本地processor_id,确保本地与Stripe端数据一致。customer_exists?:Pay Gem提供的方法,用于检查Stripe端是否存在对应客户,避免重复操作或处理无效记录。- 执行建议:通过Rails控制台或编写Rake任务执行批量操作,避免在Web请求中处理导致超时。
内容的提问来源于stack exchange,提问作者user3074558
相关产品推荐
相关产品推荐

