Install
openclaw skills install @thcjp/stripe-payment-integratoropenclaw skills install @thcjp/stripe-payment-integrator基于 Stripe 官方优选实践,实现安全、合规、可扩展的支付集成。同时提供国内支付(微信支付/支付宝/银联)替代方案,支持跨境与国内双场景。从支付意图到订阅管理,从 Webhook 到退款,全链路覆盖。
以下表格列出了支付集成专家技能特有的功能边界条件,以及对应的场景描述。
| 边界条件 | 场景描述 | 备注 |
|---|---|---|
| 最低订单金额 | 对于订单金额低于设定阈值的支付请求,系统将拒绝处理。 | 通常用于防止小额欺诈。 |
| 最大订单金额 | 对于订单金额超过设定阈值的支付请求,系统将拒绝处理。 | 通常用于防止大额欺诈。 |
| 订单重复处理 | 当系统检测到重复的订单请求时,将拒绝处理并返回错误。 | 防止重复支付。 |
| 订单取消限制 | 对于已完成的订单,系统不允许取消。 | 确保交易一致性。 |
| 订阅取消限制 | 对于处于试用期或已激活的订阅,系统不允许取消。 | 确保订阅管理的一致性。 |
| 退款限制 | 对于已完成的订单,系统不允许退款。 | 确保交易一致性。 |
| Webhook事件限制 | 系统仅处理特定类型的Webhook事件。 | 确保事件处理的精确性。 |
详细的输入输出格式请参考下方章节说明。
以下表格列出了支付集成专家技能可能遇到的错误类型、原因分析、解决方案和恢复策略。
| 错误类型 | 原因分析 | 处理方式 | 恢复策略 |
|---|---|---|---|
| API认证失败 | API密钥错误或过期 | 检查密钥配置,重新生成token | 重新配置API密钥。 |
| 接口限流 | 请求频率超出限制 | 降低调用频率,启用重试退避策略 | 调整请求频率。 |
| 响应超时 | 网络延迟或服务端负载过高 | 增加超时阈值,检查网络连接 | 优化网络连接或服务端配置。 |
| 文件不存在 | 路径错误或文件未创建 | 检查路径拼写,确认文件已生成 | 检查文件路径和文件系统。 |
| 文件格式不支持 | 扩展名不在支持列表中 | 转换为支持的格式后重试 | 转换文件格式。 |
| 权限不足 | 当前用户无读写权限 | 检查文件权限,以管理员身份运行 | 调整文件权限。 |
| 命令执行失败 | 参数错误或环境依赖缺失 | 检查命令语法,确认依赖已安装 | 检查命令参数和依赖库。 |
| 进程超时 | 命令执行时间过长 | 增加超时设置,优化命令参数 | 优化命令参数或脚本。 |
| 网络连接失败 | DNS解析失败或防火墙拦截 | 检查网络配置,确认代理设置 | 检查网络配置和防火墙设置。 |
以下表格列出了支付集成专家技能的输入输出参数说明。
| 参数名 | 类型 | 必填 | 默认值 | 取值范围 | 示例值 | 备注 |
|---|---|---|---|---|---|---|
| input | string | 是 | - | - | - | 输入数据或指令。 |
| options | object | 否 | - | - | - | 附加配置选项。 |
| callback_url | string | 否 | - | - | - | 异步处理完成后的回调通知URL。 |
| amount | number | 是 | - | - | 1000 | 订单金额,单位为分。 |
| currency | string | 是 | - | - | usd | 货币类型。 |
| description | string | 否 | - | - | Order 001 | 订单描述。 |
| metadata | object | 否 | - | - | { order_id: 'ORD-001' } | 业务数据。 |
| payment_intent_id | string | 否 | - | - | pi_001 | PaymentIntent ID。 |
| client_secret | string | 否 | - | - | pi_001_secret_001 | PaymentIntent 客户端密钥。 |
| status | string | 否 | - | - | requires_payment_method | PaymentIntent 状态。 |
详细的输入输出格式请参考下方章节说明。
| 场景 | 输入 | 输出 |
|---|---|---|
| 电商一次性支付 | 订单金额、货币、商品信息 | PaymentIntent + 前端支付表单 + 后端确认逻辑 |
| SaaS 订阅集成 | 产品定价、计费周期、试用期 | 订阅创建/管理 API + 客户门户配置 |
| 退款处理 | 订单 ID、退款金额、退款原因 | 退款 API 调用 + 财务对账记录 |
| 平台分账 | 卖家列表、分账比例、金额 | Connect 账户配置 + 分账 API + 佣金报表 |
| Webhook 集成 | 业务事件清单 | Webhook 端点 + 签名验证 + 事件处理器 |
| 国内支付改造 | Stripe 改为微信/支付宝 | SDK 替换方案 + 接口映射 + 测试用例 |
| 不适用于: |
| 维度 | Stripe(海外) | 微信支付(国内) | 支付宝(国内) |
|---|---|---|---|
| 一次性支付 | PaymentIntent | JSAPI/Native/APP | 电脑网站/手机网站/APP |
| 订阅 | Subscriptions | 委托代扣 | 周期扣款 |
| 分账 | Connect | 分账功能 | 分账功能 |
| Webhook | Stripe Webhook | 支付结果通知 | 异步通知 |
| 3D Secure | 内置支持 | 微信密码/指纹 | 支付宝密码 |
| 测试模式 | sk_test_ | 沙箱环境 | 沙箱环境 |
| 凭证 | Secret Key | mchid + apiV3Key | appid + 私钥 |
| 货币 | 多币种 | CNY | CNY |
| 费率 | 2.9% + $0.30 | 0.6% | 0.6% |
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| input | string | 是 | 支付集成专家处理的输入数据或指令 |
| options | object | 否 | 附加配置选项,如模式选择、格式偏好等 |
| callback_url | string | 否 | 异步处理完成后的回调通知URL |
用户请求:为一笔 $99.00 的订单创建支付意图,支持 3D Secure
订单ID: ORD-001
输出:
// 后端:创建 PaymentIntent
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
// ...
const paymentIntent = await stripe.paymentIntents.create({
amount: 9900, // 美分
currency: 'usd',
description: 'Order ORD-001',
metadata: { order_id: 'ORD-001' },
automatic_payment_methods: { enabled: true } // 自动启用 3D Secure
});
// ...
// 返回给前端
{
payment_intent_id: 'pi_未指定',
client_secret: 'pi_未指定_secret_未指定',
status: 'requires_payment_method',
amount: 9900,
currency: 'usd'
}
// 前端:确认支付
const stripe = Stripe('pk_live_未指定');
const result = await stripe.confirmCardPayment(clientSecret, {
payment_method: { card: elements.getElement('card') }
});
// 处理 result.error 或 result.paymentIntent
输入:
用户请求:为 ¥99.00 的订单创建微信支付(公众号内)
订单ID: ORD-002
openid: oUpF8未指定
输出:
// 后端:创建微信支付订单
const { WechatPay } = require('wechatpay-node-v3');
const pay = new WechatPay({
appid: process.env.WX_APPID,
mchid: process.env.WX_MCHID,
publicKey: process.env.WX_PUBLIC_KEY,
privateKey: process.env.WX_PRIVATE_KEY
});
// ...
const result = await pay.transactions_jsapi({
out_trade_no: 'ORD-002',
description: 'Order ORD-002',
amount: { total: 9900, currency: 'CNY' }, // 分
payer: { openid: 'oUpF8未指定' },
notify_url: 'https://api.example.com/wx/notify'
});
// ...
// 返回给前端(用于调起微信支付)
{
timeStamp: '1627000000',
nonceStr: 'abc123',
package: 'prepay_id=wx20240101未指定',
signType: 'RSA',
paySign: '<参数>'
}
输入:
用户请求:创建每月 $29 的 Pro 订阅,7天试用期
客户: cus_未指定
价格: price_未指定 (monthly $29)
输出:
const subscription = await stripe.subscriptions.create({
customer: 'cus_未指定',
items: [{ price: 'price_未指定' }],
trial_period_days: 7,
payment_behavior: 'default_incomplete',
expand: ['latest_invoice.payment_intent']
});
// ...
// 输出
{
subscription_id: 'sub_未指定',
status: 'trialing',
current_period_end: 1700000000, // 7天后
trial_end: 1700000000,
latest_invoice: 'in_未指定',
customer: 'cus_未指定'
}
| 依赖项 | 类型 | 是否必需 | 获取方式 | 国内替代 |
|---|---|---|---|---|
| Stripe SDK | SDK | 海外必需 | npm install stripe / pip install stripe | - |
| 微信支付 SDK | SDK | 国内必需 | npm install wechatpay-node-v3 | - |
| 支付宝 SDK | SDK | 国内必需 | npm install alipay-sdk | - |
| Node.js | 运行时 | 必需 | nodejs.org | npmmirror 国内镜像 |
| 公网 HTTPS 端点 | 网络 | 必需 | 用于接收 Webhook | 国内云厂商 SLB |
以下案例展示了skill的工作流程和预期输出效果,由LLM按照skill定义的流程生成。
输入:
场景: 电商网站一次性支付
订单: ORD-2024-001, 金额 $299.00 USD
要求: 支持3D Secure(SCA合规),Webhook确认支付状态
前端: React + Stripe.js
后端: Node.js + Express
LLM生成输出 (output/ecommerce-payment/server.js):
// 后端: 创建PaymentIntent
const express = require("express");
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);
const app = express();
app.use(express.json());
// ...
app.post("/api/create-payment-intent", async (req, res) => {
try {
const { orderId, amount, currency = "usd" } = req.body;
// ...
// 服务端金额校验(不信任客户端金额)
const order = await getOrderFromDB(orderId);
if (!order || order.amount !== amount) {
return res.status(400).json({ error: "金额不匹配" });
}
// ...
paymentIntents.create({
amount: Math.round(amount * 100), // 转为分
currency,
description: `Order ${orderId}`,
metadata: {
order_id: orderId,
customer_id: order.customerId,
},
automatic_payment_methods: { enabled: true }, // 自动启用3D Secure
});
// ...
res.json({
clientSecret: paymentIntent.client_secret,
paymentIntentId: paymentIntent.id,
});
} catch (error) {
console.error("创建PaymentIntent失败:", error);
res.status(500).json({ error: "支付初始化失败" });
}
});
// ...
// Webhook端点(签名验证+幂等处理)
app.post("/api/stripe/webhook", express.raw({ type: "application/json" }), async (req, res) => {
const sig = req.headers["stripe-signature"];
let event;
// ...
try {
event = stripe.webhooks.constructEvent(
req.body, sig, process.env.STRIPE_WEBHOOK_SECRET
);
} catch (err) {
console.error("签名验证失败:", err.message);
return res.status(400).send(`Webhook Error: ${err.message}`);
}
// ...
// 幂等检查:基于事件ID去重
const processed = await checkEventProcessed(event.id);
if (processed) {
return res.json({ received: true, duplicate: true });
}
await markEventProcessed(event.id);
// ...
// 事件路由
switch (event.type) {
case "payment_intent.succeeded":
await handlePaymentSuccess(event.data.object);
break;
await handlePaymentFailure(event.data.object);
break;
// 3D Secure需要用户认证
console.log("需要3D Secure认证:", event.data.object.id);
break;
}
// ...
res.json({ received: true });
});
// ...
async function handlePaymentSuccess(paymentIntent) {
const { order_id } = paymentIntent.metadata;
await updateOrderStatus(order_id, "paid", {
paidAt: new Date(),
});
await sendOrderConfirmationEmail(order_id);
}
// ...
async function handlePaymentFailure(paymentIntent) {
await updateOrderStatus(order_id, "failed", {
failureReason: paymentIntent.last_payment_error?.message,
});
}
// ...
app.listen(3000);
LLM生成输出 (output/ecommerce-payment/Checkout.jsx):
// 前端: React支付组件
import { useState } from "react";
import { loadStripe } from "@stripe/stripe-js";
import { Elements, PaymentElement, useStripe, useElements } from "@stripe/react-stripe-js";
const stripePromise = loadStripe(process.env.REACT_APP_STRIPE_PUBLISHABLE_KEY);
function CheckoutForm({ clientSecret, orderId }) {
const stripe = useStripe();
const elements = useElements();
const [processing, setProcessing] = useState(false);
const [error, setError] = useState(null);
const handleSubmit = async (e) => {
e.preventDefault();
if (!stripe || !elements) return;
setProcessing(true);
const { error, paymentIntent } = await stripe.confirmPayment({
elements,
confirmParams: {
return_url: `${window.location.origin}/payment-result?order=${orderId}`,
},
redirect: "if_required",
});
if (error) {
setError(error.message);
setProcessing(false);
} else if (paymentIntent.status === "succeeded") {
// 支付成功,跳转订单页(Webhook也会同步更新)
window.location.href = `/orders/${orderId}?status=success`;
status === "requires_action") {
// 3D Secure认证由Stripe.js自动处理
setError("需要进行3D Secure认证,请完成验证");
}
};
return (
<form onSubmit={handleSubmit}>
<PaymentElement />
{error && <div className="error">{error}</div>}
<button type="submit" disabled={!stripe || processing}>
{processing ? "处理中..." : "支付 $299.00"}
</button>
</form>
);
}
export default function Checkout({ orderId, amount }) {
const [clientSecret, setClientSecret] = useState(null);
const createIntent = async () => {
const res = await fetch("/api/create-payment-intent", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ orderId, amount }),
});
const data = await res.json();
setClientSecret(data.clientSecret);
};
return (
<div>
<button onClick={createIntent}>开始支付</button>
{clientSecret && (
<Elements stripe={stripePromise} options=<动态配置>>
<CheckoutForm clientSecret={clientSecret} orderId={orderId} />
</Elements>
)}
</div>
);
}
效果验证: ✓PaymentIntent创建含服务端金额校验 ✓3D Secure自动启用(automatic_payment_methods) ✓Webhook签名验证+幂等去重 ✓前端confirmPayment处理requires_action ✓React+Stripe.js集成完整
| 风险类型 | 防范措施 |
|---|---|
| API密钥泄露 | 通过环境变量配置,禁止硬编码到代码或配置文件中 |
| 命令执行风险 | 仅执行白名单命令,避免拼接用户输入到命令行参数中 |
| 网络通信安全 | 使用HTTPS协议,验证SSL证书有效性 |
| 敏感数据暴露 | 输出结果中不包含密钥、令牌等敏感信息 |
| 使用前请确认已阅读依赖说明章节,确保运行环境满足安全要求。 |
A: 支付集成专家支持Stripe官方优选实践,同时提供微信支付、支付宝和银联的国内替代方案。
A: 支付集成专家提供订阅管理功能,您可以通过配置订阅计划、设置自动续订和灵活调整订阅设置来管理用户订阅。
A: 支付集成专家能够处理Webhook,确保您能够实时接收支付事件通知,如支付成功、退款等,并据此执行相应的业务逻辑。
A: 支付集成专家支持退款功能,您可以通过系统提供的接口发起退款请求,并跟踪退款状态,确保退款流程的顺利进行。
A: 支付集成专家适用于电商支付、SaaS订阅、退款处理、平台分账、发票管理、Webhook集成等多种场景,能够满足不同业务需求。
注: 本SKILL.md超过500行上限, 已截断尾部非核心章节以满足L1格式要求。完整内容见版本库历史。