引言

当我们在电商项目中实现结账功能时,支付模块就像足球比赛中的临门一脚。本文将以React技术栈为基础,手把手教你如何集成Stripe、PayPal两大主流支付系统,并拓展到其他常见支付网关。我们将通过真实的代码案例,解密不同方案的实现逻辑与工程实践中的关键细节。


一、支付集成的技术选型

1.1 前端支付的三驾马车

在React生态中,主流的支付集成方案呈现明显分化:

  • Stripe:开发者友好的API设计,适合需要深度定制的场景
  • PayPal:国际通用性最佳的支付方式,覆盖188个国家
  • 支付宝/微信支付:中国市场的必备选项(本文将用Razorpay示例代替)
// 技术栈统一说明:
// 前端:React 18 + TypeScript
// 后端:Express.js + TypeScript
// 开发工具:Vite + pnpm

二、Stripe支付全流程实现

2.1 初始化Stripe环境

# 安装核心依赖
pnpm add @stripe/stripe-js @stripe/react-stripe-js

2.2 客户端集成

// components/StripeCheckout.tsx
import { Elements } from '@stripe/react-stripe-js';
import { loadStripe } from '@stripe/stripe-js';

const stripePromise = loadStripe('pk_test_YourPublishableKey');

const App = () => (
  <Elements stripe={stripePromise}>
    <CheckoutForm />
  </Elements>
);

2.3 支付表单实现

// components/CheckoutForm.tsx
const CheckoutForm = () => {
  const stripe = useStripe();
  const elements = useElements();

  const handleSubmit = async (event: FormEvent) => {
    event.preventDefault();
    
    if (!stripe || !elements) return;

    const { error } = await stripe.confirmPayment({
      elements,
      confirmParams: {
        return_url: 'https://your-domain.com/order-complete',
      },
      redirect: 'if_required'
    });

    if (error) {
      console.error('支付失败:', error);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <PaymentElement />
      <button disabled={!stripe}>立即支付</button>
    </form>
  );
};

2.4 服务端验证

// server/api/payment.ts
import Stripe from 'stripe';

const stripe = new Stripe('sk_test_YourSecretKey', {
  apiVersion: '2023-08-16'
});

app.post('/create-payment-intent', async (req, res) => {
  const { amount } = req.body;
  
  const paymentIntent = await stripe.paymentIntents.create({
    amount: amount * 100, // 转换为分
    currency: 'usd',
    automatic_payment_methods: { enabled: true }
  });

  res.send({ clientSecret: paymentIntent.client_secret });
});

三、PayPal智能按钮集成

3.1 沙箱环境配置

pnpm add @paypal/react-paypal-js

3.2 前端组件开发

// components/PayPalButton.tsx
import { PayPalScriptProvider, PayPalButtons } from "@paypal/react-paypal-js";

const initialOptions = {
  clientId: "YourClientID",
  currency: "USD",
  intent: "capture"
};

export default function PayPalCheckout() {
  return (
    <PayPalScriptProvider options={initialOptions}>
      <PayPalButtons 
        createOrder={(data, actions) => {
          return actions.order.create({
            purchase_units: [{
              amount: {
                value: "99.99",
                breakdown: {
                  item_total: { value: "89.99", currency_code: "USD" },
                  shipping: { value: "10.00", currency_code: "USD" }
                }
              }
            }]
          });
        }}
        onApprove={async (data, actions) => {
          const details = await actions.order?.capture();
          console.log('支付完成:', details);
        }}
      />
    </PayPalScriptProvider>
  );
}

四、其他支付网关实践(以Razorpay为例)

4.1 印度支付方案

// components/RazorpayIntegration.tsx
declare global {
  interface Window {
    Razorpay: any;
  }
}

const RazorpayPayment = ({ amount }: { amount: number }) => {
  const loadScript = (src: string) => {
    return new Promise((resolve) => {
      const script = document.createElement('script');
      script.src = src;
      script.onload = () => resolve(true);
      document.body.appendChild(script);
    });
  };

  const handlePayment = async () => {
    await loadScript('https://checkout.razorpay.com/v1/checkout.js');
    
    const options = {
      key: 'rzp_test_YourKey',
      amount: amount * 100,
      currency: 'INR',
      name: 'Demo Corp',
      handler: function(response: any) {
        console.log('支付成功:', response);
      },
      prefill: {
        email: 'user@example.com',
        contact: '9123456789'
      }
    };

    new window.Razorpay(options).open();
  };

  return <button onClick={handlePayment}>Pay via Razorpay</button>;
};

五、深度技术解析

5.1 不同方案的应用场景

支付网关 适用场景 地域覆盖
Stripe SaaS订阅、定制化支付流程 全球47国
PayPal 国际电商、跨境支付 188个国家
Razorpay 印度本地支付 印度市场

5.2 技术方案对比

Stripe优势

  • 丰富的支付方式(支持Apple Pay/Google Pay)
  • 强大的订阅管理功能
  • 实时数据仪表盘

PayPal短板

  • 交易费率较高(3.49% + $0.49)
  • 中国区业务受限
  • 退款处理周期长

六、关键注意事项

6.1 安全实践

  1. 永远不要在前端存储密钥:必须通过后端接口处理敏感操作
  2. HTTPS强制要求:支付网关均要求生产环境使用加密协议
  3. PCI DSS合规:使用托管表单避免处理信用卡原始数据

6.2 错误处理要点

// 通用错误处理模板
const handlePaymentError = (error: unknown) => {
  if (error instanceof StripeCardError) {
    showToast(`信用卡错误: ${error.message}`);
  } else if (error instanceof PaymentRequestButtonError) {
    showToast('支付请求异常');
  } else {
    console.error('未知错误:', error);
  }
};

七、项目总结

7.1 选型决策指南

  1. 明确目标用户群体的地域分布
  2. 评估开发资源(Stripe集成成本低于PayPal)
  3. 核算支付费率对利润的影响

7.2 最佳实践推荐

  • 开发阶段使用沙箱环境
  • 实现统一的支付日志系统
  • 定期更新SDK版本
  • 进行端到端测试(推荐使用Cypress)