결제 통합 모듈 Iamport

·2022년 5월 1일
0

TIL

목록 보기
31/36
post-thumbnail

결제 모듈?

초대형 플랫폼에서는 본인들이 만들어놓은 것을 쓰다보니 보질 못하지만,
작은 플랫폼에서는 아래와 같은 결제창을 종종 볼 수 있다.

이와 같이 결제 자체를 통째로 서비스로 제공해주고 있는 곳이 iamport다.

굳이 만들어진 것을 써야할까?

결제를 생각해보면 생각보다 단순하지 않다.
왜냐하면 유저의 현금과 직결되기 때문에 무결해야한다.
그렇기에 정말 복잡한 과정을 거쳐서 결제를 하게 된다.

또한 결제를 하기 위해서는 실제로 있는 통장의 돈이 빠져나가야 하는데 이것을 아임포트가 나오기 전이였다면
카드사쪽에 가서 벼레별 서류를 다 받고 그것으로 api를 만들어서 사용했다고 한다(....)

그렇다보니 통합 시스템이 나왔고, 국내 많은 회사에서는 아임포트를 사용한다고 한다.

어떻게 사용을 해야할까?

다양한 사용법은 공식 홈페이지에 친절한 가이드와 함께 제공이 되고 있다.
라고 글을 마치면 내가 글을 쓸 이유가 1도 없기 때문에 작성을 한 코드와 함께 고민도 적어보려고 한다.
공식 홈페이지 -> https://www.iamport.kr/

결제하기

제일 큰 벽이라고 느끼는 결제하기다. 제일 베이직이라고 느끼지만 원래 기본이 제일 어려운 법이라(....)

큰 문제가 무엇이냐면 바로 스크립트 해킹을 막을 수 없다는 것이다.

이 문제에 대해서는 아임포트 문서에도 명시가 되어있는 상태다.

솔직히 말하면 조금 헷갈리는 부분이 있다.
웹페이지를 오른쪽 마우스로 누를 경우 스크립트를 자기가 원하는 것에 맞게 변경할 수 있다는 것은 알고 있기에
가능은 하겠지만, 어떤 부분에서 해킹을 할 수 있는지 헷갈리다고 해야할까

만약 포인트 만원짜리를 결제하면 포인트 DB에서 1만원이 깎일 것이다.
그럴 경우 해킹으로 결제된 금액이 아니라 1천원을 깎는 것은 가능한 것 같다.

이러한 과정을 방지를 해야한다는 것인지, 또 다른 위험성이 존재하는지 그 부분을 확실하게 이해를 할 수가 없는 상태다.
그러다보니 현 과정중 결제~트랜잭션을 아우르는 2개의 요소가 이해가 잘 되지 않은 상태이다.

아무튼! 그것을 방지하기 위하여 결제 로직에 조금 더 세부적인 내용이 들어가야한다.


여기서 제일 먼저 알아놔야하는 것이 존재한다.

  1. 결제를 할 경우 아임포트에 의해서 고유 ID가 발급이 된다는 것.
  2. 그런 것을 조회하기 위해서는 토큰을 발급받아서 권한을 얻어야한다는 것.

토큰을 발급하는 코드는 아래와 같다.
주의! 프론트단에서 실행을 할 경우 스크립트 변조의 가능성이 있다며 cors 에러가 발생한다.
백엔드단에서 함수가 실행되도록 만들자!

iamport.service.ts

참고 엑시오스 통신을 위해서 import { HttpService } from '@nestjs/axios'; < 를 깔아서 임포트하자.

// 토큰 발급
async getToken() {
    const token = await this.httpService
      .post('https://api.iamport.kr/users/getToken', {
        imp_key: IMP_KEY, // REST API키
        imp_secret: IMP_SECRET, // REST API Secret
      })
      .toPromise();
    return token.data.response.access_token;
  }
// 결제 정보 조회
async get_data_with_impUid({ token, impUid }) {
    const check = await this.httpService
      .get(`https://api.iamport.kr/payments/${impUid}`, {
        headers: {
          authorization: token,
        },
      })
      .toPromise();
    return check.data.response;
  }

위의 과정을 거치면 토큰을 발급하고, 그 발급한 토큰으로 결제 후 받아온 아임포트의 고유ID impUid로 결제 정보를 조회하여 프론트 단에서 넘어온 결제 금액과 비교를 해서 다를 경우 결제를 쳐낼 수 있다.

이후 토큰값에 있는 유저의 디비에 값을 넣어주면 결제하기는 끝이 난다.

환불하기

환불하기의 경우는 경우의 수가 좀 복잡하다.
여기서도 궁금한 점이 있는데 부분 환불 시스템이다.
총 결제 금액이 5만원인데 14000원 16000원 30000원을 결제를 했을 경우에
3만원을 환불하면 3만원만 판매된 결제에 대해서 어떤식으로 환불이 되는가? 라는 궁금증이 남은 상태다.

같은 곳에서 결제를 할 경우에는 문제가 없겠지만, 장바구니에 다양한 스토어에 있는 것들을 모아서 결제를 할 경우
대금관련에서 조금 복잡한 것이 있어서 환불이 어떤식으로 진행이 되는지 궁금하다.

아무튼 다시 원점으로 돌아와서 환불하기에서 고려해야할 점은 이렇게 있다.

  1. 환불할 금액이 얼마인지 확인하기
  2. 환불할 만큼의 금액(포인트)만큼 유저의 포인트가 존재하는지

물론 포인트제를 쓸 경우에만 이런 과정이 존재할 것이긴 하다.
근데 반대로 물건을 결제했을 경우는 더 복잡한 과정을 찾아야한다.

  1. 택배를 발송했는지?
  2. 그 물품은 현재 어떤 상황에 있는지
  3. 반송을 했다면 그 물건을 받았는지
  4. 반송받은 물건이 다시 판매할 가치가 있는지(불가능한지)

이런 다양한 과정을 고려해야하기 때문에 포인트제로 진행하려고 한다.

async CancelPayment({ token, imp_uid, amount, reason }) {
    const cancel = await this.httpService
      .post(
        'https://api.iamport.kr/payments/cancel',
        {
          imp_uid,
          reason,
          amount,
        },
        {
          headers: {
            authorization: token,
          },
        },
      )
      .toPromise();

환불 자체를 요청하는 것은 토큰과 고유 아이디, 금액, 이유를 적어서 보낼 경우 아임포트단에서 환불을 진행해준다.

더 자세한 내용은 트랜잭션 포스트에서 이야기하려고 한다.
내용이 너무 많이 길어질 것 같아서;

profile
물류 서비스 Backend Software Developer

0개의 댓글