diff --git a/payment-service/pom.xml b/payment-service/pom.xml index 9e8f1a4..4654ce9 100644 --- a/payment-service/pom.xml +++ b/payment-service/pom.xml @@ -70,11 +70,6 @@ runtime true - - org.postgresql - postgresql - runtime - org.projectlombok lombok @@ -86,10 +81,8 @@ test - com.github.docker-java - docker-java-api - 3.4.0 - compile + org.springframework.boot + spring-boot-starter-data-jpa org.springframework.security diff --git a/payment-service/src/main/java/com/finpay/payment_service/config/MpesaConfig.java b/payment-service/src/main/java/com/finpay/payment_service/config/MpesaConfig.java deleted file mode 100644 index 07d1292..0000000 --- a/payment-service/src/main/java/com/finpay/payment_service/config/MpesaConfig.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.finpay.payment_service.config; - -import lombok.Data; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; - -@Configuration -@ConfigurationProperties(prefix = "mpesa") -@Data -public class MpesaConfig { - - private String consumerKey; - private String consumerSecret; - private String passkey; - private String businessShortCode; - private String initiatorName; - private String initiatorPassword; - private String callbackUrl; - private String registerUrl; - -} diff --git a/payment-service/src/main/java/com/finpay/payment_service/config/SecurityConfig.java b/payment-service/src/main/java/com/finpay/payment_service/config/SecurityConfig.java deleted file mode 100644 index a253d66..0000000 --- a/payment-service/src/main/java/com/finpay/payment_service/config/SecurityConfig.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.finpay.payment_service.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; -import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; -import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter; -import org.springframework.security.web.SecurityFilterChain; - -@Configuration -@EnableMethodSecurity(prePostEnabled = true) -public class SecurityConfig { - - @Bean - public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { - http - .csrf(AbstractHttpConfigurer::disable) - .authorizeHttpRequests(auth -> auth - .requestMatchers("/api/payments/initiate").hasAnyRole("USER", "ADMIN") - .requestMatchers("/api/payments/refund").hasAnyRole("USER", "ADMIN") - .requestMatchers("/api/payments/**").authenticated() - .anyRequest().permitAll() - ) - .oauth2ResourceServer(oauth2 -> oauth2 - .jwt(jwt -> jwt - .jwtAuthenticationConverter(jwtAuthenticationConverter()) - ) - ); - - return http.build(); - } - - private JwtAuthenticationConverter jwtAuthenticationConverter() { - JwtGrantedAuthoritiesConverter grantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter(); - grantedAuthoritiesConverter.setAuthoritiesClaimName("roles"); // Ensure this matches your JWT - grantedAuthoritiesConverter.setAuthorityPrefix("ROLE_"); - - JwtAuthenticationConverter authenticationConverter = new JwtAuthenticationConverter(); - authenticationConverter.setJwtGrantedAuthoritiesConverter(grantedAuthoritiesConverter); - return authenticationConverter; - } -} diff --git a/payment-service/src/main/java/com/finpay/payment_service/dtos/CardPaymentRequest.java b/payment-service/src/main/java/com/finpay/payment_service/dtos/CardPaymentRequest.java deleted file mode 100644 index 6fd7e16..0000000 --- a/payment-service/src/main/java/com/finpay/payment_service/dtos/CardPaymentRequest.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.finpay.payment_service.dtos; -import lombok.Data; -//import jakarta.validation.constraints.NotBlank; -//import jakarta.validation.constraints.Pattern; -@Data -public class CardPaymentRequest { - -// @NotBlank(message = "Card number is required") -// @Pattern(regexp = "^[0-9]{13,19}$", message = "Invalid card number") - - private String cardNumber; - -// @NotBlank(message = "Expiry month is required") -// @Pattern(regexp = "^(0[1-9]|1[0-2])$", message = "Invalid expiry month") - private String expiryMonth; - -// @NotBlank(message = "Expiry year is required") -// @Pattern(regexp = "^[0-9]{2}$", message = "Invalid expiry year") - private String expiryYear; - -// @NotBlank(message = "CVV is required") -// @Pattern(regexp = "^[0-9]{3,4}$", message = "Invalid CVV") - private String cvv; - -// @NotBlank(message = "Cardholder name is required") - private String cardHolderName; - -// @NotBlank(message = "Billing address is required") - private String billingAddress; - -} diff --git a/payment-service/src/main/java/com/finpay/payment_service/dtos/ErrorResponse.java b/payment-service/src/main/java/com/finpay/payment_service/dtos/ErrorResponse.java deleted file mode 100644 index 424d71e..0000000 --- a/payment-service/src/main/java/com/finpay/payment_service/dtos/ErrorResponse.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.finpay.payment_service.dtos; - -import lombok.AllArgsConstructor; -import lombok.Data; - -import java.time.LocalDateTime; -import java.util.UUID; - -@Data -@AllArgsConstructor -public class ErrorResponse { - private UUID errorId; - private LocalDateTime timestamp; - private int status; - private String error; - private String message; -} diff --git a/payment-service/src/main/java/com/finpay/payment_service/dtos/InvoiceResponse.java b/payment-service/src/main/java/com/finpay/payment_service/dtos/InvoiceResponse.java deleted file mode 100644 index 2a31be2..0000000 --- a/payment-service/src/main/java/com/finpay/payment_service/dtos/InvoiceResponse.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.finpay.payment_service.dtos; - -import lombok.Data; - -import java.math.BigDecimal; -import java.util.UUID; - -@Data -public class InvoiceResponse { - private UUID id; - private UUID userId; - private BigDecimal totalAmount; - private String currency; - private String status; - // Add other relevant fields as necessary -} diff --git a/payment-service/src/main/java/com/finpay/payment_service/dtos/PaymentGatewayResponse.java b/payment-service/src/main/java/com/finpay/payment_service/dtos/PaymentGatewayResponse.java deleted file mode 100644 index 5af1a5c..0000000 --- a/payment-service/src/main/java/com/finpay/payment_service/dtos/PaymentGatewayResponse.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.finpay.payment_service.dtos; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class PaymentGatewayResponse { - /** - * Status of the payment operation. - * Possible values: SUCCESS, FAILURE - */ - private String status; - - /** - * Message providing additional information about the payment operation. - */ - private String message; - - /** - * Unique identifier for the payment, provided by the payment gateway. - * Example: A transaction ID or reference number. - */ - private String paymentId; - - /** - * Additional details or metadata about the payment (optional). - */ - private String additionalDetails; -} diff --git a/payment-service/src/main/java/com/finpay/payment_service/dtos/PaymentRequest.java b/payment-service/src/main/java/com/finpay/payment_service/dtos/PaymentRequest.java deleted file mode 100644 index 5c03ebe..0000000 --- a/payment-service/src/main/java/com/finpay/payment_service/dtos/PaymentRequest.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.finpay.payment_service.dtos; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.math.BigDecimal; -import java.util.UUID; - -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor -public class PaymentRequest { - private BigDecimal amount; - private String currency; - private String paymentMethod; - private UUID invoiceId; - private String paymentGateway; -} diff --git a/payment-service/src/main/java/com/finpay/payment_service/dtos/PaymentResponse.java b/payment-service/src/main/java/com/finpay/payment_service/dtos/PaymentResponse.java deleted file mode 100644 index 0a82e94..0000000 --- a/payment-service/src/main/java/com/finpay/payment_service/dtos/PaymentResponse.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.finpay.payment_service.dtos; - -import com.finpay.payment_service.models.PaymentStatus; -import lombok.AllArgsConstructor; -import lombok.Data; - -import java.math.BigDecimal; -import java.util.UUID; - -@Data -@AllArgsConstructor -public class PaymentResponse { - private UUID id; - private String paymentReference; - private BigDecimal amount; - private String currency; - private PaymentStatus status; - private UUID invoiceId; - private String paymentGateway; - private String message; -} diff --git a/payment-service/src/main/java/com/finpay/payment_service/dtos/RefundGatewayResponse.java b/payment-service/src/main/java/com/finpay/payment_service/dtos/RefundGatewayResponse.java deleted file mode 100644 index 3bb3a7b..0000000 --- a/payment-service/src/main/java/com/finpay/payment_service/dtos/RefundGatewayResponse.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.finpay.payment_service.dtos; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class RefundGatewayResponse { - /** - * Status of the refund operation. - * Possible values: SUCCESS, FAILURE - */ - private String status; - - /** - * Message providing additional information about the refund operation. - */ - private String message; - - /** - * Unique identifier for the refund, provided by the payment gateway. - * Example: A refund transaction ID or reference number. - */ - private String refundId; - - /** - * Additional details or metadata about the refund (optional). - */ - private String additionalDetails; -} diff --git a/payment-service/src/main/java/com/finpay/payment_service/dtos/RefundRequest.java b/payment-service/src/main/java/com/finpay/payment_service/dtos/RefundRequest.java deleted file mode 100644 index 607c5d9..0000000 --- a/payment-service/src/main/java/com/finpay/payment_service/dtos/RefundRequest.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.finpay.payment_service.dtos; - -import lombok.Data; - -import java.math.BigDecimal; -import java.util.UUID; - -@Data -public class RefundRequest { - private UUID paymentId; - private BigDecimal amount; - private String reason; -} diff --git a/payment-service/src/main/java/com/finpay/payment_service/dtos/RefundResponse.java b/payment-service/src/main/java/com/finpay/payment_service/dtos/RefundResponse.java deleted file mode 100644 index dad76b8..0000000 --- a/payment-service/src/main/java/com/finpay/payment_service/dtos/RefundResponse.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.finpay.payment_service.dtos; - -import com.finpay.payment_service.models.RefundStatus; -import lombok.AllArgsConstructor; -import lombok.Data; - -import java.math.BigDecimal; -import java.time.LocalDateTime; -import java.util.UUID; - -@Data -@AllArgsConstructor -public class RefundResponse { - private UUID id; - private String refundReference; - private RefundStatus status; - private BigDecimal amount; - private String reason; - private LocalDateTime createdAt; -} diff --git a/payment-service/src/main/java/com/finpay/payment_service/dtos/TransactionRequest.java b/payment-service/src/main/java/com/finpay/payment_service/dtos/TransactionRequest.java deleted file mode 100644 index 813c516..0000000 --- a/payment-service/src/main/java/com/finpay/payment_service/dtos/TransactionRequest.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.finpay.payment_service.dtos; - -import lombok.Data; - -import java.math.BigDecimal; - -@Data -public class TransactionRequest { - private String transactionType; - private BigDecimal amount; -} diff --git a/payment-service/src/main/java/com/finpay/payment_service/dtos/TransactionResponse.java b/payment-service/src/main/java/com/finpay/payment_service/dtos/TransactionResponse.java deleted file mode 100644 index b9b0558..0000000 --- a/payment-service/src/main/java/com/finpay/payment_service/dtos/TransactionResponse.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.finpay.payment_service.dtos; - -import com.finpay.payment_service.models.TransactionStatus; -import com.finpay.payment_service.models.TransactionType; -import lombok.AllArgsConstructor; -import lombok.Data; - -import java.math.BigDecimal; -import java.time.LocalDateTime; -import java.util.UUID; - -@Data -@AllArgsConstructor -public class TransactionResponse { - private UUID id; - private String transactionReference; - private TransactionType type; - private TransactionStatus status; - private BigDecimal amount; - private LocalDateTime createdAt; -} diff --git a/payment-service/src/main/java/com/finpay/payment_service/exceptions/GlobalExceptionHandler.java b/payment-service/src/main/java/com/finpay/payment_service/exceptions/GlobalExceptionHandler.java deleted file mode 100644 index b903052..0000000 --- a/payment-service/src/main/java/com/finpay/payment_service/exceptions/GlobalExceptionHandler.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.finpay.payment_service.exceptions; -import com.finpay.payment_service.dtos.ErrorResponse; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - -import java.time.LocalDateTime; -import java.util.UUID; - -@ControllerAdvice -public class GlobalExceptionHandler { - - @ExceptionHandler(IllegalArgumentException.class) - public ResponseEntity handleBadRequest(Exception ex) { - ErrorResponse error = new ErrorResponse( - UUID.randomUUID(), - LocalDateTime.now(), - HttpStatus.BAD_REQUEST.value(), - "Bad Request", - ex.getMessage() - ); - return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST); - } - - @ExceptionHandler(IllegalStateException.class) - public ResponseEntity handleConflict(Exception ex) { - ErrorResponse error = new ErrorResponse( - UUID.randomUUID(), - LocalDateTime.now(), - HttpStatus.CONFLICT.value(), - "Conflict", - ex.getMessage() - ); - return new ResponseEntity<>(error, HttpStatus.CONFLICT); - } - - @ExceptionHandler(Exception.class) - public ResponseEntity handleInternalServerError(Exception ex) { - ErrorResponse error = new ErrorResponse( - UUID.randomUUID(), - LocalDateTime.now(), - HttpStatus.INTERNAL_SERVER_ERROR.value(), - "Internal Server Error", - "An unexpected error occurred." - ); - return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR); - } -} diff --git a/payment-service/src/main/java/com/finpay/payment_service/gateways/PaymentGateway.java b/payment-service/src/main/java/com/finpay/payment_service/gateways/PaymentGateway.java deleted file mode 100644 index 82fb05c..0000000 --- a/payment-service/src/main/java/com/finpay/payment_service/gateways/PaymentGateway.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.finpay.payment_service.gateways; - -import com.finpay.payment_service.dtos.PaymentRequest; -import com.finpay.payment_service.dtos.PaymentGatewayResponse; -import com.finpay.payment_service.dtos.RefundRequest; -import com.finpay.payment_service.dtos.RefundGatewayResponse; - -public interface PaymentGateway { - - /** - * Processes a payment through the specific gateway. - * - * @param paymentRequest The payment details. - * @return The response from the payment gateway. - */ - PaymentGatewayResponse processPayment(PaymentRequest paymentRequest); - - /** - * Processes a refund through the specific gateway. - * - * @param refundRequest The refund details. - * @return The response from the refund gateway. - */ - RefundGatewayResponse processRefund(RefundRequest refundRequest); -} diff --git a/payment-service/src/main/java/com/finpay/payment_service/gateways/mpesa/MpesaPaymentGateway.java b/payment-service/src/main/java/com/finpay/payment_service/gateways/mpesa/MpesaPaymentGateway.java deleted file mode 100644 index 87a033f..0000000 --- a/payment-service/src/main/java/com/finpay/payment_service/gateways/mpesa/MpesaPaymentGateway.java +++ /dev/null @@ -1,165 +0,0 @@ -package com.finpay.payment_service.gateways.mpesa; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.finpay.payment_service.dtos.PaymentGatewayResponse; -import com.finpay.payment_service.dtos.RefundGatewayResponse; -import com.finpay.payment_service.gateways.PaymentGateway; -import com.finpay.payment_service.config.MpesaConfig; -import com.finpay.payment_service.model.MpesaTransaction; -import com.finpay.payment_service.repository.MpesaTransactionRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.http.*; -import org.springframework.stereotype.Component; -import org.springframework.web.client.RestTemplate; - -import java.time.LocalDateTime; -import java.util.Base64; - -@Component -@RequiredArgsConstructor -public class MpesaPaymentGateway implements PaymentGateway { - - private final MpesaConfig mpesaConfig; - private final RestTemplate restTemplate; - private final ObjectMapper objectMapper; - private final MpesaTransactionRepository mpesaTransactionRepository; - - /** - * Processes a payment through M-Pesa STK-PUSH. - * - * @param paymentRequest The payment details. - * @return The response from M-Pesa. - */ - @Override - public PaymentGatewayResponse processPayment(com.finpay.payment_service.dtos.PaymentRequest paymentRequest) { - PaymentGatewayResponse response = new PaymentGatewayResponse(); - - try { - String accessToken = getAccessToken(); - - String url = "https://sandbox.safaricom.co.ke/mpesa/stkpush/v1/processrequest"; - - String timestamp = LocalDateTime.now().format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMddHHmmss")); - String password = Base64.getEncoder().encodeToString( - (mpesaConfig.getBusinessShortCode() + mpesaConfig.getPasskey() + timestamp).getBytes() - ); - - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - headers.setBearerAuth(accessToken); - - JsonNode payload = objectMapper.createObjectNode() - .put("BusinessShortCode", mpesaConfig.getBusinessShortCode()) - .put("Password", password) - .put("Timestamp", timestamp) - .put("TransactionType", "CustomerPayBillOnline") - .put("Amount", paymentRequest.getAmount()) - .put("PartyA", paymentRequest.getPhoneNumber()) - .put("PartyB", mpesaConfig.getBusinessShortCode()) - .put("PhoneNumber", paymentRequest.getPhoneNumber()) - .put("CallBackURL", mpesaConfig.getCallbackUrl()) - .put("AccountReference", paymentRequest.getAccountReference()) - .put("TransactionDesc", paymentRequest.getTransactionDesc()); - - HttpEntity entity = new HttpEntity<>(objectMapper.writeValueAsString(payload), headers); - - ResponseEntity apiResponse = restTemplate.exchange(url, HttpMethod.POST, entity, String.class); - - if (apiResponse.getStatusCode() == HttpStatus.OK) { - JsonNode responseBody = objectMapper.readTree(apiResponse.getBody()); - - String merchantRequestID = responseBody.get("MerchantRequestID").asText(); - String checkoutRequestID = responseBody.get("CheckoutRequestID").asText(); - String responseCode = responseBody.get("ResponseCode").asText(); - String responseDescription = responseBody.get("ResponseDescription").asText(); - String customerMessage = responseBody.get("CustomerMessage").asText(); - - // Save transaction details - MpesaTransaction transaction = MpesaTransaction.builder() - .merchantRequestID(merchantRequestID) - .checkoutRequestID(checkoutRequestID) - .amount(paymentRequest.getAmount()) - .phoneNumber(paymentRequest.getPhoneNumber()) - .status("PENDING") - .createdAt(LocalDateTime.now()) - .build(); - - mpesaTransactionRepository.save(transaction); - - response.setStatus("SUCCESS"); - response.setMessage("STK-PUSH initiated successfully."); - response.setPaymentReference(checkoutRequestID); - } else { - response.setStatus("FAILURE"); - response.setMessage("Failed to initiate STK-PUSH."); - } - } catch (Exception e) { - response.setStatus("FAILURE"); - response.setMessage("Error processing M-Pesa payment: " + e.getMessage()); - // Optionally, log the error using a logger - } - - return response; - } - - /** - * Processes a refund through M-Pesa. - * - * @param refundRequest The refund details. - * @return The response from M-Pesa. - */ - @Override - public RefundGatewayResponse processRefund(com.finpay.payment_service.dtos.RefundRequest refundRequest) { - RefundGatewayResponse response = new RefundGatewayResponse(); - - // Implement refund logic if M-Pesa supports it. Currently, M-Pesa's C2B API does not support refunds. - // This is a placeholder for future implementation. - - response.setStatus("FAILED"); - response.setMessage("Refunds are not supported through M-Pesa STK-PUSH."); - return response; - } - - /** - * Retrieves the current access token, fetching a new one if necessary. - * - * @return The access token. - */ - private String getAccessToken() { - // Implement caching logic with Redis or similar if desired - String accessToken = fetchAccessToken(); - return accessToken; - } - - /** - * Fetches a new access token from M-Pesa. - * - * @return The new access token. - */ - private String fetchAccessToken() { - try { - String url = "https://sandbox.safaricom.co.ke/oauth/v1/generate?grant_type=client_credentials"; - - String credentials = mpesaConfig.getConsumerKey() + ":" + mpesaConfig.getConsumerSecret(); - String encodedCredentials = Base64.getEncoder().encodeToString(credentials.getBytes()); - - HttpHeaders headers = new HttpHeaders(); - headers.set("Authorization", "Basic " + encodedCredentials); - headers.setContentType(MediaType.APPLICATION_JSON); - - HttpEntity entity = new HttpEntity<>(null, headers); - - ResponseEntity response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class); - - if (response.getStatusCode() == HttpStatus.OK) { - JsonNode node = objectMapper.readTree(response.getBody()); - return node.get("access_token").asText(); - } else { - throw new RuntimeException("Failed to fetch access token from M-Pesa"); - } - } catch (Exception e) { - throw new RuntimeException("Error fetching access token: " + e.getMessage(), e); - } - } -} diff --git a/payment-service/src/main/java/com/finpay/payment_service/models/Payment.java b/payment-service/src/main/java/com/finpay/payment_service/models/Payment.java index def3021..1fe0e72 100644 --- a/payment-service/src/main/java/com/finpay/payment_service/models/Payment.java +++ b/payment-service/src/main/java/com/finpay/payment_service/models/Payment.java @@ -1,12 +1,7 @@ package com.finpay.payment_service.models; -import jakarta.persistence.*; import lombok.*; -import org.hibernate.annotations.CreationTimestamp; -import org.hibernate.annotations.UpdateTimestamp; - import java.math.BigDecimal; -import java.time.LocalDateTime; import java.util.Set; import java.util.UUID; @@ -23,7 +18,7 @@ public class Payment { private UUID id; @Column(nullable = false, unique = true) - private String paymentReference; // Unique reference for the payment + private String paymentReference; @Column(nullable = false) private BigDecimal amount; @@ -35,11 +30,13 @@ public class Payment { @Column(nullable = false) private PaymentStatus status; - @Column(nullable = false) - private UUID invoiceId; // Reference to Invoice managed by Invoice Service + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "payment_method_id") + private PaymentMethod paymentMethod; - @Column(nullable = false) - private String paymentGateway; // e.g., Stripe, PayPal + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "payment_gateway_id") + private PaymentGateway paymentGateway; @OneToMany(mappedBy = "payment", cascade = CascadeType.ALL, orphanRemoval = true) private Set transactions; @@ -47,10 +44,8 @@ public class Payment { @OneToMany(mappedBy = "payment", cascade = CascadeType.ALL, orphanRemoval = true) private Set refunds; - @CreationTimestamp - @Column(nullable = false, updatable = false) + @Column(nullable = false) private LocalDateTime createdAt; - @UpdateTimestamp private LocalDateTime updatedAt; } diff --git a/payment-service/src/main/java/com/finpay/payment_service/models/PaymentGateway.java b/payment-service/src/main/java/com/finpay/payment_service/models/PaymentGateway.java index 5a5f3d5..774a153 100644 --- a/payment-service/src/main/java/com/finpay/payment_service/models/PaymentGateway.java +++ b/payment-service/src/main/java/com/finpay/payment_service/models/PaymentGateway.java @@ -1,6 +1,5 @@ package com.finpay.payment_service.models; -import jakarta.persistence.*; import lombok.*; import java.util.Set; import java.util.UUID; diff --git a/payment-service/src/main/java/com/finpay/payment_service/models/PaymentMethod.java b/payment-service/src/main/java/com/finpay/payment_service/models/PaymentMethod.java index 71f8894..3c8324a 100644 --- a/payment-service/src/main/java/com/finpay/payment_service/models/PaymentMethod.java +++ b/payment-service/src/main/java/com/finpay/payment_service/models/PaymentMethod.java @@ -1,6 +1,5 @@ package com.finpay.payment_service.models; -import jakarta.persistence.*; import lombok.*; import java.util.Set; import java.util.UUID; diff --git a/payment-service/src/main/java/com/finpay/payment_service/models/Refund.java b/payment-service/src/main/java/com/finpay/payment_service/models/Refund.java index fec4839..de23413 100644 --- a/payment-service/src/main/java/com/finpay/payment_service/models/Refund.java +++ b/payment-service/src/main/java/com/finpay/payment_service/models/Refund.java @@ -1,6 +1,5 @@ package com.finpay.payment_service.models; -import jakarta.persistence.*; import lombok.*; import java.math.BigDecimal; import java.time.LocalDateTime; diff --git a/payment-service/src/main/java/com/finpay/payment_service/models/Transaction.java b/payment-service/src/main/java/com/finpay/payment_service/models/Transaction.java index 4e1509a..31aabfd 100644 --- a/payment-service/src/main/java/com/finpay/payment_service/models/Transaction.java +++ b/payment-service/src/main/java/com/finpay/payment_service/models/Transaction.java @@ -4,7 +4,6 @@ import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.UUID; -import jakarta.persistence.*; @Entity @Table(name = "transactions") diff --git a/payment-service/src/main/java/com/finpay/payment_service/repository/PaymentGatewayRepository.java b/payment-service/src/main/java/com/finpay/payment_service/repository/PaymentGatewayRepository.java deleted file mode 100644 index d190941..0000000 --- a/payment-service/src/main/java/com/finpay/payment_service/repository/PaymentGatewayRepository.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.finpay.payment_service.repository; - -import com.finpay.payment_service.models.PaymentGateway; -import org.springframework.data.jpa.repository.JpaRepository; -import java.util.Optional; -import java.util.UUID; - -public interface PaymentGatewayRepository extends JpaRepository { - Optional findByName(String name); -} diff --git a/payment-service/src/main/java/com/finpay/payment_service/repository/PaymentMethodRepository.java b/payment-service/src/main/java/com/finpay/payment_service/repository/PaymentMethodRepository.java deleted file mode 100644 index ae2b4b9..0000000 --- a/payment-service/src/main/java/com/finpay/payment_service/repository/PaymentMethodRepository.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.finpay.payment_service.repository; - -import com.finpay.payment_service.models.PaymentMethod; -import org.springframework.data.jpa.repository.JpaRepository; -import java.util.Optional; -import java.util.UUID; - -public interface PaymentMethodRepository extends JpaRepository { - Optional findByType(String type); -} diff --git a/payment-service/src/main/java/com/finpay/payment_service/repository/PaymentRepository.java b/payment-service/src/main/java/com/finpay/payment_service/repository/PaymentRepository.java deleted file mode 100644 index 1dbf0fb..0000000 --- a/payment-service/src/main/java/com/finpay/payment_service/repository/PaymentRepository.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.finpay.payment_service.repository; - -import com.finpay.payment_service.models.Payment; -import org.springframework.data.jpa.repository.JpaRepository; -import java.util.Optional; -import java.util.UUID; - -public interface PaymentRepository extends JpaRepository { - Optional findByPaymentReference(String paymentReference); -} diff --git a/payment-service/src/main/java/com/finpay/payment_service/repository/RefundRepository.java b/payment-service/src/main/java/com/finpay/payment_service/repository/RefundRepository.java deleted file mode 100644 index 35938fa..0000000 --- a/payment-service/src/main/java/com/finpay/payment_service/repository/RefundRepository.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.finpay.payment_service.repository; - -import com.finpay.payment_service.models.Refund; -import org.springframework.data.jpa.repository.JpaRepository; -import java.util.Optional; -import java.util.UUID; - -public interface RefundRepository extends JpaRepository { - Optional findByRefundReference(String refundReference); -} diff --git a/payment-service/src/main/java/com/finpay/payment_service/repository/TransactionRepository.java b/payment-service/src/main/java/com/finpay/payment_service/repository/TransactionRepository.java deleted file mode 100644 index 30b864f..0000000 --- a/payment-service/src/main/java/com/finpay/payment_service/repository/TransactionRepository.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.finpay.payment_service.repository; - -import com.finpay.payment_service.models.Transaction; -import org.springframework.data.jpa.repository.JpaRepository; -import java.util.Optional; -import java.util.UUID; - -public interface TransactionRepository extends JpaRepository { - Optional findByTransactionReference(String transactionReference); -} diff --git a/payment-service/src/main/java/com/finpay/payment_service/services/PaymentService.java b/payment-service/src/main/java/com/finpay/payment_service/services/PaymentService.java deleted file mode 100644 index 4e13a1a..0000000 --- a/payment-service/src/main/java/com/finpay/payment_service/services/PaymentService.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.finpay.payment_service.services; - -import com.finpay.payment_service.dtos.PaymentRequest; -import com.finpay.payment_service.dtos.PaymentResponse; -import com.finpay.payment_service.dtos.RefundRequest; -import com.finpay.payment_service.dtos.RefundResponse; - -import java.util.Optional; -public interface PaymentService { - PaymentResponse initiatePayment(PaymentRequest paymentRequest); - Optional getPaymentByReference(String paymentReference); - RefundResponse processRefund(RefundRequest refundRequest); - -} diff --git a/payment-service/src/main/java/com/finpay/payment_service/services/PaymentServiceImpl.java b/payment-service/src/main/java/com/finpay/payment_service/services/PaymentServiceImpl.java deleted file mode 100644 index bd23b3f..0000000 --- a/payment-service/src/main/java/com/finpay/payment_service/services/PaymentServiceImpl.java +++ /dev/null @@ -1,162 +0,0 @@ -package com.finpay.payment_service.services; - -import com.finpay.payment_service.dtos.*; -import com.finpay.payment_service.gateways.PaymentGateway; -import com.finpay.payment_service.gateways.PaymentGatewayFactory; -import com.finpay.payment_service.models.Payment; -import com.finpay.payment_service.models.PaymentStatus; -import com.finpay.payment_service.models.Refund; -import com.finpay.payment_service.models.RefundStatus; -import com.finpay.payment_service.repository.PaymentRepository; -import com.finpay.payment_service.repository.RefundRepository; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.time.LocalDateTime; -import java.util.Optional; -import java.util.UUID; - -@Service -public class PaymentServiceImpl implements PaymentService { - - private final PaymentRepository paymentRepository; - private final RefundRepository refundRepository; - //private final InvoiceServiceClient invoiceServiceClient; - private final PaymentGatewayFactory paymentGatewayFactory; - - public PaymentServiceImpl(PaymentRepository paymentRepository, - RefundRepository refundRepository, -// InvoiceServiceClient invoiceServiceClient, - PaymentGatewayFactory paymentGatewayFactory) { - this.paymentRepository = paymentRepository; - this.refundRepository = refundRepository; -// this.invoiceServiceClient = invoiceServiceClient; - this.paymentGatewayFactory = paymentGatewayFactory; - } - - @Override - @Transactional - public PaymentResponse initiatePayment(PaymentRequest paymentRequest) { - // Validate Invoice -// InvoiceResponse invoice = invoiceServiceClient.getInvoiceById(paymentRequest.getInvoiceId()); -// if (invoice == null || !"PAID".equalsIgnoreCase(invoice.getStatus())) { -// throw new IllegalArgumentException("Invalid or unpaid invoice."); -// } - - // Create Payment entity - Payment payment = Payment.builder() - .paymentReference(UUID.randomUUID().toString()) - .amount(paymentRequest.getAmount()) - .currency(paymentRequest.getCurrency()) - .status(PaymentStatus.PENDING) - .invoiceId(paymentRequest.getInvoiceId()) - .paymentGateway(paymentRequest.getPaymentGateway()) - .createdAt(LocalDateTime.now()) - .build(); - - // Save Payment - paymentRepository.save(payment); - - // Get the appropriate PaymentGateway - PaymentGateway gateway = paymentGatewayFactory.getPaymentGateway(paymentRequest); - - // Process Payment via Gateway - PaymentGatewayResponse gatewayResponse = gateway.processPayment(paymentRequest); - - // Update Payment Status based on Gateway Response - if ("SUCCESS".equalsIgnoreCase(gatewayResponse.getStatus())) { - payment.setStatus(PaymentStatus.COMPLETED); - } else { - payment.setStatus(PaymentStatus.FAILED); - } - payment.setUpdatedAt(LocalDateTime.now()); - paymentRepository.save(payment); - - // Return Response - return new PaymentResponse( - payment.getId(), - payment.getPaymentReference(), - payment.getAmount(), - payment.getCurrency(), - payment.getStatus(), - payment.getInvoiceId(), - payment.getPaymentGateway(), - gatewayResponse.getMessage() - ); - } - - @Override - public Optional getPaymentByReference(String paymentReference) { - return paymentRepository.findByPaymentReference(paymentReference) - .map(payment -> new PaymentResponse( - payment.getId(), - payment.getPaymentReference(), - payment.getAmount(), - payment.getCurrency(), - payment.getStatus(), - payment.getInvoiceId(), - payment.getPaymentGateway(), - "Payment retrieved successfully." - )); - } - - @Override - @Transactional - public RefundResponse processRefund(RefundRequest refundRequest) { - // Validate Payment - Optional paymentOpt = paymentRepository.findById(refundRequest.getPaymentId()); - if (paymentOpt.isEmpty()) { - throw new IllegalArgumentException("Payment not found."); - } - - Payment payment = paymentOpt.get(); - if (payment.getStatus() != PaymentStatus.COMPLETED) { - throw new IllegalStateException("Only completed payments can be refunded."); - } - - // Create Refund entity - Refund refund = Refund.builder() - .refundReference(UUID.randomUUID().toString()) - .status(RefundStatus.INITIATED) - .amount(refundRequest.getAmount()) - .payment(payment) - .reason(refundRequest.getReason()) - .createdAt(LocalDateTime.now()) - .build(); - - // Save Refund - refundRepository.save(refund); - - // Get the appropriate PaymentGateway - //PaymentRequest dummyPaymentRequest = new PaymentRequest(); // Not used here - PaymentGateway gateway = paymentGatewayFactory.getPaymentGateway( - PaymentRequest.builder() - .paymentMethod(payment.getPaymentGateway()) - .build() - ); - - // Process Refund via Gateway - RefundGatewayResponse gatewayResponse = gateway.processRefund(refundRequest); - - // Update Refund Status based on Gateway Response - if ("SUCCESS".equalsIgnoreCase(gatewayResponse.getStatus())) { - refund.setStatus(RefundStatus.COMPLETED); - payment.setStatus(PaymentStatus.REFUNDED); - } else { - refund.setStatus(RefundStatus.FAILED); - } - refund.setUpdatedAt(LocalDateTime.now()); - refundRepository.save(refund); - paymentRepository.save(payment); - - // Return Response - return new RefundResponse( - refund.getId(), - refund.getRefundReference(), - refund.getStatus(), - refund.getAmount(), - refund.getReason(), - refund.getCreatedAt() - ); - } -} diff --git a/payment-service/src/main/resources/application.properties b/payment-service/src/main/resources/application.properties new file mode 100644 index 0000000..85f2700 --- /dev/null +++ b/payment-service/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.application.name=payment-service diff --git a/payment-service/src/main/resources/application.yml b/payment-service/src/main/resources/application.yml deleted file mode 100644 index e690158..0000000 --- a/payment-service/src/main/resources/application.yml +++ /dev/null @@ -1,21 +0,0 @@ -server: - port: 8081 - -spring: - datasource: - url: jdbc:postgresql://localhost:5432/finpay_payment - username: postgres - password: 0412@zeP - driver-class-name: org.postgresql.Driver - jpa: - hibernate: - ddl-auto: update - show-sql: true - properties: - hibernate: - format_sql: true - -eureka: - client: - service-url: - defaultZone: http://localhost:8761/eureka/