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); } } 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..8449e5c --- /dev/null +++ b/src/main/java/_11/asktpk/artisanconnectbackend/controller/PaymentController.java @@ -0,0 +1,102 @@ +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; + +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.time.LocalDateTime; +import java.util.Map; +import java.util.Optional; +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); + + 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 ==="); + 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"); + } + + 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"); + } + + private String paramsToLogString(Map params) { + return params.entrySet().stream() + .map(e -> e.getKey() + " = " + e.getValue()) + .collect(Collectors.joining("\n")); + } +} 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); } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 4f7ea0c..e4e02c7 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -22,8 +22,11 @@ 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 #jwt settings jwt.secret=DIXLsOs3FKmCAQwISd0SKsHMXJrPl3IKIRkVlkOvYW7kEcdUTbxh8zFe1B3eZWkY jwt.expiration=300000 +logging.file.name=logs/payment-notifications.log +logging.level.TpayLogger=INFO