개발춉
44
2020-03-03 18:44:57
6
452

토이프로젝트로 쇼핑몰 구현중인데 결제 관련해 질문드립니다.


안녕하세요 이것저것 물어가며 더듬어가며 쇼핑몰 구현을 하는중입니다.

다름아니라 결제 관련해서 모듈과 연동하는 과정에서 주문에대한 식별에 관련해서 궁금증이 있어서 질문드립니다

제가 먼저 주문 관련 프로세스를 생각했던건 

주문 페이지 -> 결제모듈 -> 주문 완료 를 통해 주문을 완성하는 것인데요,

여기서 DB상에서 궁금한것이, 결제모듈 API(https://github.com/iamport/iamport-manual/blob/master/%EC%9D%B8%EC%A6%9D%EA%B2%B0%EC%A0%9C/README.md)의 필요한 파라미터들을 보면 다른것은 다 어떻게 해야할지 감이 오지만 하나 merchant_uid 파라미터에 대해 처리가 참 애매한데요

모든 결제정보(pg사의 결제 승인번호등을) 포함한 후에 주문 db에 insert를 하고 주문 완료를 하려고 했는데

이미 결제모듈에서 해당 고유번호를 요구하기에 어떻게 처리해야할지 고민입니다.

물론 생각해보면 해당 결제에 대한 고유한 식별자가 있어야 추후에 결제사쪽에서도 해당 고유 아이디를 이용해 검색을 해보거나 문제처리가 가능하다는것도 생각이 가긴합니다.

그렇다면 해당 주문을 db에 결제 요청시 미리 insert 하고 결제완료가 되면, update를 통해서 해당 주문에 대한 결제완료 및 결제승인번호등을 넣어주고, 혹 결제시 에러가 난다면 transaction을 통해 해당 주문 내역을 무효화 해야하는 방법으로 가야할지 생각이 듭니다. 

다만, 실 생활에서도 결제취소나 결제 에러같은 일 들이 많이 일어나기 때문에 해당 로직은 상당히 무리가 있어보입니다.

선배님들께서는 해당 결제를 어떻게 처리하시는지 궁금합니다.


0
  • 답변 6

  • Doneky
    786
    2020-03-03 19:00:03

    저는 학생이라 선배님은 아니지만 저의 경험을 말씀드려볼게요.

    저도 IAMPORT사의 결제모듈을 이용한 e-Commerce 프로젝트를 진행해보았습니다


    order_id 생성 > merchant_id 생성 > iamport에서는 결제를 진행 > iapmort API에서 imp_uid와 결제상태 등등을 가져와서 제대로 결제가 된것이라면 > transaction_id ( 영수증 개념입니다) 생성


    이런 식으로 하나의 트랜잭션으로 처리했습니다.

    하나라도 정상처리가 되지 않으면 다음 단계가 진행되지 않고 모두 취소되는 방향으로요.

  • 개발춉
    44
    2020-03-03 19:07:37 작성 2020-03-03 20:04:16 수정됨

    Doneky 

    오 그러시군요 그럼 제가 위에 언급한것 처럼 order 내용을 db에 insert한 후에 해당 내용을 update하는 방식으로 가셨군요! 일단 이렇게 구현 해놓고 더 괜찮은 답변이 있으면 수정하는 방향으로 가야겠네요 ! 감사합니다.


  • 엡실론
    1k
    2020-03-03 19:40:00

    원래 생각하신게 맞습니다. iamport는 안 써봐서 디테일은 좀 차이날 수 있지만,

    merchant_id 생성 -> DB 저장 -> iamport 결제 요청 -> 응답시 DB 업데이트

    iamport에서 미응답시는
    옵션 1. 같은 merchant_id로 재요청 또는 결제 상태 조회후 DB 업데이트
    옵션 2. merchant_id로 취소 요청.


    여기서 DB 저장과 응답시 업데이트는 별개의 트랜잭션으로 처리해야 합니다. 그래야 만에하나 iamport에 결제 요청을 보내고 나서 쇼핑몰 서버가 죽더라도, 디비 자료를 바탕으로 복구할 수 있습니다.

  • 개발춉
    44
    2020-03-03 19:58:41 작성 2020-03-03 20:08:51 수정됨

    엡실론

    아 그렇군요 감사합니다~! 저도 해당 모듈의 디테일보단 전체 과정이 조금 궁금했어서요

    다만, 궁금한것이 있는데  DB 저장과 응답시 트랜잭션을 별개로 하라고 말씀하셨는데,  결제 모듈에서 미응답 시 

    결제가 실패하고 유저가 해당 주문을 취소할 경우에 말씀하신 옵션2의 경우가 해당되는것 같은데 그러면 트랜잭션을 통해 해당 이력이 rollback 되는것이 아니라, 그냥 해당 merchant_id를 통해 주문을 취소하라는 말씀이신거죠~?



  • 엡실론
    1k
    2020-03-03 20:10:42

    네 트랜잭션이 별개니 rollback이 아니라, merchant_id로 DB 업데이트를 통해서 시스템 로직으로 주문을 취소해야 합니다.

    혹시나 해서 조금 더 설명하면 제가 말한 응답은 결제 성공/실패를 포함합니다. 성공이든 실패든 결제 모듈에서 응답이 오면 그에 따라 주문을 진행하든, 취소하든 하면 됩니다.

    미응답시에는 두 가지 경우가 있는데, 하나는 결제가 실패한 경우, 다른 하나는 결제가 성공했으나 모종의 이유로 응답을 못 받은 경우가 있습니다. 따라서 이때는 옵션 1처럼 결제가 진짜로 성공했는지, 실패했는지를 알아내서 그에 맞게 처리하거나, 옵션 2처럼 실패했다고 간주하고 주문을 취소하고, 결제 서버에도 취소 요청을 넣어서 성공했다 하더라도 취소하는 방법이 있습니다.

  • 개발춉
    44
    2020-03-03 20:33:56 작성 2020-03-03 20:46:07 수정됨

    엡실론

    아 무슨 말씀이신지는 이해가 갑니다.

    맨처음 제가 의견을 냈던건 rollback에 의한 취소였는데 그것이 아니라, 트랜잭션을 분리하여 서비스단에서 해당 id를 검색하여 db에 입력된 주문을 취소하라고 하시는 말씀으로 이해했습니다.


    사실 제가 적은 것보다 좀더 복잡하게 구현이 되어있어서 

    주문 요청 -> 결제요청 -> 모듈결제요청 -> 모듈응답 -> 결제요청성공 -> 주문성공

    이런 식으로 두번의 DB내역 생성 로직을 한 트랜잭션에서 처리하려고 했는데 말씀해주신대로 트랜잭션을 분리하고,

    일단 결제에 대한 DB 내역만을 생성한 후에 그 성공 유무에 따라 주문 내역을 생성하는 로직으로 생각해봤습니다.

    결제요청 -> 결제생성(식별자생성) -> 모듈결제요청 -> 결제 성공시 결제내역 업데이트 -> 주문서비스 호출

                                                                              ->결제 실패시 (옵션1 : 재요청 및 업데이트) -> 주문 서비스 호출

                                                                              ->결제 실패시 (옵션2 : 결제 실패) -> 아무일도 안일어남

    요렇게가 맞을런지 모르겠지만 이렇게 하는게 좋을거 같은 생각에 한번 해보겠습니다 ㅎㅎ

    알려주셔서 너무 감사드립니다!



  • 로그인을 하시면 답변 을 등록할 수 있습니다.