LinePayGatewayAuditService.java 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. package com.ruoyi.app.pay;
  2. import com.alibaba.fastjson2.JSON;
  3. import com.alibaba.fastjson2.JSONObject;
  4. import com.ruoyi.system.domain.PaymentGatewayLog;
  5. import com.ruoyi.system.service.IPaymentGatewayLogService;
  6. import com.ruoyi.app.utils.linepay.LinePayResponse;
  7. import org.springframework.stereotype.Service;
  8. import java.util.UUID;
  9. /** Appends LINE gateway audit rows without making audit availability part of money facts. */
  10. @Service
  11. public class LinePayGatewayAuditService {
  12. private final IPaymentGatewayLogService gatewayLogService;
  13. public LinePayGatewayAuditService(IPaymentGatewayLogService gatewayLogService) {
  14. this.gatewayLogService = gatewayLogService;
  15. }
  16. public <T> T execute(String action, String source, Long paymentId, Long refundId,
  17. Long credentialId, Long storeId, String ddId,
  18. String gatewayOrderId, String transactionId,
  19. GatewayCall<T> call) throws Exception {
  20. long started = System.currentTimeMillis();
  21. String correlationId = UUID.randomUUID().toString();
  22. append(correlationId, action, source, paymentId, refundId, credentialId,
  23. storeId, ddId, gatewayOrderId, transactionId, 0, 0L, null, "REQUEST");
  24. try {
  25. T result = call.call();
  26. append(correlationId, action, source, paymentId, refundId, credentialId,
  27. storeId, ddId, gatewayOrderId, transactionId, 1,
  28. System.currentTimeMillis() - started,
  29. result instanceof LinePayResponse ? (LinePayResponse) result : null, "RESPONSE");
  30. return result;
  31. } catch (Exception exception) {
  32. append(correlationId, action, source, paymentId, refundId, credentialId,
  33. storeId, ddId, gatewayOrderId, transactionId, 0,
  34. System.currentTimeMillis() - started, null, "RESPONSE");
  35. throw exception;
  36. }
  37. }
  38. public void event(String action, String source, Long paymentId, Long credentialId,
  39. Long storeId, String ddId, String gatewayOrderId, String transactionId) {
  40. append(UUID.randomUUID().toString(), action, source, paymentId, null, credentialId,
  41. storeId, ddId, gatewayOrderId, transactionId, 1, 0L, null, "EVENT");
  42. }
  43. private void append(String correlationId, String action, String source,
  44. Long paymentId, Long refundId, Long credentialId, Long storeId,
  45. String ddId, String gatewayOrderId, String transactionId,
  46. int success, long durationMs, LinePayResponse response, String direction) {
  47. PaymentGatewayLog log = new PaymentGatewayLog();
  48. log.setCorrelationId(correlationId);
  49. log.setAction(action);
  50. log.setDirection(direction);
  51. log.setSource(source);
  52. log.setPaymentId(paymentId);
  53. log.setRefundId(refundId);
  54. log.setCredentialId(credentialId);
  55. log.setStoreId(storeId);
  56. log.setDdId(ddId);
  57. log.setGatewayOrderId(gatewayOrderId);
  58. log.setTransactionId(response != null && response.transactionId() != null
  59. ? response.transactionId() : transactionId);
  60. log.setHttpStatus(response == null ? null : response.httpStatus());
  61. log.setReturnCode(response == null ? null : response.returnCode());
  62. log.setReturnMessage(response == null ? null : response.returnMessage());
  63. log.setPayload(response == null ? null : safePayload(response.rawBody()));
  64. log.setSuccess(response == null ? success : response.isSuccess() ? 1 : 0);
  65. log.setDurationMs(durationMs);
  66. try {
  67. gatewayLogService.append(log);
  68. } catch (Exception ignored) {
  69. // Audit failure must not alter an already known gateway or payment outcome.
  70. }
  71. }
  72. private static String safePayload(String rawBody) {
  73. if (rawBody == null || rawBody.isBlank()) {
  74. return rawBody;
  75. }
  76. try {
  77. JSONObject root = JSON.parseObject(rawBody);
  78. JSONObject info = root.getJSONObject("info");
  79. if (info != null) {
  80. info.remove("paymentAccessToken");
  81. JSONObject paymentUrl = info.getJSONObject("paymentUrl");
  82. if (paymentUrl != null) {
  83. paymentUrl.remove("app");
  84. paymentUrl.remove("web");
  85. }
  86. }
  87. return root.toJSONString();
  88. } catch (RuntimeException ignored) {
  89. return null;
  90. }
  91. }
  92. @FunctionalInterface
  93. public interface GatewayCall<T> {
  94. T call() throws Exception;
  95. }
  96. }