Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 결제 환불 로직 리팩토링 #245

Merged
merged 30 commits into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
6b14711
fix: 3:3 조인 시 성별 체크
seogwoojin Dec 1, 2024
8e81c44
style: apply convention
seogwoojin Dec 1, 2024
1b1253d
fix: 미팅팀 나이 제한
seogwoojin Dec 1, 2024
d06482f
style: apply convention
seogwoojin Dec 1, 2024
2d35cba
style: apply convention
seogwoojin Dec 1, 2024
a661e2d
feat: 카카오톡 ID 중복 시, 유저 ID 체크
seogwoojin Dec 1, 2024
6156e55
style: apply convention
seogwoojin Dec 1, 2024
a44d70d
fix: 포트원 Access Token 생존 기간 60초로 수정
seogwoojin Dec 1, 2024
155609d
chore: merge with main
seogwoojin Dec 1, 2024
26a47e8
fix: 유저 정보 변경
seogwoojin Dec 2, 2024
eb38a99
Merge branch 'main' of https://github.com/uoslife/server-meeting into…
seogwoojin Dec 2, 2024
0a504f7
fix: 개발자 API 유저 삭제 시, 리프레시 토큰 초기화
seogwoojin Dec 2, 2024
fa333d4
chore: merge with main
seogwoojin Dec 2, 2024
9ed60c2
fix: MinAge MaxAge Null 값 거절
seogwoojin Dec 2, 2024
3befd4d
Merge branch 'main' of https://github.com/uoslife/server-meeting into…
seogwoojin Dec 2, 2024
eb69489
feat: Match API 엔드포인트 경로 변경
23tae Dec 3, 2024
87d0c5a
refactor: MatchService 파라미터 변경
23tae Dec 3, 2024
9fbc937
feat: teamType 사용 쿼리 메소드 추가
23tae Dec 3, 2024
97c5378
chore: 사용하지 않는 메서드 제거
23tae Dec 3, 2024
2bea39f
chore: 불필요한 예외 처리 삭제
23tae Dec 3, 2024
36dce8f
docs: Swagger 업데이트
23tae Dec 3, 2024
67d3d9c
refactor: getMatchedPartnerInformation API에서 불필요한 preference 정보 제거
23tae Dec 3, 2024
3610b27
feat: 매칭 API 시즌 파라미터 추가
23tae Dec 3, 2024
52395bf
feat: 필수 파라미터 누락시 에러 처리 추가
23tae Dec 3, 2024
cc96c51
Merge branch 'refactor/match-api-endpoints' of https://github.com/uos…
seogwoojin Dec 4, 2024
89498ca
chore: merge with main
seogwoojin Dec 7, 2024
9d7012a
Merge branch 'main' of https://github.com/uoslife/server-meeting into…
seogwoojin Dec 7, 2024
d0f6722
Merge branch 'main' of https://github.com/uoslife/server-meeting into…
seogwoojin Dec 7, 2024
1831a36
test: 테스트용 임시 이메일 전송 삭제
seogwoojin Dec 7, 2024
d7ad83a
feat: 매칭 안된 결제 정보 환불 로직 생성
seogwoojin Dec 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class AdminService(
fun refundPayment(
requestInfo: RequestInfoDto
): PaymentResponseDto.NotMatchedPaymentRefundResponse {
val result = paymentService.refundPayment()
val result = paymentService.refundUnmatchedPayment()
logger.info("[ADMIN-매칭 실패 유저 환불] $requestInfo")
return result
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ interface PaymentClient {
fun getAccessToken(
@RequestBody request: PortOneRequestDto.AccessTokenRequest
): PortOneResponseDto.AccessTokenResponse

@GetMapping("/payments/{impUid}", consumes = ["application/json"])
fun checkPayment(
@RequestHeader("Authorization") accessToken: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package uoslife.servermeeting.match.dto.response

import uoslife.servermeeting.meetingteam.dto.response.MeetingTeamInformationGetResponse
import uoslife.servermeeting.meetingteam.dto.response.UserCardProfile
import uoslife.servermeeting.meetingteam.entity.enums.TeamType
import uoslife.servermeeting.user.entity.enums.GenderType

data class MatchedPartnerInformationResponse(
val teamType: TeamType,
val teamName: String?,
val course: String?,
val gender: GenderType,
val code: String?,
val meetingTeamUserProfiles: List<UserCardProfile>?
)

object MeetingDtoConverter {
fun toMatchedPartnerInformationResponse(
response: MeetingTeamInformationGetResponse
): MatchedPartnerInformationResponse {
return MatchedPartnerInformationResponse(
teamType = response.teamType,
teamName = response.teamName,
course = response.course,
gender = response.gender,
code = response.code,
meetingTeamUserProfiles = response.meetingTeamUserProfiles
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ interface PaymentService {
userId: Long,
teamType: TeamType
): PaymentResponseDto.PaymentRefundResponse
fun refundPayment(): PaymentResponseDto.NotMatchedPaymentRefundResponse
fun refundUnmatchedPayment(): PaymentResponseDto.NotMatchedPaymentRefundResponse
fun verifyPayment(userId: Long, teamType: TeamType): PaymentResponseDto.PaymentRequestResponse
fun deleteUserPayment(user: User)
fun synchronizePayment(paymentWebhookResponse: PaymentResponseDto.PaymentWebhookResponse)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import org.springframework.beans.factory.annotation.Value
import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Service
import uoslife.servermeeting.global.auth.exception.ExternalApiFailedException
import uoslife.servermeeting.meetingteam.dao.MeetingTeamDao
import uoslife.servermeeting.match.dao.MatchedDao
import uoslife.servermeeting.meetingteam.dao.UserTeamDao
import uoslife.servermeeting.meetingteam.entity.MeetingTeam
import uoslife.servermeeting.meetingteam.entity.UserTeam
Expand All @@ -24,23 +24,22 @@ import uoslife.servermeeting.payment.entity.enums.PaymentStatus
import uoslife.servermeeting.payment.exception.*
import uoslife.servermeeting.payment.repository.PaymentRepository
import uoslife.servermeeting.payment.service.PaymentService
import uoslife.servermeeting.user.dao.UserDao
import uoslife.servermeeting.user.entity.User
import uoslife.servermeeting.user.entity.enums.GenderType
import uoslife.servermeeting.user.exception.UserNotFoundException
import uoslife.servermeeting.user.repository.UserRepository

@Service
@Qualifier("PortOneService")
class PortOneService(
private val userRepository: UserRepository,
private val userDao: UserDao,
private val userTeamDao: UserTeamDao,
private val paymentDao: PaymentDao,
private val meetingTeamDao: MeetingTeamDao,
private val paymentRepository: PaymentRepository,
private val validator: Validator,
private val userTeamRepository: UserTeamRepository,
private val portOneAPIService: PortOneAPIService,
private val matchedDao: MatchedDao,
@Value("\${portone.api.price.single}") private val singlePrice: Int,
@Value("\${portone.api.price.triple}") private val triplePrice: Int,
) : PaymentService {
Expand Down Expand Up @@ -284,27 +283,46 @@ class PortOneService(
}

@Transactional
override fun refundPayment(): PaymentResponseDto.NotMatchedPaymentRefundResponse {
val userList =
meetingTeamDao
.findUserIdWithMaleMeetingTeam()
.plus(meetingTeamDao.findUserIdWithFeMaleMeetingTeam())
val paymentList = userDao.findNotMatchedPayment(userList)
logger.info("Total payment count: " + paymentList.size)
override fun refundUnmatchedPayment(): PaymentResponseDto.NotMatchedPaymentRefundResponse {
val successPayments = paymentRepository.findByStatus(PaymentStatus.SUCCESS)

val unMatchedPayments = mutableListOf<Payment>()
successPayments.forEach { payment ->
if (!isMatchedPayment(payment)) {
unMatchedPayments.add(payment)
}
}
logger.info("Total unmatched payment count: " + unMatchedPayments.size)

val refundFailedList: MutableList<String> = mutableListOf()
paymentList.forEach { payment ->
unMatchedPayments.forEach { payment ->
try {
portOneAPIService.refundPayment(payment.impUid, payment.price)
updatePaymentStatus(payment, PaymentStatus.REFUND, payment.impUid!!)
val refundPayment = portOneAPIService.refundPayment(payment.impUid, payment.price)
if (refundPayment.code == 0) {
updatePaymentStatus(payment, PaymentStatus.REFUND, payment.impUid!!)
} else {
updatePaymentStatus(payment, PaymentStatus.REFUND_FAILED, payment.impUid!!)
refundFailedList.add(payment.impUid.toString())
}
} catch (e: ExternalApiFailedException) {
logger.info(
"[환불 실패] payment_id: ${payment.id}, impUid: ${payment.impUid}, marchantUid: ${payment.merchantUid}"
)
refundFailedList.add(payment.id.toString())
payment.status = PaymentStatus.REFUND_FAILED
updatePaymentStatus(payment, PaymentStatus.REFUND_FAILED, payment.impUid!!)
refundFailedList.add(payment.impUid.toString())
}
}
return PaymentResponseDto.NotMatchedPaymentRefundResponse(refundFailedList)
}

private fun isMatchedPayment(payment: Payment): Boolean {
val meetingTeam = payment.meetingTeam ?: throw MeetingTeamNotFoundException()
val matched =
when (meetingTeam.gender) {
GenderType.MALE -> {
matchedDao.findMatchByMaleTeamWithFemaleTeam(meetingTeam)
}
GenderType.FEMALE -> {
matchedDao.findMatchByFeMaleTeamWithMaleTeam(meetingTeam)
}
}
return matched != null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,6 @@ class AsyncEmailService(
.withBody(Body().withHtml(Content(emailBody)))
)
.withSource(emailFrom)
sesClient.sendEmail(request)
// sesClient.sendEmail(request)
}
}
Loading