diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..a22ec0d
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,65 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.2.5
+
+
+ com.acquirex
+ proj-acquirex
+ 1.0.0-SNAPSHOT
+ proj-acquirex
+ 카드 매입 승인 경로 - Spring Boot 3
+
+ 17
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+ com.h2database
+ h2
+ runtime
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ org.projectlombok
+ lombok
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/acquirex/AcquirexApplication.java b/src/main/java/com/acquirex/AcquirexApplication.java
new file mode 100644
index 0000000..daf6bca
--- /dev/null
+++ b/src/main/java/com/acquirex/AcquirexApplication.java
@@ -0,0 +1,11 @@
+package com.acquirex;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class AcquirexApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(AcquirexApplication.class, args);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/acquirex/controller/CardAcquisitionController.java b/src/main/java/com/acquirex/controller/CardAcquisitionController.java
new file mode 100644
index 0000000..0830b3f
--- /dev/null
+++ b/src/main/java/com/acquirex/controller/CardAcquisitionController.java
@@ -0,0 +1,70 @@
+package com.acquirex.controller;
+
+import com.acquirex.service.CardAcquisitionService;
+import com.acquirex.service.CardAcquisitionService.AcquisitionRequest;
+import com.acquirex.service.CardAcquisitionService.AcquisitionResponse;
+import com.acquirex.service.CardAcquisitionService.ApprovalRequest;
+import com.acquirex.service.CardAcquisitionService.AcquisitionNotFoundException;
+import com.acquirex.service.CardAcquisitionService.InvalidAcquisitionStateException;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.*;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/api/v1/acquisitions")
+@RequiredArgsConstructor
+public class CardAcquisitionController {
+ private final CardAcquisitionService service;
+
+ public record RequestDto(
+ @NotBlank(message = "카드번호 필수") @Size(min = 13, max = 19) String cardNumber,
+ @NotBlank @Size(max = 20) String merchantId,
+ @NotNull @DecimalMin("0.01") BigDecimal amount) {}
+
+ public record ApprovalDto(@NotBlank @Size(max = 50) String approvedBy) {}
+
+ @PostMapping
+ public ResponseEntity requestAcquisition(@Valid @RequestBody RequestDto dto) {
+ return ResponseEntity.status(HttpStatus.CREATED)
+ .body(service.requestAcquisition(new AcquisitionRequest(dto.cardNumber(), dto.merchantId(), dto.amount())));
+ }
+
+ @GetMapping("/{id}")
+ public ResponseEntity getAcquisition(@PathVariable Long id) {
+ return ResponseEntity.ok(service.getAcquisition(id));
+ }
+
+ @GetMapping("/pending")
+ public ResponseEntity> getPendingAcquisitions() {
+ return ResponseEntity.ok(service.getPendingAcquisitions());
+ }
+
+ @PostMapping("/{id}/approve")
+ public ResponseEntity approveAcquisition(@PathVariable Long id, @Valid @RequestBody ApprovalDto dto) {
+ return ResponseEntity.ok(service.approveAcquisition(id, new ApprovalRequest(dto.approvedBy())));
+ }
+
+ @PostMapping("/{id}/reject")
+ public ResponseEntity rejectAcquisition(@PathVariable Long id, @Valid @RequestBody ApprovalDto dto) {
+ return ResponseEntity.ok(service.rejectAcquisition(id, new ApprovalRequest(dto.approvedBy())));
+ }
+
+ @ExceptionHandler(AcquisitionNotFoundException.class)
+ public ResponseEntity