카드 매입 승인 경로 Spring Boot 3 전환 #1
1 changed files with 191 additions and 0 deletions
|
|
@ -0,0 +1,191 @@
|
|||
package com.acquirex.controller;
|
||||
|
||||
import com.acquirex.dto.ApprovalRequest;
|
||||
import com.acquirex.dto.ApprovalResponse;
|
||||
import com.acquirex.exception.ApprovalProcessingException;
|
||||
import com.acquirex.exception.GlobalExceptionHandler;
|
||||
import com.acquirex.service.AcquisitionApprovalService;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.validation.FieldError;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/acquisitions")
|
||||
public class AcquisitionApprovalController {
|
||||
|
||||
private final AcquisitionApprovalService service;
|
||||
|
||||
public AcquisitionApprovalController(AcquisitionApprovalService service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<ApprovalResponse> requestApproval(@Valid @RequestBody ApprovalRequest request) {
|
||||
ApprovalResponse response = service.requestApproval(request);
|
||||
return ResponseEntity.status(HttpStatus.CREATED).body(response);
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/approve")
|
||||
public ResponseEntity<ApprovalResponse> approve(@PathVariable Long id) {
|
||||
ApprovalResponse response = service.processApproval(id, true, null);
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/reject")
|
||||
public ResponseEntity<ApprovalResponse> reject(@PathVariable Long id, @RequestParam String reason) {
|
||||
ApprovalResponse response = service.processApproval(id, false, reason);
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public ResponseEntity<ApprovalResponse> getApproval(@PathVariable Long id) {
|
||||
ApprovalResponse response = service.getApproval(id);
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
@GetMapping("/pending")
|
||||
public ResponseEntity<List<ApprovalResponse>> getPendingApprovals() {
|
||||
List<ApprovalResponse> responses = service.getPendingApprovals();
|
||||
return ResponseEntity.ok(responses);
|
||||
}
|
||||
|
||||
@GetMapping("/merchant/{merchantId}")
|
||||
public ResponseEntity<List<ApprovalResponse>> getApprovalsByMerchant(@PathVariable String merchantId) {
|
||||
List<ApprovalResponse> responses = service.getApprovalsByMerchant(merchantId);
|
||||
return ResponseEntity.ok(responses);
|
||||
}
|
||||
}
|
||||
|
||||
// DTOs
|
||||
class ApprovalRequest {
|
||||
@jakarta.validation.constraints.NotBlank(message = "Merchant ID is required")
|
||||
private String merchantId;
|
||||
|
||||
@jakarta.validation.constraints.NotBlank(message = "Card number is required")
|
||||
@jakarta.validation.constraints.Size(min = 13, max = 19, message = "Card number must be between 13 and 19 digits")
|
||||
private String cardNumber;
|
||||
|
||||
@jakarta.validation.constraints.NotNull(message = "Amount is required")
|
||||
@jakarta.validation.constraints.DecimalMin(value = "0.01", message = "Amount must be greater than zero")
|
||||
private BigDecimal amount;
|
||||
|
||||
@jakarta.validation.constraints.NotBlank(message = "Currency is required")
|
||||
@jakarta.validation.constraints.Size(min = 3, max = 3, message = "Currency must be a 3-letter code")
|
||||
private String currency;
|
||||
|
||||
public ApprovalRequest() {}
|
||||
|
||||
public ApprovalRequest(String merchantId, String cardNumber, BigDecimal amount, String currency) {
|
||||
this.merchantId = merchantId;
|
||||
this.cardNumber = cardNumber;
|
||||
this.amount = amount;
|
||||
this.currency = currency;
|
||||
}
|
||||
|
||||
public String getMerchantId() { return merchantId; }
|
||||
public void setMerchantId(String merchantId) { this.merchantId = merchantId; }
|
||||
public String getCardNumber() { return cardNumber; }
|
||||
public void setCardNumber(String cardNumber) { this.cardNumber = cardNumber; }
|
||||
public BigDecimal getAmount() { return amount; }
|
||||
public void setAmount(BigDecimal amount) { this.amount = amount; }
|
||||
public String getCurrency() { return currency; }
|
||||
public void setCurrency(String currency) { this.currency = currency; }
|
||||
}
|
||||
|
||||
class ApprovalResponse {
|
||||
private Long id;
|
||||
private String merchantId;
|
||||
private String cardNumber;
|
||||
private BigDecimal amount;
|
||||
private String currency;
|
||||
private String status;
|
||||
private String approvalCode;
|
||||
private String rejectionReason;
|
||||
private LocalDateTime requestedAt;
|
||||
private LocalDateTime processedAt;
|
||||
|
||||
public ApprovalResponse() {}
|
||||
|
||||
public ApprovalResponse(Long id, String merchantId, String cardNumber, BigDecimal amount,
|
||||
String currency, String status, String approvalCode,
|
||||
String rejectionReason, LocalDateTime requestedAt, LocalDateTime processedAt) {
|
||||
this.id = id;
|
||||
this.merchantId = merchantId;
|
||||
this.cardNumber = cardNumber;
|
||||
this.amount = amount;
|
||||
this.currency = currency;
|
||||
this.status = status;
|
||||
this.approvalCode = approvalCode;
|
||||
this.rejectionReason = rejectionReason;
|
||||
this.requestedAt = requestedAt;
|
||||
this.processedAt = processedAt;
|
||||
}
|
||||
|
||||
public Long getId() { return id; }
|
||||
public void setId(Long id) { this.id = id; }
|
||||
public String getMerchantId() { return merchantId; }
|
||||
public void setMerchantId(String merchantId) { this.merchantId = merchantId; }
|
||||
public String getCardNumber() { return cardNumber; }
|
||||
public void setCardNumber(String cardNumber) { this.cardNumber = cardNumber; }
|
||||
public BigDecimal getAmount() { return amount; }
|
||||
public void setAmount(BigDecimal amount) { this.amount = amount; }
|
||||
public String getCurrency() { return currency; }
|
||||
public void setCurrency(String currency) { this.currency = currency; }
|
||||
public String getStatus() { return status; }
|
||||
public void setStatus(String status) { this.status = status; }
|
||||
public String getApprovalCode() { return approvalCode; }
|
||||
public void setApprovalCode(String approvalCode) { this.approvalCode = approvalCode; }
|
||||
public String getRejectionReason() { return rejectionReason; }
|
||||
public void setRejectionReason(String rejectionReason) { this.rejectionReason = rejectionReason; }
|
||||
public LocalDateTime getRequestedAt() { return requestedAt; }
|
||||
public void setRequestedAt(LocalDateTime requestedAt) { this.requestedAt = requestedAt; }
|
||||
public LocalDateTime getProcessedAt() { return processedAt; }
|
||||
public void setProcessedAt(LocalDateTime processedAt) { this.processedAt = processedAt; }
|
||||
}
|
||||
|
||||
// Exceptions
|
||||
class ApprovalProcessingException extends RuntimeException {
|
||||
public ApprovalProcessingException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
@RestControllerAdvice
|
||||
class GlobalExceptionHandler {
|
||||
|
||||
@org.springframework.web.bind.annotation.ExceptionHandler(ApprovalProcessingException.class)
|
||||
public ResponseEntity<Map<String, Object>> handleApprovalProcessingException(ApprovalProcessingException ex) {
|
||||
Map<String, Object> body = new HashMap<>();
|
||||
body.put("timestamp", LocalDateTime.now());
|
||||
body.put("status", HttpStatus.BAD_REQUEST.value());
|
||||
body.put("error", "Approval Processing Error");
|
||||
body.put("message", ex.getMessage());
|
||||
return ResponseEntity.badRequest().body(body);
|
||||
}
|
||||
|
||||
@org.springframework.web.bind.annotation.ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public ResponseEntity<Map<String, Object>> handleValidationExceptions(MethodArgumentNotValidException ex) {
|
||||
Map<String, Object> body = new HashMap<>();
|
||||
body.put("timestamp", LocalDateTime.now());
|
||||
body.put("status", HttpStatus.BAD_REQUEST.value());
|
||||
body.put("error", "Validation Error");
|
||||
|
||||
Map<String, String> errors = new HashMap<>();
|
||||
ex.getBindingResult().getAllErrors().forEach(error -> {
|
||||
String fieldName = ((FieldError) error).getField();
|
||||
String errorMessage = error.getDefaultMessage();
|
||||
errors.put(fieldName, errorMessage);
|
||||
});
|
||||
body.put("errors", errors);
|
||||
return ResponseEntity.badRequest().body(body);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue