惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

G
Google Developers Blog
Google DeepMind News
Google DeepMind News
Hugging Face - Blog
Hugging Face - Blog
D
Docker
F
Fortinet All Blogs
博客园 - 三生石上(FineUI控件)
Project Zero
Project Zero
Engineering at Meta
Engineering at Meta
J
Java Code Geeks
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Simon Willison's Weblog
Simon Willison's Weblog
S
Security Affairs
NISL@THU
NISL@THU
T
Tor Project blog
A
About on SuperTechFans
宝玉的分享
宝玉的分享
腾讯CDC
S
Schneier on Security
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
P
Privacy & Cybersecurity Law Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Stack Overflow Blog
Stack Overflow Blog
P
Privacy International News Feed
雷峰网
雷峰网
C
Cyber Attacks, Cyber Crime and Cyber Security
Vercel News
Vercel News
Cisco Talos Blog
Cisco Talos Blog
D
DataBreaches.Net
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Google Online Security Blog
Google Online Security Blog
Recorded Future
Recorded Future
L
LINUX DO - 热门话题
Microsoft Security Blog
Microsoft Security Blog
Latest news
Latest news
C
Check Point Blog
有赞技术团队
有赞技术团队
T
The Exploit Database - CXSecurity.com
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
云风的 BLOG
云风的 BLOG
SecWiki News
SecWiki News
Application and Cybersecurity Blog
Application and Cybersecurity Blog
爱范儿
爱范儿
月光博客
月光博客
V
Vulnerabilities – Threatpost
T
Threat Research - Cisco Blogs
P
Palo Alto Networks Blog
T
The Blog of Author Tim Ferriss
C
Cisco Blogs
Webroot Blog
Webroot Blog
S
Security @ Cisco Blogs

博客园 - ace--碳水化合物

English1 Tidio 官方帮助中心 ERP 相关系统介绍 蝉翼定理 选配法 利润最大化公式 写在失业的一段话 排列组合-组合 在线简历 概率论与数理统计学习章节 绝对值 比例五大定理 算术平均值与几何平均值 等价符号 公因数与最大公因数 容斥原理 英语2026 机器学习,深度学习,强化学习 分别是什么以及区别是什么 深度学习 监督学习 FAQ IVR TTS选择 k 近邻算法 kaldi 平稳核函数(stationary kernel) Karush-Kuhn-Tucker 条件 凸二次规划(convex quadratic programming) FunASR+FreeSwitch做坐席客服系统记录 freeswitch原理图 客服系统,第三方平台,对话转录音,这些可以不依赖第三方做么 STUN服务器 Gun.js原理 游戏升级记 10 OBB 边界问题 关于yolo26是否可以通过结合java开发 opencv和yolo是一回事情吗 pytorch TorchVision - ace--碳水化合物 PyTorch 和 FashionMNIST 的关系 java record 游戏升级记 9 VibeVoice实现90分钟、多角色播客生成,拓展语音合成新边界 同 WiFi 下用 Claude Code 控制另一台 Windows 电脑 Numpy 1 游戏升级记 8 开源claudecode前端 github star 9k+ 向量数据库skill 游戏升级记 7 游戏升级记 6 关系型数据库,向量数据库,ES,缓存,列式数据库,时序数据库,图数据库等的区别和共同点列举table 多Agent可视化 Agent设计模式 中文 Hermes+Obsidian+LLM wkii,构建AI知识库 Claude Code 前端工程泄露代码开源 游戏升级记 5 ai记忆 Rag 1 游戏升级记 4 游戏升级记 3 游戏升级记 2 AI学习路线 关于hermes agent安装 1 游戏升级记 1 代码迷踪 十三 代码迷踪 十二 ai智能体工程 Rust vs Go 微信小程序实名认证 怎样制作一个街机游戏 跟Claude code说 深入思考 它会思考更深入. googlebusiness profile设置统一白名单的操作,要弹窗模式的 该怎样利用ollama自己训练一个编程大模型 中华AI智能体编程一站式基站构想 打包网站到exe和app 识别的内容一般是试题模板的题号和手写的答题答案(数字) opencv怎么训练 在线SaaS系统做接口版本滚动更新 stripe相关支付流程 流程示意图 error: linker `link.exe` not found | = note: program not found - rust c++学习记20260219 奥数-平面几何经典定理 奥数-组合数学 奥数-几何 奥数-代数 奥数-数论
给我一份关于stripe平台的使用开发说明
ace--碳水化合物 · 2026-03-06 · via 博客园 - ace--碳水化合物

Stripe 的支付集成主要分为前端和后端两部分:前端负责安全收集支付信息(如使用 Stripe.js 或预构建的 Checkout 页面),后端负责处理敏感操作(如创建付款Intent)并通过 Webhook 接收异步事件。下面是一份从环境搭建到核心功能实现的开发说明,希望对你有帮助。

1. 环境准备与初始化

在开始编码之前,你需要完成 Stripe 账户的设置、安装官方 SDK 以及配置本地开发环境。

