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

Spring Boot集成PayPal高级信用卡支付(无账户用户)问题求助

Spring Boot 集成PayPal无账户信用卡支付(访客结账)完整方案

针对你遇到的OrderRequest没有PaymentSource属性的问题,核心原因是SDK版本过低或API类引用错误,下面提供完整修复方案和从零开始的集成指南:

一、依赖配置(Maven)

必须使用支持PayPal v2 Orders API的SDK版本,旧版v1 API不支持访客结账相关配置。在pom.xml中添加依赖:

<dependency>
    <groupId>com.paypal.sdk</groupId>
    <artifactId>rest-api-sdk</artifactId>
    <version>1.14.0</version> <!-- 推荐使用最新稳定版 -->
</dependency>

二、PayPal客户端配置

创建配置类初始化PayPal HTTP客户端:

import com.paypal.core.PayPalEnvironment;
import com.paypal.core.PayPalHttpClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class PayPalConfig {

    @Bean
    public PayPalHttpClient payPalHttpClient() {
        // 沙箱环境,生产环境替换为PayPalEnvironment.LIVE
        PayPalEnvironment sandboxEnv = new PayPalEnvironment.Sandbox(
                "你的PayPal Client ID",
                "你的PayPal Client Secret"
        );
        return new PayPalHttpClient(sandboxEnv);
    }
}

三、创建支持访客结账的订单

修复OrderRequest无PaymentSource属性的问题:确保导入的是com.paypal.orders.OrderRequest类(而非旧版com.paypal.api.payments.Payment),然后按以下代码实现订单创建:

import com.paypal.orders.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
public class PayPalPaymentService {

    @Autowired
    private PayPalHttpClient payPalClient;

    public String createGuestCheckoutOrder(double amount, String currency, String returnUrl, String cancelUrl) throws IOException {
        OrderRequest orderRequest = new OrderRequest();
        orderRequest.checkoutPaymentIntent("CAPTURE");

        // 设置订单金额
        AmountWithBreakdown amountBreakdown = new AmountWithBreakdown();
        amountBreakdown.currencyCode(currency);
        amountBreakdown.value(String.format("%.2f", amount));

        PurchaseUnitRequest purchaseUnit = new PurchaseUnitRequest();
        purchaseUnit.amountWithBreakdown(amountBreakdown);

        List<PurchaseUnitRequest> purchaseUnits = new ArrayList<>();
        purchaseUnits.add(purchaseUnit);
        orderRequest.purchaseUnits(purchaseUnits);

        // 关键:启用访客结账配置
        ApplicationContext appContext = new ApplicationContext();
        appContext.userAction("PAY_NOW"); // 显示直接支付按钮,允许无账户用户支付
        appContext.brandName("你的品牌名称");
        orderRequest.applicationContext(appContext);

        // 可选:指定仅信用卡支付(默认已支持,无需强制设置)
        PaymentSource paymentSource = new PaymentSource();
        CardRequest cardRequest = new CardRequest();
        paymentSource.card(cardRequest);
        orderRequest.paymentSource(paymentSource);

        // 发送创建订单请求
        CreateOrderRequest request = new CreateOrderRequest();
        request.requestBody(orderRequest);
        OrdersCreateResponse response = payPalClient.execute(request);

        // 返回PayPal支付跳转链接
        for (LinkDescription link : response.links()) {
            if (link.rel().equals("approve")) {
                return link.href();
            }
        }
        return null;
    }
}

四、处理支付回调(结合用户会话)

用户支付完成后,PayPal会跳转至你设置的回调地址,此时需结合会话信息完成业务逻辑处理:

import com.paypal.orders.CaptureOrderRequest;
import com.paypal.orders.OrderRequest;
import com.paypal.orders.OrdersCaptureResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;
import java.io.IOException;

@RestController
public class PayPalPaymentController {

    @Autowired
    private PayPalPaymentService paymentService;

    @Autowired
    private PayPalHttpClient payPalClient;

    @GetMapping("/init-pay")
    public String initPayment(HttpSession session) throws IOException {
        // 将用户会话信息存入Session,用于回调时关联业务
        session.setAttribute("userId", "当前登录用户ID");
        session.setAttribute("orderAmount", 99.99);

        String returnUrl = "http://你的域名/capture-pay";
        String cancelUrl = "http://你的域名/cancel-pay";
        return paymentService.createGuestCheckoutOrder(99.99, "USD", returnUrl, cancelUrl);
    }

    @GetMapping("/capture-pay")
    public String capturePayment(@RequestParam String token, HttpSession session) throws IOException {
        // 从Session取出用户信息
        String userId = (String) session.getAttribute("userId");
        Double orderAmount = (Double) session.getAttribute("orderAmount");

        // 捕获订单支付金额
        CaptureOrderRequest captureRequest = new CaptureOrderRequest();
        OrdersCaptureResponse response = payPalClient.execute(
                captureRequest.requestBody(new OrderRequest()).pathParam("order_id", token)
        );

        // 处理支付结果
        if ("COMPLETED".equals(response.status())) {
            // 支付成功:更新用户订单状态、写入数据库等业务操作
            return String.format("支付成功!用户ID:%s,订单ID:%s,金额:%.2f", userId, token, orderAmount);
        } else {
            // 支付失败:处理异常逻辑
            return "支付失败,状态:" + response.status();
        }
    }

    @GetMapping("/cancel-pay")
    public String cancelPayment() {
        return "支付已取消";
    }
}

五、关键注意事项

  • SDK版本验证:如果仍无法找到PaymentSource属性,检查依赖版本是否为最新,或确认导入的OrderRequest类来自com.paypal.orders包。
  • 沙箱测试:使用PayPal沙箱提供的测试信用卡号(如4111 1111 1111 1111,有效期选未来日期,CVV填任意3位)模拟无账户支付。
  • Webhook补充(推荐):除跳转回调外,配置PayPal Webhook监听CHECKOUT.ORDER.APPROVED事件,避免用户关闭页面导致的回调丢失,确保订单状态准确性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 08:05:05