본문 바로가기
  • SDXL 1.0 + 한복 LoRA
  • SDXL 1.0 + 한복 LoRA
Development/iPhone

[옛 글] [iOS] 오늘은 간만에 아이폰 개발 - IAP 영수증 인증

by 마즈다 2013. 7. 19.
반응형

최초 작성일 : 2013/05/23 17:28


곧 완성을 앞두고 있는 신규 앱에는 야심차게(?) IAP(In-App Purchase:앱내 구매)를

구현해보기로 했다.

이유는 당근 유/무료 버전을 나누는 것 보다는 IAP가 더 수익성이 좋을 것 같았기 때문이다.
그래봐야 1년이 가도록 겨우 개발자 등록비 뽑는 수준이지만...ㅠ.ㅠ

우선 기본적인 구현은 문제가 없었다.
맥부기 회원들의 도움으로 쉽게 구현을 마쳤다.
그런데 문제는 애플 서버를 이용한 영수증 인증이다.
탈옥을 통한 일종의 해킹 방지 차원이랄까?

이를 위해 특별히 애플에서 기본 소스 코드도 배포를 하고 있다.
아래 링크로 가면 간단한 설명이 있는 페이지가 나오고 그 페이지의 우상단에 보면
Companion File이라고 링크가 걸려있는데 여기에 VerificationController.h와
VerificationController.m 요렇게 약소하게 파일 2개가 들어있다.


이 파일에 적절하게 코드를 추가하여 처리하면 된다.
일단 가장 자세한 설명이 있었던 맥부기의 글이 아래 링크에 있다.


대체로 이 글을 통해 구현을 완료하였는데...
문제는 관련 글에도 있지만 SANBOX로 테스트하던 것을 애플 리뷰 후
실 상품 서버로 연결해야 하는데 이 것을 어떻게 해야 하냐는 것과

기존 코드의 paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray*)transactions
통해 수행하던 내용 중 [[SKPaymentQueue defaultQueuefinishTransaction:transaction];   
요넘을 어떻게 처리하느냐가 문제였다.

두 번째 문제의 경우 뭐 대충 델리게이트 써가면서 어렵지 않게 해결하였다.
특히 두 번째의 처리를 하지 않으니 IAP 서버에서 상품을 가져올 때마다
이전의 트랜잭션들이 모두 함께 내려와서 문제가 되었기에 반드시 처리를
해주어야 했다.

그리고 어렵게 처리한 첫 번째 문제

우선 구조가 NSMutableURLRequest를 이용해 서버에 연결하는 내용인데
처리는 우선 실 상품 서버로 연결을 하고 거기서 실패를 할 경우 테스트용 SANDBOX로
연결을 해야 하는 것이었다.

만일 테스트 계정으로 실 상품 서버로 연결을 하여 처리하게 되면
connection:didReceiveData: 함수에 response되는 결과값으로 21007이 떨어지게 된다.

이 21007이 확인된 이후 어떻게 해야 하는지에 대한 설명이 아무데도 없어서
혼자서 열심히 쌩X랄을 하였다.

우선 구매 요청부터 다시 보내보았다. 그랬더니 구매 팝업이 2번 뜨는 우스운 모양이
되어버려 실패...

다음으로는 처음 구매 요청후 생성된 transaction을 전역변수에 넣고 다시 서버 연결부 부터
진행을 해보았다. 역시 실패...

그리고 마지막에 처리한 것이 다음 방법이다.

영수증 인증을 위해 NSURLConnection을 이용하여
인증 서버로 연결할 때 인자로 넘기는 것이 transaction의 transactionReceipt 속성을
이용하여 만든 NSData형의 값이다.

그래서 전역 변수로 NSData형을 만들고 transaction. transactionReceipt를 이용하여
만든 NSData 값을 이 전역 변수에 할당 한 후 실 상품 서버에서 21007이 떨어지면
요넘만 인자로 넘겨서 다시 NSURLConnection커넥션을 하니 잘~ 처리가 되었다.

이로써 무사히 IAP 구현을 마치게 되었다...^^

위 설명한 프로세스를 요약하면 아래와 같다.

***
참고로  ITC_CONTENT_PROVIDER_SHARED_SECRET라는 값을 설정하도록 되어있는데
아무리 찾아봐도 내 계정의 아이튠즈 커넥트 화면에서는 그 값을 받아오는 링크가
보이질 않는다...ㅠ.ㅠ

설정을 안해도 테스트는 잘 되던데...이게 테스트이기 때문에 잘 되는 것인지...
요게 쪼끔 걸리네...ㅠ.ㅠ

============================================

PCStoreViewController : IAP 구매 화면 및 구매 시작을 담당함

구매버튼 터치시 아래 내용 실행
//payment는 SKPayment 타입의 전역변수

payment = [SKPayment paymentWithProduct:self.product];

 [[SKPaymentQueue defaultQueue] addPayment:payment];


addPayment 메서드 실행 후 델리게이트인 아래 메서드 실행

- (void) paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions


이 함수 내에서 transactions를 루프 돌리면서 각각의 transaction에 대해
transaction.transactionState에 따라 처리를 하게 되는데 다음 2가지 경우에 대해
VerificationController의 verifyPurchase:transaction 메서드를 호출한다.

SKPaymentTransactionStatePurchased

SKPaymentTransactionStateRestored



VerificationController : 영수증이 유효한 것인지 애플 서버를 통해 인증

 verifyPurchase:transaction 메서드 내에서 인자로 넘겨받은 transaction의
transactionReceipt 속성을 이용하여 NSData형의 값을 NSURLConnection을 통해 서버로 넘김 이 때 인자로 넘어가는 NSData를 전역변수에 할당을 해놓아 이후 21007
코드에 대비를 한다.

NSURLConnection의 델리게이트 메서드인 connection:didReceiveData:에서 최종 구매처리를 한다.
response 값으로 넘어온 NSData형의 data는 NSDictionary로 변환할 수 있는
JSON 값이며 여기에는 receipt라는 키로 NSDictionary 타입의 값이 들어있는데
이 값에는 각종 구매 정보가 들어있다.

그리고 status라는 키로 NSNumber 타입의 상태 정보가 넘어오는데 앞서 설명했듯이
테스트 계정으로 구매를 하는데 실 상품 서버로 연결을 하게 되면 이 값이 21007이
넘어온다.

만일 이 status가 이상이 없으면 (0이면) 구매 완료 처리를 하고 추가로 만든
델리게이트 메서드를 통해 finishTransaction 처리를 한 후 IAP 화면을 닫도록 하였고

21007인 경우 verifyPurchase: 메서드에서 전역변수에 저장해놓은 NSData를
인자로 하고 서버 주소는 SANDBOX(테스트)용 주소로 하여 다시 NSURLConnection
연결을 시도한다.

반응형