移除PayPal支付功能,仅保留支付宝支付

- 删除PayPalService.java和PayPalController.java
- 从PaymentMethod枚举中移除PAYPAL选项
- 移除PaymentController和PaymentApiController中的PayPal相关代码
- 移除前端PayPal支付选项和相关API
- 清理配置文件中的PayPal配置
- 修复OrderController中的PayPal引用错误
This commit is contained in:
AIGC Developer
2025-11-04 11:06:08 +08:00
parent d5f7569a3a
commit 6d834d3385
44 changed files with 89 additions and 648 deletions

View File

@@ -19,12 +19,6 @@ public class PaymentConfig {
return new AliPayConfig();
}
@Bean
@ConfigurationProperties(prefix = "paypal")
public PayPalConfig payPalConfig() {
return new PayPalConfig();
}
/**
* 支付宝配置
*/
@@ -64,34 +58,4 @@ public class PaymentConfig {
public void setAliPayRootCertPath(String aliPayRootCertPath) { this.aliPayRootCertPath = aliPayRootCertPath; }
}
/**
* PayPal支付配置
*/
public static class PayPalConfig {
private String clientId;
private String clientSecret;
private String mode;
private String returnUrl;
private String cancelUrl;
private String domain;
// Getters and Setters
public String getClientId() { return clientId; }
public void setClientId(String clientId) { this.clientId = clientId; }
public String getClientSecret() { return clientSecret; }
public void setClientSecret(String clientSecret) { this.clientSecret = clientSecret; }
public String getMode() { return mode; }
public void setMode(String mode) { this.mode = mode; }
public String getReturnUrl() { return returnUrl; }
public void setReturnUrl(String returnUrl) { this.returnUrl = returnUrl; }
public String getCancelUrl() { return cancelUrl; }
public void setCancelUrl(String cancelUrl) { this.cancelUrl = cancelUrl; }
public String getDomain() { return domain; }
public void setDomain(String domain) { this.domain = domain; }
}
}

View File