1.1 获取 API 密钥

登录 Stripe 仪表盘,在左侧菜单的 开发者 > API 密钥 中可以找到你的密钥 。

  • 可发布密钥 (Publishable Key):以 pk_test_pk_live_ 开头。用于客户端,安全地识别你的 Stripe 账户 。
  • 密钥 (Secret Key):以 sk_test_sk_live_ 开头。用于服务器端,必须严格保密,绝不能暴露在客户端代码或版本控制中 。
  • 受限密钥 (Restricted Key):为了更高的安全性,你可以创建受限密钥,仅赋予其必要的读写权限(如只允许访问 PaymentIntents 和 Webhook Endpoints),并用于特定的集成场景 。

1.2 安装官方 SDK

在服务器端(Node.js 环境),你需要安装官方的 Stripe Node.js 库 :

npm install stripe --save

在客户端(如 React),你需要安装 Stripe.js 的 React 封装库 :

npm install @stripe/react-stripe-js @stripe/stripe-js

1.3 安装 Stripe CLI (推荐)

Stripe CLI 是一个强大的命令行工具,可以帮助你模拟事件、转发 Webhook 到本地服务器,无需部署即可调试 。

  • 登录验证: 运行 stripe login,在浏览器中完成授权 。
  • 转发 Webhook: 使用以下命令将 Stripe 的事件转发到你本地的开发地址(例如 http://localhost:3000/api/webhooks):
      bash   stripe listen --forward-to localhost:3000/api/webhooks  
      运行后会生成一个 webhook 签名密钥(如 whsec_...),你需要将其配置在环境变量中 。

2. 服务器端集成

服务器端是你的应用与 Stripe 进行安全通信的核心。所有的敏感操作,如创建 PaymentIntent、处理 Webhook,都应该在这里完成。

2.1 初始化客户端

在你的后端代码中(例如 lib/stripe.js),使用你的 Secret Key 初始化 Stripe 客户端。建议采用懒加载模式,避免在构建时因缺少密钥而报错 。

import Stripe from 'stripe';

let _stripe = null;
const getStripe = () => {
  if (!_stripe) {
    _stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
      apiVersion: ‘2023-10-16’, // 指定 API 版本
      maxNetworkRetries: 2,      // 网络问题自动重试
    });
  }
  return _stripe;
};

export default getStripe;

2.2 创建 PaymentIntent

PaymentIntent 代表一个面向客户的支付意图。当你需要自定义支付流程(如使用 Payment Element 或 Card Element)时,你需要先创建一个 PaymentIntent 并返回其 client_secret 给前端 。

// API 路由: /api/create-payment-intent
import getStripe from ‘../lib/stripe’;

export default async function handler(req, res) {
  const stripe = getStripe();
  const { amount, currency, paymentMethodTypes } = req.body;

  try {
    const paymentIntent = await stripe.paymentIntents.create({
      amount: amount,           // 单位是分(例如 1000 表示 $10.00)
      currency: currency,       // 例如 ‘usd’, ‘cny’ (人民币是分)
      payment_method_types: paymentMethodTypes || [‘card’],
      // 可选项:捕获方式,自动还是手动
      capture_method: ‘automatic’,
    });

    res.json({
      clientSecret: paymentIntent.client_secret,
    });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
}

2.3 处理 Webhook

Webhook 是 Stripe 通知你的服务器异步事件的方式(例如支付成功、退款、订阅状态变更)。你需要构建一个原始的 POST 端点来接收这些事件,并使用 constructEvent 方法验证签名,以确保请求确实来自 Stripe 。

在你的 Webhook 处理器中(例如 /api/webhooks):

import getStripe from ‘../lib/stripe’;

export const config = {
  api: {
    bodyParser: false, // 需要获取原始请求体用于验证
  },
};

export default async function webhookHandler(req, res) {
  const stripe = getStripe();
  const sig = req.headers[‘stripe-signature’];
  const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET;

  let event;

  try {
    // 获取原始请求体
    const rawBody = await getRawBody(req);
    event = stripe.webhooks.constructEvent(rawBody, sig, endpointSecret);
  } catch (err) {
    console.log(`⚠️ Webhook signature verification failed.`, err.message);
    return res.status(400).send(`Webhook Error: ${err.message}`);
  }

  // 处理事件类型
  switch (event.type) {
    case ‘payment_intent.succeeded’:
      const paymentIntent = event.data.object;
      console.log(`PaymentIntent for ${paymentIntent.amount} succeeded.`);
      // 在这里更新数据库中的订单状态
      break;
    case ‘payment_intent.payment_failed’:
      console.log(‘Payment failed.’);
      break;
    case ‘checkout.session.completed’:
      const session = event.data.object;
      // 处理 Checkout 会话完成逻辑
      break;
    // ... 处理其他事件(如 customer.subscription.created, invoice.paid 等)
    default:
      console.log(`Unhandled event type ${event.type}`);
  }

  res.json({received: true});
}

3. 前端集成

前端负责安全地收集支付信息,并通过 client_secret 与 Stripe 完成最终的确认支付。

3.1 配置 Stripe Provider

在 React 应用中,你需要使用 loadStripe 加载 Stripe.js,并使用 Elements 包裹你的支付表单组件 。

import { Elements } from ‘@stripe/react-stripe-js’;
import { loadStripe } from ‘@stripe/stripe-js’;
import CheckoutForm from ‘../components/CheckoutForm’;

// 使用你的 Publishable Key 加载 Stripe
const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PK);

