// iOSInAppPlugin.h
#import <StoreKit/StoreKit.h>
@interface iOSInAppPlugin : NSObject<
///< 상품 정보를 얻어올 때 쓰는 딜리게이트
SKProductsRequestDelegate,
///< 상품 구매 관련 옵저버
SKPaymentTransactionObserver>
+ (iOSInAppPlugin*) sharediOSInAppPlugin;
- (BOOL) initInApp;
- (void) requestProductData:(NSString*)strProductId;
- (void) completeTransaction:(SKPaymentTransaction*)transaction;
- (void) restoreTransaction:(SKPaymentTransaction*)transaction;
- (void) failedTransaction:(SKPaymentTransaction*)transaction;
- (void) restoreCompletedTransactions;
@end
// iOSInAppPlugin.m
#import "iOSInAppPlugin.h"
extern "C"
{
void iOSInAppInit()
{
[[iOSInAppPlugin sharediOSInAppPlugin] initInApp];
}
void iOSBuyItem(const char* pszProductId)
{
NSString* strProductId = [NSString stringWithUTF8String:pszProductId];
[[iOSInAppPlugin sharediOSInAppPlugin] requestProductData:strProductId];
}
void iOSRestoreCompletedTransactions()
{
[[iOSInAppPlugin sharediOSInAppPlugin] restoreCompletedTransactions];
}
}
@implementation iOSInAppPlugin
+ (iOSInAppPlugin*) sharediOSInAppPlugin
{
static iOSInAppPlugin* pInstance;
if(pInstance == NULL)
{
pInstance = [[iOSInAppPlugin alloc] init];
}
return pInstance;
}
- (BOOL) initInApp
{
///< 인앱 결제 시스템을 사용 가능한지 체크
if( [SKPaymentQueue canMakePayments] == NO )
return NO;
///< Product 결제 진행에 필요한 딜리게이트 등록
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
NSLog(@"InAppPurchase init OK");
return true;
}
///< 아이템 정보 요청
- (void) requestProductData:(NSString*)strProductId
{
///< iTunes Connect에 설정한 Product ID들
NSSet* productIdentifiers = [NSSet setWithObject:strProductId];
SKProductsRequest* request = [[SKProductsRequest alloc]initWithProductIdentifiers:productIdentifiers];
request.delegate = self;
[request start];
NSLog(@"requestProductData %@", strProductId);
}
///< 아이템 정보 요청 결과 callback
- (void) productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
NSLog( @"InAppPurchase didReceiveResponse" );
for( SKProduct* product in response.products )
{
if( product != nil )
{
NSLog(@"InAppPurchase Product title: %@", product.localizedTitle);
NSLog(@"InAppPurchase Product description: %@", product.localizedDescription);
NSLog(@"InAppPurchase Product price: %@", product.price);
//product.priceLocale
NSLog(@"InAppPurchase Product id: %@", product.productIdentifier);
///< 구매 요청
SKPayment* payment = [SKPayment paymentWithProduct:product];
//payment.quantity = 10;
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
}
[request release];
for (NSString *invalidProductId in response.invalidProductIdentifiers)
{
NSLog(@"InAppPurchase Invalid product id: %@", invalidProductId);
}
}
///< 새로운 거래가 발생하거나 갱신될 때 호출된다.
- (void) paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray*)transactions
{
for (SKPaymentTransaction *transaction in transactions)
{
switch (transaction.transactionState)
{
///< 서버에 거래 처리중
case SKPaymentTransactionStatePurchasing:
NSLog(@"InAppPurchase SKPaymentTransactionStatePurchasing");
break;
///< 구매 완료
case SKPaymentTransactionStatePurchased:
[self completeTransaction:transaction];
break;
///< 거래 실패 또는 취소
case SKPaymentTransactionStateFailed:
[self failedTransaction:transaction];
break;
///< 재구매
case SKPaymentTransactionStateRestored:
[self restoreTransaction:transaction];
break;
}
}
}
- (void) completeTransaction:(SKPaymentTransaction *)transaction
{
NSLog(@"InAppPurchase completeTransaction");
NSLog(@"InAppPurchase Transaction Identifier : %@", transaction.transactionIdentifier );
NSLog(@"InAppPurchase Transaction Data : %@", transaction.transactionDate );
///< 구매 완료 후 아이템 인벤등 게임쪽 후 처리 진행
/* 빌트 인 모델
const char* pszProductId = [[[transaction payment] productIdentifier] UTF8String];
UnitySendMessage("iOSManager", "ResultBuyItem", pszProductId);
*/
NSString* strReceipt = [[NSString alloc]initWithBytes:transaction.transactionReceipt.byteslength:transaction.transactionReceipt.length encoding:NSUTF8StringEncoding];
UnitySendMessage("iOSManager", "ResultBuyItem", [strReceipt UTF8String]);
// Remove the transaction from the payment queue.
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
- (void) restoreTransaction:(SKPaymentTransaction *)transaction
{
NSLog(@"InAppPurchase restoreTransaction");
const char* pszRestoreProductId = [transaction.originalTransaction.payment.productIdentifier UTF8String];
UnitySendMessage("iOSManager", "ResultRestoreItem", pszRestoreProductId);
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
- (void) failedTransaction:(SKPaymentTransaction *)transaction
{
NSLog(@"InAppPurchase failedTransaction.");
const char* pszResult = 0;
if( transaction.error.code != SKErrorPaymentCancelled )
{
pszResult = "faileIAP";
NSLog(@"InAppPurchase failedTransaction SKErrorDomain - %d", transaction.error.code );
}
else
{
pszResult = "cancelIAP";
NSLog(@"InAppPurchase failedTransaction SKErrorPaymentCancelled");
}
UnitySendMessage("iOSManager", "ResultBuyItem", pszResult);
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
// 비소모성 아이템 복원 요청
- (void) restoreCompletedTransactions
{
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
@end
// iOSManager.cs
using UnityEngine;
using System.Runtime.InteropServices;
public class iOSManager : MonoBehaviour
{
static iOSManager _instance;
private string strLog = "Unity3D iOS In App Purchase Sample";
public string strPostMsg = string.Empty;
[DllImport("__Internal")]
private static extern void iOSInAppInit();
[DllImport("__Internal")]
private static extern void iOSBuyItem(string strProductId);
[DllImport("__Internal")]
private static extern void iOSRestoreCompletedTransactions();
public static iOSManager GetInstance()
{
if( _instance == null )
{
_instance = new GameObject("iOSManager").AddComponent<iOSManager>();
}
return _instance;
}
public void InAppInit()
{
iOSInAppInit();
}
public void BuyItem(string strProductId)
{
iOSBuyItem(strProductId);
}
public void ResultBuyItem(string strResult)
{
// strResult is transaction.transactionReceipt or faileIAP or cancelIAP.
SetLog("ResultBuyItem " + strResult);
}
public void RestoreCompletedTransactions()
{
iOSRestoreCompletedTransactions();
}
public void ResultRestoreItem(string strRestoreItemId)
{
SetLog("ResultRestoreItem " + strRestoreItemId);
}
public void SetLog(string _strLog)
{
strLog = _strLog;
}
public string GetLog()
{
return strLog;
}
}
출처 : http://westwoodforever.blogspot.kr/2013/10/unity3d-integration-ios-in-app-purchase.html#links