카드 매입 승인 경로 Spring Boot 3 전환 (ACX-E2E-1785394564819)
This commit is contained in:
parent
692278427d
commit
9e8112e4d7
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