Rails集成PayPal:如何引导用户跳转至PayPal页面完成支付
在Rails中实现PayPal跳转式支付(支持PayPal账户/直接信用卡支付)
嘿,我完全懂你的需求——你想要用户直接跳转到PayPal官方页面完成所有支付操作(不管是用PayPal账户登录,还是直接输入信用卡信息,不需要注册PayPal账户也能付),支付完成后再自动跳回你的Rails站点。你提到的那个教程用的是旧的流程,才会让用户跳回你的站点输卡信息,咱们用PayPal现在主推的Smart Payment Buttons就能完美解决这个问题,下面是具体的实现步骤:
1. 配置PayPal开发者账户
- 先去PayPal开发者平台创建应用,获取
CLIENT_ID和CLIENT_SECRET(先在沙箱环境测试,上线前再切换到生产环境) - 在Rails项目的
config/application.yml(用Figaro管理配置的话)或者config/secrets.yml里配置这两个参数:paypal_client_id: "你的沙箱/生产环境CLIENT_ID" paypal_client_secret: "你的沙箱/生产环境CLIENT_SECRET"
2. 集成前端支付按钮
在你需要显示支付按钮的视图(比如app/views/orders/show.html.erb)里添加PayPal的脚本和按钮代码:
<script src="https://www.paypal.com/sdk/js?client-id=<%= Rails.application.credentials.paypal_client_id %>¤cy=USD"></script> <div id="paypal-button-container"></div> <script> paypal.Buttons({ createOrder: function(data, actions) { // 调用Rails后端接口创建PayPal订单,获取订单ID return fetch('/orders/<%= @order.id %>/create_paypal_order', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': '<%= form_authenticity_token %>' } }).then(function(response) { return response.json(); }).then(function(orderData) { return orderData.id; }); }, onApprove: function(data, actions) { // 支付成功后,调用后端接口确认支付状态 return fetch('/orders/<%= @order.id %>/capture_paypal_order', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': '<%= form_authenticity_token %>' }, body: JSON.stringify({ order_id: data.orderID }) }).then(function(response) { return response.json(); }).then(function(details) { // 跳转到你的站点支付成功页面 window.location.href = '/orders/<%= @order.id %>/success'; }); }, onError: function(err) { // 处理支付错误,给用户提示 console.error('PayPal支付出错:', err); alert('支付过程中出现错误,请稍后重试'); } }).render('#paypal-button-container'); </script>
3. 编写后端API接口
在config/routes.rb里添加对应路由:
resources :orders do post :create_paypal_order, on: :member post :capture_paypal_order, on: :member get :success, on: :member end
然后在app/controllers/orders_controller.rb里实现对应的方法:
require 'paypal-sdk-rest' PayPal::SDK::REST.set_config( mode: Rails.env.production? ? 'live' : 'sandbox', client_id: Rails.application.credentials.paypal_client_id, client_secret: Rails.application.credentials.paypal_client_secret ) class OrdersController < ApplicationController # 创建PayPal订单 def create_paypal_order @order = Order.find(params[:id]) paypal_order = PayPal::SDK::REST::Order.new({ intent: 'CAPTURE', purchase_units: [{ amount: { currency_code: 'USD', value: @order.total_amount.to_s # 注意要转成字符串格式 } }] }) if paypal_order.create render json: { id: paypal_order.id } else render json: { error: paypal_order.error }, status: :unprocessable_entity end end # 捕获PayPal订单(确认支付完成) def capture_paypal_order @order = Order.find(params[:id]) paypal_order = PayPal::SDK::REST::Order.find(params[:order_id]) capture = paypal_order.capture({}) if capture.status == 'COMPLETED' # 更新你的本地订单状态为已支付,记录PayPal交易ID @order.update(status: 'paid', paypal_transaction_id: capture.id) render json: { success: true } else render json: { error: capture.error }, status: :unprocessable_entity end end # 支付成功页面 def success @order = Order.find(params[:id]) end end
4. 关键注意点
- 这个流程里,用户点击PayPal按钮后会直接跳转到PayPal官方页面,在这里用户可以自由选择用PayPal账户登录支付或者直接输入信用卡信息支付(完全不需要注册PayPal账户),全程在PayPal侧完成,完美符合你的需求。
- 支付完成后,PayPal会自动触发前端的
onApprove方法,我们再调用后端接口确认支付状态,最后跳回你的站点成功页面。 - 记得先在沙箱环境用PayPal提供的测试买家/卖家账户验证整个流程,没问题后再切换到生产环境的API密钥。
内容的提问来源于stack exchange,提问作者ckeat9




