dmuratshin 8 anos atrás
pai
commit
4e66c00c68
3 arquivos alterados com 296 adições e 3 exclusões
  1. 31 3
      src/billing.cpp
  2. 23 0
      src/ios/IOSBilling.h
  3. 242 0
      src/ios/IOSBilling.mm

+ 31 - 3
src/billing.cpp

@@ -1,11 +1,19 @@
 #include "billing.h"
 
+
+#define IOS_STORE 1
+
+
 #ifdef __ANDROID__
 #include "android/AndroidBilling.h"
+#elif IOS_STORE
+#include "ios/IOSBilling.h"
 #else
 #include "sim/BillingSimulator.h"
 #endif
 
+
+
 namespace oxygine
 {
     namespace billing
@@ -25,6 +33,8 @@ namespace oxygine
 
 #ifdef __ANDROID__
             jniBillingInit();
+#elif IOS_STORE
+            iosBillingInit();
 #else
             billingSimulatorInit();
 #endif
@@ -36,6 +46,10 @@ namespace oxygine
 
 #ifdef __ANDROID__
             jniBillingFree();
+#elif IOS_STORE
+            iosBillingFree();
+#else
+            billingSimulatorFree();
 #endif
             _dispatcher->removeAllEventListeners();
             _dispatcher = 0;
@@ -44,8 +58,8 @@ namespace oxygine
 
         MarketType getMarketType()
         {
-#ifdef __APPLE__
-            return simulator;
+#ifdef IOS_STORE
+            return ios;
 #elif __ANDROID__
             string tp = jniBillingGetType();
             if (tp == "google")
@@ -65,6 +79,8 @@ namespace oxygine
 
 #ifdef __ANDROID__
             jniBillingPurchase(id, payload);
+#elif IOS_STORE
+            iosBillingPurchase(id);
 #else
             billingSimulatorPurchase(id, payload);
 #endif
@@ -76,6 +92,8 @@ namespace oxygine
 
 #ifdef __ANDROID__
             jniBillingConsume(token);
+#elif IOS_STORE
+            iosBillingConsume(token);
 #else
             billingSimulatorConsume(token);
 #endif
@@ -87,6 +105,8 @@ namespace oxygine
 
 #ifdef __ANDROID__
             jniBillingGetPurchases();
+#elif IOS_STORE
+            iosBillingGetPurchases();
 #else
             billingSimulatorGetPurchases();
 #endif
@@ -98,6 +118,8 @@ namespace oxygine
 
 #ifdef __ANDROID__
             jniBillingUpdate(items);
+#elif IOS_STORE
+            iosBillingUpdate(items);
 #else
             billingSimulatorRequestDetails(items);
 #endif
@@ -106,7 +128,7 @@ namespace oxygine
         void simulatorSetDetails(const Json::Value& details)
         {
 #ifdef __ANDROID__
-
+#elif  IOS_STORE
 #else
             billingSimulatorSetDetails(details);
 #endif
@@ -225,6 +247,12 @@ namespace oxygine
                 purchaseToken = data["receiptId"].asString();
                 productID = data["sku"].asString();
             }
+            
+            if (mt == ios)
+            {
+                productID = data["productIdentifier"].asString();
+                purchaseToken = data["transactionIdentifier"].asString();
+            }
         }
     }
 }

+ 23 - 0
src/ios/IOSBilling.h

@@ -0,0 +1,23 @@
+
+
+#ifndef Oxygine_BillingIOS_h
+#define Oxygine_BillingIOS_h
+
+#include <vector>
+#include <string>
+
+#ifdef __OBJC__
+
+#endif
+
+
+using namespace std;
+
+void iosBillingInit();
+void iosBillingFree();
+void iosBillingUpdate(const vector<string> &items);
+void iosBillingPurchase(const string &product);
+void iosBillingConsume(const string &token);
+void iosBillingGetPurchases();
+
+#endif

+ 242 - 0
src/ios/IOSBilling.mm

