diff --git a/apps/commerce-api/src/main/java/com/loopers/application/example/ExampleFacade.java b/apps/commerce-api/src/main/java/com/loopers/application/example/ExampleFacade.java
deleted file mode 100644
index 552a9ad62..000000000
--- a/apps/commerce-api/src/main/java/com/loopers/application/example/ExampleFacade.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.loopers.application.example;
-
-import com.loopers.domain.example.ExampleModel;
-import com.loopers.domain.example.ExampleService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Component;
-
-@RequiredArgsConstructor
-@Component
-public class ExampleFacade {
-    private final ExampleService exampleService;
-
-    public ExampleInfo getExample(Long id) {
-        ExampleModel example = exampleService.getExample(id);
-        return ExampleInfo.from(example);
-    }
-}
diff --git a/apps/commerce-api/src/main/java/com/loopers/application/example/ExampleInfo.java b/apps/commerce-api/src/main/java/com/loopers/application/example/ExampleInfo.java
deleted file mode 100644
index 877aba96c..000000000
--- a/apps/commerce-api/src/main/java/com/loopers/application/example/ExampleInfo.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.loopers.application.example;
-
-import com.loopers.domain.example.ExampleModel;
-
-public record ExampleInfo(Long id, String name, String description) {
-    public static ExampleInfo from(ExampleModel model) {
-        return new ExampleInfo(
-            model.getId(),
-            model.getName(),
-            model.getDescription()
-        );
-    }
-}
diff --git a/apps/commerce-api/src/main/java/com/loopers/application/members/MemberFacade.java b/apps/commerce-api/src/main/java/com/loopers/application/members/MemberFacade.java
new file mode 100644
index 000000000..527ed09d1
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/members/MemberFacade.java
@@ -0,0 +1,36 @@
+package com.loopers.application.members;
+
+import com.loopers.domain.members.Gender;
+import com.loopers.domain.members.MemberModel;
+import com.loopers.domain.members.MemberService;
+import com.loopers.domain.points.PointService;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+@RequiredArgsConstructor
+@Component
+public class MemberFacade {
+    private final MemberService memberService;
+    private final PointService pointService;
+
+    @Transactional
+    public MemberInfo registerMember(String memberId, String email, String password, String birthDate, Gender gender) {
+        MemberModel member = memberService.registerMember(memberId, email, password, birthDate, gender);
+        pointService.initializeMemberPoints(memberId);
+        return MemberInfo.from(member);
+    }
+
+    public MemberInfo getMemberByMemberId(String memberId) {
+        MemberModel member = memberService.getMemberByMemberId(memberId);
+        if (member == null) {
+            throw new CoreException(
+                    ErrorType.NOT_FOUND,
+                    "존재하지 않는 회원입니다."
+            );
+        }
+        return MemberInfo.from(member);
+    }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/application/members/MemberInfo.java b/apps/commerce-api/src/main/java/com/loopers/application/members/MemberInfo.java
new file mode 100644
index 000000000..c6708ba0c
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/members/MemberInfo.java
@@ -0,0 +1,24 @@
+package com.loopers.application.members;
+
+import com.loopers.domain.members.Gender;
+import com.loopers.domain.members.MemberModel;
+
+import java.time.LocalDate;
+
+public record MemberInfo(
+        Long id, 
+        String memberId, 
+        String email, 
+        LocalDate birthDate, 
+        Gender gender
+) {
+    public static MemberInfo from(MemberModel model) {
+        return new MemberInfo(
+                model.getId(),
+                model.getMemberId(),
+                model.getEmail(),
+                model.getBirthDate(),
+                model.getGender()
+        );
+    }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/config/SecurityConfig.java b/apps/commerce-api/src/main/java/com/loopers/config/SecurityConfig.java
new file mode 100644
index 000000000..cc4ae7646
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/config/SecurityConfig.java
@@ -0,0 +1,28 @@
+package com.loopers.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.web.SecurityFilterChain;
+
+@Configuration
+@EnableWebSecurity
+public class SecurityConfig {
+
+    @Bean
+    public PasswordEncoder passwordEncoder() {
+        return new BCryptPasswordEncoder();
+    }
+
+    @Bean
+    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
+        return http
+                .csrf(AbstractHttpConfigurer::disable)
+                .authorizeHttpRequests(authz -> authz.anyRequest().permitAll())
+                .build();
+    }
+}
\ No newline at end of file
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/example/ExampleModel.java b/apps/commerce-api/src/main/java/com/loopers/domain/example/ExampleModel.java
deleted file mode 100644
index c588c4a8a..000000000
--- a/apps/commerce-api/src/main/java/com/loopers/domain/example/ExampleModel.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package com.loopers.domain.example;
-
-import com.loopers.domain.BaseEntity;
-import com.loopers.support.error.CoreException;
-import com.loopers.support.error.ErrorType;
-import jakarta.persistence.Entity;
-import jakarta.persistence.Table;
-
-@Entity
-@Table(name = "example")
-public class ExampleModel extends BaseEntity {
-
-    private String name;
-    private String description;
-
-    protected ExampleModel() {}
-
-    public ExampleModel(String name, String description) {
-        if (name == null || name.isBlank()) {
-            throw new CoreException(ErrorType.BAD_REQUEST, "이름은 비어있을 수 없습니다.");
-        }
-        if (description == null || description.isBlank()) {
-            throw new CoreException(ErrorType.BAD_REQUEST, "설명은 비어있을 수 없습니다.");
-        }
-
-        this.name = name;
-        this.description = description;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public void update(String newDescription) {
-        if (newDescription == null || newDescription.isBlank()) {
-            throw new CoreException(ErrorType.BAD_REQUEST, "설명은 비어있을 수 없습니다.");
-        }
-        this.description = newDescription;
-    }
-}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/example/ExampleRepository.java b/apps/commerce-api/src/main/java/com/loopers/domain/example/ExampleRepository.java
deleted file mode 100644
index 3625e5662..000000000
--- a/apps/commerce-api/src/main/java/com/loopers/domain/example/ExampleRepository.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.loopers.domain.example;
-
-import java.util.Optional;
-
-public interface ExampleRepository {
-    Optional<ExampleModel> find(Long id);
-}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/example/ExampleService.java b/apps/commerce-api/src/main/java/com/loopers/domain/example/ExampleService.java
deleted file mode 100644
index c0e8431e8..000000000
--- a/apps/commerce-api/src/main/java/com/loopers/domain/example/ExampleService.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.loopers.domain.example;
-
-import com.loopers.support.error.CoreException;
-import com.loopers.support.error.ErrorType;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Component;
-import org.springframework.transaction.annotation.Transactional;
-
-@RequiredArgsConstructor
-@Component
-public class ExampleService {
-
-    private final ExampleRepository exampleRepository;
-
-    @Transactional(readOnly = true)
-    public ExampleModel getExample(Long id) {
-        return exampleRepository.find(id)
-            .orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, "[id = " + id + "] 예시를 찾을 수 없습니다."));
-    }
-}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/members/Gender.java b/apps/commerce-api/src/main/java/com/loopers/domain/members/Gender.java
new file mode 100644
index 000000000..7eb92b9ee
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/members/Gender.java
@@ -0,0 +1,7 @@
+package com.loopers.domain.members;
+
+public enum Gender {
+    MALE,
+    FEMALE,
+    OTHER
+}
\ No newline at end of file
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/members/MemberModel.java b/apps/commerce-api/src/main/java/com/loopers/domain/members/MemberModel.java
new file mode 100644
index 000000000..b51ae5282
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/members/MemberModel.java
@@ -0,0 +1,97 @@
+package com.loopers.domain.members;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.loopers.domain.BaseEntity;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.EnumType;
+import jakarta.persistence.Enumerated;
+import jakarta.persistence.Table;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
+import java.util.regex.Pattern;
+
+@NoArgsConstructor
+@Getter
+@Entity
+@Table(name = "members")
+public class MemberModel extends BaseEntity {
+
+    private static final Pattern MEMBER_ID_REGEX = Pattern.compile("^[a-zA-Z0-9]{1,10}$");
+    private static final Pattern EMAIL_REGEX = Pattern.compile("^[^@]+@[^@]+\\.[^@]+$");
+    private static final DateTimeFormatter BIRTH_DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+
+    @Column(name = "member_id", nullable = false, unique = true, length = 10)
+    private String memberId;
+
+    @Column(name = "email", nullable = false)
+    private String email;
+
+    @Column(name = "birth_date", nullable = false)
+    private LocalDate birthDate;
+
+    @Enumerated(EnumType.STRING)
+    @Column(name = "gender", nullable = false)
+    private Gender gender;
+
+    @Column(name = "password", nullable = false)
+    @JsonIgnore
+    private String password;
+
+    public MemberModel(String memberId, String email, String password, String birthDate, Gender gender) {
+        validateMemberId(memberId);
+        validateEmail(email);
+        validateGender(gender);
+
+        this.memberId = memberId;
+        this.email = email;
+        this.password = password;
+        this.birthDate = parseBirthDate(birthDate);
+        this.gender = gender;
+    }
+
+    private static void validateMemberId(String memberId) {
+        if (!MEMBER_ID_REGEX.matcher(memberId).matches()) {
+            throw new CoreException(
+                    ErrorType.BAD_REQUEST,
+                    "ID는 영문 및 숫자 10자 이내여야 합니다."
+            );
+        }
+    }
+
+    private static void validateEmail(String email) {
+        if (!EMAIL_REGEX.matcher(email).matches()) {
+            throw new CoreException(
+                    ErrorType.BAD_REQUEST,
+                    "이메일은 xx@yy.zz 형식이어야 합니다."
+            );
+        }
+    }
+
+    public static void validateGender(Gender gender) {
+        if (gender == null) {
+            throw new CoreException(
+                    ErrorType.BAD_REQUEST,
+                    "성별은 필수입니다."
+            );
+        }
+    }
+
+    private static LocalDate parseBirthDate(String birthDate) {
+        try {
+            return LocalDate.parse(birthDate, BIRTH_DATE_FORMATTER);
+        } catch (DateTimeParseException e) {
+            throw new CoreException(
+                    ErrorType.BAD_REQUEST,
+                    "생년월일은 yyyy-MM-dd 형식이어야 합니다."
+            );
+        }
+    }
+
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/members/MemberRepository.java b/apps/commerce-api/src/main/java/com/loopers/domain/members/MemberRepository.java
new file mode 100644
index 000000000..d7f4eb274
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/members/MemberRepository.java
@@ -0,0 +1,7 @@
+package com.loopers.domain.members;
+
+public interface MemberRepository {
+    MemberModel save(MemberModel member);
+    MemberModel findByMemberId(String memberId);
+    boolean existsByMemberId(String memberId);
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/members/MemberService.java b/apps/commerce-api/src/main/java/com/loopers/domain/members/MemberService.java
new file mode 100644
index 000000000..109574080
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/members/MemberService.java
@@ -0,0 +1,37 @@
+package com.loopers.domain.members;
+
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import lombok.RequiredArgsConstructor;
+import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+@RequiredArgsConstructor
+@Component
+public class MemberService {
+
+    private final MemberRepository memberRepository;
+    private final PasswordEncoder passwordEncoder;
+
+    @Transactional
+    public MemberModel registerMember(String memberId, String email, String password, String birthDate, Gender gender) {
+        String encodedPassword = passwordEncoder.encode(password);
+        MemberModel member = new MemberModel(memberId, email, encodedPassword, birthDate, gender);
+
+        try {
+            return memberRepository.save(member);
+        } catch (DataIntegrityViolationException e) {
+            throw new CoreException(
+                    ErrorType.CONFLICT,
+                    "이미 가입된 ID 입니다."
+            );
+        }
+    }
+
+    @Transactional(readOnly = true)
+    public MemberModel getMemberByMemberId(String memberId) {
+        return memberRepository.findByMemberId(memberId);
+    }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/points/PointModel.java b/apps/commerce-api/src/main/java/com/loopers/domain/points/PointModel.java
new file mode 100644
index 000000000..862c44e5b
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/points/PointModel.java
@@ -0,0 +1,40 @@
+package com.loopers.domain.points;
+
+import com.loopers.domain.BaseEntity;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Table;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Entity
+@Table(name = "point")
+public class PointModel extends BaseEntity {
+
+    @Column(unique = true, nullable = false, length = 10)
+    private String memberId;
+
+    @Column(nullable = false)
+    private BigDecimal amount;
+
+    public static PointModel create(String memberId, BigDecimal amount) {
+        if (amount == null || amount.compareTo(BigDecimal.ZERO) < 0) {
+            throw new IllegalArgumentException("포인트는 0 이상이어야 합니다");
+        }
+
+        return new PointModel(memberId, amount);
+    }
+
+    public void addAmount(BigDecimal addAmount) {
+        if (addAmount.compareTo(BigDecimal.ZERO) <= 0) {
+            throw new IllegalArgumentException("추가하는 포인트는 0보다 커야 합니다");
+        }
+        this.amount = this.amount.add(addAmount);
+    }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/points/PointRepository.java b/apps/commerce-api/src/main/java/com/loopers/domain/points/PointRepository.java
new file mode 100644
index 000000000..67ddc7c2c
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/points/PointRepository.java
@@ -0,0 +1,8 @@
+package com.loopers.domain.points;
+
+import java.util.Optional;
+
+public interface PointRepository {
+    Optional<PointModel> findByMemberId(String memberId);
+    PointModel save(PointModel pointModel);
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/points/PointService.java b/apps/commerce-api/src/main/java/com/loopers/domain/points/PointService.java
new file mode 100644
index 000000000..5436e5dd4
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/points/PointService.java
@@ -0,0 +1,27 @@
+package com.loopers.domain.points;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+
+@RequiredArgsConstructor
+@Component
+public class PointService {
+
+    private final PointRepository pointRepository;
+
+    @Transactional(readOnly = true)
+    public BigDecimal getMemberPoints(String memberId) {
+        return pointRepository.findByMemberId(memberId)
+                .map(PointModel::getAmount)
+                .orElse(null);
+    }
+
+    @Transactional
+    public PointModel initializeMemberPoints(String memberId) {
+        PointModel point = PointModel.create(memberId, BigDecimal.ZERO);
+        return pointRepository.save(point);
+    }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/infrastructure/example/ExampleJpaRepository.java b/apps/commerce-api/src/main/java/com/loopers/infrastructure/example/ExampleJpaRepository.java
deleted file mode 100644
index ce6d3ead0..000000000
--- a/apps/commerce-api/src/main/java/com/loopers/infrastructure/example/ExampleJpaRepository.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.loopers.infrastructure.example;
-
-import com.loopers.domain.example.ExampleModel;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-public interface ExampleJpaRepository extends JpaRepository<ExampleModel, Long> {}
diff --git a/apps/commerce-api/src/main/java/com/loopers/infrastructure/example/ExampleRepositoryImpl.java b/apps/commerce-api/src/main/java/com/loopers/infrastructure/example/ExampleRepositoryImpl.java
deleted file mode 100644
index 37f2272f0..000000000
--- a/apps/commerce-api/src/main/java/com/loopers/infrastructure/example/ExampleRepositoryImpl.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.loopers.infrastructure.example;
-
-import com.loopers.domain.example.ExampleModel;
-import com.loopers.domain.example.ExampleRepository;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Component;
-
-import java.util.Optional;
-
-@RequiredArgsConstructor
-@Component
-public class ExampleRepositoryImpl implements ExampleRepository {
-    private final ExampleJpaRepository exampleJpaRepository;
-
-    @Override
-    public Optional<ExampleModel> find(Long id) {
-        return exampleJpaRepository.findById(id);
-    }
-}
diff --git a/apps/commerce-api/src/main/java/com/loopers/infrastructure/members/MemberJpaRepository.java b/apps/commerce-api/src/main/java/com/loopers/infrastructure/members/MemberJpaRepository.java
new file mode 100644
index 000000000..2df08f60a
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/members/MemberJpaRepository.java
@@ -0,0 +1,11 @@
+package com.loopers.infrastructure.members;
+
+import com.loopers.domain.members.MemberModel;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface MemberJpaRepository extends JpaRepository<MemberModel, Long> {
+    MemberModel findByMemberId(String memberId);
+    boolean existsByMemberId(String memberId);
+}
\ No newline at end of file
diff --git a/apps/commerce-api/src/main/java/com/loopers/infrastructure/members/MemberRepositoryImpl.java b/apps/commerce-api/src/main/java/com/loopers/infrastructure/members/MemberRepositoryImpl.java
new file mode 100644
index 000000000..ed01e7076
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/members/MemberRepositoryImpl.java
@@ -0,0 +1,27 @@
+package com.loopers.infrastructure.members;
+
+import com.loopers.domain.members.MemberModel;
+import com.loopers.domain.members.MemberRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Repository;
+
+@RequiredArgsConstructor
+@Repository
+public class MemberRepositoryImpl implements MemberRepository {
+    private final MemberJpaRepository memberJpaRepository;
+
+    @Override
+    public MemberModel save(MemberModel member) {
+        return memberJpaRepository.save(member);
+    }
+
+    @Override
+    public MemberModel findByMemberId(String memberId) {
+        return memberJpaRepository.findByMemberId(memberId);
+    }
+
+    @Override
+    public boolean existsByMemberId(String memberId) {
+        return memberJpaRepository.existsByMemberId(memberId);
+    }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/infrastructure/points/PointJpaRepository.java b/apps/commerce-api/src/main/java/com/loopers/infrastructure/points/PointJpaRepository.java
new file mode 100644
index 000000000..639ed2bf2
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/points/PointJpaRepository.java
@@ -0,0 +1,10 @@
+package com.loopers.infrastructure.points;
+
+import com.loopers.domain.points.PointModel;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.Optional;
+
+public interface PointJpaRepository extends JpaRepository<PointModel, Long> {
+    Optional<PointModel> findByMemberId(String memberId);
+}
\ No newline at end of file
diff --git a/apps/commerce-api/src/main/java/com/loopers/infrastructure/points/PointRepositoryImpl.java b/apps/commerce-api/src/main/java/com/loopers/infrastructure/points/PointRepositoryImpl.java
new file mode 100644
index 000000000..79193a4a3
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/points/PointRepositoryImpl.java
@@ -0,0 +1,24 @@
+package com.loopers.infrastructure.points;
+
+import com.loopers.domain.points.PointModel;
+import com.loopers.domain.points.PointRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+
+import java.util.Optional;
+
+@RequiredArgsConstructor
+@Component
+public class PointRepositoryImpl implements PointRepository {
+    private final PointJpaRepository pointJpaRepository;
+
+    @Override
+    public Optional<PointModel> findByMemberId(String memberId) {
+        return pointJpaRepository.findByMemberId(memberId);
+    }
+
+    @Override
+    public PointModel save(PointModel pointModel) {
+        return pointJpaRepository.save(pointModel);
+    }
+}
\ No newline at end of file
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/example/ExampleV1ApiSpec.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/example/ExampleV1ApiSpec.java
deleted file mode 100644
index 219e3101e..000000000
--- a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/example/ExampleV1ApiSpec.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.loopers.interfaces.api.example;
-
-import com.loopers.interfaces.api.ApiResponse;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.media.Schema;
-import io.swagger.v3.oas.annotations.tags.Tag;
-
-@Tag(name = "Example V1 API", description = "Loopers 예시 API 입니다.")
-public interface ExampleV1ApiSpec {
-
-    @Operation(
-        summary = "예시 조회",
-        description = "ID로 예시를 조회합니다."
-    )
-    ApiResponse<ExampleV1Dto.ExampleResponse> getExample(
-        @Schema(name = "예시 ID", description = "조회할 예시의 ID")
-        Long exampleId
-    );
-}
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/example/ExampleV1Controller.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/example/ExampleV1Controller.java
deleted file mode 100644
index 917376016..000000000
--- a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/example/ExampleV1Controller.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.loopers.interfaces.api.example;
-
-import com.loopers.application.example.ExampleFacade;
-import com.loopers.application.example.ExampleInfo;
-import com.loopers.interfaces.api.ApiResponse;
-import lombok.RequiredArgsConstructor;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/api/v1/examples")
-public class ExampleV1Controller implements ExampleV1ApiSpec {
-
-    private final ExampleFacade exampleFacade;
-
-    @GetMapping("/{exampleId}")
-    @Override
-    public ApiResponse<ExampleV1Dto.ExampleResponse> getExample(
-        @PathVariable(value = "exampleId") Long exampleId
-    ) {
-        ExampleInfo info = exampleFacade.getExample(exampleId);
-        ExampleV1Dto.ExampleResponse response = ExampleV1Dto.ExampleResponse.from(info);
-        return ApiResponse.success(response);
-    }
-}
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/example/ExampleV1Dto.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/example/ExampleV1Dto.java
deleted file mode 100644
index 4ecf0eea5..000000000
--- a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/example/ExampleV1Dto.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.loopers.interfaces.api.example;
-
-import com.loopers.application.example.ExampleInfo;
-
-public class ExampleV1Dto {
-    public record ExampleResponse(Long id, String name, String description) {
-        public static ExampleResponse from(ExampleInfo info) {
-            return new ExampleResponse(
-                info.id(),
-                info.name(),
-                info.description()
-            );
-        }
-    }
-}
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/members/MemberV1ApiSpec.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/members/MemberV1ApiSpec.java
new file mode 100644
index 000000000..29b214171
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/members/MemberV1ApiSpec.java
@@ -0,0 +1,15 @@
+package com.loopers.interfaces.api.members;
+
+import com.loopers.interfaces.api.ApiResponse;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+
+@Tag(name = "Member V1", description = "회원 관리 API")
+public interface MemberV1ApiSpec {
+
+    @Operation(summary = "회원 가입", description = "새로운 회원을 등록합니다.")
+    ApiResponse<MemberV1Dto.MemberResponse> registerMember(MemberV1Dto.RegisterMemberRequest request);
+
+    @Operation(summary = "내 정보 조회", description = "회원 ID로 정보를 조회합니다.")
+    ApiResponse<MemberV1Dto.MemberResponse> getMemberByMemberId(String memberId);
+}
\ No newline at end of file
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/members/MemberV1Controller.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/members/MemberV1Controller.java
new file mode 100644
index 000000000..3aaad045d
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/members/MemberV1Controller.java
@@ -0,0 +1,51 @@
+package com.loopers.interfaces.api.members;
+
+import com.loopers.application.members.MemberFacade;
+import com.loopers.application.members.MemberInfo;
+import com.loopers.interfaces.api.ApiResponse;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import jakarta.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/api/v1")
+public class MemberV1Controller implements MemberV1ApiSpec {
+
+    private final MemberFacade memberFacade;
+
+    @PostMapping("/members")
+    @Override
+    public ApiResponse<MemberV1Dto.MemberResponse> registerMember(
+            @Valid @RequestBody MemberV1Dto.RegisterMemberRequest request
+    ) {
+        MemberInfo memberInfo = memberFacade.registerMember(
+                request.memberId(),
+                request.email(),
+                request.password(),
+                request.birthDate(),
+                request.gender()
+        );
+        
+        MemberV1Dto.MemberResponse response = MemberV1Dto.MemberResponse.from(memberInfo);
+        return ApiResponse.success(response);
+    }
+
+    @GetMapping("/members/{memberId}")
+    @Override
+    public ApiResponse<MemberV1Dto.MemberResponse> getMemberByMemberId(
+            @PathVariable String memberId
+    ) {
+        MemberInfo memberInfo = memberFacade.getMemberByMemberId(memberId);
+        MemberV1Dto.MemberResponse response = MemberV1Dto.MemberResponse.from(memberInfo);
+        return ApiResponse.success(response);
+    }
+}
\ No newline at end of file
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/members/MemberV1Dto.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/members/MemberV1Dto.java
new file mode 100644
index 000000000..bc0e9ae90
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/members/MemberV1Dto.java
@@ -0,0 +1,67 @@
+package com.loopers.interfaces.api.members;
+
+import com.loopers.application.members.MemberInfo;
+import com.loopers.domain.members.Gender;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Pattern;
+import java.time.LocalDate;
+
+public class MemberV1Dto {
+
+    @Schema(description = "회원 가입 요청")
+    public record RegisterMemberRequest(
+            @Schema(description = "회원 ID", example = "test123")
+            @NotBlank(message = "회원 ID는 필수입니다.")
+            @Pattern(regexp = "^[a-zA-Z0-9]{1,10}$", message = "ID는 영문 및 숫자 10자 이내여야 합니다.")
+            String memberId,
+            
+            @Schema(description = "이메일", example = "test@example.com")
+            @NotBlank(message = "이메일은 필수입니다.")
+            @Email(message = "이메일 형식이 올바르지 않습니다.")
+            String email,
+            
+            @Schema(description = "비밀번호", example = "password123")
+            @NotBlank(message = "비밀번호는 필수입니다.")
+            String password,
+            
+            @Schema(description = "생년월일", example = "1990-01-01")
+            @NotBlank(message = "생년월일은 필수입니다.")
+            @Pattern(regexp = "^\\d{4}-\\d{2}-\\d{2}$", message = "생년월일은 yyyy-MM-dd 형식이어야 합니다.")
+            String birthDate,
+            
+            @Schema(description = "성별", example = "MALE")
+            @NotNull(message = "성별은 필수입니다.")
+            Gender gender
+    ) {}
+
+    @Schema(description = "회원 정보 응답")
+    public record MemberResponse(
+            @Schema(description = "회원 ID")
+            Long id,
+            
+            @Schema(description = "회원 ID")
+            String memberId,
+            
+            @Schema(description = "이메일")
+            String email,
+            
+            @Schema(description = "생년월일")
+            LocalDate birthDate,
+            
+            @Schema(description = "성별")
+            Gender gender
+    ) {
+        public static MemberResponse from(MemberInfo info) {
+            return new MemberResponse(
+                    info.id(),
+                    info.memberId(),
+                    info.email(),
+                    info.birthDate(),
+                    info.gender()
+            );
+        }
+    }
+}
\ No newline at end of file
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/points/PointV1ApiSpec.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/points/PointV1ApiSpec.java
new file mode 100644
index 000000000..001eaf99e
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/points/PointV1ApiSpec.java
@@ -0,0 +1,15 @@
+package com.loopers.interfaces.api.points;
+
+import com.loopers.interfaces.api.ApiResponse;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+
+@Tag(name = "Point", description = "포인트 관리 API")
+public interface PointV1ApiSpec {
+
+    @Operation(summary = "포인트 조회", description = "현재 로그인한 회원의 포인트를 조회합니다.")
+    ApiResponse<PointV1Dto.PointResponse> getMemberPoints(
+            @Parameter(description = "사용자 ID", required = true) String userId
+    );
+}
\ No newline at end of file
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/points/PointV1Controller.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/points/PointV1Controller.java
new file mode 100644
index 000000000..5af0340db
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/points/PointV1Controller.java
@@ -0,0 +1,35 @@
+package com.loopers.interfaces.api.points;
+
+import com.loopers.domain.points.PointService;
+import com.loopers.interfaces.api.ApiResponse;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.math.BigDecimal;
+
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/api/v1/points")
+public class PointV1Controller implements PointV1ApiSpec {
+
+    private final PointService pointService;
+
+    @GetMapping
+    @Override
+    public ApiResponse<PointV1Dto.PointResponse> getMemberPoints(
+            @RequestHeader(value = "X-USER-ID", required = false) String userId
+    ) {
+        if (userId == null || userId.isBlank()) {
+            throw new CoreException(ErrorType.MISSING_REQUEST_HEADER, "X-USER-ID 헤더는 필수입니다.");
+        }
+        
+        BigDecimal points = pointService.getMemberPoints(userId);
+        PointV1Dto.PointResponse response = new PointV1Dto.PointResponse(points);
+        return ApiResponse.success(response);
+    }
+}
\ No newline at end of file
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/points/PointV1Dto.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/points/PointV1Dto.java
new file mode 100644
index 000000000..de662c0b8
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/points/PointV1Dto.java
@@ -0,0 +1,14 @@
+package com.loopers.interfaces.api.points;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import java.math.BigDecimal;
+
+public class PointV1Dto {
+
+    @Schema(description = "포인트 응답")
+    public record PointResponse(
+            @Schema(description = "보유 포인트")
+            BigDecimal points
+    ) {}
+}
\ No newline at end of file
diff --git a/apps/commerce-api/src/main/java/com/loopers/support/error/ErrorType.java b/apps/commerce-api/src/main/java/com/loopers/support/error/ErrorType.java
index 5d142efbf..d3c212936 100644
--- a/apps/commerce-api/src/main/java/com/loopers/support/error/ErrorType.java
+++ b/apps/commerce-api/src/main/java/com/loopers/support/error/ErrorType.java
@@ -7,11 +7,16 @@
 @Getter
 @RequiredArgsConstructor
 public enum ErrorType {
-    /** 범용 에러 */
+    /**
+     * 범용 에러
+     */
     INTERNAL_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase(), "일시적인 오류가 발생했습니다."),
     BAD_REQUEST(HttpStatus.BAD_REQUEST, HttpStatus.BAD_REQUEST.getReasonPhrase(), "잘못된 요청입니다."),
     NOT_FOUND(HttpStatus.NOT_FOUND, HttpStatus.NOT_FOUND.getReasonPhrase(), "존재하지 않는 요청입니다."),
-    CONFLICT(HttpStatus.CONFLICT, HttpStatus.CONFLICT.getReasonPhrase(), "이미 존재하는 리소스입니다.");
+    CONFLICT(HttpStatus.CONFLICT, HttpStatus.CONFLICT.getReasonPhrase(), "이미 존재하는 리소스입니다."),
+
+    MISSING_REQUEST_HEADER(HttpStatus.BAD_REQUEST, HttpStatus.BAD_REQUEST.getReasonPhrase(), "헤더 값은 필수입니다."),
+    INVALID_TOKEN(HttpStatus.BAD_REQUEST, HttpStatus.BAD_REQUEST.getReasonPhrase(), "적절하지 않은 토큰 값입니다.");
 
     private final HttpStatus status;
     private final String code;
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/example/ExampleModelTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/example/ExampleModelTest.java
deleted file mode 100644
index 44ca7576e..000000000
--- a/apps/commerce-api/src/test/java/com/loopers/domain/example/ExampleModelTest.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.loopers.domain.example;
-
-import com.loopers.support.error.CoreException;
-import com.loopers.support.error.ErrorType;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Nested;
-import org.junit.jupiter.api.Test;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertAll;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-class ExampleModelTest {
-    @DisplayName("예시 모델을 생성할 때, ")
-    @Nested
-    class Create {
-        @DisplayName("제목과 설명이 모두 주어지면, 정상적으로 생성된다.")
-        @Test
-        void createsExampleModel_whenNameAndDescriptionAreProvided() {
-            // arrange
-            String name = "제목";
-            String description = "설명";
-
-            // act
-            ExampleModel exampleModel = new ExampleModel(name, description);
-
-            // assert
-            assertAll(
-                () -> assertThat(exampleModel.getId()).isNotNull(),
-                () -> assertThat(exampleModel.getName()).isEqualTo(name),
-                () -> assertThat(exampleModel.getDescription()).isEqualTo(description)
-            );
-        }
-
-        @DisplayName("제목이 빈칸으로만 이루어져 있으면, BAD_REQUEST 예외가 발생한다.")
-        @Test
-        void throwsBadRequestException_whenTitleIsBlank() {
-            // arrange
-            String name = "   ";
-
-            // act
-            CoreException result = assertThrows(CoreException.class, () -> {
-                new ExampleModel(name, "설명");
-            });
-
-            // assert
-            assertThat(result.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
-        }
-
-        @DisplayName("설명이 비어있으면, BAD_REQUEST 예외가 발생한다.")
-        @Test
-        void throwsBadRequestException_whenDescriptionIsEmpty() {
-            // arrange
-            String description = "";
-
-            // act
-            CoreException result = assertThrows(CoreException.class, () -> {
-                new ExampleModel("제목", description);
-            });
-
-            // assert
-            assertThat(result.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
-        }
-    }
-}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/example/ExampleServiceIntegrationTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/example/ExampleServiceIntegrationTest.java
deleted file mode 100644
index bbd5fdbe1..000000000
--- a/apps/commerce-api/src/test/java/com/loopers/domain/example/ExampleServiceIntegrationTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package com.loopers.domain.example;
-
-import com.loopers.infrastructure.example.ExampleJpaRepository;
-import com.loopers.support.error.CoreException;
-import com.loopers.support.error.ErrorType;
-import com.loopers.utils.DatabaseCleanUp;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Nested;
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertAll;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-@SpringBootTest
-class ExampleServiceIntegrationTest {
-    @Autowired
-    private ExampleService exampleService;
-
-    @Autowired
-    private ExampleJpaRepository exampleJpaRepository;
-
-    @Autowired
-    private DatabaseCleanUp databaseCleanUp;
-
-    @AfterEach
-    void tearDown() {
-        databaseCleanUp.truncateAllTables();
-    }
-
-    @DisplayName("예시를 조회할 때,")
-    @Nested
-    class Get {
-        @DisplayName("존재하는 예시 ID를 주면, 해당 예시 정보를 반환한다.")
-        @Test
-        void returnsExampleInfo_whenValidIdIsProvided() {
-            // arrange
-            ExampleModel exampleModel = exampleJpaRepository.save(
-                new ExampleModel("예시 제목", "예시 설명")
-            );
-
-            // act
-            ExampleModel result = exampleService.getExample(exampleModel.getId());
-
-            // assert
-            assertAll(
-                () -> assertThat(result).isNotNull(),
-                () -> assertThat(result.getId()).isEqualTo(exampleModel.getId()),
-                () -> assertThat(result.getName()).isEqualTo(exampleModel.getName()),
-                () -> assertThat(result.getDescription()).isEqualTo(exampleModel.getDescription())
-            );
-        }
-
-        @DisplayName("존재하지 않는 예시 ID를 주면, NOT_FOUND 예외가 발생한다.")
-        @Test
-        void throwsException_whenInvalidIdIsProvided() {
-            // arrange
-            Long invalidId = 999L; // Assuming this ID does not exist
-
-            // act
-            CoreException exception = assertThrows(CoreException.class, () -> {
-                exampleService.getExample(invalidId);
-            });
-
-            // assert
-            assertThat(exception.getErrorType()).isEqualTo(ErrorType.NOT_FOUND);
-        }
-    }
-}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/members/MemberModelTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/members/MemberModelTest.java
new file mode 100644
index 000000000..5457fa32f
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/members/MemberModelTest.java
@@ -0,0 +1,83 @@
+package com.loopers.domain.members;
+
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+class MemberModelTest {
+
+    @DisplayName("Member 객체를 생성 시,")
+    @Nested
+    class CreateMemberTest {
+
+        @DisplayName("정상 값이 들어오면 Member 객체 생성에 성공한다")
+        @Test
+        void shouldSaveMember_whenRequestIsValid() {
+            MemberModel member = new MemberModel("test123", "test@example.com", "password123", "1990-01-01", Gender.MALE);
+
+            assertThat(member).isNotNull();
+            assertThat(member.getMemberId()).isEqualTo("test123");
+            assertThat(member.getEmail()).isEqualTo("test@example.com");
+            assertThat(member.getBirthDate()).isEqualTo(java.time.LocalDate.of(1990, 1, 1));
+            assertThat(member.getGender()).isEqualTo(Gender.MALE);
+        }
+
+        @ParameterizedTest
+        @ValueSource(strings = {"abcdefghijklmn", "abc123daas456"})
+        @DisplayName("Member ID가 10자 초과이면 예외가 발생한다")
+        void shouldThrowException_whenMemberIdTooLong(String invalidMemberId) {
+            assertThatThrownBy(() ->
+                    new MemberModel(invalidMemberId, "test@example.com", "password", "2002-02-02", Gender.FEMALE)
+            ).isInstanceOf(CoreException.class)
+                    .hasMessageContaining("ID는 영문 및 숫자 10자 이내여야 합니다.");
+        }
+
+        @ParameterizedTest
+        @ValueSource(strings = {"aaa", "bcdef"})
+        @DisplayName("ID가 영문으로만 이루어지면 예외가 발생한다")
+        void shouldThrowException_IfMemberIdIsLetterOnly(String letterOnlyId) {
+            assertThatThrownBy(() ->
+                    new MemberModel(letterOnlyId, "test@example.com", "password", "2002-02-02", Gender.FEMALE)
+            ).isInstanceOf(CoreException.class)
+                    .hasMessageContaining("ID는 영문 및 숫자 10자 이내여야 합니다.");
+        }
+
+        @ParameterizedTest
+        @ValueSource(strings = {"123", "44445"})
+        @DisplayName("ID가 숫자로만 이루어지면 예외가 발생한다")
+        void shouldThrowException_IfMemberIdIsNumberOnly(String numberOnlyId) {
+            assertThatThrownBy(() ->
+                    new MemberModel(numberOnlyId, "test@example.com", "password", "2002-02-02", Gender.FEMALE)
+            ).isInstanceOf(CoreException.class)
+                    .hasMessageContaining("ID는 영문 및 숫자 10자 이내여야 합니다.");
+        }
+
+        @ParameterizedTest
+        @ValueSource(strings = {"test@", "@example.com", "test@example"})
+        @DisplayName("이메일이 xx@yy.zz 형식에 맞지 않으면, Member 객체 생성에 실패한다")
+        void shouldThrowException_whenEmailFormatIsInvalid(String invalidEmail) {
+            assertThatThrownBy(() ->
+                    new MemberModel("test123", invalidEmail, "password", "1990-01-01", Gender.MALE)
+            ).isInstanceOf(CoreException.class)
+                    .hasMessageContaining("이메일은 xx@yy.zz 형식이어야 합니다.");
+        }
+
+        @ParameterizedTest
+        @ValueSource(strings = {"19900101", "1990/01/01", "90-01-01", "1990-13-01", "1990-01-32"})
+        @DisplayName("생년월일이 yyyy-MM-dd 형식에 맞지 않으면, Member 객체 생성에 실패한다")
+        void shouldThrowException_whenBirthDateFormatIsInvalid(String invalidBirthDate) {
+            assertThatThrownBy(() ->
+                    new MemberModel("test123", "test@example.com", "password", invalidBirthDate, Gender.MALE)
+            ).isInstanceOf(CoreException.class)
+                    .hasMessageContaining("생년월일은 yyyy-MM-dd 형식이어야 합니다.");
+        }
+
+    }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/members/MemberServiceIntegrationTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/members/MemberServiceIntegrationTest.java
new file mode 100644
index 000000000..c85217430
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/members/MemberServiceIntegrationTest.java
@@ -0,0 +1,93 @@
+package com.loopers.domain.members;
+
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import com.loopers.utils.DatabaseCleanUp;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertAll;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+@SpringBootTest
+class MemberServiceIntegrationTest {
+
+    @Autowired
+    private MemberService memberService;
+
+    @MockitoSpyBean
+    private MemberRepository memberRepository;
+
+    @Autowired
+    private DatabaseCleanUp databaseCleanUp;
+
+    @AfterEach
+    void tearDown() {
+        databaseCleanUp.truncateAllTables();
+    }
+
+    @DisplayName("회원 가입 시,")
+    @Nested
+    class RegisterMember {
+
+        @DisplayName("회원 가입시 Member 저장이 수행된다 (spy)")
+        @Test
+        void shouldSaveMember_whenMemberRegisters() {
+            assertThat(memberRepository).isNotNull();
+            memberService.registerMember("test123", "test@example.com", "password", "1990-01-01", Gender.MALE);
+            verify(memberRepository, times(1)).save(any(MemberModel.class));
+
+            boolean exists = memberRepository.existsByMemberId("test123");
+            assertThat(exists).isTrue();
+        }
+
+        @DisplayName("이미 가입된 ID로 회원가입 시도 시, 실패한다")
+        @Test
+        void shouldThrowException_whenDuplicateMemberIdIsUsed() {
+            memberService.registerMember("test123", "test@example.com", "password", "1990-01-01", Gender.MALE);
+
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                memberService.registerMember("test123", "kim@example.com", "password", "1985-05-05", Gender.MALE);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.CONFLICT);
+        }
+    }
+
+    @DisplayName("회원 조회 시,")
+    @Nested
+    class GetMember {
+
+        @DisplayName("해당 ID의 회원이 존재할 경우, 회원 정보가 반환된다")
+        @Test
+        void shouldReturnMemberInfo_whenMemberExists() {
+            memberService.registerMember("test123", "test@example.com", "password", "1990-01-01", Gender.MALE);
+
+            MemberModel result = memberService.getMemberByMemberId("test123");
+
+            assertAll(
+                    () -> assertThat(result).isNotNull(),
+                    () -> assertThat(result.getMemberId()).isEqualTo("test123"),
+                    () -> assertThat(result.getEmail()).isEqualTo("test@example.com"),
+                    () -> assertThat(result.getGender()).isEqualTo(Gender.MALE)
+            );
+        }
+
+        @DisplayName("해당 ID의 회원이 존재하지 않을 경우, null이 반환된다")
+        @Test
+        void shouldReturnNull_whenMemberDoesNotExist() {
+            MemberModel result = memberService.getMemberByMemberId("nonexistent");
+
+            assertThat(result).isNull();
+        }
+    }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/members/MemberServicePasswordTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/members/MemberServicePasswordTest.java
new file mode 100644
index 000000000..be68d1e07
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/members/MemberServicePasswordTest.java
@@ -0,0 +1,62 @@
+package com.loopers.domain.members;
+
+import com.loopers.utils.DatabaseCleanUp;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@SpringBootTest
+class MemberServicePasswordTest {
+
+    @Autowired
+    private MemberService memberService;
+
+    @Autowired
+    private MemberRepository memberRepository;
+
+    @Autowired
+    private PasswordEncoder passwordEncoder;
+
+    @Autowired
+    private DatabaseCleanUp databaseCleanUp;
+
+    @AfterEach
+    void tearDown() {
+        databaseCleanUp.truncateAllTables();
+    }
+
+    @DisplayName("회원 가입 시 비밀번호가 암호화되어 저장된다")
+    @Test
+    void shouldEncryptPassword_whenRegisterMember() {
+        String plainPassword = "password123";
+
+        memberService.registerMember("test123", "홍길동", "test@example.com", plainPassword, "1990-01-01", "MALE");
+
+        MemberModel savedMember = memberRepository.findByMemberId("test123").orElseThrow();
+
+        assertThat(savedMember.getPassword()).isNotEqualTo(plainPassword);
+        assertThat(savedMember.getPassword()).startsWith("$2a$");
+        assertThat(passwordEncoder.matches(plainPassword, savedMember.getPassword())).isTrue();
+    }
+
+    @DisplayName("같은 비밀번호라도 매번 다른 해시값이 생성된다")
+    @Test
+    void shouldGenerateDifferentHash_forSamePassword() {
+        String plainPassword = "password123";
+
+        memberService.registerMember("test1", "홍길동1", "test1@example.com", plainPassword, "1990-01-01", "MALE");
+        memberService.registerMember("test2", "홍길동2", "test2@example.com", plainPassword, "1990-01-01", "MALE");
+
+        MemberModel member1 = memberRepository.findByMemberId("test1").orElseThrow();
+        MemberModel member2 = memberRepository.findByMemberId("test2").orElseThrow();
+
+        assertThat(member1.getPassword()).isNotEqualTo(member2.getPassword());
+        assertThat(passwordEncoder.matches(plainPassword, member1.getPassword())).isTrue();
+        assertThat(passwordEncoder.matches(plainPassword, member2.getPassword())).isTrue();
+    }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/points/PointServiceIntegrationTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/points/PointServiceIntegrationTest.java
new file mode 100644
index 000000000..ff346ca69
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/points/PointServiceIntegrationTest.java
@@ -0,0 +1,51 @@
+package com.loopers.domain.points;
+
+import com.loopers.utils.DatabaseCleanUp;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import java.math.BigDecimal;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@SpringBootTest
+class PointServiceIntegrationTest {
+    @Autowired
+    private PointService pointService;
+
+    @Autowired
+    private DatabaseCleanUp databaseCleanUp;
+
+    @AfterEach
+    void tearDown() {
+        databaseCleanUp.truncateAllTables();
+    }
+
+    @DisplayName("포인트 조회 시,")
+    @Nested
+    class GetMemberPoints {
+        
+        @DisplayName("해당 ID의 회원이 존재할 경우, 보유 포인트가 반환된다")
+        @Test
+        void shouldReturnPoints_whenMemberExists() {
+            String memberId = "test123";
+            pointService.initializeMemberPoints(memberId);
+
+            BigDecimal result = pointService.getMemberPoints(memberId);
+
+            assertThat(result).isEqualTo(BigDecimal.ZERO);
+        }
+
+        @DisplayName("해당 ID의 회원이 존재하지 않을 경우, null이 반환된다")
+        @Test
+        void shouldReturnNull_whenMemberDoesNotExist() {
+            BigDecimal result = pointService.getMemberPoints("nonexistent");
+
+            assertThat(result).isNull();
+        }
+    }
+}
\ No newline at end of file
diff --git a/apps/commerce-api/src/test/java/com/loopers/interfaces/api/ExampleV1ApiE2ETest.java b/apps/commerce-api/src/test/java/com/loopers/interfaces/api/ExampleV1ApiE2ETest.java
deleted file mode 100644
index 1bb3dba65..000000000
--- a/apps/commerce-api/src/test/java/com/loopers/interfaces/api/ExampleV1ApiE2ETest.java
+++ /dev/null
@@ -1,114 +0,0 @@
-package com.loopers.interfaces.api;
-
-import com.loopers.domain.example.ExampleModel;
-import com.loopers.infrastructure.example.ExampleJpaRepository;
-import com.loopers.interfaces.api.example.ExampleV1Dto;
-import com.loopers.utils.DatabaseCleanUp;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Nested;
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.web.client.TestRestTemplate;
-import org.springframework.core.ParameterizedTypeReference;
-import org.springframework.http.HttpEntity;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-
-import java.util.function.Function;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertAll;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
-class ExampleV1ApiE2ETest {
-
-    private static final Function<Long, String> ENDPOINT_GET = id -> "/api/v1/examples/" + id;
-
-    private final TestRestTemplate testRestTemplate;
-    private final ExampleJpaRepository exampleJpaRepository;
-    private final DatabaseCleanUp databaseCleanUp;
-
-    @Autowired
-    public ExampleV1ApiE2ETest(
-        TestRestTemplate testRestTemplate,
-        ExampleJpaRepository exampleJpaRepository,
-        DatabaseCleanUp databaseCleanUp
-    ) {
-        this.testRestTemplate = testRestTemplate;
-        this.exampleJpaRepository = exampleJpaRepository;
-        this.databaseCleanUp = databaseCleanUp;
-    }
-
-    @AfterEach
-    void tearDown() {
-        databaseCleanUp.truncateAllTables();
-    }
-
-    @DisplayName("GET /api/v1/examples/{id}")
-    @Nested
-    class Get {
-        @DisplayName("존재하는 예시 ID를 주면, 해당 예시 정보를 반환한다.")
-        @Test
-        void returnsExampleInfo_whenValidIdIsProvided() {
-            // arrange
-            ExampleModel exampleModel = exampleJpaRepository.save(
-                new ExampleModel("예시 제목", "예시 설명")
-            );
-            String requestUrl = ENDPOINT_GET.apply(exampleModel.getId());
-
-            // act
-            ParameterizedTypeReference<ApiResponse<ExampleV1Dto.ExampleResponse>> responseType = new ParameterizedTypeReference<>() {};
-            ResponseEntity<ApiResponse<ExampleV1Dto.ExampleResponse>> response =
-                testRestTemplate.exchange(requestUrl, HttpMethod.GET, new HttpEntity<>(null), responseType);
-
-            // assert
-            assertAll(
-                () -> assertTrue(response.getStatusCode().is2xxSuccessful()),
-                () -> assertThat(response.getBody().data().id()).isEqualTo(exampleModel.getId()),
-                () -> assertThat(response.getBody().data().name()).isEqualTo(exampleModel.getName()),
-                () -> assertThat(response.getBody().data().description()).isEqualTo(exampleModel.getDescription())
-            );
-        }
-
-        @DisplayName("숫자가 아닌 ID 로 요청하면, 400 BAD_REQUEST 응답을 받는다.")
-        @Test
-        void throwsBadRequest_whenIdIsNotProvided() {
-            // arrange
-            String requestUrl = "/api/v1/examples/나나";
-
-            // act
-            ParameterizedTypeReference<ApiResponse<ExampleV1Dto.ExampleResponse>> responseType = new ParameterizedTypeReference<>() {};
-            ResponseEntity<ApiResponse<ExampleV1Dto.ExampleResponse>> response =
-                testRestTemplate.exchange(requestUrl, HttpMethod.GET, new HttpEntity<>(null), responseType);
-
-            // assert
-            assertAll(
-                () -> assertTrue(response.getStatusCode().is4xxClientError()),
-                () -> assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST)
-            );
-        }
-
-        @DisplayName("존재하지 않는 예시 ID를 주면, 404 NOT_FOUND 응답을 받는다.")
-        @Test
-        void throwsException_whenInvalidIdIsProvided() {
-            // arrange
-            Long invalidId = -1L;
-            String requestUrl = ENDPOINT_GET.apply(invalidId);
-
-            // act
-            ParameterizedTypeReference<ApiResponse<ExampleV1Dto.ExampleResponse>> responseType = new ParameterizedTypeReference<>() {};
-            ResponseEntity<ApiResponse<ExampleV1Dto.ExampleResponse>> response =
-                testRestTemplate.exchange(requestUrl, HttpMethod.GET, new HttpEntity<>(null), responseType);
-
-            // assert
-            assertAll(
-                () -> assertTrue(response.getStatusCode().is4xxClientError()),
-                () -> assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND)
-            );
-        }
-    }
-}
diff --git a/apps/commerce-api/src/test/java/com/loopers/interfaces/api/members/MemberPasswordSecurityTest.java b/apps/commerce-api/src/test/java/com/loopers/interfaces/api/members/MemberPasswordSecurityTest.java
new file mode 100644
index 000000000..085cb2bc3
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/interfaces/api/members/MemberPasswordSecurityTest.java
@@ -0,0 +1,89 @@
+package com.loopers.interfaces.api.members;
+
+import com.loopers.application.members.MemberFacade;
+import com.loopers.utils.DatabaseCleanUp;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+class MemberPasswordSecurityTest {
+
+    private final TestRestTemplate testRestTemplate;
+    private final MemberFacade memberFacade;
+    private final DatabaseCleanUp databaseCleanUp;
+
+    @Autowired
+    public MemberPasswordSecurityTest(
+            TestRestTemplate testRestTemplate,
+            MemberFacade memberFacade,
+            DatabaseCleanUp databaseCleanUp
+    ) {
+        this.testRestTemplate = testRestTemplate;
+        this.memberFacade = memberFacade;
+        this.databaseCleanUp = databaseCleanUp;
+    }
+
+    @AfterEach
+    void tearDown() {
+        databaseCleanUp.truncateAllTables();
+    }
+
+    @DisplayName("회원 가입 응답에 비밀번호가 포함되지 않는다")
+    @Test
+    void shouldNotIncludePassword_inRegistrationResponse() {
+        MemberV1Dto.MemberRegisterRequest request = new MemberV1Dto.MemberRegisterRequest(
+                "test123", "홍길동", "test@example.com", "secretPassword123", "1990-01-01", "MALE"
+        );
+
+        ResponseEntity<String> response = testRestTemplate.exchange(
+                "/api/v1/members/register",
+                HttpMethod.POST,
+                new HttpEntity<>(request),
+                String.class
+        );
+
+        String responseBody = response.getBody();
+
+        assertThat(responseBody).doesNotContain("password");
+        assertThat(responseBody).doesNotContain("secretPassword123");
+
+        assertThat(responseBody).contains("test123");
+        assertThat(responseBody).contains("홍길동");
+        assertThat(responseBody).contains("test@example.com");
+    }
+
+    @DisplayName("내 정보 조회 응답에 비밀번호가 포함되지 않는다")
+    @Test
+    void shouldNotIncludePassword_inMemberInfoResponse() {
+        memberFacade.registerMember("test123", "홍길동", "test@example.com", "secretPassword123", "1990-01-01", "MALE");
+
+        HttpHeaders headers = new HttpHeaders();
+        headers.set("X-USER-ID", "test123");
+
+        ResponseEntity<String> response = testRestTemplate.exchange(
+                "/api/v1/members/me",
+                HttpMethod.GET,
+                new HttpEntity<>(null, headers),
+                String.class
+        );
+
+        String responseBody = response.getBody();
+
+        assertThat(responseBody).doesNotContain("password");
+        assertThat(responseBody).doesNotContain("secretPassword123");
+
+        assertThat(responseBody).contains("test123");
+        assertThat(responseBody).contains("홍길동");
+        assertThat(responseBody).contains("test@example.com");
+    }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/interfaces/api/members/MemberV1ApiE2ETest.java b/apps/commerce-api/src/test/java/com/loopers/interfaces/api/members/MemberV1ApiE2ETest.java
new file mode 100644
index 000000000..4689342cf
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/interfaces/api/members/MemberV1ApiE2ETest.java
@@ -0,0 +1,140 @@
+package com.loopers.interfaces.api.members;
+
+import com.loopers.application.members.MemberFacade;
+import com.loopers.interfaces.api.ApiResponse;
+import com.loopers.utils.DatabaseCleanUp;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.*;
+
+import java.util.Objects;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertAll;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+class MemberV1ApiE2ETest {
+
+    private final TestRestTemplate testRestTemplate;
+    private final MemberFacade memberFacade;
+    private final DatabaseCleanUp databaseCleanUp;
+
+    @Autowired
+    public MemberV1ApiE2ETest(
+            TestRestTemplate testRestTemplate,
+            MemberFacade memberFacade,
+            DatabaseCleanUp databaseCleanUp
+    ) {
+        this.testRestTemplate = testRestTemplate;
+        this.memberFacade = memberFacade;
+        this.databaseCleanUp = databaseCleanUp;
+    }
+
+    @AfterEach
+    void tearDown() {
+        databaseCleanUp.truncateAllTables();
+    }
+
+    @DisplayName("회원 가입 (POST /api/v1/members/register)")
+    @Nested
+    class MemberRegistration {
+
+        @DisplayName("유효한 정보로 가입 시 201과 회원 정보를 반환한다")
+        @Test
+        void shouldReturn201AndMemberInfo_whenValidDataProvided() {
+            MemberV1Dto.MemberRegisterRequest request = new MemberV1Dto.MemberRegisterRequest(
+                    "test123", "홍길동", "test@example.com", "password", "1990-01-01", "MALE"
+            );
+
+            ParameterizedTypeReference<ApiResponse<MemberV1Dto.MemberResponse>> responseType =
+                    new ParameterizedTypeReference<>() {
+                    };
+            ResponseEntity<ApiResponse<MemberV1Dto.MemberResponse>> response =
+                    testRestTemplate.exchange("/api/v1/members/register", HttpMethod.POST,
+                            new HttpEntity<>(request), responseType);
+
+            assertAll(
+                    () -> assertTrue(response.getStatusCode().is2xxSuccessful()),
+                    () -> assertThat(Objects.requireNonNull(response.getBody()).data().memberId()).isEqualTo("test123"),
+                    () -> assertThat(Objects.requireNonNull(response.getBody()).data().name()).isEqualTo("홍길동"),
+                    () -> assertThat(Objects.requireNonNull(response.getBody()).data().email()).isEqualTo("test@example.com"),
+                    () -> assertThat(Objects.requireNonNull(response.getBody()).data().gender()).isEqualTo("MALE")
+            );
+        }
+
+        @DisplayName("성별이 누락된 경우 400 Bad Request를 반환한다")
+        @Test
+        void shouldReturn400_whenGenderIsMissing() {
+            MemberV1Dto.MemberRegisterRequest request = new MemberV1Dto.MemberRegisterRequest(
+                    "test123", "홍길동", "test@example.com", "password", "1990-01-01", null
+            );
+
+            ParameterizedTypeReference<ApiResponse<MemberV1Dto.MemberResponse>> responseType =
+                    new ParameterizedTypeReference<>() {
+                    };
+            ResponseEntity<ApiResponse<MemberV1Dto.MemberResponse>> response =
+                    testRestTemplate.exchange("/api/v1/members/register", HttpMethod.POST,
+                            new HttpEntity<>(request), responseType);
+
+            assertAll(
+                    () -> assertTrue(response.getStatusCode().is4xxClientError()),
+                    () -> assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST)
+            );
+        }
+    }
+
+    @DisplayName("내 정보 조회 (GET /api/v1/members/me)")
+    @Nested
+    class MyInfoRetrieval {
+
+        @DisplayName("유효한 사용자 ID로 조회 시 200과 회원 정보를 반환한다")
+        @Test
+        void shouldReturn200AndMemberInfo_whenValidUserIdProvided() {
+            memberFacade.registerMember("test123", "홍길동", "test@example.com", "password", "1990-01-01", "MALE");
+
+            HttpHeaders headers = new HttpHeaders();
+            headers.set("X-USER-ID", "test123");
+
+            ParameterizedTypeReference<ApiResponse<MemberV1Dto.MemberResponse>> responseType =
+                    new ParameterizedTypeReference<>() {
+                    };
+            ResponseEntity<ApiResponse<MemberV1Dto.MemberResponse>> response =
+                    testRestTemplate.exchange("/api/v1/members/me", HttpMethod.GET,
+                            new HttpEntity<>(null, headers), responseType);
+
+            assertAll(
+                    () -> assertTrue(response.getStatusCode().is2xxSuccessful()),
+                    () -> assertThat(response.getBody().data().memberId()).isEqualTo("test123"),
+                    () -> assertThat(response.getBody().data().name()).isEqualTo("홍길동"),
+                    () -> assertThat(response.getBody().data().email()).isEqualTo("test@example.com")
+            );
+        }
+
+        @DisplayName("존재하지 않는 사용자 ID로 조회 시 404를 반환한다")
+        @Test
+        void shouldReturn404_whenUserNotFound() {
+            HttpHeaders headers = new HttpHeaders();
+            headers.set("X-USER-ID", "nonexistent");
+
+            ParameterizedTypeReference<ApiResponse<MemberV1Dto.MemberResponse>> responseType =
+                    new ParameterizedTypeReference<>() {
+                    };
+            ResponseEntity<ApiResponse<MemberV1Dto.MemberResponse>> response =
+                    testRestTemplate.exchange("/api/v1/members/me", HttpMethod.GET,
+                            new HttpEntity<>(null, headers), responseType);
+
+            assertAll(
+                    () -> assertTrue(response.getStatusCode().is4xxClientError()),
+                    () -> assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND)
+            );
+        }
+    }
+
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/interfaces/api/points/PointV1ApiE2ETest.java b/apps/commerce-api/src/test/java/com/loopers/interfaces/api/points/PointV1ApiE2ETest.java
new file mode 100644
index 000000000..d2ba1fdd5
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/interfaces/api/points/PointV1ApiE2ETest.java
@@ -0,0 +1,88 @@
+package com.loopers.interfaces.api.points;
+
+import com.loopers.application.members.MemberFacade;
+import com.loopers.interfaces.api.ApiResponse;
+import com.loopers.utils.DatabaseCleanUp;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+
+import java.math.BigDecimal;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertAll;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+class PointV1ApiE2ETest {
+
+    private final TestRestTemplate testRestTemplate;
+    private final MemberFacade memberFacade;
+    private final DatabaseCleanUp databaseCleanUp;
+
+    @Autowired
+    public PointV1ApiE2ETest(
+            TestRestTemplate testRestTemplate,
+            MemberFacade memberFacade,
+            DatabaseCleanUp databaseCleanUp
+    ) {
+        this.testRestTemplate = testRestTemplate;
+        this.memberFacade = memberFacade;
+        this.databaseCleanUp = databaseCleanUp;
+    }
+
+    @AfterEach
+    void tearDown() {
+        databaseCleanUp.truncateAllTables();
+    }
+
+    @DisplayName("포인트 조회 (GET /api/v1/points)")
+    @Nested
+    class PointInquiry {
+        
+        @DisplayName("유효한 사용자 ID로 조회 시 200과 보유 포인트를 반환한다")
+        @Test
+        void shouldReturn200AndPoints_whenValidUserIdProvided() {
+            memberFacade.registerMember("test123", "홍길동", "test@example.com", "password", "1990-01-01", "MALE");
+
+            HttpHeaders headers = new HttpHeaders();
+            headers.set("X-USER-ID", "test123");
+
+            ParameterizedTypeReference<ApiResponse<PointV1Dto.PointResponse>> responseType = 
+                    new ParameterizedTypeReference<>() {};
+            ResponseEntity<ApiResponse<PointV1Dto.PointResponse>> response =
+                    testRestTemplate.exchange("/api/v1/points", HttpMethod.GET, 
+                            new HttpEntity<>(null, headers), responseType);
+
+            assertAll(
+                    () -> assertTrue(response.getStatusCode().is2xxSuccessful()),
+                    () -> assertThat(response.getBody().data().points()).isEqualTo(BigDecimal.ZERO)
+            );
+        }
+
+        @DisplayName("X-USER-ID 헤더가 누락된 경우 400 Bad Request를 반환한다")
+        @Test
+        void shouldReturn400_whenUserIdHeaderIsMissing() {
+            ParameterizedTypeReference<ApiResponse<PointV1Dto.PointResponse>> responseType = 
+                    new ParameterizedTypeReference<>() {};
+            ResponseEntity<ApiResponse<PointV1Dto.PointResponse>> response =
+                    testRestTemplate.exchange("/api/v1/points", HttpMethod.GET, 
+                            new HttpEntity<>(null), responseType);
+
+            assertAll(
+                    () -> assertTrue(response.getStatusCode().is4xxClientError()),
+                    () -> assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST)
+            );
+        }
+    }
+}
\ No newline at end of file
