如何在Phoenix应用中将Stripe.createToken返回的token传入控制器?
如何在Phoenix应用中接收Stripe.createToken返回的支付令牌
没问题!我来一步步帮你把Stripe生成的支付令牌传给Phoenix控制器,流程很清晰,分这几步来:
第一步:前端处理令牌并发送到服务器
你已经通过stripe.createToken(card)拿到了令牌,接下来要把它传给Phoenix。这里有两种常用方式:
方式1:通过表单隐藏字段提交(页面刷新)
在拿到result.token后,动态创建一个隐藏字段存储令牌,再提交原表单:
// Handle form submission var form = document.getElementById('payment-form'); form.addEventListener('submit', function(event) { event.preventDefault(); stripe.createToken(card).then(function(result) { console.log('card-result', result); if (result.error) { // Inform the user if there was an error var errorElement = document.getElementById('card-errors'); errorElement.textContent = result.error.message; } else { // 动态创建隐藏字段存储令牌 const tokenInput = document.createElement('input'); tokenInput.type = 'hidden'; tokenInput.name = 'stripe_token'; tokenInput.value = result.token.id; // 把字段加入表单 form.appendChild(tokenInput); // 提交表单到Phoenix的/charge路由 form.submit(); } }); });
关键注意:Phoenix默认开启CSRF保护,所以你的表单里必须带上CSRF令牌。修改page.html的表单,添加Phoenix的CSRF标签:
<form action="/charge" method="post" id="payment-form"> <%= csrf_token_tag() %> <!-- 新增这一行 --> <div class="form-row"> <label for="card-element"> Credit or debit card </label> <div id="card-element"> <!-- a Stripe Element will be inserted here. --> </div> <!-- Used to display form errors --> <div id="card-errors" role="alert"></div> </div> <button class="btn btn-primary">Submit Payment</button> </form>
方式2:用AJAX发送(无页面刷新)
如果不想刷新页面,可以用fetch API直接发送JSON请求:
// Handle form submission var form = document.getElementById('payment-form'); form.addEventListener('submit', function(event) { event.preventDefault(); stripe.createToken(card).then(function(result) { console.log('card-result', result); if (result.error) { var errorElement = document.getElementById('card-errors'); errorElement.textContent = result.error.message; } else { // 用fetch发送POST请求 fetch('/charge', { method: 'POST', headers: { 'Content-Type': 'application/json', // 带上CSRF令牌,需要页面有对应的meta标签 'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content }, body: JSON.stringify({ stripe_token: result.token.id }) }) .then(response => response.json()) .then(data => { console.log('服务器响应:', data); // 这里可以添加支付成功后的逻辑,比如显示成功提示 }) .catch(err => console.error('请求出错:', err)); } }); });
对应配置:确保页面head里有CSRF的meta标签(Phoenix默认layout一般已包含,没有的话手动添加):
<head> <!-- 其他标签 --> <meta name="csrf-token" content="<%= get_csrf_token() %>"> </head>
第二步:Phoenix后端配置路由和控制器
1. 添加路由
打开lib/your_app_web/router.ex,添加POST请求路由,指向你的支付控制器:
# 替换成你实际的控制器名称,比如PaymentController post "/charge", PaymentController, :create
2. 创建/修改控制器
创建lib/your_app_web/controllers/payment_controller.ex(如果还没有),在create动作里接收令牌:
defmodule YourAppWeb.PaymentController do use YourAppWeb, :controller def create(conn, %{"stripe_token" => stripe_token}) do # 这里你已经拿到了Stripe令牌!接下来可以调用Stripe API创建支付订单 # 示例:使用stripe-elixir库创建Charge(需要先安装依赖) # case Stripe.Charge.create(%{ # amount: 1000, # 金额,单位是分(这里是10美元) # currency: "usd", # source: stripe_token, # description: "示例支付" # }) do # {:ok, charge} -> # # 支付成功,返回响应 # conn |> json(%{status: "success", charge_id: charge.id}) # {:error, error} -> # # 支付失败,返回错误信息 # conn |> put_status(400) |> json(%{status: "error", message: error.message}) # end # 先测试用:返回接收到的令牌 conn |> json(%{received_stripe_token: stripe_token}) end end
3. 安装Stripe Elixir依赖(可选但推荐)
如果要调用Stripe API处理支付,需要安装官方Elixir库。打开mix.exs,在deps里添加:
defp deps do [ # 其他依赖 {:stripe, "~> 0.16.0"} # 请使用最新版本号 ] end
运行mix deps.get安装依赖,再在config/config.exs里配置Stripe密钥:
config :stripe, api_key: "sk_test_你的Stripe测试密钥", webhook_secret: "whsec_你的Webhook密钥" # 如果用到Webhook的话
这样就完成了从前端获取Stripe令牌,到后端Phoenix控制器接收的整个流程啦!如果遇到CSRF相关的403错误,检查一下令牌有没有正确带上就行。
内容的提问来源于stack exchange,提问作者Arjun Singh
相关产品推荐
相关产品推荐

