PayPal REST API能否访问个人账户数据?如何实现多账户授权访问?
嘿,这个问题我刚好折腾过,PayPal的多账户授权其实就是标准的OAuth 2.0授权码流程,针对你的场景(用Business沙箱账户创建的应用访问Personal沙箱账户),具体步骤是这样的:
1. 先检查你的应用配置是否正确
登录PayPal开发者平台,找到你用Business沙箱账户创建的应用,确保这两点:
- 权限(Scopes)配置:根据你要访问的Personal账户信息,勾选对应的权限。比如要获取用户基本信息就选
openid、profile、email;要访问交易记录就加transaction:read等。别请求多余权限,不然用户授权时会犹豫。 - 回调URL(Redirect URI)配置:在应用的“Sandbox”标签下(你用沙箱环境就选这个),添加你要接收授权码的回调地址,比如
http://localhost:3000/callback(本地测试用),这个地址必须和后面授权URL里的redirect_uri完全一致。
2. 引导Personal沙箱账户用户完成授权
你需要构造一个授权URL,让目标Personal账户用户打开并登录授权:
https://www.sandbox.paypal.com/signin/authorize?client_id=你的Business应用ID&response_type=code&redirect_uri=你配置的回调URL&scope=openid%20profile%20email&state=随机字符串
参数说明:
client_id:就是你Business应用的客户端ID,在开发者平台应用详情里能找到。response_type=code:固定值,告诉PayPal返回授权码。scope:用%20分隔你需要的权限,比如上面的openid%20profile%20email。state:生成一个随机字符串,用来防止CSRF攻击,回调时会原样返回,你要验证这个值是否和你发送的一致。
用户打开这个URL后,会跳转到PayPal沙箱登录页,用他们的Personal沙箱账户登录,然后确认授权你的应用访问他们的账户信息。
3. 用授权码交换Personal账户的Access Token
用户授权成功后,PayPal会跳转到你配置的回调URL,并带上code参数(授权码)和你之前传的state参数。
接下来,你需要向PayPal的沙箱Token端点发起POST请求,交换Access Token:
- 端点地址:
https://api-m.sandbox.paypal.com/v1/oauth2/token - 请求头:
Content-Type: application/x-www-form-urlencoded,还要用Base64编码你的client_id:client_secret作为Authorization: Basic 编码后的字符串 - 请求体:
grant_type=authorization_code&code=回调拿到的授权码&redirect_uri=你配置的回调URL
成功请求后,你会得到包含access_token、refresh_token、expires_in等字段的响应,这个access_token就是用来访问该Personal账户信息的凭证。
4. 使用Access Token访问Personal账户信息
拿到access_token后,就可以调用PayPal的API来获取该账户的信息了。比如获取用户基本信息:
- 端点:
https://api-m.sandbox.paypal.com/v1/identity/oauth2/userinfo - 请求头:
Authorization: Bearer 刚才拿到的access_token
发起GET请求后,就能得到该Personal沙箱账户的姓名、邮箱、用户ID等信息。如果需要访问其他资源(比如交易记录),只要你申请了对应的权限,调用对应的API即可。
5. (可选)用Refresh Token长期访问
如果需要在Access Token过期后继续访问,不用让用户重新授权,可以用refresh_token来刷新Access Token:
- 同样向Token端点发起POST请求,请求体改为:
grant_type=refresh_token&refresh_token=之前拿到的refresh_token
- 响应会返回新的
access_token和可能更新的refresh_token,保存下来继续使用即可。
需要注意的是,每个Personal账户授权后都会生成独立的access_token和refresh_token,你需要把这些凭证和对应的用户关联起来存储,这样就能实现一个应用访问多个账户的需求啦。
内容的提问来源于stack exchange,提问作者Ismaiel Nosairat




