오늘은 어제의 로직을 이어서 이번엔 실제로 결제는 안되지만 결제가 된다는 느낌을 가지는 테스트로 결제를 하게 된다면 다이아를 추가되는 로직을 추가했다.
우선 사진으로 보자면

기본 아이템 상점에 다이아를 추가할 수 있게 추가했다.

구매하기 누르면 이렇게 자신의 상품내용하고 가격, 결제방법을 선택할 수 있다.

이렇게 각자 결제 방법에 맞게 입력을 해주고 다음으로 넘어가면

이런식으로 충전이 완료되었다는 메세지 하고

실제로 다이아가 추가가 된게 보인다.(사진찍겠다고 한번 넘어가버려서 다시 한번 더 한건 안비밀)
# TIL (Today I Learned) - Toss 결제 연동과 다이아 충전 구현
## 1. 구현 목표
- Toss Payments를 이용한 결제 시스템 구축
- 결제 완료 후 사용자의 다이아 수량 자동 업데이트
- 안전한 결제 처리와 사용자 인증 구현
## 2. 주요 구현 내용
### 2.1 결제 프로세스 구현
```typescript
// UserService에 다이아 충전 메서드 추가
async chargeDiamond(userId: number, amount: number) {
try {
const user = await this.userRepository.findId(userId);
if (!user) {
throw new NotFoundException('사용자를 찾을 수 없습니다.');
}
// 다이아 수량 업데이트
const updateData: UpdateUserDto = {
pink_dia: user.pink_dia + amount
};
await this.userRepository.updateUser(userId, updateData);
// 캐시 업데이트
const cacheKey = `user:${user.email}`;
const cachedUser = await this.valkeyService.get<CachedUser>(cacheKey);
if (cachedUser) {
cachedUser.pink_dia = user.pink_dia + amount;
await this.valkeyService.set(cacheKey, cachedUser, 60 * 60 * 12);
}
return {
success: true,
message: `${amount} 다이아가 충전되었습니다.`,
currentDiamond: user.pink_dia + amount
};
} catch (error) {
throw new InternalServerErrorException('다이아 충전 중 오류가 발생했습니다.');
}
}
```
### 2.2 결제 완료 처리
```javascript
// success.html에서 결제 완료 후 처리
document.addEventListener('DOMContentLoaded', async () => {
const accessToken = localStorage.getItem('accessToken');
if (!accessToken) {
alert('로그인이 필요합니다.');
window.location.href = '/public/log-in.html';
return;
}
try {
if (urlParams.get('type') === 'diamond') {
const itemName = urlParams.get('itemName');
const diamondAmount = Number(itemName.replace(/[^0-9]/g, ''));
const response = await fetch('/user/charge-diamond', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `${accessToken}`
},
body: JSON.stringify({
amount: diamondAmount,
paymentKey: urlParams.get('paymentKey'),
orderId: urlParams.get('orderId')
})
});
// ... 결과 처리
}
} catch (error) {
console.error('결제 처리 실패:', error);
}
});
```
## 3. 주요 기술 포인트
### 3.1 사용자 인증
- LocalStorage에 저장된 accessToken을 활용한 사용자 인증
- API 요청 시 Authorization 헤더에 토큰 포함
### 3.2 데이터 동기화
- DB 업데이트와 캐시(Valkey) 동시 업데이트로 데이터 일관성 유지
- 트랜잭션 처리로 안전한 다이아 충전 구현
### 3.3 에러 처리
- 결제 실패, 인증 오류 등 다양한 예외 상황 처리
- 사용자에게 적절한 에러 메시지 표시
## 4. 개선사항
1. 결제 검증 로직 추가 필요
- 실제 결제 금액과 상품 금액 일치 여부 확인
- 중복 결제 방지 로직 구현
2. 보안 강화
- 토큰 만료 처리
- 결제 위변조 방지 로직 추가
3. 사용자 경험 개선
- 결제 진행 상태 표시
- 결제 실패 시 적절한 안내 메시지 제공
## 5. 학습 내용
1. Toss Payments API 연동 방법
2. 결제 프로세스 설계 및 구현
3. 캐시와 DB 동기화 처리
4. 사용자 인증 및 보안 처리
5. 프론트엔드와 백엔드 간의 데이터 흐름 관리
이제 할 건 앞으로 결제를 진행할때 취소를 누르면 다시 홈 화면이나 아님 마지막 화면(아이템상점)으로 돌아와야 되는데 아직 돌아가는 로직이 없다. 수정을 해야 될 것 같다.
따로 환불하는거나 아님 플러스할 서비스? 같은걸 추가해야 될 것 같다.
'TIL' 카테고리의 다른 글
| 80일차 TIL (0) | 2025.03.07 |
|---|---|
| 79일차 TIL (토스 구현 3일차) (0) | 2025.03.06 |
| 77일차 TIL (0) | 2025.03.03 |
| 76일차 TIL ( 면접 카타 9일차 ) (0) | 2025.02.21 |
| 75일차 TIL ( 면접 카타 8일차 ) (0) | 2025.02.20 |