ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Wee.T] 아임포트(Iamport) 결제모듈을 연동하여 결제시스템 구현하기
    DEVELOP/Wee.T 2022. 9. 18. 01:47

     

     

    https://chai-iamport.gitbook.io/iamport/ready

     

    결제 연동 준비하기 - 결제연동 메뉴얼

    아임포트 회원가입 이후 관리자 페이지 내 결제연동 -> 테스트 연동 관리 탭에서 연동하고자 하는 PG사를 선택합니다.

    chai-iamport.gitbook.io

    아임포트 결제 API를 사용하면 실제 결제가 가능한 서비스를 구현해볼 수 있습니다.

    초기설정 메뉴얼은 해당 가이드를 참고하여 회원가입과 PG사 설정, 인증키를 발급받습니다.

     

     


    결제서비스의 전체적인 흐름

     

    구현한 전체적인 로직의 흐름은 다음과 같습니다.

     

    1. 클라이언트에서 결제창을 통해 결제 요청을 보낸다. (아임포트 API 사용)
    2. 결제 성공시 ajax통신을 사용하여 결제를 검증하는 컨트롤러로 요청을 보낸다.
    3. 서버에서 검증처리를 하고, 검증 성공시 DB에 저장하는 서비스 메소드를 수행한다.
    4. 서비스 메소드에서는 (1) 결제정보 저장, (2) 쿠폰사용 업데이트, (3) 수강 테이블에 등록하는 로직을 수행한다.
    4-1. 이를 트랜잭션으로 처리 후 결과를 반환한다. (ex. "SUCCESS")
    5. ajax에서 받은 응답에 따라 성공시 결제완료창으로 이동한다.
    6. 결제 완료창에서는 파라미터로 주문번호를 전달 받는다. (주문 테이블의 PK)
    7. 해당 PK로 결제정보 조회 후 model에 담아 화면에 뿌려준다.

     

     

    결제 서비스를 구현할 때에는 특히 다음 두가지 고려사항을 염두에 두었습니다.

     

    결제 서비스 구현 시 고려한 점

    1. 서버에서 한번 더 결제검증 절차를 거칠 것
    2. 결제완료 후 결제정보를 안전하게 DB에 저장할 것

     


     

    1. 결제를 요청하고 결제정보를 검증하기

     

    결제검증이란 클라이언트에서 전달받은 결제 결과 데이터를 바탕으로 결제금액 위변조 여부를 검증하는 절차입니다. 클라이언트에서 스크립트 조작을 통해 결제금액을 쉽게 변경할 수 있기 때문에 검증절차는 아임포트 가이드에서도 권장하는 방법입니다.

     

     

     

    https://github.com/iamport/iamport-rest-client-java

     

    GitHub - iamport/iamport-rest-client-java: JAVA사용자를 위한 아임포트 REST API 연동 모듈입니다

    JAVA사용자를 위한 아임포트 REST API 연동 모듈입니다. Contribute to iamport/iamport-rest-client-java development by creating an account on GitHub.

    github.com

    Java 사용자를 위한 아임포트 REST API연동 모듈을 사용하였습니다.

     

    <repositories>
        <repository>
            <id>jitpack.io</id>
            <url>https://jitpack.io</url>
        </repository>
    </repositories>
    
    <dependencies>
    	<dependency>
    	    <groupId>com.github.iamport</groupId>
    	    <artifactId>iamport-rest-client-java</artifactId>
    	    <version>0.2.22</version>
    	</dependency>
    </dependencies>

     

    pom.xml에 repository와 dependency 설정이 필요합니다.

     

     

    PayController.java

    컨트롤러에 IamportClient를 필드로 추가하고, 생성자에서 초기화 합니다.

    매개변수로는 관리자콘솔에 있는 API Key와 Secret을 추가합니다.

     

    (메소드의 리턴타입인 APIResponse는 응답정보를 저장하기 위해 직접 작성한 클래스입니다.)

     

    Payment payment = this.api.paymentByImpUid(imp_uid).getResponse(); // 검증처리

     

    해당 메소드가 검증처리를 담당합니다. 클라이언트에서 처음 결제를 수행하게되면 아임포트 서버에서 고유의 imp_uid를 반환합니다. 이 uid를 Pathvariable로 가지는 uri에 POST요청을 보내고 검증 메소드의 매개변수로 전달하도록 작성하였습니다. 

     

    메소드의 리턴값은 Payment타입으로 반환되고, getter를 통해 구매자 이름, 결제금액, 결제 수단 등의 정보를 얻어낼 수 있습니다.

     

    Payment객체는 status를 가집니다. 이 status는 문자열이며, "paid"와 "failed"로 구분됩니다.

    paid일 시 결제 처리가 성공되었다는 뜻이고, failed이면 결제처리에 실패했다는 뜻입니다.

    switch문을 사용하여 status가 paid일 시 결제정보를 저장하고, failed일 시 실패했다는 것을 클라이언트에게 알려주도록 하였습니다.

     


    2. 결제 정보를 DB에 저장하기

     

    Wee.T의 서비스는 결제 시 크게 3가지의 DB조작 로직이 필요합니다.

    1. 결제정보를 저장
    2. 쿠폰 사용 완료 처리
    3. 수강 테이블에 회원을 등록

    이 로직들은 수행과정에서 어느 하나라도 오류가 나거나 부분처리돼서는 안됩니다. 따라서 트랜잭션 처리가 필요합니다.

     

     

     

    간단한 insert문과 update문을 만들고 mapper 인터페이스에 등록해두었습니다.

     

     

    PayServiceImpl.java

    서비스 메소드에서 매개변수로 필요한 정보들을 받습니다.

    그리고 PaymentDTO 객체에 payment객체의 getter를 사용하여 저장할 정보들을 세팅합니다.

    각각의 매퍼 메소드를 수행하고, 모두 수행시 "SUCCESS"를 반환하고, 문제가 있을 경우 FAIL에 번호를 붙여 리턴하도록 하였습니다.

     

    오류코드를 반환하는 이유?

    @Transactional 어노테이션을 붙였기 때문에 자동으로 오류가 발생할 시 모두 롤백됩니다. 그러나 메소드 별로 체크해서 오류코드를 다르게 반환한 이유는, 시스템적으로는 잘 수행되었는데 insert가 0이거나 update가 0일 경우를 한번 더 체크하기 위해서입니다. 

     

     

    PayController.java

     

    다시 컨트롤러로 돌아와서, 메소드 실행 결과를 문자열 result에 담아 응답객체에 추가하고, 주문번호와 함께 반환합니다.

     

     


     

    3. 클라이언트 처리

     

     

    이 코드는 아임포트의 결제창을 띄우는 코드로, 클라이언트가 처음 결제를 진행하는 부분입니다.

    여기서 rsp.success 부분에 결제검증 컨트롤러로 요청을 보내는 로직을 작성하면 됩니다.

    저는 함수로 따로 만들어서 넣어주었습니다.

     

     

     

    컨트롤러에서 요구하는 파라미터를 수집한 후, ajax를 사용해 해당 uri로 POST요청을 보냅니다.

    작성해둔 대로 result에는 문자열이 반환됩니다.

    SUCCESS시 결제완료 창으로 이동하면 됩니다.

     

    결제완료창에는 주문번호로 결제정보를 불러와서 화면에 영수증처럼 출력되도록 구현해 놓았습니다.

     

     


    결과

     

     

     

    결제화면에서 결제를 진행한 후 결제완료 화면으로 넘어갑니다.

     

    t_pay
    t_class_listener
    t_coupon_usage

     

    DB에도 모두 정상적으로 추가가 된 것을 확인할 수 있습니다.

     


     

    * 전체 소스코드 보기

    https://github.com/weeeeeeet/weet/tree/main/src/main/java/com/weet/app/pay

     

    GitHub - weeeeeeet/weet

    Contribute to weeeeeeet/weet development by creating an account on GitHub.

    github.com

     

    댓글

Designed by Tistory.