主题
PayPal 配置(含沙箱账号与 webhook)
一句话
建应用拿三个值(Client ID / Secret / Webhook ID),再建两个沙箱账号(一买一卖), 用沙箱买家账号走一遍。
界面会变,功能不会
PayPal 开发者后台改版很频繁。下面写的是要找什么,不是"点第几个按钮"。
你要拿的三个值
| 后台字段 | 长什么样 | 在 PayPal 哪里 |
|---|---|---|
| Client ID | AeA1QIZ... | Apps & Credentials → 你的 App |
| Client Secret | EO422dn3... | 同一个 App 页面,要点「Show」 |
| Webhook ID | 8PT597110X687430L | 同一个 App 里添加 webhook 之后生成 |
Webhook ID 不是 URL,也不是密钥
它是 PayPal 给每个 webhook 端点分配的编号,形如 8PT597110X687430L。 系统用它去 PayPal 那儿验证回调的真伪。
很多人在这一格填成了回调地址,或者填成了 Client Secret —— 结果所有回调被判为伪造。
第 1 步:进开发者后台
打开 https://developer.paypal.com,用你的 PayPal 账号登录。
区分两个环境
页面上有 Sandbox(沙箱) 和 Live(生产) 的切换。 两边的应用、密钥、沙箱账号、webhook 全部独立,互不相通。
先在 Sandbox 里跑通,最后再去 Live 建一遍。
第 2 步:⭐ 先建沙箱测试账号
这一步很多教程会漏,但漏了就没法测
PayPal 沙箱不能用你真实的 PayPal 账号付款。你必须先建一个沙箱买家账号, 支付时用它登录。
进 Testing Tools → Sandbox Accounts(旧版菜单里叫 Sandbox → Accounts)。
通常 PayPal 会自动给你两个默认账号:
| 类型 | 用途 |
|---|---|
| Business(商家) | 收款方 —— 你的应用就建在它下面 |
| Personal(个人) | 付款方 —— 支付时用它登录 |
如果没有,或者想自己建
点 Create account:
| 项 | 买家账号 | 商家账号 |
|---|---|---|
| Account Type | Personal | Business |
| Country | 选一个和你测试场景一致的(如 United States) | 同左 |
| 余额 | 给一个够花的数(如 5000) | 不用管 |
拿到账号的邮箱和密码
在账号列表里点那一行 → View/Edit account(或三个点菜单):
- Email ID:形如
sb-abc123@personal.example.com - System Generated Password:一串随机密码,复制下来
把这两个存好
每次测试支付都要用。密码是系统生成的,记不住 —— 但可以在这个页面随时改成你自己设的。
沙箱账号的国家会影响能不能付
沙箱买家账号的国家和你的收货国家差太远时,PayPal 可能拒绝这笔交易。 测试时让买家账号国家和收货地址国家保持一致最省事。
第 3 步:创建应用
进 Apps & Credentials,确认左上角在 Sandbox 环境,点 Create App。
| 项 | 填什么 |
|---|---|
| App Name | 随便,比如 mall-shop |
| App Type | Merchant |
| Sandbox Business Account | 选上一步那个 Business 账号 |
创建完这一页就有:
- Client ID:直接可见,复制
- Secret:点 Show 才显示,复制
Secret 泄露 = 别人能用你的账号收款和退款
不要贴到聊天工具,不要截图发出去。系统会加密存库,后台读取时只返回掩码。
第 4 步:先在后台把通道建出来
顺序不能反
回调地址里带着通道 ID,而 ID 是保存之后才有的。
后台 → 站点管理 → 支付通道 → PayPal 那一行的「新增」
| 字段 | 填什么 |
|---|---|
| 环境 | 沙箱 |
| Client ID | 刚复制的 |
| Client Secret | 刚复制的 |
| Webhook ID | 先留空,第 6 步再填 |
| 启用 | 打开 |
保存时要输验证器上的 6 位码(见 支付通道总览)。
保存后,列表里那一行会出现**「回调地址(webhook)」和一个复制**按钮。
第 5 步:在 PayPal 添加 webhook
回到你那个 App 的页面,往下拉找 Webhooks → Add Webhook。
Webhook URL:回后台点复制按钮,直接粘过来。形如:
https://jdz.io/api/open/payment/callback/paypal/4PayPal 只接受 https
沙箱也一样。所以没法用 localhost 测,直接在服务器上测最省事。
Event types(要订阅的事件),至少选这几个:
PAYMENT.CAPTURE.COMPLETED 支付完成
PAYMENT.CAPTURE.DENIED 支付被拒
PAYMENT.CAPTURE.REFUNDED 退款完成
CHECKOUT.ORDER.APPROVED 买家已批准找不到就选「All events」
PayPal 的事件有一百多种,绝大多数我们不处理。 如果有耐心建议订阅重要的几个事件。
第 6 步:拿 Webhook ID 填回后台
添加完,那条 webhook 下面会显示一个 Webhook ID,形如:
8PT597110X687430L复制它 → 回后台 → 支付通道 → 编辑刚才那个 PayPal 通道 → 填进 Webhook ID → 保存 (再输一次 6 位码)。
这一步漏了会怎样
所有回调会被判为伪造并拒绝。表现和"完全没配 webhook"一样: 买家付了钱订单还是待付款,然后被超时关单。
第 7 步:用沙箱账号走一遍
- 打开商城,加购 → 结算 → 选 PayPal
- 跳到 PayPal 的登录页
- ⚠️ 用第 2 步那个沙箱 Personal 账号登录(不是你自己的真实 PayPal 账号)
- 确认付款 → 跳回商城
要走完整条:
加购 → 结算 → 选 PayPal → 用沙箱买家账号登录付款 → 跳回来
→ 订单几秒内变成「已付款」→ 收到订单确认邮件顺便验一下取消的情况
在 PayPal 页面点「取消并返回」,确认回到商城后订单仍是待付款、 页面给出了能看懂的提示,而不是报错。
第 8 步:切正式环境
先纠正一个常见误解
不需要、也不可能建第二条 PayPal 通道。
系统里一个支付方式只能有一条通道(再建会报「已配置过 paypal」)。 「沙箱 / 生产」是这一条通道上的一个开关,不是两套配置 —— 所以你切换它的时候,看到的密钥框内容是一样的,这是正常的。
跟着的好消息:回调地址从头到尾不变(地址里的数字是通道 ID)。
沙箱跑通之后:
- PayPal 开发者后台切到 Live
- Live 环境重新建一个 App(沙箱那个不能用),拿 live 的 Client ID / Secret
- 在 Live App 里再添加一次 webhook,地址填同一个 (就是你在沙箱阶段用的那个
.../callback/paypal/2),拿到 Live 的 Webhook ID - 回后台打开这条通道 → 环境切到「生产」 → 此时三个密钥框会自动清空并弹出红色提示,把 live 的三个值填进去 → 保存(要过 TOTP)
- 点「测试连接」,必须显示「连接成功(生产)」
- 清掉测试订单
为什么切环境会清空密钥
沙箱和生产在 PayPal 那边是两套完全独立的凭据,三个值全不一样。
不清空的话会出现一种界面上完全看不出来的错配:三个框里显示的是 ••••••1234 掩码, 看着是填好的,而系统对密钥的规则是「空或掩码 = 不修改」—— 于是通道标着生产、握着沙箱密钥。后果是每一笔真实付款的回调都验签失败 (PayPal 的验签接口跟着环境开关走,会去问沙箱服务器),订单永远停在待付款, 而后台一切正常。
所以前后端都做了强制:换环境不继承旧密钥,不重填就启用不了。
第 3 步最容易漏
沙箱阶段配过 webhook 就以为完事 —— 但 Live 是完全独立的一套 App, webhook 要在 Live App 里再加一次(地址一样,但生成的 Webhook ID 是新的)。
漏了的话:上线后买家付了钱,订单全是「待付款」,半小时后被自动关单。
沙箱的 webhook 不用特意去删
切到生产之后,沙箱那边如果还有 webhook 打过来,会因为 Webhook ID 对不上而 验签失败返回 401,不会被当成真实付款处理。这是安全的失败方向。 当然删掉更干净。
Live 应用可能需要额外资质
PayPal 对某些国家/行业的商家账号会要求补充材料才能收款。 建 Live App 时如果提示要验证,先按它的指引把商家账号验证完。
常见问题
支付页显示「Things don't appear to be working at the moment」
最常见是 Client ID 填错,或者沙箱通道里填了 live 的 Client ID。 浏览器控制台(F12)里通常能看到 PayPal SDK 的具体报错。
用自己的真实 PayPal 账号登录沙箱,提示账号不存在
正常的。 沙箱环境只认沙箱账号,去 Testing Tools → Sandbox Accounts 拿那个 sb-xxxx@personal.example.com 和系统生成的密码。
沙箱账号密码忘了
在 Sandbox Accounts 里点那个账号 → View/Edit → 可以直接改成你自己设的密码。
PayPal 回调日志里全是失败
在 App 页面的 webhook 那里有 Webhook Events / Event logs,能看到每次投递的结果。
- 401 / 验签失败 → Webhook ID 填错(最常见),或者填成了 Secret / URL
- 404 → 地址不对,回后台用「复制」按钮重新取一次
- 超时 → 服务器没响应,看
/opt/mall/logs/mall.log
退款失败
- 那笔订单是用这个通道收的吗 —— 换过账号的话,老订单要用老通道退 (所以通道只停用不删)
- PayPal 账户余额够吗
- 后台售后页面会显示 PayPal 返回的原文,照着它查
沙箱交易在哪看
用沙箱商家账号登录 https://www.sandbox.paypal.com(注意是 sandbox. 开头), 能看到沙箱里的收款记录,和真实后台长得一样。