PaymentGatewayImpl.java
package com.ctrlbuy.webshop.service.impl;
import com.ctrlbuy.webshop.model.*;
import com.ctrlbuy.webshop.enums.PaymentStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.UUID;
@Service
@Slf4j
public class PaymentGatewayImpl implements PaymentGateway {
@Override
public PaymentResult processPayment(PaymentInfo paymentInfo) {
log.info("Processing payment for amount: {}", paymentInfo.getAmount());
try {
// Simulate payment processing
Thread.sleep(1000); // Simulate network call
// Simple validation
if (paymentInfo.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
return PaymentResult.failure("INVALID_AMOUNT", "Invalid payment amount");
}
// Generate mock transaction ID
String transactionId = "TXN_" + UUID.randomUUID().toString().substring(0, 8).toUpperCase();
// Simulate 90% success rate
boolean success = Math.random() > 0.1;
if (success) {
log.info("Payment successful with transaction ID: {}", transactionId);
return PaymentResult.success(transactionId, "Payment processed successfully");
} else {
log.warn("Payment failed for amount: {}", paymentInfo.getAmount());
return PaymentResult.failure("PAYMENT_DECLINED", "Payment was declined by the bank");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error("Payment processing interrupted", e);
return PaymentResult.failure("PROCESSING_ERROR", "Payment processing was interrupted");
} catch (Exception e) {
log.error("Error processing payment", e);
return PaymentResult.failure("SYSTEM_ERROR", "An error occurred while processing the payment");
}
}
@Override
public boolean refund(String transactionId, BigDecimal amount) {
log.info("Processing refund for transaction: {} amount: {}", transactionId, amount);
try {
// Simulate refund processing
Thread.sleep(500);
// Simulate 95% success rate for refunds
boolean success = Math.random() > 0.05;
if (success) {
log.info("Refund successful for transaction: {}", transactionId);
} else {
log.warn("Refund failed for transaction: {}", transactionId);
}
return success;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error("Refund processing interrupted", e);
return false;
} catch (Exception e) {
log.error("Error processing refund", e);
return false;
}
}
@Override
public PaymentResult authorizePayment(PaymentInfo paymentInfo) {
log.info("Authorizing payment for amount: {}", paymentInfo.getAmount());
try {
Thread.sleep(800);
String authorizationId = "AUTH_" + UUID.randomUUID().toString().substring(0, 8).toUpperCase();
boolean success = Math.random() > 0.05;
if (success) {
log.info("Payment authorized with ID: {}", authorizationId);
return PaymentResult.success(authorizationId, "Payment authorized successfully");
} else {
return PaymentResult.failure("AUTH_DECLINED", "Authorization declined");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return PaymentResult.failure("PROCESSING_ERROR", "Authorization interrupted");
}
}
@Override
public boolean capturePayment(String authorizationId, BigDecimal amount) {
log.info("Capturing payment for authorization: {} amount: {}", authorizationId, amount);
try {
Thread.sleep(600);
boolean success = Math.random() > 0.02;
if (success) {
log.info("Payment captured successfully for authorization: {}", authorizationId);
} else {
log.warn("Payment capture failed for authorization: {}", authorizationId);
}
return success;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error("Payment capture interrupted", e);
return false;
}
}
@Override
public boolean voidAuthorization(String authorizationId) {
log.info("Voiding authorization: {}", authorizationId);
try {
Thread.sleep(300);
boolean success = Math.random() > 0.01;
if (success) {
log.info("Authorization voided successfully: {}", authorizationId);
} else {
log.warn("Failed to void authorization: {}", authorizationId);
}
return success;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error("Authorization void interrupted", e);
return false;
}
}
@Override
public PaymentResult verifyCard(PaymentInfo paymentInfo) {
log.info("Verifying card for order: {}", paymentInfo.getOrderId());
try {
Thread.sleep(400);
// Basic card validation
if (paymentInfo.getCardNumber() == null || paymentInfo.getCardNumber().length() < 13) {
return PaymentResult.failure("INVALID_CARD", "Invalid card number");
}
boolean success = Math.random() > 0.1;
if (success) {
return PaymentResult.success("VERIFIED", "Card verified successfully");
} else {
return PaymentResult.failure("VERIFICATION_FAILED", "Card verification failed");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return PaymentResult.failure("PROCESSING_ERROR", "Card verification interrupted");
}
}
@Override
public boolean isHealthy() {
log.debug("Checking payment gateway health");
try {
// Simulate health check
Thread.sleep(100);
// Simulate 99% uptime
return Math.random() > 0.01;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return false;
}
}
@Override
public PaymentGatewayInfo getGatewayInfo() {
return PaymentGatewayInfo.builder()
.name("Mock Payment Gateway")
.version("1.0.0")
.supportedCurrencies(java.util.List.of("SEK", "USD", "EUR"))
.provider("Mock Provider")
.supportsRefunds(true)
.status("ACTIVE")
.build();
}
@Override
public ValidationResult validatePaymentInfo(PaymentInfo paymentInfo) {
log.debug("Validating payment info for order: {}", paymentInfo.getOrderId());
ValidationResult.ValidationResultBuilder resultBuilder = ValidationResult.builder();
// Basic validation
if (paymentInfo == null) {
return resultBuilder
.valid(false)
.errorCode("NULL_PAYMENT_INFO")
.errorMessage("Payment information is null")
.build();
}
if (paymentInfo.getAmount() == null || paymentInfo.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
return resultBuilder
.valid(false)
.errorCode("INVALID_AMOUNT")
.errorMessage("Invalid payment amount")
.build();
}
if (paymentInfo.getOrderId() == null) {
return resultBuilder
.valid(false)
.errorCode("MISSING_ORDER_ID")
.errorMessage("Order ID is required")
.build();
}
// For credit card payments, validate card info
if (paymentInfo.getCardNumber() != null) {
if (paymentInfo.getCardNumber().length() < 13 || paymentInfo.getCardNumber().length() > 19) {
return resultBuilder
.valid(false)
.errorCode("INVALID_CARD_NUMBER")
.errorMessage("Invalid card number length")
.build();
}
if (paymentInfo.getCvv() == null || paymentInfo.getCvv().length() < 3) {
return resultBuilder
.valid(false)
.errorCode("INVALID_CVV")
.errorMessage("Invalid CVV")
.build();
}
if (paymentInfo.getExpiryMonth() == null ||
paymentInfo.getExpiryMonth() < 1 || paymentInfo.getExpiryMonth() > 12) {
return resultBuilder
.valid(false)
.errorCode("INVALID_EXPIRY_MONTH")
.errorMessage("Invalid expiry month")
.build();
}
if (paymentInfo.getExpiryYear() == null ||
paymentInfo.getExpiryYear() < LocalDateTime.now().getYear()) {
return resultBuilder
.valid(false)
.errorCode("INVALID_EXPIRY_YEAR")
.errorMessage("Invalid expiry year")
.build();
}
}
log.debug("Payment info validation successful");
return resultBuilder
.valid(true)
.errorCode(null)
.errorMessage("Validation successful")
.build();
}
}