결제 시스템 디자인을 어떻게 해야 좋을까요?

조회수 2140회

레일즈로 안드로이드 클라이언트를 위한 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

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)