You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Ruby on Rails中实现Stripe支付成功后向用户发送邮件

看起来你已经搞定了Stripe Webhook的基础处理逻辑,现在要给完成结账的用户自动发邮件对吧?我来一步步帮你实现这个功能:

在Stripe结账完成后发送用户邮件的实现方案

1. 从Stripe Session提取用户与订单信息

首先在你已有的checkout.session.completed分支里,我们可以从Stripe返回的Session对象中拿到用户邮箱,同时整理好订单商品信息,作为邮件内容的基础:

when 'checkout.session.completed'
  session = event.data.object
  # 获取用户邮箱(优先取Session里的直接邮箱,关联了Customer的话也可以从Customer对象取)
  customer_email = session.customer_email || session.customer&.email
  # 拉取并整理订单商品详情
  session_with_expand = Stripe::Checkout::Session.retrieve({id: session.id, expand: ["line_items"] })
  order_items = session_with_expand.line_items.data.map do |line_item|
    product = Product.find_by(stripe_product_id: line_item.price.product)
    product.increment!(:sales_count)
    # 格式化商品信息,方便在邮件里展示
    "#{product.name} x #{line_item.quantity} - $#{line_item.price.unit_amount.to_f / 100}"
  end.join("\n")

  # 提取订单总额(Stripe返回的单位是分,转成美元)
  total_amount = session.amount_total.to_f / 100

2. 创建Action Mailer邮件模板

Rails里用Action Mailer来处理邮件发送最方便,先生成一个邮件控制器:

rails generate mailer OrderMailer thank_you

然后在app/mailers/order_mailer.rb里编写发送逻辑:

class OrderMailer < ApplicationMailer
  # 设置默认发件人
  default from: '你的商城名称 <your-support-email@example.com>'

  def thank_you(customer_email, order_items, total_amount)
    # 把变量传递给视图模板
    @order_items = order_items
    @total_amount = total_amount

    # 发送邮件
    mail(to: customer_email, subject: '感谢你的订单!')
  end
end

接下来编辑邮件的视图文件,分别准备HTML和纯文本格式(确保不同邮箱客户端都能正常显示):

  • HTML格式(app/views/order_mailer/thank_you.html.erb):
<h1>嗨~感谢你的订单!</h1>
<p>你的订单详情如下:</p>
<ul>
  <% @order_items.split("\n").each do |item| %>
    <li><%= item %></li>
  <% end %>
</ul>
<p>订单总额:$<%= @total_amount %></p>
<p>如果有任何问题,随时联系我们哦!</p>
  • 纯文本格式(app/views/order_mailer/thank_you.text.erb):
嗨~感谢你的订单!

你的订单详情如下:
<%= @order_items %>

订单总额:$<%= @total_amount %>

如果有任何问题,随时联系我们哦!

3. 在Webhook中触发邮件发送

回到你的WebhooksController,在整理好所有信息后调用邮件发送方法。重点:一定要用deliver_later异步发送,避免因为邮件服务延迟导致Stripe Webhook超时重试:

when 'checkout.session.completed'
  session = event.data.object
  customer_email = session.customer_email || session.customer&.email
  session_with_expand = Stripe::Checkout::Session.retrieve({id: session.id, expand: ["line_items"] })
  
  order_items = session_with_expand.line_items.data.map do |line_item|
    product = Product.find_by(stripe_product_id: line_item.price.product)
    product.increment!(:sales_count)
    "#{product.name} x #{line_item.quantity} - $#{line_item.price.unit_amount.to_f / 100}"
  end.join("\n")
  
  total_amount = session.amount_total.to_f / 100

  # 确保有邮箱才发送,同时捕获异常避免影响Webhook响应
  if customer_email.present?
    begin
      OrderMailer.thank_you(customer_email, order_items, total_amount).deliver_later
    rescue => e
      Rails.logger.error "订单邮件发送失败: #{e.message}"
    end
  end

4. 额外注意事项

  • 测试验证:开发环境可以用letter_opener gem直接在浏览器查看发送的邮件;也可以用Stripe测试模式模拟结账完成事件,验证Webhook和邮件流程是否正常。
  • 个性化优化:如果你的系统有本地用户模型,可以通过邮箱关联到用户,在邮件里添加更多个性化内容(比如用户名、历史订单入口等)。
  • 重试机制:如果邮件发送失败,Rails的异步任务队列(比如Sidekiq)会自动重试,确保用户能收到邮件。

内容的提问来源于stack exchange,提问作者StrikerGs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 00:32:36