@@ -1,9 +1,9 @@
package com.example.demo.controller;
import com.example.demo.model.*;
import com.example.demo.service.OrderService;
import com.example.demo.service.PaymentService;
import jakarta.validation.Valid;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -15,11 +15,24 @@ import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Optional;
import com.example.demo.model.Order;
import com.example.demo.model.OrderItem;
import com.example.demo.model.OrderStatus;
import com.example.demo.model.OrderType;
import com.example.demo.model.Payment;
import com.example.demo.model.PaymentMethod;
import com.example.demo.model.User;
import com.example.demo.service.OrderService;
import com.example.demo.service.PaymentService;
import jakarta.validation.Valid;
@Controller
@RequestMapping("/orders")
@@ -362,8 +375,6 @@ public class OrderController {
// 根据支付方式跳转到相应的支付页面
if (paymentMethod == PaymentMethod.ALIPAY) {
return "redirect:/payment/alipay/create?paymentId=" + savedPayment.getId();
} else if (paymentMethod == PaymentMethod.PAYPAL) {
return "redirect:/payment/paypal/create?paymentId=" + savedPayment.getId();
} else {
model.addAttribute("error", "不支持的支付方式");
return "redirect:/orders/" + id;

View File

@@ -1,162 +0,0 @@
package com.example.demo.controller;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* PayPal支付控制器
* 基于IJPay实现
*/
@RestController
@RequestMapping("/api/payments/paypal")
public class PayPalController {
private static final Logger logger = LoggerFactory.getLogger(PayPalController.class);
/**
* 创建支付订单
*/
@PostMapping("/create-order")
public ResponseEntity<Map<String, Object>> createOrder(@RequestParam String outTradeNo,
@RequestParam String totalAmount,
@RequestParam String subject,
@RequestParam String body) {
Map<String, Object> response = new HashMap<>();
try {
// TODO: 实现PayPal订单创建逻辑
// 这里需要根据实际的PayPal API进行实现
response.put("success", true);
response.put("message", "PayPal订单创建功能待实现");
response.put("outTradeNo", outTradeNo);
response.put("totalAmount", totalAmount);
response.put("subject", subject);
logger.info("PayPal订单创建请求: outTradeNo={}, totalAmount={}", outTradeNo, totalAmount);
} catch (Exception e) {
logger.error("PayPal订单创建失败", e);
response.put("success", false);
response.put("message", "订单创建失败: " + e.getMessage());
}
return ResponseEntity.ok(response);
}
/**
* 捕获支付
*/
@PostMapping("/capture")
public ResponseEntity<Map<String, Object>> captureOrder(@RequestParam String orderId) {
Map<String, Object> response = new HashMap<>();
try {
// TODO: 实现PayPal支付捕获逻辑
response.put("success", true);
response.put("message", "PayPal支付捕获功能待实现");
response.put("orderId", orderId);
logger.info("PayPal支付捕获请求: orderId={}", orderId);
} catch (Exception e) {
logger.error("PayPal支付捕获失败", e);
response.put("success", false);
response.put("message", "支付捕获失败: " + e.getMessage());
}
return ResponseEntity.ok(response);
}
/**
* 查询订单
*/
@GetMapping("/query")
public ResponseEntity<Map<String, Object>> queryOrder(@RequestParam String orderId) {
Map<String, Object> response = new HashMap<>();
try {
// TODO: 实现PayPal订单查询逻辑
response.put("success", true);
response.put("message", "PayPal订单查询功能待实现");
response.put("orderId", orderId);
logger.info("PayPal订单查询请求: orderId={}", orderId);
} catch (Exception e) {
logger.error("PayPal订单查询失败", e);
response.put("success", false);
response.put("message", "订单查询失败: " + e.getMessage());
}
return ResponseEntity.ok(response);
}
/**
* 退款
*/
@PostMapping("/refund")
public ResponseEntity<Map<String, Object>> refund(@RequestParam String captureId,
@RequestParam String refundAmount,
@RequestParam String refundReason) {
Map<String, Object> response = new HashMap<>();
try {
// TODO: 实现PayPal退款逻辑
response.put("success", true);
response.put("message", "PayPal退款功能待实现");
response.put("captureId", captureId);
response.put("refundAmount", refundAmount);
logger.info("PayPal退款请求: captureId={}, amount={}", captureId, refundAmount);
} catch (Exception e) {
logger.error("PayPal退款失败", e);
response.put("success", false);
response.put("message", "退款失败: " + e.getMessage());
}
return ResponseEntity.ok(response);
}
/**
* 支付成功回调
*/
@GetMapping("/return")
public ResponseEntity<Map<String, Object>> returnUrl(HttpServletRequest request) {
Map<String, Object> response = new HashMap<>();
try {
String token = request.getParameter("token");
String payerId = request.getParameter("PayerID");
logger.info("PayPal支付成功回调: token={}, payerId={}", token, payerId);
response.put("success", true);
response.put("message", "PayPal支付回调功能待实现");
response.put("token", token);
response.put("payerId", payerId);
} catch (Exception e) {
logger.error("PayPal支付回调处理失败", e);
response.put("success", false);
response.put("message", "支付处理失败: " + e.getMessage());
}
return ResponseEntity.ok(response);
}
/**
* 支付取消回调
*/
@GetMapping("/cancel")
public ResponseEntity<Map<String, Object>> cancelUrl(HttpServletRequest request) {
Map<String, Object> response = new HashMap<>();
try {
String token = request.getParameter("token");
logger.info("PayPal支付取消: token={}", token);
response.put("success", false);
response.put("message", "PayPal支付取消功能待实现");
response.put("token", token);
} catch (Exception e) {
logger.error("PayPal支付取消处理失败", e);
response.put("success", false);
response.put("message", "支付取消处理失败: " + e.getMessage());
}
return ResponseEntity.ok(response);
}
}

View File

@@ -22,7 +22,6 @@ import org.springframework.web.bind.annotation.RestController;
import com.example.demo.model.Payment;
import com.example.demo.model.PaymentStatus;
import com.example.demo.service.AlipayService;
import com.example.demo.service.PayPalService;
import com.example.demo.service.PaymentService;
@RestController
@@ -36,9 +35,6 @@ public class PaymentApiController {
@Autowired
private AlipayService alipayService;
@Autowired
private PayPalService payPalService;
/**
@@ -418,50 +414,6 @@ public class PaymentApiController {
}
}
/**
* 创建PayPal支付
*/
@PostMapping("/paypal/create")
public ResponseEntity<Map<String, Object>> createPayPalPayment(
@RequestBody Map<String, Object> paymentData,
Authentication authentication) {
try {
String username;
if (authentication != null && authentication.isAuthenticated()) {
username = authentication.getName();
} else {
return ResponseEntity.badRequest()
.body(createErrorResponse("请先登录后再创建支付"));
}
Long paymentId = Long.valueOf(paymentData.get("paymentId").toString());
Payment payment = paymentService.findById(paymentId)
.orElseThrow(() -> new RuntimeException("支付记录不存在"));
// 检查权限
if (!payment.getUser().getUsername().equals(username)) {
return ResponseEntity.status(403)
.body(createErrorResponse("无权限操作此支付记录"));
}
// 调用PayPal接口创建支付
String paymentUrl = payPalService.createPayment(payment);
Map<String, Object> response = new HashMap<>();
response.put("success", true);
response.put("message", "PayPal支付创建成功");
response.put("data", Map.of("paymentUrl", paymentUrl));
return ResponseEntity.ok(response);
} catch (Exception e) {
logger.error("创建PayPal支付失败", e);
return ResponseEntity.badRequest()
.body(createErrorResponse("创建PayPal支付失败: " + e.getMessage()));
}
}
private Map<String, Object> createErrorResponse(String message) {
Map<String, Object> response = new HashMap<>();
response.put("success", false);

View File

@@ -15,14 +15,12 @@ import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.example.demo.model.Payment;
import com.example.demo.model.PaymentMethod;
import com.example.demo.model.User;
import com.example.demo.service.AlipayService;
import com.example.demo.service.PayPalService;
import com.example.demo.service.PaymentService;
import jakarta.servlet.http.HttpServletRequest;
@@ -40,9 +38,6 @@ public class PaymentController {
@Autowired
private AlipayService alipayService;
@Autowired
private PayPalService payPalService;
/**
* 显示支付页面
*/
@@ -78,7 +73,6 @@ public class PaymentController {
}
// 根据支付方式创建支付
String redirectUrl;
if (payment.getPaymentMethod() == PaymentMethod.ALIPAY) {
Map<String, Object> paymentResult = alipayService.createPayment(payment);
if (paymentResult.containsKey("qrCode")) {
@@ -86,9 +80,6 @@ public class PaymentController {
return "redirect:/payment/qr?qrCode=" + paymentResult.get("qrCode");
}
return "redirect:/payment/error";
} else if (payment.getPaymentMethod() == PaymentMethod.PAYPAL) {
redirectUrl = payPalService.createPayment(payment);
return "redirect:" + redirectUrl;
} else {
model.addAttribute("error", "不支持的支付方式");
model.addAttribute("paymentMethods", PaymentMethod.values());
@@ -158,65 +149,6 @@ public class PaymentController {
}
}
/**
* PayPal支付返回
*/
@GetMapping("/paypal/return")
public String paypalReturn(@RequestParam("paymentId") String paymentId,
@RequestParam("PayerID") String payerId,
Model model) {
try {
boolean success = payPalService.executePayment(paymentId, payerId);
if (success) {
Payment payment = paymentService.findByExternalTransactionId(paymentId)
.orElseThrow(() -> new RuntimeException("支付记录不存在"));
model.addAttribute("payment", payment);
model.addAttribute("success", true);
return "payment/result";
} else {
model.addAttribute("error", "支付执行失败");
return "payment/result";
}
} catch (Exception e) {
logger.error("处理PayPal支付返回失败", e);
model.addAttribute("error", "支付处理失败:" + e.getMessage());
return "payment/result";
}
}
/**
* PayPal支付取消
*/
@GetMapping("/paypal/cancel")
public String paypalCancel(Model model) {
model.addAttribute("error", "支付已取消");
return "payment/result";
}
/**
* PayPal Webhook通知
*/
@PostMapping("/paypal/webhook")
@ResponseBody
public String paypalWebhook(HttpServletRequest request) {
try {
Map<String, String> params = request.getParameterMap().entrySet().stream()
.collect(java.util.stream.Collectors.toMap(
Map.Entry::getKey,
entry -> entry.getValue()[0]
));
boolean success = payPalService.handleWebhook(params);
return success ? "success" : "fail";
} catch (Exception e) {
logger.error("处理PayPal Webhook失败", e);
return "fail";
}
}
/**
* 支付记录列表
*/

View File

@@ -67,3 +67,4 @@ public class MailMessage {
}

View File

@@ -1,8 +1,7 @@
package com.example.demo.model;
public enum PaymentMethod {
ALIPAY("支付宝"),
PAYPAL("PayPal");
ALIPAY("支付宝");
private final String displayName;

View File

@@ -201,3 +201,4 @@ public class PointsFreezeRecord {

View File

@@ -269,3 +269,4 @@ public class TaskQueue {

View File

@@ -261,3 +261,4 @@ public class TaskStatus {

View File

@@ -69,3 +69,4 @@ public interface TaskStatusRepository extends JpaRepository<TaskStatus, Long> {

View File

@@ -38,5 +38,6 @@ public class PlainTextPasswordEncoder implements PasswordEncoder {

View File

@@ -1,202 +0,0 @@
package com.example.demo.service;
import com.example.demo.model.Payment;
import com.example.demo.model.PaymentMethod;
import com.example.demo.model.PaymentStatus;
import com.example.demo.repository.PaymentRepository;
import com.paypal.api.payments.*;
import com.paypal.base.rest.APIContext;
import com.paypal.base.rest.PayPalRESTException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.*;
@Service
public class PayPalService {
private static final Logger logger = LoggerFactory.getLogger(PayPalService.class);
private final PaymentRepository paymentRepository;
@Value("${paypal.client-id}")
private String clientId;
@Value("${paypal.client-secret}")
private String clientSecret;
@Value("${paypal.mode}")
private String mode;
@Value("${paypal.return-url}")
private String returnUrl;
@Value("${paypal.cancel-url}")
private String cancelUrl;
public PayPalService(PaymentRepository paymentRepository) {
this.paymentRepository = paymentRepository;
}
/**
* 创建PayPal支付订单
*/
public String createPayment(Payment payment) {
try {
// 设置支付状态
payment.setStatus(PaymentStatus.PENDING);
payment.setPaymentMethod(PaymentMethod.PAYPAL);
payment.setOrderId(generateOrderId());
payment.setReturnUrl(returnUrl);
// 保存支付记录
paymentRepository.save(payment);
// 创建API上下文
APIContext apiContext = new APIContext(clientId, clientSecret, mode);
// 创建支付金额
Amount amount = new Amount();
amount.setCurrency(payment.getCurrency());
amount.setTotal(payment.getAmount().toString());
// 创建交易
Transaction transaction = new Transaction();
transaction.setAmount(amount);
transaction.setDescription(payment.getDescription() != null ? payment.getDescription() : "商品支付");
// 创建交易列表
List<Transaction> transactions = new ArrayList<>();
transactions.add(transaction);
// 创建支付者
Payer payer = new Payer();
payer.setPaymentMethod("paypal");
// 创建支付
com.paypal.api.payments.Payment paypalPayment = new com.paypal.api.payments.Payment();
paypalPayment.setIntent("sale");
paypalPayment.setPayer(payer);
paypalPayment.setTransactions(transactions);
// 设置重定向URL
RedirectUrls redirectUrls = new RedirectUrls();
redirectUrls.setReturnUrl(returnUrl + "?paymentId={PAY_ID}&PayerID={PAYER_ID}");
redirectUrls.setCancelUrl(cancelUrl);
paypalPayment.setRedirectUrls(redirectUrls);
// 创建支付
com.paypal.api.payments.Payment createdPayment = paypalPayment.create(apiContext);
// 更新支付记录
payment.setExternalTransactionId(createdPayment.getId());
paymentRepository.save(payment);
logger.info("PayPal支付订单创建成功订单号{}PayPal ID{}",
payment.getOrderId(), createdPayment.getId());
// 获取批准URL
for (Links link : createdPayment.getLinks()) {
if ("approval_url".equals(link.getRel())) {
return link.getHref();
}
}
throw new RuntimeException("未找到PayPal批准URL");
} catch (PayPalRESTException e) {
logger.error("PayPal API调用异常", e);
payment.setStatus(PaymentStatus.FAILED);
paymentRepository.save(payment);
throw new RuntimeException("PayPal支付服务异常" + e.getMessage());
}
}
/**
* 执行PayPal支付
*/
public boolean executePayment(String paymentId, String payerId) {
try {
// 创建API上下文
APIContext apiContext = new APIContext(clientId, clientSecret, mode);
// 创建支付执行
PaymentExecution paymentExecution = new PaymentExecution();
paymentExecution.setPayerId(payerId);
// 获取支付信息
com.paypal.api.payments.Payment payment = com.paypal.api.payments.Payment.get(apiContext, paymentId);
// 执行支付
com.paypal.api.payments.Payment executedPayment = payment.execute(apiContext, paymentExecution);
// 查找支付记录
Payment paymentRecord = paymentRepository.findByExternalTransactionId(paymentId)
.orElseThrow(() -> new RuntimeException("支付记录不存在:" + paymentId));
// 更新支付状态
if ("approved".equals(executedPayment.getState())) {
paymentRecord.setStatus(PaymentStatus.SUCCESS);
paymentRecord.setPaidAt(LocalDateTime.now());
logger.info("PayPal支付成功订单号{}", paymentRecord.getOrderId());
} else {
paymentRecord.setStatus(PaymentStatus.FAILED);
logger.warn("PayPal支付失败订单号{},状态:{}",
paymentRecord.getOrderId(), executedPayment.getState());
}
paymentRepository.save(paymentRecord);
return true;
} catch (PayPalRESTException e) {
logger.error("PayPal支付执行异常", e);
return false;
}
}
/**
* 处理PayPal Webhook通知
*/
public boolean handleWebhook(Map<String, String> params) {
try {
String eventType = params.get("event_type");
String resourceType = params.get("resource_type");
logger.info("收到PayPal Webhook通知事件类型{},资源类型:{}", eventType, resourceType);
if ("PAYMENT.SALE.COMPLETED".equals(eventType) && "sale".equals(resourceType)) {
String paymentId = params.get("resource.id");
// 查找支付记录
Payment payment = paymentRepository.findByExternalTransactionId(paymentId)
.orElseThrow(() -> new RuntimeException("支付记录不存在:" + paymentId));
// 更新支付状态
payment.setStatus(PaymentStatus.SUCCESS);
payment.setPaidAt(LocalDateTime.now());
paymentRepository.save(payment);
logger.info("PayPal Webhook处理成功订单号{}", payment.getOrderId());
return true;
}
return false;
} catch (Exception e) {
logger.error("处理PayPal Webhook异常", e);
return false;
}
}
/**
* 生成订单号
*/
private String generateOrderId() {
return "PP" + System.currentTimeMillis() + UUID.randomUUID().toString().substring(0, 8).toUpperCase();
}
}

View File

@@ -38,12 +38,6 @@ alipay.sign-type=RSA2
alipay.notify-url=${ALIPAY_NOTIFY_URL}
alipay.return-url=${ALIPAY_RETURN_URL}
# PayPal配置 (生产环境)
paypal.client-id=${PAYPAL_CLIENT_ID}
paypal.client-secret=${PAYPAL_CLIENT_SECRET}
paypal.mode=live
paypal.return-url=${PAYPAL_RETURN_URL}
paypal.cancel-url=${PAYPAL_CANCEL_URL}
# JWT配置 - 使用环境变量
jwt.secret=${JWT_SECRET}

View File

@@ -28,3 +28,4 @@ CREATE TABLE IF NOT EXISTS task_queue (

View File

@@ -27,3 +27,4 @@ CREATE TABLE IF NOT EXISTS points_freeze_records (

View File

@@ -30,3 +30,4 @@ CREATE TABLE task_status (

View File

@@ -574,5 +574,6 @@

View File

@@ -490,5 +490,6 @@

View File

@@ -529,5 +529,6 @@

View File

@@ -52,15 +52,6 @@
</div>
</div>
</div>
<div class="col-md-6">
<div class="card payment-card h-100" onclick="selectPaymentMethod('PAYPAL')">
<div class="card-body text-center">
<i class="fab fa-paypal payment-icon paypal-icon"></i>
<h5 class="card-title">PayPal</h5>
<p class="card-text">全球领先的在线支付</p>
</div>
</div>
</div>
</div>
<div class="mb-3">
@@ -128,9 +119,6 @@
if (method === 'ALIPAY') {
currencySelect.value = 'CNY';
currencySelect.options[0].selected = true;
} else if (method === 'PAYPAL') {
currencySelect.value = 'USD';
currencySelect.options[1].selected = true;
}
}