결제 시스템 디자인을 어떻게 해야 좋을까요?
조회수 2158회
레일즈로 안드로이드 클라이언트를 위한 REST API를 구축하여 사용 중입니다.
저희 서비스의 결제 방법은 기본적으로 정기결제를 사용합니다. 첫 구매시에 결제가 이뤄지고, 유저가 Purchase에 count를 올리다가 일정 시기가 되면 다시 결제 요청을 보내는 방식입니다.
이를 구현하기 위해서 Purchase 모델 내에 아래와 같이 구현되어 있는데요
class Purchase << ActiveRecord::Base
validate :request_payment, if: :is_payday?
def request_payment
response = PaymentService.purchase(...)
if response.success?
...
else
body = JSON.parse(response.body)
errors.add(:wallet, body['message'])
end
end
def is_payday?
...
end
end
제가 해결하고 싶은 문제는 1. 일단 validate 단에서 결제요청을 하고 있는 부분이 찝찝하고 (실제 validation은 아니지만 결제 실패 시에 Purchase의 count 가 올라가면 안되서 validate 에서 처리하고 있습니다) 2. Model에서 하는 역할이 너무 커서 Service 오브젝트로 빼던가 Observing을 하던가 해서 리팩토링하고 싶습니다.
딱히 좋은 해결책이 떠오르지 않아 도움을 요청합니다
-
(•́ ✖ •̀)
알 수 없는 사용자
2 답변
-
다음과 같이 before_save에서 결제 처리를 하고, 에러가 발생한 경우 errors에 에러를 추가하고, return false를 하시면 될 것 같습니다.
class Purchase << ActiveRecord::Base before_save :request_payment, if: :is_payday? def request_payment begin PaymentService.purchase(...) rescue => e errors.add(:base, "결제 오류") return false end true end def is_payday? ... end end
-
(•́ ✖ •̀)
알 수 없는 사용자
-
-
결제 요청을 model에서 callback을 통해서 하는 것보다 controller에서 명시적으로 호출하는 것이 더 낫지 않을까 생각됩니다.
그리고, request_payment 메소드에서 response를 parsing하고 에러 처리를 하는 것보다 PaymentService.purchase 내에서 처리하고 에러가 난 경우 exception으로 처리하시면 어떨까 싶습니다.
-
(•́ ✖ •̀)
알 수 없는 사용자
- controller에서 명시적으로 호출하는 것도 생각했었는데요 create와 update 두 부분에서 호출해야 하는 점이 맘에 걸려서 모델에서 처리하려고 했긴 합니다. 그리고 지금 API용 controller와 Web의 controller가 분리되어 있어서 두 controller에 구현해야 하기도 하구요. 알 수 없는 사용자 2016.3.25 15:10
- 에러를 exception 처리하는 건 그렇게 수정하는게 더 나을 것 같습니다 :D 감사드려요 알 수 없는 사용자 2016.3.25 15:10
- 만약 callback에서 해야한다면 validate보다는 after_save callback에서 하는게 더 나아보입니다 ^^ 알 수 없는 사용자 2016.3.25 15:24
- after_save callback에서 했었는데요 그러면 error가 추가가 되지 않더라구요. 그렇게 되면 결제가 실패했을 때 save 된 건 rollback 해줘야 하구요. 제가 잘 못 알고 있을까요? 알 수 없는 사용자 2016.3.25 15:26
-
댓글 입력