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

C# WinForms应用调用PayPal REST API退款遇401未授权问题求助

Troubleshooting PayPal REST API 401 Unauthorized in C#

Hey Alan, sorry to hear you're stuck on this 401 error even with a confirmed valid access token—PayPal's REST API can throw these curveballs over tiny, easy-to-miss details. Let's walk through the most likely fixes and checkpoints for your scenario:

Common Causes & Fixes

  • Token Scope Mismatch
    PayPal access tokens are tied to specific scopes (permissions) you request when generating them. If you're trying to call a transaction-related API (like creating an order or capturing payment) but didn't include the required scopes upfront, you'll get a 401 even with a "valid" token. For example:

    • Creating orders needs order:write
    • Capturing payments needs payment:capture
    • Querying transactions needs transaction:read
      Double-check the scope parameter in your token-generation request to ensure it covers the API endpoint you're targeting.
  • Environment Misalignment
    Sandbox and production environments are completely separate—using a sandbox token to hit the production API (or vice versa) will instantly trigger a 401. Verify your base API URL matches the environment you generated the token for:

    • Sandbox: https://api-m.sandbox.paypal.com
    • Production: https://api-m.paypal.com
  • Incorrect Authorization Header Format
    This is one of the most frequent mistakes. The header must follow the exact format: Bearer {your-access-token}—note the space between Bearer and the token. In C#, make sure you're setting it correctly with AuthenticationHeaderValue:

    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", yourValidAccessToken);
    

    Avoid extra spaces, quotes, or typos in the "Bearer" keyword.

  • Token Expiry (Even if You Think It's Valid)
    PayPal access tokens expire after 8 hours. If you generated the token hours ago and haven't refreshed it, it might be dead in the water. Grab a fresh token and test again to rule this out.

  • Wrong API Endpoint Path
    Using outdated v1 endpoints (like /v1/payments) with a v2 token (or vice versa) can cause 401s. Ensure you're using the correct v2 paths for modern transactions:

    • Create order: /v2/checkout/orders
    • Capture order: /v2/checkout/orders/{orderId}/capture

Transaction-Specific Checks

Since you mentioned needing to address transaction details, here are a few extra things to verify:

  • Ensure your request body uses valid JSON formatting (no missing commas, correct field names like purchase_units, amount with currency_code and value).
  • Confirm the currency code is supported by PayPal (e.g., USD, EUR) and the value is a valid decimal (no leading zeros, correct decimal separator).
  • If you're passing customer or shipping details, make sure all required fields are included (PayPal will sometimes reject requests with incomplete data, masking as a 401).

Example Working Code Snippet

Here's a quick C# example using HttpClient to call the v2 Create Order endpoint with a valid token—use this as a reference to compare against your code:

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

public async Task<string> CreatePayPalOrder(string accessToken, bool isSandbox)
{
    using var httpClient = new HttpClient();
    var baseUrl = isSandbox ? "https://api-m.sandbox.paypal.com" : "https://api-m.paypal.com";
    httpClient.BaseAddress = new Uri(baseUrl);
    
    // Set authorization header correctly
    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
    httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    // Build valid order request body
    var orderPayload = new
    {
        intent = "CAPTURE",
        purchase_units = new[]
        {
            new
            {
                amount = new
                {
                    currency_code = "USD",
                    value = "15.99"
                }
            }
        }
    };

    var jsonContent = new StringContent(
        JsonConvert.SerializeObject(orderPayload),
        Encoding.UTF8,
        "application/json");

    var response = await httpClient.PostAsync("/v2/checkout/orders", jsonContent);
    
    // Debug: Check error details if request fails
    if (!response.IsSuccessStatusCode)
    {
        var errorDetails = await response.Content.ReadAsStringAsync();
        throw new Exception($"PayPal API Error: {response.StatusCode} - {errorDetails}");
    }

    return await response.Content.ReadAsStringAsync();
}

Give these checks a run-through, and if you're still stuck, sharing the exact API endpoint you're calling and a snippet of your request setup (redact sensitive data like tokens) would help narrow things down further.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:31:46