You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用PayPal REST API获取发票详情时遭遇403错误的解决方法

PayPal REST API发票查询403权限问题排查

问题背景

我正在将PayPal REST API集成到Python脚本中,目标是通过发票ID从个人账户获取发票详情,使用的PayPal端点为:https://api-m.paypal.com/v2/invoicing/invoices/{invoice_id}。

已完成前置步骤:获取了有效access token,且在PayPal后台配置了相关权限,但调用接口时始终无法获取指定发票的信息,返回403 Forbidden错误。

相关代码

发票查询接口调用代码

async def get_invoice_info(self, access_token, invoice_id: str):
        url = f"https://api-m.paypal.com/v2/invoicing/invoices/{invoice_id}"
        headers = {
            'Content-Type': 'application/json',
            'Authorization': f'Bearer {access_token}'
        }

        async with aiohttp.ClientSession() as session:
            async with session.get(url, headers=headers) as resp:
                print(resp.text)  # 此处打印的是方法对象,无法看到具体错误
                if resp.status != 200:
                    raise Exception("Failed to retrieve invoice information!")
                return await resp.json()

Access Token返回的权限Scope

打印access token详情后,发现完全缺失发票接口对应的权限:

{'scope': 'https://uri.paypal.com/services/checkout/one-click-with-merchant-issued-token https://uri.paypal.com/services/payments/realtimepayment https://uri.paypal.com/services/payments/payment/authcapture openid https://uri.paypal.com/services/payments/refund https://api.paypal.com/v1/vault/credit-card https://uri.paypal.com/services/billing-agreements https://api.paypal.com/v1/payments/.* https://uri.paypal.com/services/reporting/search/read https://api.paypal.com/v1/vault/credit-card/.* https://uri.paypal.com/services/shipping/trackers/readwrite https://uri.paypal.com/services/applications/webhooks', 'access_token': 'XXX', 'token_type': 'Bearer', 'app_id': 'XXX', 'expires_in': XXX, 'nonce': 'XXX'}

获取Access Token的代码(曾尝试添加Scope但未生效)

async def get_paypal_access_token(self):

        d = {"grant_type" : "client_credentials"} # 曾在此处添加过需要的Scope,但无效果
        h = {"Accept": "application/json", "Accept-Language": "en_US"}

        async with aiohttp.ClientSession() as session:
            async with session.post('https://api.paypal.com/v1/oauth2/token', auth=aiohttp.BasicAuth(CLIENT_ID, SECRET), headers=h, data=d) as resp:
                r = await resp.json()
                print(r)
                access_token = r['access_token']
                return access_token

错误信息

<bound method ClientResponse.text of <ClientResponse(https://api-m.paypal.com/v2/invoicing/invoices/) [403 Forbidden]>

问题排查与解决步骤

  1. 补全发票接口所需的Scope
    发票查询接口对应的权限Scope是https://uri.paypal.com/services/invoicing,必须在获取access token时显式指定该参数,修改后的获取token代码如下:

    async def get_paypal_access_token(self):
        d = {
            "grant_type": "client_credentials",
            "scope": "https://uri.paypal.com/services/invoicing"
        }
        h = {"Accept": "application/json", "Accept-Language": "en_US"}
    
        async with aiohttp.ClientSession() as session:
            async with session.post(
                'https://api.paypal.com/v1/oauth2/token',
                auth=aiohttp.BasicAuth(CLIENT_ID, SECRET),
                headers=h,
                data=d
            ) as resp:
                r = await resp.json()
                print(r)
                # 验证返回的Scope是否包含发票权限
                if 'https://uri.paypal.com/services/invoicing' not in r.get('scope', ''):
                    raise Exception("Access token未获取到发票权限")
                access_token = r['access_token']
                return access_token
    
  2. 确认PayPal后台权限配置生效

    • 检查后台是否已开启**发票(Invoicing)**相关的读权限
    • 修改权限后,需重新生成Client ID/Secret并更新到代码中,否则旧凭证不会加载新权限
    • 确认使用的是对应环境的凭证(沙箱/生产环境不要混淆)
  3. 修复接口调用的调试细节
    将print(resp.text)改为print(await resp.text()),这样可以打印出完整的错误响应内容,PayPal的403错误通常会明确说明缺少的权限类型,便于进一步排查。

内容的提问来源于stack exchange,提问作者user22401170

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 07:52:54