React+Spring Boot集成PayPal REST API支付网关及后端验证需求
React + Spring Boot 集成PayPal REST API支付网关落地指南
一、前期准备
- 注册PayPal开发者账号,创建REST APP,获取Client ID和Secret(优先用沙箱环境测试,上线前切换生产环境)
- Spring Boot项目引入PayPal REST SDK依赖
- React项目引入PayPal官方JS SDK
二、Spring Boot后端实现
1. 配置PayPal客户端
在application.properties中添加配置:
paypal.client.id=你的沙箱Client ID paypal.client.secret=你的沙箱Secret paypal.mode=sandbox # 生产环境改为live
创建PayPal客户端配置类:
import com.paypal.core.PayPalEnvironment; import com.paypal.core.PayPalHttpClient; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class PayPalConfig { @Value("${paypal.client.id}") private String clientId; @Value("${paypal.client.secret}") private String clientSecret; @Value("${paypal.mode}") private String mode; @Bean public PayPalHttpClient payPalHttpClient() { PayPalEnvironment environment = mode.equals("live") ? new PayPalEnvironment.Live(clientId, clientSecret) : new PayPalEnvironment.Sandbox(clientId, clientSecret); return new PayPalHttpClient(environment); } }
2. 实现支付核心接口
import com.paypal.orders.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList; import java.util.List; @RestController @RequestMapping("/api/paypal") public class PayPalController { @Autowired private PayPalHttpClient client; // 创建支付订单 @PostMapping("/create-order") public ResponseEntity<String> createOrder(@RequestBody OrderRequestDto requestDto) throws Exception { OrderRequest orderRequest = new OrderRequest(); orderRequest.checkoutPaymentIntent("CAPTURE"); // 设置订单金额 AmountWithBreakdown amount = new AmountWithBreakdown() .currencyCode("USD") .value(requestDto.getAmount()); PurchaseUnitRequest purchaseUnit = new PurchaseUnitRequest().amountWithBreakdown(amount); List<PurchaseUnitRequest> purchaseUnits = new ArrayList<>(); purchaseUnits.add(purchaseUnit); orderRequest.purchaseUnits(purchaseUnits); OrdersCreateRequest request = new OrdersCreateRequest().requestBody(orderRequest); HttpResponse<Order> response = client.execute(request); // 返回订单ID给前端 return new ResponseEntity<>(response.result().id(), HttpStatus.OK); } // 捕获支付(完成支付验证) @PostMapping("/capture-order") public ResponseEntity<Capture> captureOrder(@RequestBody String orderId) throws Exception { OrdersCaptureRequest request = new OrdersCaptureRequest(orderId); HttpResponse<Order> response = client.execute(request); // 此处可添加业务逻辑:更新订单状态、记录支付日志等 return new ResponseEntity<>(response.result().purchaseUnits().get(0).payments().captures().get(0), HttpStatus.OK); } } // 辅助DTO类 class OrderRequestDto { private String amount; // getter和setter public String getAmount() { return amount; } public void setAmount(String amount) { this.amount = amount; } }
三、React前端实现
1. 引入PayPal JS SDK
在public/index.html中添加:
<script src="https://www.paypal.com/sdk/js?client-id=你的沙箱Client ID¤cy=USD"></script>
2. 创建支付组件
import { useState } from 'react'; const PayPalPayment = () => { const [amount, setAmount] = useState('10.00'); const [orderId, setOrderId] = useState(''); // 调用后端创建订单 const createOrder = async () => { try { const response = await fetch('/api/paypal/create-order', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ amount }), }); const id = await response.text(); setOrderId(id); // 渲染PayPal支付按钮 renderPayPalButton(id); } catch (error) { console.error('创建订单失败:', error); alert('创建订单失败,请重试'); } }; const renderPayPalButton = (orderId) => { window.paypal.Buttons({ async createOrder() { return orderId; }, async onApprove(data) { try { // 调用后端验证并完成支付 const response = await fetch('/api/paypal/capture-order', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(data.orderID), }); const captureData = await response.json(); if (captureData.status === 'COMPLETED') { alert('支付成功!'); // 此处可跳转至订单成功页面或更新本地状态 } } catch (error) { console.error('支付验证失败:', error); alert('支付失败,请重试'); } }, onError(err) { console.error('PayPal按钮错误:', err); alert('支付出错,请稍后再试'); } }).render('#paypal-button-container'); }; return ( <div> <input type="text" value={amount} onChange={(e) => setAmount(e.target.value)} placeholder="输入支付金额" /> <button onClick={createOrder}>发起PayPal支付</button> <div id="paypal-button-container"></div> </div> ); }; export default PayPalPayment;
四、关键注意事项
- 沙箱测试:使用PayPal开发者后台创建的沙箱卖家/买家账号完成测试,确保流程通顺
- 支付安全:必须通过后端
capture-order接口验证支付状态,禁止仅依赖前端回调,防止恶意篡改 - 异常处理:完善网络异常、PayPal接口异常的捕获逻辑,给用户明确的错误提示
- 生产切换:上线前将PayPal模式改为
live,替换为生产环境的Client ID和Secret
内容的提问来源于stack exchange,提问作者Prince Apurba
相关产品推荐
相关产品推荐