export default function PaymentPage() {
  const [clientSecret, setClientSecret] = useState(‘’);

  useEffect(() => {
    // 调用后端 API 创建 PaymentIntent 并获取 clientSecret
    fetch(‘/api/create-payment-intent’, {
      method: ‘POST’,
      headers: { ‘Content-Type’: ‘application/json’ },
      body: JSON.stringify({ amount: 2000, currency: ‘usd’ }),
    })
      .then((res) => res.json())
      .then((data) => setClientSecret(data.clientSecret));
  }, []);

  return (
    <div>
      {clientSecret && (
        <Elements stripe={stripePromise} options={{ clientSecret }}>
          <CheckoutForm />
        </Elements>
      )}
    </div>
  );
}

3.2 创建并处理支付表单

CheckoutForm 组件中,使用 useStripeuseElements 钩子来获取 Stripe 实例,并使用 confirmPayment 方法完成支付 。

import { useStripe, useElements, CardElement } from ‘@stripe/react-stripe-js’;

export default function CheckoutForm() {
  const stripe = useStripe();
  const elements = useElements();
  const [loading, setLoading] = useState(false);

  const handleSubmit = async (e) => {
    e.preventDefault();
    setLoading(true);

    if (!stripe || !elements) {
      return; // Stripe.js 尚未加载完成
    }

    const cardElement = elements.getElement(CardElement);

    const { error, paymentIntent } = await stripe.confirmCardPayment(clientSecret, {
      payment_method: {
        card: cardElement,
        billing_details: {
          name: ‘Customer Name’,
          // 其他账单信息
        },
      },
    });

    if (error) {
      console.log(‘Payment failed:’, error.message);
    } else if (paymentIntent && paymentIntent.status === ‘succeeded’) {
      console.log(‘Payment succeeded!’);
      // 重定向到成功页面或刷新购物车 
    }

    setLoading(false);
  };

  return (
    <form onSubmit={handleSubmit}>
      <CardElement />
      <button type=“submit” disabled={!stripe || loading}>
        Pay
      </button>
    </form>
  );
}

3.3 使用 Stripe Checkout (更简单的方案)

如果你不想构建复杂的表单,可以使用 Stripe 托管的 Checkout 页面。这种方式最快速,且 PCI-DSS 合规由 Stripe 负责。

在后端创建一个 Checkout Session 并重定向用户 :

// 后端代码
const session = await stripe.checkout.sessions.create({
  payment_method_types: [‘card’],
  line_items: [
    {
      price: ‘price_1234567890’, // 价格 ID
      quantity: 1,
    },
  ],
  mode: ‘payment’, // 或 ‘subscription’
  success_url: ‘https://yourdomain.com/success?session_id={CHECKOUT_SESSION_ID}’,
  cancel_url: ‘https://yourdomain.com/cancel’,
});

// 返回 session.url 给前端,前端直接重定向到该 URL
res.json({ url: session.url });

4. 测试与上线

4.1 使用测试卡号

Stripe 提供了大量的测试卡号。例如,使用 4242 4242 4242 4242,输入任意未来的到期日(如 12/34)和任意 CVC(如 123),即可模拟支付成功 。

  • 成功: 4242 4242 4242 4242
  • 需身份验证(3D Secure): 4000 0025 0000 3155
  • 失败: 4000 0000 0000 0002

4.2 处理零金额订单

如果你的购物车总额为 0(例如使用了折扣码),Stripe 不允许创建金额为 0 的 PaymentIntent 或 Checkout 会话。在这种情况下,你需要在前端或后端特殊处理:跳过 Stripe 支付流程,直接调用订单完成接口 。

4.3 上线前的检查清单

  1. 切换密钥:将代码和环境变量中的测试密钥(pk_test_/sk_test_)替换为生产环境密钥(pk_live_/sk_live_)。
  2. 配置生产 Webhook:在 Stripe 仪表盘的 开发者 > Webhook 中,添加你的生产服务器端点 URL,并订阅必要的事件(如 checkout.session.completedinvoice.paid)。
  3. 验证端点安全性:确保生产环境的 Webhook 端点正确使用了 constructEvent 进行签名验证。

通过以上步骤,你就完成了一个基于 Stripe 的标准支付集成。如果需要处理更复杂的业务逻辑,如订阅、Connect 平台账务等,可以参考 Stripe 官方文档中的对应指南。