手把手教你跑通出海支付!Stripe接入+扣款成功全流程实录

0 阅读5分钟

图片

哈喽,大家好

我是阿星

一个没有支付功能的项目总不是那么回事。

阿星之前做过一些小红书卡片工具但都没接支付👉🏻Gemini3做小红书封面生成器,效率暴增1000% ,实现爆款封面自由!,刚好今天和大家一起把支付加上。先不管其他完善没有,先让它能有基础支付功能再说。

如果你不知道为什么要注册或者大概出海的支付是怎么搞的,可以看我之前写的这一篇👉手把手教你Stripe Atlas注册美国公司,搞定AI出海支付第一步

图片

在做的过程中,如果你用的是codex,系统会提醒你要不要安装 Stripe MCP ,可以加快你的工作节奏。

但是我下面给大家展示的基本是纯手工主要还是一起熟悉步骤。

图片

可以先简单浏览熟悉一下大概步骤

    1. 先把 Stripe 右上角切到 测试模式(Test mode)  。 作用:先用测试数据走流程,不会产生真实扣款。
    1. 在 Stripe(测试模式)创建 Product ,再创建 3 个 Recurring Price (月/季/年)。 作用:把你要卖的会员套餐先定义好,后面代码只认 price_xxx。
    1. 后端实现 create-checkout-session,前端点击“购买”只做一件事:跳转到 Stripe Checkout 。 作用:支付页交给 Stripe 托管,前端不直接处理银行卡信息。
    1. 后端实现 webhook (验签 signature verification + 幂等 idempotency)。 作用:webhook 是会员状态的唯一真相源(source of truth),防止前端状态不准。
    1. 把 webhook 事件写入你的订阅表(如 customerId/subscriptionId/status/currentPeriodEnd);前端只读后端会员状态;接入 Customer Portal 。 作用:用户可自助改卡、取消订阅、看账单;你的权限判断统一可靠。
    1. 跑完整测试流:支付成功、续费成功、续费失败、取消订阅;全部通过后再切到 live key 上线。 作用:先把坑踩完,再上生产,避免真实用户出问题。

图片

图片

需要先获取的东西(必须)

1、获取公钥私钥

一个是公钥

一个是私钥

stripe 公钥
pk_live_开头的

stripe私钥
sk_live_开头的

图片

2、三个价格 ID:price_monthly、price_quarterly、price_yearly

进 Product catalog,创建一个产品(比如 Pro Membership)。

图片

在这个产品下分别创建 3 个价格:

    1.   Monthly:Recurring + interval=month
    1.   Quarterly:Recurring + interval=month,interval_count=3
    1.   Yearly:Recurring + interval=year

图片

然后点进Price详情页,把所有的价格id复制下来。你刚设置了三种价格就会有3个价格id。

图片

比如

每月
price_xxxx
每年
price_xxxx
每个季度
price_xxxx

3、前端地址(frontend_url)后端公网地址(backend_url)

前端:https://xxxxx
后端(同域):https://xxxx/api
Webhook:https://xxxxx/api/webhooks/stripe(后端地址 + /webhooks/stripe)

4、业务成功页和取消页地址(例如 /billing/success、/pricing)

你自己定义前端页面路径。

常用:

/xxx.com/billing/success 和 //xxx.com/pricing。

静态站就直接建对应 html 路径即可。

5、Stripe webhook endpoint 的签名密钥 whsec_...

在stripe搜索webhook

图片

在“事件”里用搜索框至少勾选这 5 个:

    1.   checkout.session.completed
    1.   invoice.paid
    1.   invoice.payment_failed
    1.   customer.subscription.updated
    1.   customer.subscription.deleted

图片

创建完成后,进入该 endpoint 详情页,

点 Signing secret / 签名密钥 -> Reveal ,

复制 whsec_...。

图片

如果你是部署在vercel部署的,还需要创建一些变量。

直接在Environment Variables添加就可以了。

图片

添加你环境变量,一定不要少复制了,我自己就少复制了一个字母找半天。也不要随便空格。也不要加引号之类的会错。

SUPABASE_URL
SUPABASE_ANON_KEY
SUPABASE_SERVICE_ROLE_KEY
AUTH_JWT_SECRET(在终端用openssl rand -hex 32这句代码生成。)
STRIPE_SECRET_KEY
STRIPE_WEBHOOK_SECRET
STRIPE_PRICE_MONTHLY
STRIPE_PRICE_QUARTERLY
STRIPE_PRICE_YEARLY
APP_BASE_URL=https://snaptools.work
STRIPE_TRIAL_DAYS=0
STRIPE_ALLOW_PROMO_CODES=true
STRIPE_PORTAL_ENABLED=true

添加完成后大概是这个样子

图片

数据库

去到supabase(一个数据库工具)创建项目 👉🏻 通过代码创建表头,直接在spabase的左边SQL Editor输入下面大段代码即可。

图片

下面这段ai帮我写的代码只能帮你做一些简单的字段,你自己构建用户auth的时候可以直接搜下怎么接入谷歌登录,或者我们下期再讲。

create extension if not exists pgcrypto;
create extension if not exists citext;

create table if not exists public.billing_users (
  id uuid primary key default gen_random_uuid(),
  email citext not null unique,
  stripe_customer_id text unique,
  subscription_status text not null default 'inactive',
  created_at timestamptz not null default now(),
  updated_at timestamptz not null default now()
);

create table if not exists public.subscriptions (
  id bigserial primary key,
  user_id uuid not null references public.billing_users(id) on delete cascade,
  stripe_customer_id text not null,
  stripe_subscription_id text not null unique,
  stripe_price_id text,
  stripe_product_id text,
  plan_key text,
  status text not null default 'incomplete',
  current_period_start timestamptz,
  current_period_end timestamptz,
  cancel_at_period_end boolean not null default false,
  cancel_at timestamptz,
  canceled_at timestamptz,
  trial_start timestamptz,
  trial_end timestamptz,
  currency text,
  interval text,
  interval_count integer,
  livemode boolean not null default false,
  latest_invoice_status text,
  created_at timestamptz not null default now(),
  updated_at timestamptz not null default now(),
  unique (user_id)
);

create index if not exists idx_billing_users_stripe_customer_id
  on public.billing_users(stripe_customer_id);

create index if not exists idx_subscriptions_stripe_customer_id
  on public.subscriptions(stripe_customer_id);

另外用户登录与数据库这部分是支付稳定运行的基础。

1、推荐统一用 Google 登录 作为用户唯一标识来源(userId)。

2、订阅状态写入数据库(上面这段代码创建的两张表),并通过后端接口 返回给前端。

3、前端 localStorage 只做显示缓存,会员权限判断必须以后端数据为准。

你可以让 Codex 帮你实现,但先把这 3 条规则说清楚再开始。

等完成之后记得在vercel 的deployment里选择最新的那条点击三个点,就可以直接redeploy一下,你刚编辑的东西就会生效了。

图片

直接点击按钮测试一下

图片

然后就可以看到,点击网页里的price页面就可以进行支付了。

他会直接显示成对应的币种,

下图的106其实就是我们之前设置的15美刀一个月。

图片

ok我是阿星,

更多AI应用,我们下期再见!

图片