From 281cc627de9fc0a3b2fa948e1b42cee62624c0aa Mon Sep 17 00:00:00 2001 From: Patryk Date: Mon, 26 May 2025 20:36:39 +0200 Subject: [PATCH 1/3] add payment notification endpoint --- .../controller/PaymentController.java | 62 +++++++++++++++++++ src/main/resources/application.properties | 3 + 2 files changed, 65 insertions(+) create mode 100644 src/main/java/_11/asktpk/artisanconnectbackend/controller/PaymentController.java diff --git a/src/main/java/_11/asktpk/artisanconnectbackend/controller/PaymentController.java b/src/main/java/_11/asktpk/artisanconnectbackend/controller/PaymentController.java new file mode 100644 index 0000000..7706e5f --- /dev/null +++ b/src/main/java/_11/asktpk/artisanconnectbackend/controller/PaymentController.java @@ -0,0 +1,62 @@ +package _11.asktpk.artisanconnectbackend.controller; + +import org.springframework.beans.factory.annotation.Value; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.util.DigestUtils; +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; + +import java.util.Map; +import java.util.stream.Collectors; + +@RestController +@RequestMapping("/api/v1/payments") +public class PaymentController { + + @Value("${tpay.securityCode}") + private String sellerSecurityCode; + + private static final Logger log = LoggerFactory.getLogger(PaymentController.class); + + @PostMapping(value = "/notification", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) + public ResponseEntity handleTpayNotification(@RequestParam Map params) { + log.info("=== ODEBRANO NOTYFIKACJĘ Tpay ==="); + log.info("Parametry:\n{}", paramsToLogString(params)); + + String id = params.get("id"); + String trId = params.get("tr_id"); + String trAmount = params.get("tr_amount"); + String trCrc = params.get("tr_crc"); + String md5sum = params.get("md5sum"); + String trStatus = params.get("tr_status"); + + String expectedMd5 = DigestUtils.md5DigestAsHex( + (id + trId + trAmount + trCrc + sellerSecurityCode).getBytes() + ); + + if (!expectedMd5.equals(md5sum)) { + log.warn("❌ Błędna suma kontrolna! Otrzymano: {}, Oczekiwano: {}", md5sum, expectedMd5); + return ResponseEntity.status(400).body("INVALID CHECKSUM"); + } + + if ("true".equals(trStatus)) { + log.info("✅ Transakcja opłacona: tr_id={}, kwota={}", trId, params.get("tr_paid")); + } else if ("chargeback".equals(trStatus)) { + log.warn("⚠️ Chargeback: {}", trId); + } + + return ResponseEntity.ok("TRUE"); + } + + private String paramsToLogString(Map params) { + return params.entrySet().stream() + .map(e -> e.getKey() + " = " + e.getValue()) + .collect(Collectors.joining("\n")); + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index ca1826a..ed4cdfd 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -22,4 +22,7 @@ tpay.clientId = 01JQKC048X62ST9V59HNRSXD92-01JQKC2CQHPYXQFSFX8BKC24BX tpay.clientSecret = 44898642be53381cdcc47f3e44bf5a15e592f5d270fc3a6cf6fb81a8b8ebffb9 tpay.authUrl = https://openapi.sandbox.tpay.com/oauth/auth tpay.transactionUrl = https://openapi.sandbox.tpay.com/transactions +tpay.securityCode = )IY7E)YSM!A)Q6O-GN#U7U_33s9qObk8 +logging.file.name=logs/payment-notifications.log +logging.level.TpayLogger=INFO From 12cb37127ba0a2f10dffe1735ac81049efe607ae Mon Sep 17 00:00:00 2001 From: Patryk Date: Mon, 26 May 2025 21:51:24 +0200 Subject: [PATCH 2/3] ad: handling of payment notifications --- .../controller/PaymentController.java | 48 +++++++++++++++++-- .../repository/PaymentRepository.java | 4 +- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/main/java/_11/asktpk/artisanconnectbackend/controller/PaymentController.java b/src/main/java/_11/asktpk/artisanconnectbackend/controller/PaymentController.java index 7706e5f..8449e5c 100644 --- a/src/main/java/_11/asktpk/artisanconnectbackend/controller/PaymentController.java +++ b/src/main/java/_11/asktpk/artisanconnectbackend/controller/PaymentController.java @@ -1,5 +1,10 @@ package _11.asktpk.artisanconnectbackend.controller; +import _11.asktpk.artisanconnectbackend.entities.Notice; +import _11.asktpk.artisanconnectbackend.entities.Order; +import _11.asktpk.artisanconnectbackend.entities.Payment; +import _11.asktpk.artisanconnectbackend.repository.PaymentRepository; +import _11.asktpk.artisanconnectbackend.utils.Enums; import org.springframework.beans.factory.annotation.Value; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -12,7 +17,9 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import java.time.LocalDateTime; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; @RestController @@ -24,6 +31,12 @@ public class PaymentController { private static final Logger log = LoggerFactory.getLogger(PaymentController.class); + private final PaymentRepository paymentRepository; + + public PaymentController(PaymentRepository paymentRepository) { + this.paymentRepository = paymentRepository; + } + @PostMapping(value = "/notification", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) public ResponseEntity handleTpayNotification(@RequestParam Map params) { log.info("=== ODEBRANO NOTYFIKACJĘ Tpay ==="); @@ -45,10 +58,37 @@ public class PaymentController { return ResponseEntity.status(400).body("INVALID CHECKSUM"); } - if ("true".equals(trStatus)) { - log.info("✅ Transakcja opłacona: tr_id={}, kwota={}", trId, params.get("tr_paid")); - } else if ("chargeback".equals(trStatus)) { - log.warn("⚠️ Chargeback: {}", trId); + Optional optionalPayment = paymentRepository.findByTransactionId(trId); + if (optionalPayment.isPresent()) { + Payment payment = optionalPayment.get(); + + if ("true".equalsIgnoreCase(trStatus) || "PAID".equalsIgnoreCase(trStatus)) { + log.info("✅ Transakcja opłacona: tr_id={}, kwota={}", trId, params.get("tr_paid")); + payment.setStatus(Enums.PaymentStatus.CORRECT); + + if (payment.getOrder() != null) { + Order order = payment.getOrder(); + order.setStatus(Enums.OrderStatus.COMPLETED); + Notice notice = order.getNotice(); + if (order.getOrderType() == Enums.OrderType.ACTIVATION) { + notice.setStatus(Enums.Status.ACTIVE); + } else if (order.getOrderType() == Enums.OrderType.BOOST) { + notice.setPublishDate(LocalDateTime.now()); + } + } + + } else if ("false".equalsIgnoreCase(trStatus)) { + log.warn("❌ Transakcja nieudana: {}", trId); + payment.setStatus(Enums.PaymentStatus.INCORRECT); + + if (payment.getOrder() != null) { + payment.getOrder().setStatus(Enums.OrderStatus.CANCELLED); + } + } + + paymentRepository.save(payment); + } else { + log.warn("⚠️ Brak płatności o tr_id={}", trId); } return ResponseEntity.ok("TRUE"); diff --git a/src/main/java/_11/asktpk/artisanconnectbackend/repository/PaymentRepository.java b/src/main/java/_11/asktpk/artisanconnectbackend/repository/PaymentRepository.java index 922dc58..486d80d 100644 --- a/src/main/java/_11/asktpk/artisanconnectbackend/repository/PaymentRepository.java +++ b/src/main/java/_11/asktpk/artisanconnectbackend/repository/PaymentRepository.java @@ -4,7 +4,9 @@ import _11.asktpk.artisanconnectbackend.entities.Payment; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.Optional; + @Repository public interface PaymentRepository extends JpaRepository { - + Optional findByTransactionId(String transactionId); } From 9b64dc8da8e891be8dfaa83d53c7c694626f5579 Mon Sep 17 00:00:00 2001 From: Patryk Date: Mon, 26 May 2025 21:59:26 +0200 Subject: [PATCH 3/3] fix return url --- .../artisanconnectbackend/controller/OrderController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/_11/asktpk/artisanconnectbackend/controller/OrderController.java b/src/main/java/_11/asktpk/artisanconnectbackend/controller/OrderController.java index f557e3b..9bb77d1 100644 --- a/src/main/java/_11/asktpk/artisanconnectbackend/controller/OrderController.java +++ b/src/main/java/_11/asktpk/artisanconnectbackend/controller/OrderController.java @@ -46,6 +46,6 @@ public class OrderController { String response = paymentService.createTransaction(order,authPaymentDTO.getAccess_token(), request); System.out.println(response); - return ResponseEntity.ok(authPaymentDTO.getAccess_token()); + return ResponseEntity.ok(response); } }