Tech

구독결제를 시작해보자!! 그런데 이제 백엔드를 곁들인…

Nov 26, 2024
-
Backend Developer
-
Mario

Before Start — 구독결제?

구독/정기결제는 특정 서비스를 기간제로 이용하면서 사용기간이 종료될 경우 미리 등록해두었던 결제방식을 이용해서 자동으로 결제가 이루어지는 결제방식을 의미합니다. 코로나 시절을 지나며 OTT가 범람하는 현대사회에서는 제법 많은 사람에게 익숙한 단어입니다.

유저에게 매력적인 서비스경험을 제공할 수만 있다면 정기적인 결제를 통해서 기업의 매출을 안정시킬 수 있기때문에 긍정적인 매출수단 중 한 가지라고 할 수 있습니다.

우리도 구독결제를 통해서 돈 좀 벌어보자!!

LiNC도 Revenue Model의 하나로 구독결제를 넣어보자는 요구사항에 의해 구독결제개발이라는 미지의 바다로 돛을 펴고 나아가게 되었습니다. 정확히는 결제시스템을 개발하는 수준은 아니고 기존 결제시스템을 LiNC에서 사용할 수 있게 하는 것이지만 백엔드개발자, 앱개발자, QA까지 누구도 구독결제개발을 경험해보지 못했기때문에 나름 두근거리는 여정의 시작이었습니다.

일단 설계도부터 그려봅시다

사용하려는 결제시스템인 Play Store(구글)와 App Store(애플)의 공식문서 및 동영상등을 참고했습니다. 상세한 내용은 아래 공식문서 및 영상에서 확인하실 수 있습니다.

https://developer.apple.com/videos/play/wwdc2020/10671/?source=post_page-----583a8f378e93--------------------------------

https://developer.android.com/google/play/billing/backend?hl=ko&source=post_page-----583a8f378e93--------------------------------

첫 여정을 위한 지도

그에 따라 최종적으로 완성한 결제의 흐름은 위와 같습니다. 이 중에서 오늘 소개하고자 하는 내용은 크게 다음 두 가지입니다.

  1. 결제알림 받기
  2. 결제정보 확인하기

각각의 내용에 대해서 각 스토어별로 차례대로 살펴보도록 하겠습니다. (이번 글에서는 구독상품의 등록과 그 정보를 관리하기 위한 내용은 생략하겠습니다.)

결제 알림 받기 — App Store