@@ -0,0 +1,242 @@
+//
+//  BillingIOS.m
+//  Match3Quest
+//
+//  Created by Denis on 15/01/15.
+//  Copyright (c) 2015 Mac. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <StoreKit/StoreKit.h>
+#include "IOSBilling.h"
+
+
+#include "billing.h"
+
+using namespace oxygine;
+
+@interface Billing:NSObject<SKProductsRequestDelegate, SKPaymentTransactionObserver>
+{
+    //NSArray *_products;
+    NSMutableDictionary *_products;
+    NSMutableDictionary *_transactions;
+    
+}
+@end
+
+@implementation Billing
+
+#import <CommonCrypto/CommonCrypto.h>
+
+// Custom method to calculate the SHA-256 hash using Common Crypto
+- (NSString *)hashedValueForAccountName:(NSString*)userAccountName
+{
+    const int HASH_SIZE = 32;
+    unsigned char hashedChars[HASH_SIZE];
+    const char *accountName = [userAccountName UTF8String];
+    size_t accountNameLen = strlen(accountName);
+    
+    // Confirm that the length of the user name is small enough
+    // to be recast when calling the hash function.
+    if (accountNameLen > UINT32_MAX) {
+        NSLog(@"Account name too long to hash: %@", userAccountName);
+        return nil;
+    }
+    CC_SHA256(accountName, (CC_LONG)accountNameLen, hashedChars);
+    
+    // Convert the array of bytes into a string showing its hex representation.
+    NSMutableString *userAccountHash = [[NSMutableString alloc] init];
+    for (int i = 0; i < HASH_SIZE; i++) {
+        // Add a dash every four bytes, for readability.
+        if (i != 0 && i%4 == 0) {
+            [userAccountHash appendString:@"-"];
+        }
+        [userAccountHash appendFormat:@"%02x", hashedChars[i]];
+    }
+    
+    return userAccountHash;
+}
+
+-(id)init {
+    self = [super init];
+    
+    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
+    
+    _products = [NSMutableDictionary dictionary];
+    _transactions = [NSMutableDictionary dictionary];
+    
+    return self;
+}
+
+-(void)updateProducts:(NSArray*)items
+{
+    SKProductsRequest *productsRequest = [[SKProductsRequest alloc]
+                                          initWithProductIdentifiers: [NSSet setWithArray:items]];
+    productsRequest.delegate = self;
+    [productsRequest start];
+}
+
+
+- (void)paymentQueue:(SKPaymentQueue *)queue
+ updatedTransactions:(NSArray *)transactions
+{
+    for (SKPaymentTransaction *transaction in transactions) {
+        switch (transaction.transactionState) {
+                // Call the appropriate custom method for the transaction state.
+            case SKPaymentTransactionStatePurchasing:
+                //[self showTransactionAsInProgress:transaction deferred:NO];
+                log::messageln("billing::transactions SKPaymentTransactionStatePurchasing %s", transaction.transactionIdentifier.UTF8String);
+                break;
+                
+            case SKPaymentTransactionStateDeferred:
+                log::messageln("billing::transactions SKPaymentTransactionStateDeferred %s", transaction.transactionIdentifier.UTF8String);
+                //[self showTransactionAsInProgress:transaction deferred:YES];
+                break;
+                
+            case SKPaymentTransactionStateFailed:
+                log::messageln("billing::transactions SKPaymentTransactionStateFailed %s", transaction.transactionIdentifier.UTF8String);
+                break;
+                
+            case SKPaymentTransactionStatePurchased: {
+            
+                
+                log::messageln("billing::transactions SKPaymentTransactionStatePurchased %s", transaction.transactionIdentifier.UTF8String);
+                [_transactions setObject:transaction forKey:transaction.transactionIdentifier];
+                //[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
+                
+                /*
+                const data::goods *g = [self getGoods:transaction.payment.productIdentifier];
+                SKProduct *product = (__bridge SKProduct*)g->userData;
+                
+                billing::details det;
+                det.orderID = transaction.transactionIdentifier.UTF8String;
+                
+                NSString *currencyCode = [product.priceLocale objectForKey:NSLocaleCurrencyCode];
+                det.currency = currencyCode.UTF8String;
+                det.price = product.price.doubleValue;
+                det.sandbox = true;
+                billing::addCurrency(g, false, &det);
+                 */
+                //[self completeTransaction:transaction];
+                //string data;
+                string sign;
+                
+                Json::Value data(Json::objectValue);
+                
+                data["transactionIdentifier"] = transaction.transactionIdentifier;
+                data["productIdentifier"] = transaction.payment.productIdentifier;
+                
+                
+                Json::FastWriter writer;
+                
+                billing::internal::purchased(billing::internal::ActivityOK, billing::internal::RC_OK, writer.write(data), sign);
+            }
+                break;
+            case SKPaymentTransactionStateRestored:
+                //[self restoreTransaction:transaction];
+                break;
+            default:
+                // For debugging
+                NSLog(@"Unexpected transaction state %@", @(transaction.transactionState));
+                break;
+        }
+    }
+}
+
+
+
+- (void)productsRequest:(SKProductsRequest *)request
+     didReceiveResponse:(SKProductsResponse *)response
+{
+    NSArray *products = [response products];
+    
+    NSArray *inv = response.invalidProductIdentifiers;
+    int q=0;
+    
+    
+    for (NSString *invalidIdentifier in response.invalidProductIdentifiers) {
+        // Handle any invalid product identifiers.
+    }
+    
+    
+    Json::Value data(Json::arrayValue);
+    
+    for (SKProduct *product in response.products) {
+        [_products setObject:product forKey:product.productIdentifier];
+        
+        Json::Value item(Json::ArrayIndex);
+        data.append(item);
+    }
+    
+    
+    
+    Json::FastWriter writer;
+    
+    billing::internal::detailed(writer.write(data));
+}
+
+- (void)purchase:(const char *)prod
+{
+    
+    NSString *str = [NSString stringWithUTF8String:prod];
+    
+    SKProduct *product = _products[str];
+    SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:product];
+    payment.quantity = 1;
+    //payment.applicationUsername =
+    
+    [[SKPaymentQueue defaultQueue] addPayment:payment];
+}
+
+- (void)consume:(const char *)token
+{
+    
+    NSString *str = [NSString stringWithUTF8String:token];
+    
+    SKPaymentTransaction *trans = _transactions[str];
+    [[SKPaymentQueue defaultQueue] finishTransaction:trans];
+}
+
+@end
+
+Billing *_billing = 0;
+
+
+void iosBillingInit()
+{
+    _billing = [[Billing alloc] init];
+}
+
+void iosBillingFree()
+{
+    _billing = nil;
+}
+
+void iosBillingUpdate(const vector<string> &items)
+{
+    NSArray *array = [[NSArray alloc] init];
+    
+    for (size_t i = 0; i < items.size(); ++i)
+    {
+        const string &item = items[i];
+        
+        NSString *str = [NSString stringWithUTF8String:item.c_str()];
+        array = [array arrayByAddingObject:str];
+    }
+    
+    [_billing updateProducts:array];
+}
+
+void iosBillingPurchase(const string &product)
+{
+    [_billing purchase: product.c_str()];
+}
+
+void iosBillingConsume(const string &token)
+{
+    [_billing consume:token.c_str()];
+}
+
+void iosBillingGetPurchases()
+{
+}