앱을 만들다보면 피할수 없는 상황을 드디어 만났다.
이번에 다뤄볼 내용은 아임포트를 이용한 결제 시스템 연동이다.
몇년전에는 HTML에 전부 적어 웹뷰로 실행시키는 방법이 있었다고 한다.
하지만 개발자분들이 열심히 노력한 결과 아임포트 SDK를 완성시켰다.
하지만 주니어인 나에겐 구현조차 어려웠기에 차근차근 내가 한 방법과 로직을 설명하고자 한다.
로직
기본적으로 아임포트라는 회사는 결제 대행사이다. 개발자들이 각각의 결제 방식에 따라 각기 다른 결제 회사들의 모든 결제기능을 구현하려면 하염없이 시간이 지나갈텐데 아임포트는 이 것을 대신해준다고 생각하면 된다.
크게 일반결제와 정기결제로 나뉜다.
일반결제는 우리가 흔히 아는 카드번호를 입력하고 확인을 누르면 결제가 완료되는 창이 뜨는것이다.
결제방법을 선택할 수 있고 선택에 따라 pg사(나의 경우에는 KG이니시스였다.)에서 제공하는 결제화면이 나온다. 결제화면에 정보를 입력하면 앱을 만드는 사람은 알 수 없지만 기입된 정보들은 KG이니시스에 전달되고 결제가 완료된다.
앱에서는 결제완료에 대한 response값으로 성공/실패, 에러메세지를 받을수 있고 끝나는 결과에 콜백을 달아서 원하는 동작을 실행시킨다. ( 예를들어 성공시 성공fragment를 보여주거나, 실패시 실패 fragmen를 보여준다.)
정기결제는 기본적으로 구독과 비슷한 시스템이다.
원래 제공하는 이유는 카드를 아임포트에 등록을 하고 그 등록된 카드로 달마다 결제를 자동 결제하는 용도였다.
정확히는 카드 등록시 customer_uid를 입력한다. 그러면 아임포트에서는 customer_uid와 결제시 사용할 빌링키라는것을 서로 매핑시킨다. 이후에 결제를 할때 우리는 customer_uid를 던져주면 매핑된 빌링키를 이용하여 결제가 진행된다.
한번 등록하면 사용자의 추가 동의없이 등록한 카드로 결제가 되는것이다.
카드 등록 로직
카드 등록 유무를 확인후 진행되는 로직입니다.
등록 유무를 판단하여 카드를 삭제, 비밀번호 변경, 초기화가 가능하며
등록하지 않았을 경우 다음과 같은 경로를 통하여 카드를 등록합니다.
카드를 등록할때의 로직입니다.
- 먼저 클라이언트에서 빌링 생성요청을 진행합니다.
- 서버에서 빌링키를 위해 customreUid를 생성해주고 클라이언트에 내려줍니다.
- 리스폰스로 받은 uid를 이용하여 아임포트 서버에 제출할 리퀘스트를 작성합니다.
이때 리퀘스트에는 uid를 반드시 적어주어야 하는데 이것은 추후에 사용자가 등록한 카드를 사용하기 위한 빌링키라는 것과 1:1 매칭이 되며 아임포트 서버에는 빌링키가 우리 서버에는 customerUid가 등록됩니다.
- 아임포트 웹뷰가 호출되고 이곳에 카드의 정보를 제출합니다.
- 서버에 빌링이 등록 완료가 되었다는 API를 호출합니다.
- 서버에서 아임포트 서버로 카드의 정보에 관한 것들을 요청합니다.
- 서버에서의 요청을 보고 아임포트에서는 해당 customerUid에 매핑되어있는 빌링키를 확인하고 그 빌링키에 해당되는 카드에 관한 정보를 서버에 보내줍니다.
- 카드에 대한 정보를 서버에 저장하고 리스폰스로 클라이언트에 돌려줍니다.(이때 카드에 대한 정보는 카드번호 앞 6자리, 뒷1자리 그리고 카드 이름이 제공됩니다.)
- 이 시점에서 아임포트 서버에는 카드(빌링키)가 저장 : 우리 서버에는 카드(CustomerUid, 카드 정보)가 저장됩니다.
💡 기존의 아임포트 결제중 정기결제는 카드 등록을 이용한 방법은 없지만 위의 로직을 이용하여 결제를 진행할 수 있습니다.
추가적으로 등록된 카드를 이용할때 비밀번호를 사용하고싶은 경우가 있을것입니다.
이 부분은 결제서버와는 관련이 없고 순수하게 클라이언트와 서버에서 해결을 합니다.
패스워드를 등록하여 서버에 저장하고 관리합니다.
클라이언트에서는 서버의 패스워드를 이용하고 패스웓드가 일치한다면 결제를 진행시키는 방법으로 응용하여 사용이 가능합니다
다음은 일반결제에 대한 로직입니다.
- 주문을 생성합니다. 이때 말하는 주문 생성이란 추후에 아임포트서버에 제출할 리퀘스트를 채우는 과정중 하나이다.
- 서버에서는 주문 생성요청에 따른 order id를 보낸다.
- 아임포트 리퀘스트를 생성합니다. 이 객체에는 상품정보, 주문자정보, 금액, 결제방법, 전화번호, 이메일 등등이 들어갑니다.
아임포트 리퀘스트를 Iamport.payment라는 메서드의 파라미터로 넣습니다. 이것은 아임포트 서버에 리퀘스트를 보내는 동시에 웹뷰를 호출합니다.
- 결제에 관련된 정보를 입력하고 클라이언트와 서버에 결제에 대한 결과를 전달합니다.
- 클라이언트는 아임포트에서 보내주는 리스폰스에서 결과에 대한 값에 따른 콜백함수를 지정해줍니다. 저의 경우에는 성공시 서버에 결제가 정상적으로 진행되었음을 알려주고, 실패시 토스트메세지를 띄워줍니다.
- 클라이언트와 서버에 결제에 관한 결과를 알려주는데 6번은 서버에 알려주는 과정입니다.
- 서버에서는 아임포트 서버에서 전달받은 결제 결과와 클라이언트가 제출한 결제 정보를 비교합니다.
DB에서 merchant_uid를 이용하여 결제 정보를 검색하고 아임포트의 리스폰스값을 비교하여 만약 두개가 다를시 이를 알려줍니다.
다음은 결제에 대한 전체적인 로직입니다.
이처럼 결제에 관련된 사항들은 서버 2개를 동시에 신경써야하며 낯선 영역이기 때문에 처음 시작하면 어려울 수 있습니다. 하지만 안드로이드는 SDK가 있습니다.
SDK에는 일반 결제에 대한 로직과 과정만 설명이 되어있지만 혹시 저처럼 카드를 등록하여 사용하고 싶다면 정기결제를 응용할 수 있습니다.
참고 : https://blog.iamport.kr/2021/06/02/android/
리액트로 포트원(아임포트)로 카드등록만 만들려고하는데 가능한가요?? 계속 결제창이 떠서 방법을 알아보고있는데 계속 결제창만 뜨는 것 밖에 없네요 IMP.request_pay(data, callback) <- 이 함수가 결제창 이 뜨는 함수인데 카드등록창만 뜰려면 뭔가 해줘야하나요??