上篇文章聊完大陆用户如何注册Stripe,鼓励大家多多注册多多尝试新的赚钱方式。 本篇文章想介绍下Stripe简明开发教程,把我的实战经历分享出来。 Stripe开发文档写的很详细,部分文档有中文版。英文版文档很适合学习英语。
接入方式
进入开发文档页面,文档罗列出开发遇到的所有可能,并且支持:
API
:通过直接调用 Stripe 的 RESTful API,您可以实现所有支付功能,包括创建客户、处理支付、管理订阅等。适合中大型复杂的企业项目。Stripe Checkout
:使用 Stripe 提供的托管支付页面,用户在这个安全页面上完成支付。适合小型或个人项目,大多数producthunt打榜产品都在用。Stripe Elements
:使用 Stripe 提供的可自定义 UI 组件,开发者可以在自己的网页中构建支付表单。适合有一定灵活度的项目。
无论哪种方式,开发体验都极度舒适,官方都给出可直接上手的Template,开发成本极低。
Stripe-host page(API)
笔者采用了Stripe-host page方式,无论哪种方式,按照文档来上手都很快。
我的支付功能是网页web,Python后端服务的组合开发测试,到部署上线。
官网提供了手机端SDK,以及其他语言包括Ruby,Node,Go等。感兴趣的可自行探索。
查看官方源码
public目录是网页端代码
- 通过访问网页的URL来调取python后端服务。
- 前端项目接入可新开页加载这个URL,注意这是一个完整的支付页面,不是类似支付宝二维码小组件可以嵌入在页面。
- 开发者只需要改下配置即可,包括公钥,接口路径。(配置信息在后面会讲)
server.py是服务端代码
,- 就一个文件是不是很简单?首次使用,需要pip3 install stripe。
- 服务端主要用来校验商品信息、签名信息,以及接收webhook等服务。
关键功能解释
stripe.checkout.Session.create()
:调用 Stripe 的 API 创建一个新的 Checkout 会话。- 参数:
line_items
:定义要出售的商品,price
是商品的价格 ID,quantity
是数量。mode
:设置为'payment'
,表示这是一次支付。success_url
:支付成功后重定向的 URL。cancel_url
:支付取消后重定向的 URL。automatic_tax
:启用自动税务计算。
@app.route('/create-checkout-session', methods=['POST'])
def create_checkout_session():
try:
checkout_session = stripe.checkout.Session.create( line_items=[
{
# Provide the exact Price ID (for example, pr_1234) of the product you want to sell
'price': '{{PRICE_ID}}',
'quantity': 1,
}, ],mode='payment',
success_url=YOUR_DOMAIN + '/success.html',
cancel_url=YOUR_DOMAIN + '/cancel.html',
automatic_tax={'enabled': True},
) except Exception as e:
return str(e)
return redirect(checkout_session.url, code=303)
配置4个key
代码中存在多个key,用于不同的场景。主要有4类:
- 公钥(Publishable Key):
- 用途:用于在前端应用中进行支付处理和创建客户信息。
- 特性:
- 安全性较低,可以暴露在客户端代码中。
- 用于初始化 Stripe.js 和创建支付请求。
-
密钥(Secret Key):
- 用途:用于后端服务器与 Stripe 的 API 进行通信,执行敏感操作。
- 特性:
- 高度敏感,必须保密,不应暴露在客户端代码中。
- 用于创建支付会话、处理退款、查询交易等。
-
端点密钥(Webhook Signing Secret):
- 用途:用于验证来自 Stripe 的 Webhook 请求,以确保请求的真实性。
- 特性:
- 每个 Webhook 端点都有一个唯一的签名密钥。
- 验证请求的签名以确保请求确实来自 Stripe。
- 价格 ID(Price ID):
- 用途:用于标识 Stripe 中的具体商品或服务的价格。
- 特性:
- 每个产品可以有多个价格(如不同的计费周期、不同的货币等)。
- 在创建 Checkout 会话或订阅时,需要使用价格 ID。
支付调试
Stripe 提供了一些用于测试的信用卡信息,您可以在测试模式下使用这些卡号进行交易:
- 成功支付:
4242 4242 4242 4242
- 失败支付:
4000 0000 0000 0002
- 需要额外验证:
4000 0000 0000 0341
Webhook
使用 Stripe Webhook 可以让您的应用接收来自 Stripe 的异步事件通知,如支付成功、退款等。以下是如何设置和使用 Stripe Webhook 的步骤:
1. 创建 Webhook 端点
- 登录到 Stripe Dashboard。
- 转到 Developers > Webhooks。
- 点击 Add endpoint。
- 输入您的 Webhook 端点 URL(例如
https://yourdomain.com/webhook
)。 - 选择接收的事件类型(如
payment_intent.succeeded
、charge.refunded
等)。
2. 编写 Webhook 处理代码
在后端服务器中,编写代码来处理接收到的 Webhook 事件。以下是我的Flask 的项目示例:
from flask import Flask, request, jsonify
import stripe
app = Flask(__name__)
# 设置 Stripe 密钥
stripe.api_key = 'sk_test_...'
@app.route('/webhook', methods=['POST'])
def webhook():
payload = request.get_data(as_text=True)
sig_header = request.headers.get('Stripe-Signature')
# 验证 Webhook 签名
try:
event = stripe.Webhook.construct_event(
payload, sig_header, 'whsec_...'
)
except ValueError as e:
# 无效的负载
return jsonify({'error': str(e)}), 400
except stripe.error.SignatureVerificationError as e:
# 无效的签名
return jsonify({'error': str(e)}), 400
# 处理事件
if event['type'] == 'payment_intent.succeeded':
payment_intent = event['data']['object'] # 付款确认
print('PaymentIntent was successful!')
return jsonify({'status': 'success'}), 200
if __name__ == '__main__':
app.run(port=5000)
3. 验证 Webhook 签名
- 使用
stripe.Webhook.construct_event
方法验证收到的事件签名,以确保事件确实来自 Stripe。 - 需要在 Webhook 设置中找到的 Signing secret(格式为
whsec_...
)。 - 如果使用 Stripe CLI ,命令执行后需要用命令好下的签名
4. 测试 Webhook
- 在开发环境中,可以使用 Stripe CLI 来测试 Webhook。安装 Stripe CLI 后,可以运行以下命令:
stripe listen --forward-to localhost:5000/webhook
这将使 Stripe CLI 监听事件并将其转发到您的本地服务器。
5. 处理不同类型的事件
根据您的业务需求,在 Webhook 处理代码中添加对不同事件的处理逻辑。
6. 监控和调试
- 可以在 Stripe Dashboard 的 Webhooks 页面查看发送的事件和响应,以便进行调试。
Metadata
最后一点了,上面讲的都是支付过程,状体回传。
用户信息、订单信息的数据也是我们流程中需要传递的,
在创建 Stripe 对象时,可以通过 metadata
参数传递附加信息。例如,创建客户时:
import stripe
stripe.api_key = 'sk_test_...'
customer = stripe.Customer.create(
email='customer@example.com',
metadata={
'internal_id': '12345',
'notes': 'VIP customer'
}
)
metadata会在付款成功的webhook中回传,开发者可在获得metadata数据后,来更新用户状态,订单状态。
有一点需要注意的是,metadata在checkout.session.completed这个端点事件里回传,在payment_intent.succeeded等事件不回传。
好了,我们再会!