App Store의 경우 등록된 상품정보를 이용해 결제를 하게되면 해당 결제에 대한 정보를 우리가 지정한 엔드포인트로 받을 수 있습니다. 해당 기능은 App Store Connect(https://appstoreconnect.apple.com/) -> 앱 -> 일반 정보 -> 앱 정보 -> App Store 서버 알림 항목에서 간단하게 설정할 수 있습니다.

프로덕션과 Sandbox로 나누어서 설정할 수 있다.

App Store 결제 알림은 JWT형태의 signed_payload라는 데이터를 확인할 수 있는데 해당 데이터의 하위 property인 signed_renewal_info와 signed_transaction_info 또한 JWT형태로 되어있습니다.

결제 알림 받기 — Play Store

Play Store의 경우 기본적으로 Pub/Sub을 이용해서 결제에 대한 알림을 받을 수 있으며 App Store에 비해서 조금 더 다양한 선택지를 제공합니다. 해당 페이지에서 각 선택지에 대한 자세한 정보를 확인할 수 있습니다.

https://cloud.google.com/pubsub/docs/subscriber?hl=ko&source=post_page-----583a8f378e93--------------------------------

결론적으로 LiNC에서는 다음과 같은 이유로 Push 구독을 이용하기로 했습니다.

  1. Pull이나 내보내기를 이용할만큼 처리량이 많지 않음
  2. 엔드포인트 설정이 용이
  3. 개발자의 숙련도를 생각했을 때 App Store와 동일한 형태가 유리

해당 기능을 이용하기 위해서는 몇 가지 설정이 필요합니다.

  1. Google Cloud Console → 해당프로젝트 → API 및 서비스 → API 및 서비스 사용 설정 에서 Google Play Android Developer API 를 사용하도록 설정
  2. Google Cloud Pub/Sub에서 주제 생성 후 권한 → 주 구성원 추가 에서 google-play-developer-notifications@system.gserviceaccount.com 을 추가해주고 역할을 게시/구독 게시자로 설정
  3. Google Cloud Pub/Sub에서 2에서 생성한 주제를 바라보는 구독 생성 후 전송 유형을 푸시로 설정하고 엔드포인트 URL을 입력
  4. Google Play Console → 해당앱 → Play를 통한 수익 창출 → 수익 창출 설정 → Google Play 결제에서 실시간 알림 설정을 체크 후 주제 이름에 2번에서 사용한 주제를 설정
구독에서 전송 유형을 설정(3번)
앱에서 해당 주제로 메시지를 전달할 수 있도록 설정(4번)

Play Store 결제 알림은 base64로 인코딩된 message.data 라는 데이터를 확인할 수 있습니다.

결제 정보 알림

앱에서 결제가 이루어졌다는 확인 응답을 받으면 해당 영수증(결제정보)을 담아서 우리 서버의 API로 요청하게 됩니다. 이때 해당 API에서 각 스토어에 실제로 해당결제가 존재하고 결제가 제대로 이루어졌는지 확인 후 결제정보를 DB에 등록하는 과정을 거치도록 했습니다. 각 스토어별로 제공하는 상세한 API는 아래 페이지에서 확인할 수 있습니다.

https://developer.apple.com/documentation/appstoreserverapi?source=post_page-----583a8f378e93--------------------------------

https://developers.google.com/android-publisher/api-ref/rest?hl=ko&source=post_page-----583a8f378e93--------------------------------

결제정보 확인하기 — App Store

App Store API를 요청하기 위해서는 JWT가 필요합니다. 이를 위해 필요한 항목들은 아래 페이지에서 확인할 수 있습니다.

https://developer.apple.com/documentation/appstoreserverapi/generating-json-web-tokens-for-api-requests

필요한 항목들 중에서 kid와 PRIVATE KEY를 설정하는 방법을 확인해보겠습니다. App Store Connect(https://appstoreconnect.apple.com/) -> 사용자 및 엑세스 -> 키 -> 앱 내 구입 -> 활성화됨에 키를 추가해주면 됩니다. 키를 추가하면서 해당 키의 PRIVATE KEY도 다운받을 수 있습니다. 해당 정보들로 생성한 JWT를 이용해서 App Store의 getTransactionInfo API를 요청하고 결제정보를 확인합니다. 올바른 경제로 확인이 될 경우 결제한 유저와 해당 영수증 정보를 기록하고 구독기능을 사용할 수 있게 됩니다.

https://developer.apple.com/documentation/appstoreserverapi/get_transaction_info?source=post_page-----583a8f378e93--------------------------------

결제정보 확인하기 — Play Store

Play Store API를 요청하기 위해서도 JWT가 필요합니다. 다만 Play Store의 경우 JWT 발급또한 API를 통해서 이루어집니다. 필요한 항목들은 마찬가지로 아래 페이지에서 확인할 수 있습니다.

https://developers.google.com/identity/protocols/oauth2/service-account?hl=ko&source=post_page-----583a8f378e93--------------------------------#httprest

우선 JWT 발급을 위한 토큰을 생성하기 위해서 몇 가지 설정이 필요합니다.

  1. Google Cloud Console → 해당프로젝트 → 서비스 계정 → 서비스 계정 만들기 에서 서비스 계정을 생성합니다.
  2. 생성한 서비스 계정 → 키 → 키 추가 → 새 키 만들기 를 통해서 새로운 키를 생성하고 키 정보를 다운받습니다.

해당 정보들로 생성한 토큰을 이용해서 API를 요청하기 위한 JWT를 발급받을 수 있습니다. scope의 경우 Google Play Android Developer API v3를 사용하기 위해 ‘https://www.googleapis.com/auth/androidpublisher'로 설정했습니다. 해당 JWT를 이용해서 Play Store의 purchases.subscriptionsv2.get API를 요청하려면 추가적인 설정이 필요합니다.

  1. Google Play Console → 사용자 및 권한 → 생성한 서비스 계정의 관리 → 권한 → 계정 권한 → 재무 데이터 → 재무 데이터 보기, 주문 및 구독 관리 를 설정 및 적용합니다.
  2. Google Play Console → 사용자 및 권한 → 생성한 서비스 계정의 관리 → 권한 → 앱 권한 → 애플리케이션 추가 → 해당앱 → 앱 액세스 권한 → 앱 정보 보기(읽기 전용) 설정 및 적용합니다.

이후 Play Store 의 API를 통해서 App Store와 같은 과정을 통해서 구독정보를 기록하고 구독기능을 사용할 수 있게 됩니다.

https://developers.google.com/android-publisher/api-ref/rest/v3/purchases.subscriptionsv2/get?hl=ko&source=post_page-----583a8f378e93--------------------------------

그리고 남은 일들…

현재 Play Store에서 사용하고 있는 설정들중 기능을 완전하게 파악하지 못한 부분들이 존재합니다.

  1. 토큰발급시 scope를 ‘https://www.googleapis.com/auth/androidpublisher' 로 설정
  2. 사용자계정의 권한을 편집자로 설정
  3. 사용자계정의 계정 권한에서 재무 데이터에 대한 설정

추가적으로 현재 개선해야할 사항들은 다음과 같습니다.

  1. 스토어에서 결제는 성공했지만 앱에서 보낸 결제알림을 서버에서 처리하다가 오류가 발생할 경우에 대한 처리 방법 고려 (현재는 단순하게 에러로그를 남겨서 수동으로 처리중)
  2. 각 스토어별 결제에 대한 알림내역에 대해서 상세한 파악

이번 글에서는 단순하게 작성한 흐름도를 따라 결제가 이루어지도록 설정하는 부분들만 살펴보았습니다. 추후 2부를 작성할 기회가 있다면 그 외에 생략했던 부분들과 개선사항으로 남은 부분들에 대해서 다루어 보도록 하겠습니다.

Backend Developer
-
Mario

스테이지랩스는 목표와 성장에 몰입할 수
있도록 최고의 환경을 제공해요.

Culture 바로가기