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

Java PayPal SDK支付异常:支付后无到账及Payout授权错误求助

PayPal Java 集成问题解决方案

一、支付后无资金到账问题

核心原因

你只完成了订单创建和用户授权跳转,但未执行订单捕获(Capture)操作。PayPal的订单流程是:创建订单 → 用户授权 → 捕获订单资金,缺了最后一步就不会触发扣款。

完整支付流程代码

1. Maven依赖配置

<dependency>
    <groupId>com.paypal.sdk</groupId>
    <artifactId>rest-api-sdk</artifactId>
    <version>1.14.0</version>
</dependency>

2. 初始化PayPal客户端

import com.paypal.core.PayPalEnvironment;
import com.paypal.core.PayPalHttpClient;

public class PayPalClient {
    public static PayPalHttpClient getClient() {
        // 沙箱环境,生产环境替换为PayPalEnvironment.LIVE
        PayPalEnvironment environment = new PayPalEnvironment.Sandbox(
                "你的ClientID",
                "你的SecretID"
        );
        return new PayPalHttpClient(environment);
    }
}

3. 创建订单接口

import com.paypal.http.HttpResponse;
import com.paypal.orders.*;
import java.util.ArrayList;
import java.util.List;

public class CreateOrder {
    public HttpResponse<Order> createOrder() throws Exception {
        OrderRequest orderRequest = new OrderRequest();
        orderRequest.checkoutPaymentIntent("CAPTURE"); // 直接捕获模式,也可设为AUTHORIZE后续再手动捕获

        // 设置订单金额与服务描述
        AmountWithBreakdown amountBreakdown = new AmountWithBreakdown()
                .currencyCode("USD")
                .value("10.00");
        PurchaseUnitRequest purchaseUnit = new PurchaseUnitRequest()
                .amountWithBreakdown(amountBreakdown)
                .description("你的服务名称");
        List<PurchaseUnitRequest> purchaseUnits = new ArrayList<>();
        purchaseUnits.add(purchaseUnit);
        orderRequest.purchaseUnits(purchaseUnits);

        // 设置跳转URL
        ApplicationContext applicationContext = new ApplicationContext()
                .returnUrl("http://你的域名/return") // 用户支付成功后跳转地址
                .cancelUrl("http://你的域名/cancel"); // 用户取消支付跳转地址
        orderRequest.applicationContext(applicationContext);

        OrdersCreateRequest request = new OrdersCreateRequest().requestBody(orderRequest);
        return PayPalClient.getClient().execute(request);
    }
}

4. 捕获订单接口(关键步骤!)

用户从PayPal跳转回你的returnUrl后,必须调用此接口完成资金捕获:

import com.paypal.http.HttpResponse;
import com.paypal.orders.*;

public class CaptureOrder {
    public HttpResponse<Order> captureOrder(String orderId) throws Exception {
        OrdersCaptureRequest request = new OrdersCaptureRequest(orderId);
        request.requestBody(new OrderActionRequest());
        return PayPalClient.getClient().execute(request);
    }
}

注意事项

  • 不要仅依赖前端跳转触发捕获,建议结合PayPal Webhook监听订单状态变化,确保捕获逻辑可靠执行。
  • 沙箱测试必须使用PayPal开发者控制台创建的沙箱买家账户,真实账户无法在沙箱环境使用。

二、Payouts SDK 授权错误问题

可能原因及解决

  1. 沙箱商家账户未启用Payouts权限:
    登录PayPal开发者控制台,进入「Sandbox → Accounts」,找到你的商家账户,点击「Profile → Settings → Permissions」,确认开启「Send Money/Make Payments」权限,未开启则手动勾选。

  2. API权限范围缺失:
    初始化客户端时,确保SDK自动获取的OAuth令牌包含payouts相关权限;若手动获取令牌,请求时需指定scope=urn:ietf:params:oauth:scope:paypal:payouts。

  3. 环境密钥不匹配:
    确认使用的ClientID/Secret对应沙箱环境,不要混用生产环境密钥在沙箱调用,反之亦然。

正确Payouts代码示例

import com.paypal.core.PayPalEnvironment;
import com.paypal.core.PayPalHttpClient;
import com.paypal.http.HttpResponse;
import com.paypal.payouts.*;
import java.util.ArrayList;
import java.util.List;

public class PayPalPayouts {
    public static void main(String[] args) throws Exception {
        PayPalEnvironment environment = new PayPalEnvironment.Sandbox(
                "你的ClientID",
                "你的SecretID"
        );
        PayPalHttpClient client = new PayPalHttpClient(environment);

        // 创建 payout 批次
        PayoutSenderBatchHeader senderBatchHeader = new PayoutSenderBatchHeader()
                .senderBatchId("batch-" + System.currentTimeMillis())
                .emailSubject("付款通知");

        // 创建单个 payout 项
        PayoutItem payoutItem = new PayoutItem()
                .recipientType("EMAIL")
                .amount(new Currency().value("5.00").currencyCode("USD"))
                .receiver("沙箱接收方邮箱@example.com")
                .note("服务费用结算");

        List<PayoutItem> items = new ArrayList<>();
        items.add(payoutItem);

        PayoutsPostRequest request = new PayoutsPostRequest()
                .requestBody(new PayoutsRequest().senderBatchHeader(senderBatchHeader).items(items));

        HttpResponse<PayoutBatch> response = client.execute(request);
        System.out.println("批次ID: " + response.result().batchHeader().payoutBatchId());
    }
}

额外检查

  • 沙箱商家账户需有足够测试余额才能发起Payout,可在开发者控制台给沙箱账户充值。
  • 接收方必须是有效的沙箱账户,真实账户无法接收沙箱环境的Payout。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 11:46:35