Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #import "MLWalletAPI.h"
- #import "MLWalletEvent.h"
- #import "MLWalletAcquisitionSource.h"
- #import "MLWalletAcquisition.h"
- #import "MLPayoutRecipient.h"
- #import "MLHALClient.h"
- #import "MLApplication.h"
- #import "MLPurchase.h"
- #import "NSString+URLEncode.h"
- #import <PromiseKit/PromiseKit.h>
- #import "UIActionSheet+AnyPromise.h"
- #import "Stripe.h"
- #import "MLSubledgerParser.h"
- #import "MLSubscriptionTier.h"
- #import "MLSubscriptionPlan.h"
- #import "MLSubscription.h"
- #import "MLNavigationStackController.h"
- #import "MLRootNavigationController.h"
- #import "MLStripePaymentModel.h"
- #import "MLGiftManager.h"
- #import "PMKUIKit.h"
- #import "MLInAppPurchaseManager.h"
- #import "NSString+MD5.h"
- #import "NSData+MD5.h"
- #import "MLPayoutRequest.h"
- #import "NSDecimalNumber+Modulo.h"
- #import "MLGift.h"
- #import "UIAlertView+AnyPromise.h"
- #import <AudioToolbox/AudioServices.h>
- #import "MLSoundEffects.h"
- #import "MLLeaderBoardEntry.h"
- @interface MLWalletAPI()
- @property (nonatomic, strong) NSMutableArray * subscriptionTiers;
- @property (nonatomic, strong) NSMutableDictionary * subscriptions;
- @end
- @implementation MLWalletAPI
- #pragma mark -
- #pragma mark API interface
- +(void)setSubscriptionPlanForChannel:(MLChannel*)channel withTier:(MLSubscriptionTier*)tier{
- //channels' subscriptionTiers should also be populated during fetch
- channel.subscriptionTier = tier;
- [self getCurrentUserWalletsWithCompletion:^(NSError *error, NSArray *wallets) {
- if(!error){
- MLWallet * currentUserWallet = [wallets firstObject];
- [self getSubscriptionPlanForChannel:channel withCompletion:^(NSError *error, MLSubscriptionPlan *subscriptionPlan) {
- if(!error && subscriptionPlan){
- MLLog(@"Subscription plan already exists - update tier?");
- }
- else{
- MLSubscriptionPlan * p = [MLSubscriptionPlan planForChannel:channel withTier:tier];
- [[self sharedInstance] performRequestWithPath:[NSString stringWithFormat:@"%@/subscription_plans", currentUserWallet.objectId] andMethod:@"POST" andJSONDictionary:p.jsonDictionary andCompletion:^(NSError *error, id jsonDict) {
- if(!error){
- MLLog(@"setSubscriptionPlanForChannel %@: No error", channel.objectId);
- }
- else{
- MLLog(@"setSubscriptionPlanForChannel %@: Error! %@", channel.objectId, error);
- }
- }];
- }
- }];
- }
- else{
- [MLHelper showTempAlertWithString:@"Could not fetch wallet for plan"];
- }
- }];
- }
- +(AnyPromise*)promiseSubscriptionPlanForChannel:(MLChannel*)channel{
- return [AnyPromise promiseWithResolverBlock:^(PMKResolver _Nonnull resolve) {
- [self getSubscriptionPlanForChannel:channel withCompletion:^(NSError *error, MLSubscriptionPlan *subscriptionPlan) {
- if(!error){
- resolve(subscriptionPlan);
- }
- else{
- resolve(error);
- }
- }];
- }];
- }
- +(void)getSubscriptionPlanForChannel:(MLChannel*)channel withCompletion:(MLSubscriptionPlanCompletionBlock)completion{
- MLLog(@"MLWalletAPI get subscription plan for channel %@", channel.objectId);
- //get author's wallet
- [self getWalletWithLabel:channel.author.username withCompletion:^(NSError *error, MLWallet *wallet) {
- if(!error){
- MLLog(@"getSubscriptionPlanForChannel: success fetching wallet for user %@", channel.author.username);
- //get subscription plans from wallet
- [self getSubscriptionPlansFromWallet:wallet withCompletion:^(NSError *error, NSArray *subscriptionPlans) {
- if(!error){
- MLLog(@"getSubscriptionPlanForChannel: success getting subscriptionPlans for wallet %@", wallet.objectId);
- //match channel id
- MLSubscriptionPlan * planForChannel = nil;
- for(MLSubscriptionPlan * sp in subscriptionPlans){
- if([sp.channelUrl isEqualToString:channel.objectId]){
- MLLog(@"getSubscriptionPlanForChannel Found a matching channel in subscription plans %@", channel.objectId);
- planForChannel = sp;
- }
- }
- if(!planForChannel){
- MLLog(@"getSubscriptionPlanForChannel did not find matching subscription plan");
- }
- completion(error, planForChannel);
- }
- else{
- completion(error, nil);
- MLLog(@"getSubscriptionPlanForChannel: Error getting subscriptionPlans for wallet %@ %@", wallet.objectId, error);
- }
- }];
- }
- else{
- completion(error, nil);
- MLLog(@"getSubscriptionPlanForChannel: Error fetching wallet for user %@ %@", channel.author.username, error);
- }
- }];
- //return plan with correct id
- }
- +(void)getSubscriptionStatusForChannels:(NSArray *)channels withCompletion:(MLSubscriptionStatusCompletionBlock)completion{
- NSLog(@"Get subscription status for channels");
- [self checkForCurrentUserPaymentMethodsAndCustomerId:^(NSError *error, MLWallet *wallet, BOOL hasPaymentMethod, BOOL hasStripeCustomerId) {
- if(!error){
- [self getSubscriptionsFromWallet:wallet withCompletion:^(NSError *error, NSArray *subscriptions) {
- //this should be enough for us to tell if a user is subscribed
- MLLog(@"getSubscriptionsFromWallet completion in getSubscriptionStatusForChannels error: %@", error);
- completion(error);
- }];
- }
- else{
- completion(error);
- }
- }];
- }
- + (void) populateSubscriptionTierForChannel: (MLChannel *) channel withCompletion: (MLSingleSubscriptionTierCompletionBlock) completion {
- [self getSubscriptionPlanForChannel:channel withCompletion:^(NSError *error, MLSubscriptionPlan *subscriptionPlan) {
- if(!error){
- [self getSubscriptionTiersWithCompletion:^(NSError *error, NSArray *subscriptionTiers) {
- if(!error){
- MLSubscriptionTier * correctTier = nil;
- for(MLSubscriptionTier * t in subscriptionTiers){
- if([t.objectId.lastPathComponent intValue] == subscriptionPlan.subscriptionTierId){
- correctTier = t;
- }
- }
- channel.subscriptionTier = correctTier;
- completion(error, channel.subscriptionTier);
- }
- else{
- completion(error, nil);
- }
- }];
- //subscriptionPlan.subscriptionTierId
- //calculate subscription price
- }
- else{
- //error getting subscription plan for channel
- completion(error, nil);
- }
- }];
- }
- +(void)checkIfCurrentUserHasPurchasedChannel:(MLChannel*)channel withCompletion:(MLCurrentUserHasPurchasedChannelCompletionBlock)completion{
- if(channel.currentUserHasPurchased){
- completion(nil, YES);
- return;
- }
- if([channel.author isCurrentUser]){
- completion(nil, YES);
- return;
- }
- NSLog(@"MLWalletAPI checkIfCurrentHasPurchasedChannel - needs to query for payment plans / methods etc.%@", channel.objectId);
- //if we don't have the subscription info on hand - this should only fire if a subscription is new and/or the first time?
- [self getCurrentUserWalletsWithCompletion:^(NSError *error, NSArray *wallets) {
- if(!error){
- //current user wallet
- MLWallet * w = [wallets objectAtIndex:0];
- [self getWalletEventsForWallet:w withCompletion:^(NSError *error, NSMutableArray *walletEvents) {
- NSLog(@"MLWalletAPI checkIfCurrentHasPurchasedChannel %@ after gettingWalletEvents %i", channel.objectId, [walletEvents count]);
- if(!error){
- BOOL hasPurchased = NO;
- //find paywall purchase event with object id
- for(MLWalletEvent * e in walletEvents){
- NSLog(@"Checking wallet event %@ withType %i item.objectId %@", e.objectId, e.type, e.item.objectId);
- if(e.type == MLWalletEventTypePaywallPurchase && [e.item.objectId isEqualToString:channel.objectId]){
- NSLog(@"Found a matching WalletDeal for channel %@", e.item.objectId);
- hasPurchased = YES;
- channel.currentUserHasPurchased = YES;
- }
- }
- channel.currentUserHasPurchased = hasPurchased;
- completion(error, hasPurchased);
- }
- else{
- NSLog(@"MLWalletAPI checkIfCurrentHasPurchasedChannel %@ error getting wallet events %@", channel.objectId, error);
- completion(error, nil);
- }
- }];
- }
- else{
- NSLog(@"MLWalletAPI checkIfCurrentHasPurchasedChannel %@ error getting wallet %@", channel.objectId, error);
- //error finding wallet
- completion(error, nil);
- }
- }];
- }
- +(void)checkIfCurrentUserSubscribesToChannel:(MLChannel*)channel withCompletion:(MLCurrentUserSubscribesToChannelCompletionBlock)completion{
- completion(nil, NO, nil);
- return;
- if([self currentUserSubscribesToChannel:channel]){
- completion(nil, YES, nil);
- return;
- }
- MLLog(@"MLWalletAPI checkIfCurrentUserSubscribesToChannel - needs to query for payment plans / methods etc.%@", channel.objectId);
- //if we don't have the subscription info on hand - this should only fire if a subscription is new and/or the first time?
- [self checkForCurrentUserPaymentMethodsAndCustomerId:^(NSError *error, MLWallet *wallet, BOOL hasPaymentMethod, BOOL hasStripeCustomerId) {
- if(!error){
- [self getSubscriptionsFromWallet:wallet withCompletion:^(NSError *error, NSArray *subscriptions) {
- MLLog(@"getSubscriptionsFromWallet completion in checkIfCurrentUserSubscribesToChannel error: %@", error);
- if(!error){
- BOOL subscribes = NO;
- MLLog(@"No error getting subscriptions %i", [subscriptions count]);
- if([self currentUserSubscribesToChannel:channel]){
- subscribes = YES;
- completion(error, subscribes, nil);
- }
- else{
- MLLog(@"Doesnt subscribe to channel - get subscription tier to pass back to prompt user for signing up");
- [self getSubscriptionPlanForChannel:channel withCompletion:^(NSError *error, MLSubscriptionPlan *subscriptionPlan) {
- if(!error){
- [self getSubscriptionTiersWithCompletion:^(NSError *error, NSArray *subscriptionTiers) {
- if(!error){
- MLSubscriptionTier * correctTier = nil;
- for(MLSubscriptionTier * t in subscriptionTiers){
- if([t.objectId.lastPathComponent intValue] == subscriptionPlan.subscriptionTierId){
- correctTier = t;
- }
- }
- channel.subscriptionTier = correctTier;
- completion(error, NO, correctTier);
- }
- else{
- completion(error, NO, NO);
- }
- }];
- //subscriptionPlan.subscriptionTierId
- //calculate subscription price
- }
- else{
- //error getting subscription plan for channel
- completion(error, NO, nil);
- }
- }];
- }
- }
- else{
- completion(error, NO, nil);
- }
- }];
- }
- else{
- completion(error, NO, nil);
- }
- }];
- }
- -(void)setupSubscriptions{
- if(!self.subscriptions){
- self.subscriptions = [NSMutableDictionary new];
- }
- }
- -(void)setSubscription:(MLSubscription*)sub forChannelId:(NSString*)string{
- [self setupSubscriptions];
- if(![self.subscriptions objectForKey:string]){
- [self.subscriptions setObject:sub forKey:string];
- }
- }
- -(BOOL)hasSubscriptionForChannelWithId:(NSString*)string{
- //NSLog(@"MLWalletAPI: hasSubscriptionForChannelWithId: %@", string);
- //NSLog(@"MLWalletAPI: subscribesToChannelWithId: %@", string);
- if([self.subscriptions objectForKey:string]){
- MLLog(@"Found %@ in dictionary", string);
- return YES;
- }
- else{
- //MLLog(@"MLWalletAPI: did not find string: %@ in dictionary keys %@", string, [self.subscriptions allKeys]);
- return NO;
- }
- }
- +(BOOL)currentUserSubscribesToChannel:(MLChannel *)channel{
- //MLLog(@"current user subscribes to channel - synchronous approach");
- if([channel.author.objectId isEqualToString:[[MLUser currentUser] objectId]]){
- return YES;
- }
- else{
- return [[self sharedInstance] hasSubscriptionForChannelWithId:channel.objectId];
- }
- }
- +(AnyPromise*)promiseChannelInfoForSubscription:(MLSubscription*)sub{
- return [AnyPromise promiseWithResolverBlock:^(PMKResolver _Nonnull resolve) {
- NSLog(@"Promise Channel Infor For Subscription");
- [self fetchChannelInfoForSubscription:sub withCompletion:^(NSError *error, id result) {
- if(!error){
- resolve((MLSubscription *)result);
- }
- else{
- resolve(error);
- }
- }];
- }];
- }
- +(AnyPromise*)subscribedChannelsForUser:(MLUser*)user{
- NSLog(@"promise subscribedChannelsForUser");
- return [AnyPromise promiseWithResolverBlock:^(PMKResolver _Nonnull resolve) {
- [self getSubscribedChannelsForUser:user withCompletion:^(NSError *error, NSArray *results) {
- resolve(error ?: results);
- }];
- }];
- }
- +(void)getSubscribedChannelsForUser:(MLUser *)user withCompletion:(MLResultsErrorCompletionBlock)completion{
- NSLog(@"getSubscribedChannelsForUser");
- [self getWalletWithLabel:user.username withCompletion:^(NSError *error, MLWallet *wallet) {
- if(!error){
- [self getSubscriptionsFromWallet:wallet withCompletion:^(NSError *error, NSArray *subscriptions) {
- NSMutableArray * followedChannels = [NSMutableArray new];
- for(MLSubscription * s in subscriptions){
- MLChannel * c = (MLChannel*)[MLChannel instanceFromId:s.channelObjectId];
- if(c){
- [followedChannels addObject:c];
- }
- else{
- MLLog(@"Nil channel from object cache - was assuming this would return an empty one");
- }
- }
- NSLog(@"Calling populate channels in getSubscribedChannelsForUser");
- [MLHALClient populateChannels:followedChannels].then(^(NSArray*channels){
- completion(nil, channels);
- }).catch(^(NSError * error){
- completion(error, nil);
- });
- }];
- }
- else{
- completion(error, nil);
- }
- }];
- }
- +(void)fetchChannelInfoForSubscription:(MLSubscription*)sub withCompletion:(MLSingleResultErrorCompletionBlock)completion{
- if(!sub.subscriptionPlanObjectId){
- completion(nil, sub);
- }
- MLLog(@"Populating subscription %@ by fetching subscriptionPlanId", sub.subscriptionPlanObjectId);
- [[self sharedInstance] performRequestWithPath:sub.subscriptionPlanObjectId andMethod:@"GET" andCompletion:^(NSError *error, id jsonDict) {
- MLLog(@"got subscription plan for channel %@", jsonDict);
- MLSubscriptionPlan * sp = [MLSubscriptionPlan instanceFromJSON:jsonDict withObjectId:sub.subscriptionPlanObjectId];
- sub.subscriptionPlan = sp;
- sub.channelObjectId = [jsonDict objectForKey:@"channelUrl"];
- [[self sharedInstance] setSubscription:sub forChannelId:sub.channelObjectId];
- completion(error, sub);
- }];
- }
- +(void)getSubscriptionsFromWallet:(MLWallet*)wallet withCompletion:(MLSubscriptionsCompletionBlock)completion{
- NSLog(@"getSubscriptionsFromWallet");
- [[self sharedInstance] setupSubscriptions];
- //POST /wallets/{walletId}/subscription_plans
- [[self sharedInstance] performRequestWithPath:[NSString stringWithFormat:@"%@/subscriptions", wallet.objectId] andMethod:@"GET" andCompletion:^(NSError *error, id jsonDict) {
- __block NSMutableArray * subscriptionResults = [NSMutableArray new];
- if(!error){
- MLLog(@"getSubscriptionsWithCompletion results %@", jsonDict);
- for(NSDictionary * d in jsonDict){
- MLSubscription * s = [MLSubscription instanceFromJSON:[NSMutableDictionary dictionaryWithDictionary:d] withObjectId:[NSString stringWithFormat:@"%@/subscriptions/%@",[wallet objectId], [d valueForKey:@"id"]]];
- [subscriptionResults addObject:s];
- MLLog(@"MLWalletAPI: just added subscription to subscription results %@", s.objectId);
- }
- }
- else{
- MLLog(@"MLWalletAPI: getSubscriptionsWithCompletion error %@", error);
- }
- NSMutableDictionary * subPromises = [NSMutableDictionary new];
- for(MLSubscription * s in subscriptionResults){
- if(s.subscriptionPlanObjectId && s.objectId){
- [subPromises setObject:[MLWalletAPI promiseChannelInfoForSubscription:s] forKey:s.objectId];
- }
- else{
- MLLog(@"MLWalletAPI: getSubscriptionsFromWallet ignoring subscription with no subplanid");
- }
- }
- MLLog(@"MLWalletAPI: getSubscriptionsFromWallet got %i subpromises", [[subPromises allKeys] count]);
- PMKWhen(subPromises).then(^(NSDictionary*results){
- MLLog(@"MLWalletAPI: getSubscriptionsFromWallet callback in PMKWhen %@", [results allKeys]);
- NSMutableArray * outputResults = [NSMutableArray new];
- for(MLSubscription * s in subscriptionResults){
- if(s.subscriptionPlanObjectId){
- MLLog(@"object for key is of class %@", [[results objectForKey:s.objectId] class]);
- MLSubscription * populatedSub = [results objectForKey:s.objectId];
- MLLog(@"Adding subscription after promises %@ subPlanId %@ channelObjectId %@", s.objectId, s.subscriptionPlan.objectId, s.channelObjectId);
- if(populatedSub){
- [outputResults addObject:populatedSub];
- }
- else{
- MLLog(@"Nil subscription from populated subscriptions?");
- }
- }
- else{
- MLLog(@"MLWalletAPI: ignoring subscription without subscriptionPlanObjectId after promises %@", s.objectId);
- }
- }
- MLLog(@"MLWalletAPI: completed loading subscriptions from wallet");
- completion(error, outputResults);
- });
- }];
- }
- +(void)checkForCurrentUserPaymentMethodsAndCustomerId:(MLWalletCheckForPaymentMethodsAndCustomerIdCompletionBlock)completion{
- [self getCurrentUserWalletsWithCompletion:^(NSError *error, NSArray *wallets) {
- if(!error){
- __block MLWallet * currentUserWallet = [wallets firstObject];
- MLLog(@"Got wallet %@ with stripeCustomerId %@", currentUserWallet.objectId, currentUserWallet.stripeCustomerId);
- __block BOOL hasCustomerID = YES;
- if(!currentUserWallet.stripeCustomerId || currentUserWallet.stripeCustomerId.length == 0){
- hasCustomerID = NO;
- }
- [self getPaymentMethodsForWallet:currentUserWallet withCompletion:^(NSError *error, MLPaymentMethod *paymentMethod) {
- BOOL hasPaymentMethod = paymentMethod ? YES : NO;
- completion(error, currentUserWallet, hasPaymentMethod, hasCustomerID);
- }];
- }
- else{
- MLLog(@"subscribeToChannel: error getting current user wallet %@", error);
- completion(error, nil, NO, NO);
- }
- }];
- }
- +(void)presentSubscriptionPromptForChannel:(MLChannel*)channel withCompletion:(MLBoolCompletionBlockWithError)completion{
- [[self sharedInstance] presentSubscriptionPromptForChannel:channel withCompletion:completion];
- }
- -(void)presentSubscriptionPromptForChannel:(MLChannel*)channel withCompletion:(MLBoolCompletionBlockWithError)completion{
- NSLog(@"presentSubscriptionPromptForChannelEntry pause");
- MLLog(@"Does not subscribe so now we will make a subscription for a channel here %@", channel.objectId);
- UIAlertView *alert = [UIAlertView new];
- int membershipPriceInCoins = channel.membershipPriceInBits;
- BOOL channelNameIsBlank = [MLHelper stringTrimmedOfWhiteSpace:channel.name].length < 1;
- NSString *title = channelNameIsBlank ? [NSString stringWithFormat:@"Unlock this post"] : [NSString stringWithFormat:@"Unlock '%@'", channel.name];
- title = [title stringByAppendingString:[NSString stringWithFormat:@" for %i %@?", membershipPriceInCoins, [MLHelper conditionallyPluralString:@"Coin" withCount:membershipPriceInCoins]]];
- alert.title = title;
- [alert addButtonWithTitle:@"Not Now"];
- [alert addButtonWithTitle:@"Unlock"];
- [alert promise].then(^(NSNumber *dismissedButtonIndex){
- //…
- if(dismissedButtonIndex.intValue == 1){
- [MLWalletAPI purchaseChannel:channel withCompletion:^(NSError *error, BOOL success) {
- completion(YES, error);
- }];
- }
- else{
- completion(NO, nil);
- //[MLHelper showTempAlertWithString:@"Purchase cancelled."];
- }
- });
- }
- +(void)subscribeToChannel:(MLChannel*)channel withCompletion:(MLSubscribeToChannelCompletionBlock)completion{
- //registered customer_id and payment method in wallet before creating a subscription
- NSLog(@"MLWalletAPI: subscribe to channel %@", channel.objectId);
- [self checkForCurrentUserPaymentMethodsAndCustomerId:^(NSError *error, MLWallet *wallet, BOOL hasPaymentMethod, BOOL hasStripeCustomerId) {
- if(!error){
- if(!wallet || !hasPaymentMethod || !hasStripeCustomerId){
- MLLog(@"subscribeToChannel: Something wrong with user payment setup %@ hasPaymentMethod:%@ hasStripeCustomerId:%@", wallet, hasPaymentMethod ? @"YES" : @"NO", hasStripeCustomerId ? @"YES" : @"NO");
- completion(error, NO);
- }
- MLWallet * currentUserWallet = wallet;
- [self getSubscriptionPlanForChannel:channel withCompletion:^(NSError *error, MLSubscriptionPlan *subscriptionPlan) {
- if(!error){
- MLSubscription * s = [MLSubscription subscriptionForPlan:subscriptionPlan];
- [[self sharedInstance] performRequestWithPath:[NSString stringWithFormat:@"%@/subscriptions", currentUserWallet.objectId] andMethod:@"POST" andJSONDictionary:s.jsonDictionary andCompletion:^(NSError *error, id jsonDict) {
- if(!error){
- [self getSubscriptionsFromWallet:wallet withCompletion:^(NSError *error, NSArray *subscriptionPlans) {
- completion(error, YES);
- MLLog(@"subscribeToChannel %@: No error", channel.objectId);
- }];
- }
- else{
- completion(error, NO);
- MLLog(@"subscribeToChannel %@: Error! %@", channel.objectId, error);
- }
- }];
- }
- else{
- MLLog(@"subscribeToChannel %@: Error getting subsciption plan for channel %@", channel.objectId, error);
- completion(error, NO);
- }
- }];
- }
- else{
- MLLog(@"subscribeToChannel: error getting current user wallet %@", error);
- completion(error, NO);
- }
- }];
- }
- +(void)unsubscribeFromChannel:(MLChannel*)channel withCompletion:(MLErrorCompletionBlock)completion{
- if(!channel.objectId){
- [MLHelper showTempAlertWithString:@"Channel doesnt have ID"];
- return;
- }
- [self getCurrentUserWalletsWithCompletion:^(NSError *error, NSArray *wallets) {
- if(!error){
- [self getSubscriptionsFromWallet:[wallets firstObject] withCompletion:^(NSError *error, NSArray *subscriptions) {
- if(!error){
- MLSubscription * subForChannel;
- for(MLSubscription * s in subscriptions){
- NSLog(@"Compaing %@ to %@", s.channelObjectId, channel.objectId);
- if([s.channelObjectId isEqualToString:channel.objectId]){
- subForChannel = s;
- }
- }
- if(subForChannel){
- [subForChannel deleteWithCompletion:^(NSError *error) {
- if(error){
- NSLog(@"Error deleting MLSubscription %@", error);
- }
- completion(error);
- }];
- }
- }
- else{
- completion(error);
- }
- }];
- }
- else{
- [MLHelper showTempAlertWithString:@"Error getting your wallets - try again"];
- }
- }];
- }
- +(void)getSubscriptionPlansFromWallet:(MLWallet*)wallet withCompletion:(MLSubscriptionPlansCompletionBlock)completion{
- //POST /wallets/{walletId}/subscription_plans
- [[self sharedInstance] performRequestWithPath:[NSString stringWithFormat:@"%@/subscription_plans", wallet.objectId] andMethod:@"GET" andCompletion:^(NSError *error, id jsonDict) {
- NSMutableArray * plans = [NSMutableArray new];
- if(!error){
- for(NSDictionary * d in jsonDict){
- [plans addObject:[MLSubscriptionPlan instanceFromJSON:[NSMutableDictionary dictionaryWithDictionary:d] withObjectId:[NSString stringWithFormat:@"%@/subscription_plans/%@",[wallet objectId], [d valueForKey:@"id"]]]];
- }
- MLLog(@"getSubscriptionPlansWithCompletion results %@", jsonDict);
- }
- else{
- MLLog(@"getSubscriptionPlansWithCompletion error %@", error);
- }
- completion(error, plans);
- }];
- }
- +(void)getSubscriptionTiersWithCompletion:(MLSubscriptionTiersCompletionBlock)completion{
- NSLog(@"GET SUBSCRIPTION TIERS WITH COMPLETION");
- [[self sharedInstance] performRequestWithPath:[NSString stringWithFormat:@"%@/subscription_tiers", kWalletServerAddress] andMethod:@"GET" andCompletion:^(NSError *error, id jsonDict) {
- NSMutableArray * tiers = [NSMutableArray new];
- if(!error){
- for(NSDictionary * d in jsonDict){
- [tiers addObject:[MLSubscriptionTier instanceFromJSON:[NSMutableDictionary dictionaryWithDictionary:d] withObjectId:[NSString stringWithFormat:@"%@/subscription_tiers/%@",kWalletServerAddress, [d valueForKey:@"id"]]]];
- }
- MLLog(@"getSubscriptionTiersWithCompletion results %@", jsonDict);
- }
- else{
- MLLog(@"getSubscriptionTiersWithCompletion error %@", error);
- }
- completion(error, tiers);
- }];
- }
- +(void)testWalletAPI{
- [self getWalletsWithCompletion:^(NSError *error, NSArray *wallets) {
- MLLog(@"getWalletsWithCompletion: completion: error:%@ data:%@", error, wallets);
- }];
- [self getWalletWithLabel:@"whittle" withCompletion:^(NSError *error, MLWallet *wallet) {
- if(!error){
- MLLog(@"getWalletsWithLabel:whitte completion: data:%@", wallet.objectId);
- }
- else{
- MLLog(@"getWalletsWithLabel:whitte completion: error:%@", error);
- }
- }];
- MLWallet * testWallet;
- testWallet.label = @"testLabel";
- MLWallet * knownWallet = [MLWallet new];
- knownWallet.objectId = [NSString stringWithFormat:@"%@/%@", kWalletServerAddress, @"wallets/1"];
- [self getWallet:knownWallet withCompletion:^(NSError *error, MLWallet *wallet) {
- MLLog(@"getWallet:WithCompletion: completion: error:%@ data:%@", error, wallet);
- [self getBalanceOfWallet:knownWallet withCompletion:^(NSError *error, NSDecimalNumber * balance) {
- MLLog(@"getBalanceOfWallet:WithCompletion: completion: error:%@ data:%@", error, balance);
- [self postWalletEvent:nil toWallet:knownWallet withCompletion:^(NSError *error, MLWalletEvent *walletEvent) {
- MLLog(@"postEvent: completion: error:%@ data:%@", error, walletEvent);
- }];
- }];
- }];
- MLWalletEvent * knownWalletEvent;
- knownWalletEvent.objectId = [NSString stringWithFormat:@"%@/%@", kWalletServerAddress, @"wallets/1/deals/1"];
- [self getWalletEvent:knownWalletEvent withCompletion:^(NSError *error, MLWalletEvent *walletEvent) {
- MLLog(@"getWalletEvent: completion: error:%@ data:%@", error, walletEvent);
- }];
- MLUser * demoUser = [MLUser factoryInstance];
- demoUser.username = @"orpheus";
- }
- #pragma mark -
- #pragma mark API interface
- +(void)tipUser:(MLUser*)seller forPost:(MLPost *)post gift:(MLGift*)gift withCompletion:(MLSingleWalletEventCompletionBlock)completion{
- int amountInBits = [MLWalletAPI convertDollarsToBits:gift.amountInDollars];
- NSLog(@"tipUser: Tip user a gift %@ %i",gift.name, amountInBits);
- [self ensureBalanceMinimum:amountInBits before:^(NSError *error) {
- NSLog(@"tipUser: Return in ensure balance minimum %i error:%@", amountInBits, error);
- if(!error){
- __block MLWalletEvent * mlwe = [MLWalletEvent tipForUser:seller forPost:post ofGift:gift];
- NSMutableDictionary * walletPromises = [NSMutableDictionary new];
- [walletPromises setObject:[self promiseWalletForUser:mlwe.seller] forKey:@"seller"];
- [walletPromises setObject:[self promiseWalletForUser:mlwe.customer] forKey:@"customer"];
- NSLog(@"tipUser: about to launch wallet promises");
- PMKWhen(walletPromises).then(^(NSDictionary *promiseResults){
- NSLog(@"tipUser: Is this where the crash is? %@", [[promiseResults objectForKey:@"seller"] class]);
- MLWallet * sellerWallet = [[promiseResults objectForKey:@"seller"] firstObject];
- MLWallet * customerWallet = [[promiseResults objectForKey:@"customer"] firstObject];
- if(sellerWallet && customerWallet){
- NSLog(@"tipUser: wallets are both there");
- mlwe.debitedWallet = customerWallet;
- mlwe.creditedWallet = sellerWallet;
- //assuming they have object ids ?
- //new money server
- [self postWalletEvent:mlwe toWallet:mlwe.debitedWallet withCompletion:completion];
- }
- else if(!sellerWallet){
- [MLHelper showTempAlertWithString:[NSString stringWithFormat:@"%@ is not set up to receive tips!", mlwe.seller.username]];
- }
- }).catch(^(NSError *error){
- NSLog(@"tipUser: catch error");
- [MLHelper showTempAlertWithString:[NSString stringWithFormat:@"%@ is not set up to receive tips! %@",mlwe.seller.username, error.localizedDescription]];
- NSLog(@"Can't load wallets %@", error.localizedDescription);
- });
- }
- }];
- }
- +(void)purchaseChannel:(MLChannel*)channel withCompletion:(MLSingleWalletEventCompletionBlock)completion{
- MLLog(@"purchase Channel %@", channel.objectId);
- [self ensureBalanceMinimum:channel.membershipPriceInBits before:^(NSError *error) {
- if(!error){
- __block MLWalletEvent * mlwe = [MLWalletEvent purchaseForChannel:channel];
- NSMutableDictionary * walletPromises = [NSMutableDictionary new];
- [walletPromises setObject:[self promiseWalletForUser:mlwe.seller] forKey:@"seller"];
- [walletPromises setObject:[self promiseWalletForUser:mlwe.customer] forKey:@"customer"];
- PMKWhen(walletPromises).then(^(NSDictionary *promiseResults){
- MLLog(@"Is this where the crash is?");
- MLWallet * sellerWallet = [[promiseResults objectForKey:@"seller"] firstObject];
- MLWallet * customerWallet = [[promiseResults objectForKey:@"customer"] firstObject];
- if(sellerWallet && customerWallet){
- mlwe.debitedWallet = customerWallet;
- mlwe.creditedWallet = sellerWallet;
- //assuming they have object ids ?
- [self postWalletEvent:mlwe toWallet:mlwe.debitedWallet withCompletion:completion];
- [MLGiftManager showCelebrationForPaywallUnlock];
- }
- else if(!sellerWallet){
- [MLHelper showTempAlertWithString:[NSString stringWithFormat:@"%@ is not set up to receive tips!", mlwe.seller.username]];
- }
- }).catch(^(NSError *error){
- [MLHelper showTempAlertWithString:[NSString stringWithFormat:@"%@ is not set up to receive tips! %@",mlwe.seller.username, error.localizedDescription]];
- MLLog(@"Can't load wallets %@", error.localizedDescription);
- });
- }
- }];
- }
- +(void)refreshWalletAPIModel:(MLModel*)source withCompletion:(MLSingleResultErrorCompletionBlock)completion{
- NSLog(@"MLWalletAPI 2.0: refreshWalletAPIModel: %@", source.objectId);
- [[self sharedInstance] performRequestWithPath:source.objectId andMethod:@"GET" andCompletion:^(NSError *error, id jsonDict) {
- if(!error){
- [source populateWithJSON:jsonDict];
- completion(nil, source);
- }
- else{
- completion(error, source);
- }
- }];
- }
- +(void) getAcquisitionSourcesForWallet: (MLWallet *) wallet withCompletion: (MLMultipleWalletAcquisitionSourcesCompletionBlock) completion {
- NSLog(@"MLWalletAPI 2.0: getAcquisitionSourcesForWallet: %@", wallet.objectId);
- NSNumber *walletId = [NSNumber numberWithInteger:[[[wallet.objectId componentsSeparatedByString:@"/"] lastObject] integerValue]];
- NSString * collectionPath = [NSString stringWithFormat:@"%@/acquisition_sources", wallet.objectId];
- [[self sharedInstance] performRequestWithPath:collectionPath andMethod:@"GET" andCompletion:^(NSError *error, id jsonDict) {
- if(jsonDict){
- NSLog(@"MLWalletAPI 2.0: getAcquisitionSourcesForWallet: %@ json dict is %@", wallet.objectId, jsonDict);
- NSArray *sources = [NSArray arrayWithArray:jsonDict];
- NSMutableArray * sourceModels = [NSMutableArray new];
- if (sources.count > 0) {
- MLLog(@"found payment methods");
- for(NSDictionary * d in sources){
- MLWalletAcquisitionSource *as = [MLWalletAcquisitionSource instanceFromJSON:d withObjectId:[NSString stringWithFormat:@"%@/acquisition_sources/%@", kWalletServerAddress,[d valueForKey:@"id"]]];
- NSLog(@"Populating AcquisitionSource with ID %@", as.objectId);
- as.wallet = wallet;
- NSLog(@"");
- [sourceModels addObject:as];
- }
- }
- completion(nil, sourceModels);
- }
- else{
- //handle request error
- completion(error, nil);
- MLLog(@"Error getAcquisitionSourcesForWallet! %@", error.localizedDescription);
- }
- }];
- }
- +(void)makeInAppPurchaseAcquisitionSourceWithWallet:(MLWallet*)wallet andCompletion:(MLWalletAcquisitionSourceCompletionBlock)completion{
- NSLog(@"MLWalletAPI 2.0: makeInAppPurchaseAcquisitionSourceWithWallet: %@", wallet.objectId);
- MLWalletAcquisitionSource * as = [MLWalletAcquisitionSource new];
- as.type = MLWalletAcquisitionSourceTypeInAppPurchase;
- as.wallet = wallet;
- [as saveWithCompletion:^(NSError *error, MLModel *model) {
- if(!error){
- NSLog(@"MLWalletAPI 2.0: makeInAppPurchaseAcquisitionSourceWithWallet: %@ no error", wallet.objectId);
- NSLog(@"MLWalletAcquisitionSource: saveWithCompletion %@", model.objectId);
- completion(nil, (MLWalletAcquisitionSource*)model);
- }
- else{
- NSLog(@"MLWalletAPI 2.0: makeInAppPurchaseAcquisitionSourceWithWallet: %@ error %@ ", wallet.objectId, error);
- completion(error, nil);
- }
- }];
- }
- +(void)getInAppPurchaseAcquisitionSourceForWallet:(MLWallet *)wallet withCompletion:(MLWalletAcquisitionSourceCompletionBlock)completion{
- NSLog(@"MLWalletAPI 2.0: getInAppPurchaseAcquisitionSourceForWallet: %@", wallet.objectId);
- [self getAcquisitionSourcesForWallet:wallet withCompletion:^(NSError *error, NSMutableArray *acquisitionSources) {
- if(!error){
- NSLog(@"MLWalletAPI 2.0: getInAppPurchaseAcquisitionSourceForWallet: %@ no error %i acquisition sources", wallet.objectId, [acquisitionSources count]);
- MLWalletAcquisitionSource * inAppAcquisitionSource;
- //check for inapppurchase acquisition source
- for(MLWalletAcquisitionSource * as in acquisitionSources){
- if(as.type == MLWalletAcquisitionSourceTypeInAppPurchase){
- inAppAcquisitionSource = as;
- }
- }
- if(inAppAcquisitionSource){
- NSLog(@"MLWalletAPI 2.0: getInAppPurchaseAcquisitionSourceForWallet: %@ found inAppAcquisitionSource %@", wallet.objectId, inAppAcquisitionSource.objectId);
- completion(nil, inAppAcquisitionSource);
- }
- else{
- NSLog(@"MLWalletAPI 2.0: getInAppPurchaseAcquisitionSourceForWallet: %@ did not find in App acquisition source now will make inAppPurchaseAcquisitionSource", wallet.objectId);
- //need to create acquisition source
- [self makeInAppPurchaseAcquisitionSourceWithWallet:wallet andCompletion:completion];
- }
- }
- else{
- NSLog(@"MLWalletAPI 2.0: getInAppPurchaseAcquisitionSourceForWallet: %@ error getting acquisition sources %@", wallet.objectId, error);
- completion(error, nil);
- }
- }];
- }
- +(void)purchaseCoinsAtTierLevel:(MLCoinPurchaseTier)tier withCompletion:(MLSingleWalletEventCompletionBlock)completion {
- MLLog(@"purchaseCoinsAtTierLevel: %li", (long)tier);
- NSLog(@"MLWalletAPI 2.0 purchaseCoinsAtTierLevel: %i withCompletion", (int)tier);
- //then posting the event
- //MLWalletEvent * mlwe = [MLWalletEvent bitsPurchaseOfAmount:amountInBits];
- //get current user wallet
- NSMutableDictionary * walletPromises = [NSMutableDictionary new];
- [walletPromises setObject:[self promiseWalletForUser:[MLUser currentUser]] forKey:@"customer"];
- PMKWhen(walletPromises).then(^(NSDictionary *promiseResults){
- NSLog(@"MLWalletAPI 2.0 purchaseCoinsAtTierLevel: after getting wallets", (int)tier);
- MLWallet * customerWallet = [[promiseResults objectForKey:@"customer"] firstObject];
- //get/make acquisition source for wallet in app purchases
- [self getInAppPurchaseAcquisitionSourceForWallet:customerWallet withCompletion:^(NSError *error, MLWalletAcquisitionSource *acquisitionSource) {
- if(!error){
- NSLog(@"MLWalletAPI 2.0 purchaseCoinsAtTierLevel: successfully got inAppPurchaseAcquistiionSource %@", acquisitionSource.objectId);
- //perform actual in app purchase
- [MLInAppPurchaseManager purchaseCoinsAtInAppPurchaseTier:tier withCompletion:^(NSError *error, NSData *receipt) {
- if(!error){
- [[NSNotificationCenter defaultCenter] postNotificationName:kPurchaseNotification object:nil userInfo:@{@"success":@YES}];
- NSLog(@"MLWalletAPI 2.0 MLInAppPurchaseManager transactionCompleted with receipt %@", receipt);
- //create acquistion
- MLWalletAcquisition * a = [acquisitionSource acquisitionWithReceipt:receipt];
- NSMutableURLRequest * mur = [[self sharedInstance] requestWithPath:[NSString stringWithFormat:@"%@/acquisitions", acquisitionSource.objectId] andMethod:@"POST" andBody:a.receipt];
- [mur setValue:@"application/pkcs7-mime" forHTTPHeaderField:@"Content-Type"];
- [mur setValue:@"base64" forHTTPHeaderField:@"Content-Encoding"];
- [mur setValue:[a.receipt MD5] forHTTPHeaderField:@"Content-MD5"];
- [[self sharedInstance] performRequest:mur forJSONDictionaryWithCompletion:^(NSError *error, id jsonDict) {
- NSLog(@"Just performed save of MLWalletAcquisition %@", jsonDict);
- if(!error){
- completion(nil, nil);
- NSLog(@"MLWalletAPI 2.0 successfully saved MLWalletAcquisition %@", jsonDict);
- }
- else{
- completion(error, nil);
- NSLog(@"MLWalletAPI 2.0 error saving MLWalletAcquisition %@", error);
- }
- }];
- }
- else{
- [[NSNotificationCenter defaultCenter] postNotificationName:kPurchaseNotification object:nil userInfo:@{@"success":@NO}];
- NSLog(@"MLWalletAPI 2.0 error purchasing coins %@", error);
- completion(error, nil);
- }
- }];
- }
- }];
- }).catch(^(NSError *error){
- MLLog(@"Can't load wallets %@", error.localizedDescription);
- completion(error, nil);
- // any errors in any of the above promises land here
- });
- }
- /*
- */
- +(void)purchaseBits:(NSInteger)amountInBits withCompletion:(MLSingleWalletEventCompletionBlock)completion {
- MLLog(@"Purchase bits:: %li", (long)amountInBits);
- //then posting the event
- MLWalletEvent * mlwe = [MLWalletEvent bitsPurchaseOfAmount:amountInBits];
- //get current user wallet
- NSMutableDictionary * walletPromises = [NSMutableDictionary new];
- [walletPromises setObject:[self promiseWalletForUser:mlwe.customer] forKey:@"customer"];
- PMKWhen(walletPromises).then(^(NSDictionary *promiseResults){
- MLWallet * customerWallet = [[promiseResults objectForKey:@"customer"] firstObject];
- //get payment method
- NSMutableDictionary * paymentMethodPromises = [NSMutableDictionary new];
- [paymentMethodPromises setObject:[self promisePaymentMethodForWallet:customerWallet] forKey:@"paymentMethod"];
- PMKWhen(paymentMethodPromises).then(^(NSDictionary *paymentPromiseResults){
- MLLog(@"payment promise results %@", paymentMethodPromises);
- MLPaymentMethod * paymentMethod = [[paymentPromiseResults objectForKey:@"paymentMethod"] firstObject];
- //if (paymentMethod.methodId) {
- MLLog(@"purchaseBits paymentMethodPromises");
- mlwe.paymentMethod = paymentMethod;
- [self postWalletEvent:mlwe toWallet:customerWallet withCompletion:completion];
- //}
- // else {
- // MLLog(@"purchaseBits show CC screen");
- // //show credit card screen
- // completion(nil, nil);
- // }
- }).catch(^(NSError *error){
- MLLog(@"Error with payment method promises");
- completion(error, nil);
- });
- }).catch(^(NSError *error){
- MLLog(@"Can't load wallets %@", error.localizedDescription);
- completion(error, nil);
- // any errors in any of the above promises land here
- });
- }
- +(AnyPromise*)promisePaymentMethodForWallet:(MLWallet*)wallet{
- MLLog(@"promise payment method for wallet %@", wallet);
- return [AnyPromise promiseWithResolverBlock:^(PMKResolver _Nonnull resolve) {
- [self getPaymentMethodsForWallet:wallet withCompletion:^(NSError *error, MLPaymentMethod *paymentMethod) {
- MLLog(@"Promise payment method completion %@ %@", error.localizedDescription, wallet);
- if (paymentMethod) {
- resolve(error ?: @[paymentMethod]);
- }
- else {
- if (error) {
- resolve(error ?: nil);
- }
- else {
- int errCode = MLWalletErrorNoPaymentMethod;
- NSString *errorDomain = @"com.masslab.error";
- NSError *underlyingError = [[NSError alloc] initWithDomain:errorDomain
- code:errCode userInfo:nil];
- // Create and return the custom domain error.
- NSDictionary *errorDictionary = @{ NSLocalizedDescriptionKey : @"Payment method does not exist",
- NSUnderlyingErrorKey : underlyingError };
- NSError *anError = [[NSError alloc] initWithDomain:errorDomain
- code:errCode userInfo:errorDictionary];
- resolve(anError ?: nil);
- }
- }
- }];
- }];
- }
- +(AnyPromise*)promiseWalletForUser:(MLUser*)user{
- return [AnyPromise promiseWithResolverBlock:^(PMKResolver _Nonnull resolve) {
- NSLog(@"Promise wallet for user %@", user.username);
- [self getWalletWithLabel:user.username withCompletion:^(NSError *error, MLWallet *wallet) {
- NSLog(@"Promise wallet for user completion %@ %@", error.localizedDescription, wallet);
- if (wallet) {
- resolve(error ?: @[wallet]);
- }
- else {
- if (error) {
- resolve(error ?: nil);
- }
- else {
- int errCode = MLWalletErrorNoWallet;
- NSString *errorDomain = @"com.masslab.error";
- NSError *underlyingError = [[NSError alloc] initWithDomain:errorDomain
- code:errCode userInfo:nil];
- // Create and return the custom domain error.
- NSDictionary *errorDictionary = @{ NSLocalizedDescriptionKey : @"Wallet does not exist",
- NSUnderlyingErrorKey : underlyingError };
- NSError *anError = [[NSError alloc] initWithDomain:errorDomain
- code:errCode userInfo:errorDictionary];
- resolve(anError ?: nil);
- }
- }
- }];
- }];
- }
- +(void)getBalanceForCurrentUserWithCompletion:(MLWalletCurrentUserBalanceCompletionBlock)completion{
- MLLog(@"MLWalletAPI :: Get balance with completion");
- NSMutableDictionary * walletPromises = [NSMutableDictionary new];
- [walletPromises setObject:[self promiseWalletForUser:[MLUser currentUser]] forKey:@"user"];
- PMKWhen(walletPromises).then(^(NSDictionary *promiseResults){
- MLLog(@"MLWalletAPI :: Get balance with completion inside promise");
- MLWallet * sellerWallet = [[promiseResults objectForKey:@"user"] firstObject];
- [self getBalanceOfWallet:sellerWallet withCompletion:^(NSError *error, NSDecimalNumber * balance) {
- MLLog(@"MLWalletAPI :: Get balance with completion inside get balance of wallet");
- completion(error,balance);
- }];
- }).catch(^(NSError *error){
- completion(error, nil); //used to be nil
- // any errors in any of the above promises land here
- MLLog(@"Can't load wallets %@", error.localizedDescription);
- });
- }
- +(void)getEarningsForCurrentUserWithCompletion:(MLWalletCurrentUserBalanceCompletionBlock)completion{
- MLLog(@"MLWalletAPI :: Get balance with completion");
- NSMutableDictionary * walletPromises = [NSMutableDictionary new];
- [walletPromises setObject:[self promiseWalletForUser:[MLUser currentUser]] forKey:@"user"];
- PMKWhen(walletPromises).then(^(NSDictionary *promiseResults){
- MLLog(@"MLWalletAPI :: Get balance with completion inside promise");
- MLWallet * sellerWallet = [[promiseResults objectForKey:@"user"] firstObject];
- [self getEarningsOfWallet:sellerWallet withCompletion:^(NSError *error, NSDecimalNumber * balance) {
- MLLog(@"MLWalletAPI :: Get balance with completion inside get balance of wallet");
- completion(error,balance);
- }];
- }).catch(^(NSError *error){
- completion(error, nil); //used to be nil
- // any errors in any of the above promises land here
- MLLog(@"Can't load wallets %@", error.localizedDescription);
- });
- }
- /*
- +(void)getTipsForPost:(MLPost*)post withCompletion:(MLWalletCurrentUserActivityCompletionBlock)completion{
- [self getWalletActivityForCurrentUserWithCompletion:^(NSError *error, NSMutableArray *purchases) {
- if(!error){
- NSMutableArray * output = [NSMutableArray new];
- for(MLPurchase * p in purchases){
- NSLog(@"Purchase isTip:%@ byUser:%@ objectId:%@", p.isTip ? @"YES" : @"NO", p.seller.username, p.post.objectId);
- if([p.post.objectId isEqualToString:post.objectId] && p.type == MLPurchaseGroupTypeTipsReceived){
- [output addObject:p];
- }
- }
- completion(error, output);
- }
- else{
- NSLog(@"Get tips for post %@ error %@", post.objectId, error);
- completion(error, nil);
- }
- }];
- }
- */
- +(void)getTipsForPost:(MLPost*)post withCompletion:(MLWalletCurrentUserActivityCompletionBlock)completion{
- NSLog(@"MLWalletAPI: getTipsForPost: %@", post.objectId);
- [self getCurrentUserWalletsWithCompletion:^(NSError *error, NSArray *wallets) {
- if(!error){
- NSLog(@"MLWalletAPI: getTipsForPost: %@ got current user wallets", post.objectId);
- MLWallet * wallet = [wallets firstObject];
- [self getWalletEventsForWallet:wallet withCompletion:^(NSError *error, NSMutableArray *walletLines) {
- NSLog(@"MLWalletAPI: getTipsForPost: %@ got wallet events %@ %lu", post.objectId, error, (unsigned long)[walletLines count]);
- if(!error){
- NSMutableArray * tips = [NSMutableArray new];
- for(MLWalletEvent * e in walletLines){
- if((e.type == MLWalletEventTypeTip || e.type == MLWalletEventTypeGift) && e.item.objectId == post.objectId){
- NSLog(@"Found a tip that matches");
- [tips addObject:e];
- }
- }
- completion(nil, tips);
- }
- else{
- NSLog(@"MLWalletAPI: getTipsForPost: error getting wallet events %@", error);
- completion(error, nil);
- }
- }];
- }
- else{
- NSLog(@"MLWalletAPI: getTipsForPost: error getting current user wallets %@", error);
- completion(error, nil);
- }
- }];
- }
- +(void)getTopTipperForPost:(MLPost*)post withCompletion:(MLSingleResultErrorCompletionBlock)completion{
- //1. Search for the _content reference_ matching the video URL.
- ///example
- //https://money-dev.portalserv.net/content_references?uri=https%3A%2F%2Fcontent-dev.portalserv.net%2Fvideos%2F314
- NSURL * url = [NSURL URLWithString:@"content_references" relativeToURL:[NSURL URLWithString:kWalletServerAddress]];
- NSURLComponents *components = [NSURLComponents componentsWithString:url.absoluteString];
- NSURLQueryItem *uri = [NSURLQueryItem queryItemWithName:@"uri" value:post.objectId];
- if(!components.queryItems){
- components.queryItems = [NSArray new];
- }
- components.queryItems = [components.queryItems arrayByAddingObjectsFromArray:@[uri]];
- NSLog(@"MLWalletAPI:: getTopTipperForPost: about to request content reference leaderboard id at %@", components.URL.absoluteString);
- //this should return an id for the leaderboard
- [self performRequestWithPath:components.URL.absoluteString andMethod:@"GET" andCompletion:^(NSError *error, id jsonDict) {
- if(!error){
- NSLog(@"MLWalletAPI:: getTopTipperForPost: content reference leaderboard id json %@", jsonDict);
- NSString * identifier = [[jsonDict firstObject] objectForKey:@"id"];
- if(!identifier){
- NSLog(@"MLWalletAPI:: getTopTipperForPost: no identifier for leaderboard found");
- completion(nil, nil);
- return;
- }
- //2. Fetch the _gift leaderboards_ for that content reference.
- //money/content_references/<ContentReferenceId>/gift_leaderboards
- NSURL * leaderBoardURL = [NSURL URLWithString:[NSString stringWithFormat:@"content_references/%@/gift_leaderboards", identifier] relativeToURL:[NSURL URLWithString:kWalletServerAddress]];
- [self performRequestWithPath:leaderBoardURL.absoluteString andMethod:@"GET" andCompletion:^(NSError *error, id jsonDict2) {
- if(!error){
- MLLeaderBoardEntry * lbe = nil;
- NSLog(@"MLWalletAPI:: getTopTipperForPost: leaderBoard json %@", jsonDict2);
- for(NSDictionary * actualDict in jsonDict2){
- NSString * leaderBoardEntryId = [NSString stringWithFormat:@"%@/leaderboard_entries/%@", kWalletServerAddress, [actualDict objectForKey:@"id"]];
- MLLeaderBoardEntry * leaderBoardEntry = [MLLeaderBoardEntry instanceFromJSON:[jsonDict2 firstObject] withObjectId:leaderBoardEntryId];
- if(!lbe){
- lbe = leaderBoardEntry;
- }
- else if([leaderBoardEntry amountInCoins] > [lbe amountInCoins]){
- lbe = leaderBoardEntry;
- }
- }
- if(lbe){
- [MLHALClient syncModel:lbe.user withCompletion:^(NSError *error, id result) {
- if(!error){
- NSLog(@"MLWalletAPI:: getTopTipperForPost: username of top tipper is %@ with %i coins", lbe.user.username, [lbe amountInCoins]);
- completion(nil, lbe);
- }
- else{
- NSLog(@"MLWalletAPI:: getTopTipperForPost: error syncing user");
- completion(error, nil);
- }
- }];
- }
- else{
- NSLog(@"MLWalletAPI:: getTopTipperForPost: no leaderboard found in results %@", jsonDict2);
- completion([NSError errorWithDomain:@"com.masslab.portal" code:404 userInfo:@{@"localizedDescription":@"No leaderboard found"}], nil);
- }
- }
- else{
- NSLog(@"MLWalletAPI:: getTopTipperForPost: error requesting content reference leaderboard body at %@ error: %@", leaderBoardURL.absoluteString, error);
- completion(error, nil);
- }
- }];
- }
- else{
- NSLog(@"MLWalletAPI:: getTopTipperForPost: error requesting content reference leaderboard id at %@ error: %@", components.URL.absoluteString, error);
- completion(error, nil);
- }
- }];
- }
- +(void)getWalletActivityForCurrentUserWithCompletion:(MLWalletCurrentUserActivityCompletionBlock)completion{
- MLLog(@"MLWalletAPI :: Get balance with completion");
- NSMutableDictionary * walletPromises = [NSMutableDictionary new];
- [walletPromises setObject:[self promiseWalletForUser:[MLUser currentUser]] forKey:@"user"];
- PMKWhen(walletPromises).then(^(NSDictionary *promiseResults){
- MLLog(@"MLWalletAPI :: Get balance with completion inside promise");
- MLWallet * sellerWallet = [[promiseResults objectForKey:@"user"] firstObject];
- [self getLinesOfWallet:sellerWallet withCompletion:^(NSError *error, NSMutableArray *walletLines) {
- completion(error, walletLines);
- }];
- }).catch(^(NSError *error){
- MLLog(@"Can't load wallets %@", error.localizedDescription);
- completion(error, nil);
- // any errors in any of the above promises land here
- });
- }
- #pragma mark -
- #pragma mark API interface - direct
- //GET me/wallets
- +(void)getCurrentUserWalletsWithCompletion:(MLWalletsCompletionBlock)completion{
- NSLog(@"MLWalletAPI getCurrentUserWalletsWithCompletion before making request");
- [[self sharedInstance] performRequestWithPath:@"/" andMethod:@"GET" andCompletion:^(NSError *error, id jsonResults) {
- if(!error){
- NSLog(@"getCurrentUserWalletsWithCompletion: %@", jsonResults);
- NSMutableArray * outputArray = [NSMutableArray new];
- for(NSDictionary * d in jsonResults){
- NSLog(@"adding Wallet to outputAray %@", d);
- [outputArray addObject:[MLWallet instanceFromJSON:d withObjectId:[NSString stringWithFormat:@"%@/wallets/%@",kWalletServerAddress, [d valueForKey:@"id"]]]];
- }
- completion(nil, outputArray);
- }
- else{
- NSLog(@"Error getting current user's Wallets! %@", error.localizedDescription);
- completion(error, nil);
- }
- }];
- }
- //GET /wallets
- //List all wallets: currently for debugging only
- +(void)getWalletsWithCompletion:(MLWalletsCompletionBlock)completion{
- NSLog(@"Get wallets with completion for user %@", [[MLUser currentUser] objectId]);
- [[self sharedInstance] performRequestWithPath:@"/wallets" andMethod:@"GET" andCompletion:^(NSError *error, id jsonResults) {
- if(!error){
- NSLog(@"getWalletsWithCompletion: %@", jsonResults);
- NSMutableArray * outputArray = [NSMutableArray new];
- for(NSDictionary * d in jsonResults){
- [outputArray addObject:[MLWallet instanceFromJSON:d withObjectId:[NSString stringWithFormat:@"%@/wallets/%@",kWalletServerAddress, [d valueForKey:@"id"]]]];
- NSLog(@"Just added wallet %@", [[outputArray lastObject] objectId]);
- }
- completion(nil, outputArray);
- }
- else{
- MLLog(@"Error getting Wallets! %@", error.localizedDescription);
- completion(error, nil);
- }
- }];
- }
- //GET /wallets?label={label}
- //Search for wallets by label
- +(void)getWalletWithLabel:(NSString*)label withCompletion:(MLSingleWalletCompletionBlock)completion{
- [[self sharedInstance] performRequestWithPath:[NSString stringWithFormat:@"/wallets?label=%@",[label urlencode]] andMethod:@"GET" andCompletion:^(NSError *error, NSDictionary *jsonDict) {
- if(!error && jsonDict){
- MLLog(@"success: getWalletWithLabel: %@", jsonDict);
- MLWallet * tw = [MLWallet instanceFromJSON:jsonDict withObjectId:[NSString stringWithFormat:@"%@/wallets/%@",kWalletServerAddress, [jsonDict valueForKey:@"id"]]];
- completion(nil, tw);
- }
- else{
- MLLog(@"Error getWalletWithLabel! %@", error.localizedDescription);
- completion(error, nil);
- }
- }];
- }
- //POST /wallets
- //Create a new wallet
- +(void)postNewWalletWithCompletion:(MLWallet*)wallet withCompletion:(MLSingleWalletCompletionBlock)completion{
- [[self sharedInstance] performRequestWithPath:@"wallets" andMethod:@"POST" andJSONDictionary:[wallet jsonDictionary] andCompletion:^(NSError *error, NSDictionary *jsonDict) {
- if(!error){
- MLLog(@"postNewWalletWithCompletion: %@", jsonDict);
- completion(error, [MLWallet instanceFromJSON:jsonDict withObjectId:[NSString stringWithFormat:@"%@/wallets/%@",kWalletServerAddress, [jsonDict valueForKey:@"id"]]]);
- }
- else{
- MLLog(@"Error postNewWalletWithCompletion! %@", error.localizedDescription);
- completion(error, nil);
- }
- }];
- }
- //GET /wallets/{walletId}
- //View a wallet
- +(void)getWallet:(MLWallet*)wallet withCompletion:(MLSingleWalletCompletionBlock)completion{
- [[self sharedInstance] performRequestWithPath:wallet.objectId andMethod:@"GET" andCompletion:^(NSError *error, NSDictionary *jsonDict) {
- if(!error){
- MLLog(@"getWallet (by id): %@", jsonDict);
- completion(nil, [MLWallet instanceFromJSON:jsonDict withObjectId:[NSString stringWithFormat:@"%@/wallets/%@",kWalletServerAddress, [jsonDict valueForKey:@"id"]]]);
- }
- else{
- MLLog(@"Error getWallet (by id) %@", error.localizedDescription);
- completion(error, nil);
- }
- }];
- }
- //GET /wallets/{walletId}/balance
- //Check the balance of a wallet
- +(void)getBalanceOfWallet:(MLWallet*)wallet withCompletion:(MLWalletBalanceCompletionBlock)completion{
- [[self sharedInstance] performRequestWithPath:[NSString stringWithFormat:@"%@/balance",wallet.objectId] andMethod:@"GET" andCompletion:^(NSError *error, NSDictionary *jsonDict) {
- if(!error){
- MLLog(@"getBalanceOfWallet: %@", jsonDict);
- NSDecimal dbalance = [[[[jsonDict objectForKey:@"balance"] objectForKey:@"value"] objectForKey:@"amount"] decimalValue];
- NSDecimalNumber * balance = [NSDecimalNumber decimalNumberWithDecimal:dbalance];
- NSLog(@"Type of balance is %@", [[[jsonDict objectForKey:@"balance"] objectForKey:@"value"] objectForKey:@"type"]);
- if([[[[jsonDict objectForKey:@"balance"] objectForKey:@"value"] objectForKey:@"type"] isEqualToString:@"debit"]){
- balance = [balance decimalNumberByMultiplyingBy:[NSDecimalNumber decimalNumberWithString:@"-1"]];
- }
- MLLog(@"getBalanceOfWallet: %@", [MLHelper formattedDecimalNumber:balance]);
- /*
- [self getEarningsOfWallet:wallet withCompletion:^(NSError *error, NSDecimalNumber *balanceInDollars) {
- completion(error, [balance decimalNumberBySubtracting:balanceInDollars]);
- }];
- */
- //now we are subtracting earnings from this wallet
- completion(error, balance);
- }
- else{
- completion(error, nil);
- MLLog(@"Error getBalanceOfWallet: %@", error.localizedDescription);
- }
- }];
- }
- //GET /wallets/{walletId}/balance
- //Check the balance of a wallet
- +(void)getEarningsOfWallet:(MLWallet*)wallet withCompletion:(MLWalletBalanceCompletionBlock)completion{
- [self getWalletEventsForWallet:wallet withCompletion:^(NSError *error, NSMutableArray *walletLines) {
- NSDecimalNumber * earningsInDollars = [NSDecimalNumber decimalNumberWithString:@"0.0"];
- if(!error){
- NSLog(@"About to compile earnings from %i events for wallet %@", [walletLines count], wallet.objectId);
- for(MLWalletEvent * event in walletLines){
- NSLog(@"Event: debited wallet: %@ credited: %@ type:%i", event.debitedWallet.objectId, event.creditedWallet.objectId, event.type);
- if([event.creditedWallet.objectId isEqualToString:wallet.objectId]){
- NSLog(@"Found an event credited to current user");
- if(event.type == MLWalletEventTypeTip || event.type == MLWalletEventTypeGift || event.type == MLWalletEventTypePaywallPurchase){
- NSLog(@"Found an event: Adding %f", event.amountInDollars.floatValue);
- earningsInDollars = [earningsInDollars decimalNumberByAdding:event.amountInDollars];
- }
- }
- }
- }
- completion(error, earningsInDollars);
- }];
- }
- //GET /wallets/{walletId}/balance
- //Check the balance of a wallet
- +(void)getTipTotalForWallet:(MLWallet*)wallet withCompletion:(MLWalletBalanceCompletionBlock)completion{
- [self getWalletEventsForWallet:wallet withCompletion:^(NSError *error, NSMutableArray *walletLines) {
- NSDecimalNumber * earningsInDollars = [NSDecimalNumber decimalNumberWithString:@"0.0"];
- if(!error){
- NSLog(@"About to compile earnings from %i events for wallet %@", [walletLines count], wallet.objectId);
- for(MLWalletEvent * event in walletLines){
- NSLog(@"Event: debited wallet: %@ credited: %@ type:%i", event.debitedWallet.objectId, event.creditedWallet.objectId, event.type);
- if([event.creditedWallet.objectId isEqualToString:wallet.objectId]){
- NSLog(@"Found an event credited to current user");
- if(event.type == MLWalletEventTypeTip || event.type == MLWalletEventTypeGift){
- NSLog(@"Found an event: Adding %f", event.amountInDollars.floatValue);
- earningsInDollars = [earningsInDollars decimalNumberByAdding:event.amountInDollars];
- }
- }
- }
- }
- completion(error, earningsInDollars);
- }];
- }
- //GET /wallets/{walletId}/balance
- //Check the balance of a wallet
- +(void)getPaywallTotalForWallet:(MLWallet*)wallet withCompletion:(MLWalletBalanceCompletionBlock)completion{
- [self getWalletEventsForWallet:wallet withCompletion:^(NSError *error, NSMutableArray *walletLines) {
- NSDecimalNumber * earningsInDollars = [NSDecimalNumber decimalNumberWithString:@"0.0"];
- if(!error){
- NSLog(@"About to compile earnings from %i events for wallet %@", [walletLines count], wallet.objectId);
- for(MLWalletEvent * event in walletLines){
- NSLog(@"Event: debited wallet: %@ credited: %@ type:%i", event.debitedWallet.objectId, event.creditedWallet.objectId, event.type);
- if([event.creditedWallet.objectId isEqualToString:wallet.objectId]){
- NSLog(@"Found an event credited to current user");
- if(event.type == MLWalletEventTypePaywallPurchase){
- NSLog(@"Found an event: Adding %f", event.amountInDollars.floatValue);
- earningsInDollars = [earningsInDollars decimalNumberByAdding:event.amountInDollars];
- }
- }
- }
- }
- completion(error, earningsInDollars);
- }];
- }
- +(void)getTipTotalForCurrentUserWithCompletion:(MLWalletCurrentUserBalanceCompletionBlock)completion{
- MLLog(@"MLWalletAPI :: Get balance with completion");
- NSMutableDictionary * walletPromises = [NSMutableDictionary new];
- [walletPromises setObject:[self promiseWalletForUser:[MLUser currentUser]] forKey:@"user"];
- PMKWhen(walletPromises).then(^(NSDictionary *promiseResults){
- MLLog(@"MLWalletAPI :: Get balance with completion inside promise");
- MLWallet * sellerWallet = [[promiseResults objectForKey:@"user"] firstObject];
- [self getTipTotalForWallet:sellerWallet withCompletion:^(NSError *error, NSDecimalNumber * balance) {
- MLLog(@"MLWalletAPI :: Get balance with completion inside get balance of wallet");
- completion(error,balance);
- }];
- }).catch(^(NSError *error){
- completion(error, nil); //used to be nil
- // any errors in any of the above promises land here
- MLLog(@"Can't load wallets %@", error.localizedDescription);
- });
- }
- +(void)getPaywallTotalForCurrentUserWithCompletion:(MLWalletCurrentUserBalanceCompletionBlock)completion{
- MLLog(@"MLWalletAPI :: Get balance with completion");
- NSMutableDictionary * walletPromises = [NSMutableDictionary new];
- [walletPromises setObject:[self promiseWalletForUser:[MLUser currentUser]] forKey:@"user"];
- PMKWhen(walletPromises).then(^(NSDictionary *promiseResults){
- MLLog(@"MLWalletAPI :: Get balance with completion inside promise");
- MLWallet * sellerWallet = [[promiseResults objectForKey:@"user"] firstObject];
- [self getPaywallTotalForWallet:sellerWallet withCompletion:^(NSError *error, NSDecimalNumber * balance) {
- MLLog(@"MLWalletAPI :: Get balance with completion inside get balance of wallet");
- completion(error,balance);
- }];
- }).catch(^(NSError *error){
- completion(error, nil); //used to be nil
- // any errors in any of the above promises land here
- MLLog(@"Can't load wallets %@", error.localizedDescription);
- });
- }
- //POST /wallets/{walletId}/deals
- //Create a transaction crediting the wallet specified in the URL
- +(void)postWalletEvent:(MLWalletEvent*)event toWallet:(MLWallet*)wallet withCompletion:(MLSingleWalletEventCompletionBlock)completion{
- NSLog(@"postWalletEvent:");
- //should use walletevent collection path here
- //sort of a hack here:
- NSString * pathToPost;
- if(event.type == MLWalletEventTypeTip || event.type == MLWalletEventTypeGift || event.type == MLWalletEventTypePaywallPurchase){
- pathToPost = [NSString stringWithFormat:@"%@/deals",wallet.objectId];
- }
- else if(event.type == MLWalletEventTypeExternal){
- pathToPost = [NSString stringWithFormat:@"%@/deals",event.paymentMethod.objectId];
- MLLog(@"postWalletEvent pathToPost: %@", pathToPost);
- }
- [[self sharedInstance] performRequestWithPath:pathToPost andMethod:@"POST" andJSONDictionary:[event jsonDictionary] andCompletion:^(NSError *error, NSDictionary *jsonDict) {
- if(!error){
- completion(error, event);
- }
- else{
- completion(error, event);
- MLLog(@"Error postNewEventWithCompletion! %@", error.localizedDescription);
- }
- }];
- }
- //GET /wallets/{walletId}/deals/{eventId}
- //View an event: currently for debugging only
- +(void)getWalletEvent:(MLWalletEvent*)event withCompletion:(MLSingleWalletEventCompletionBlock)completion{
- [[self sharedInstance] performRequestWithPath:event.objectId andMethod:@"GET" andCompletion:^(NSError *error, NSDictionary *jsonDict) {
- if(!error){
- MLLog(@"getWalletEvent: %@", jsonDict);
- }
- else{
- MLLog(@"Error getWalletEvent: (by id) %@", error.localizedDescription);
- }
- }];
- }
- //GET /wallets/{walletId}/lines
- //Get a list of prior transactions for a wallet
- +(void)getLinesOfWallet:(MLWallet*)wallet withCompletion:(MLWalletLinesCompletionBlock)completion{
- [[self sharedInstance] performRequestWithPath:[NSString stringWithFormat:@"%@/lines",wallet.objectId] andMethod:@"GET" andCompletion:^(NSError *error, NSDictionary *jsonDict) {
- if(!error){
- MLLog(@"getLinesOfWallet jsonDict: %@", jsonDict);
- }
- else{
- MLLog(@"Error getLinesOfWallet: %@", error.localizedDescription);
- }
- completion(error, [MLSubledgerParser purchasesFromSubledgerData:jsonDict]);
- }];
- }
- //
- +(void)getWalletEventsForWallet:(MLWallet*)wallet withCompletion:(MLWalletLinesCompletionBlock)completion{
- [[self sharedInstance] performRequestWithPath:[NSString stringWithFormat:@"%@/deals",wallet.objectId] andMethod:@"GET" andCompletion:^(NSError *error, NSDictionary *jsonDict) {
- if(!error){
- MLLog(@"getEventsOfWallet jsonDict: %@", jsonDict);
- //
- NSArray *events = [NSArray arrayWithArray:jsonDict];//is it an array
- NSMutableArray * results = [NSMutableArray new];
- for(NSDictionary * dict in events){
- static int id_int = 0;
- if([dict objectForKey:@"id"]){
- id_int = [[dict objectForKey:@"id"] intValue];
- }
- else{
- id_int++;
- }
- MLWalletEvent * e = [MLWalletEvent instanceFromJSON:dict withObjectId:[NSString stringWithFormat:@"%@/deals/%i", kWalletServerAddress, id_int]];
- [results addObject:e];
- }
- completion(error, results);
- }
- else{
- completion(error, nil);
- MLLog(@"Error getEventsOfWallet: %@", error.localizedDescription);
- }
- }];
- }
- #pragma mark Stripe
- +(void)getStripePublishableKeyWithCompletion:(MLWalletStripePublishableKeyCompletionBlock)completion{
- [[self sharedInstance] performRequestWithPath:@"/keys" andMethod:@"GET" andCompletion:^(NSError *error, NSDictionary *jsonDict) {
- if(!error){
- [Stripe setDefaultPublishableKey:[jsonDict objectForKey:@"stripePublishableKey"]];
- MLLog(@"stripe key jsonDict: %@", jsonDict);
- }
- else{
- MLLog(@"Error stipe key: %@", error.localizedDescription);
- }
- completion(error, [jsonDict objectForKey:@"key"]);
- }];
- }
- +(void) createStripeTokenWithCard:(STPCardParams *) card withCompletion:(MLWalletStripeTokenCompletionBlock)completion {
- [[STPAPIClient sharedClient] createTokenWithCard:card completion:^(STPToken *token, NSError *error) {
- if (token) {
- completion(nil, token);
- } else {
- completion(error, nil);
- MLLog(@"error creating stripe token %@", error);
- }
- }];
- }
- +(void) getPaymentMethodsForWallet: (MLWallet *) wallet withCompletion: (MLWalletPaymentMethodsCompletionBlock) completion {
- NSNumber *walletId = [NSNumber numberWithInteger:[[[wallet.objectId componentsSeparatedByString:@"/"] lastObject] integerValue]];
- NSString * collectionPath = [NSString stringWithFormat:@"/wallets/%@/payment_methods", walletId];
- [[self sharedInstance] performRequestWithPath:collectionPath andMethod:@"GET" andCompletion:^(NSError *error, id jsonDict) {
- if(jsonDict){
- MLLog(@"getPaymentMethodsForWallet: %@", jsonDict);
- //for now each user only has one payment method
- //NSString *methodId = [[jsonDict objectAtIndex:0] objectForKey:@"id"]; //first object in array returned is method id
- NSArray *methods = [NSArray arrayWithArray:jsonDict];
- if (methods.count > 0) {
- MLLog(@"found payment methods");
- MLPaymentMethod *paymentMethod = [MLPaymentMethod instanceFromJSON:jsonDict withObjectId:[NSString stringWithFormat:@"%@/%@/%@",kWalletServerAddress, collectionPath,[jsonDict valueForKey:@"id"]]];
- completion(nil, paymentMethod);
- }
- // else {
- // MLLog(@"found no payment methods");
- // MLPaymentMethod *dummyMethod = [MLPaymentMethod new];
- // completion(nil, dummyMethod);
- // }
- }
- else{
- //handle request error
- completion(error, nil);
- MLLog(@"Error getPaymentMethodsForWallet! %@", error.localizedDescription);
- }
- }];
- }
- +(void) postPaymentMethod:(MLPaymentMethod *)paymentMethod toWallet:(MLWallet *) wallet withCompletion:(MLWalletPostPaymentMethodCompletionBlock)completion {
- NSNumber *walletId = [NSNumber numberWithInteger:[[[wallet.objectId componentsSeparatedByString:@"/"] lastObject] integerValue]];
- NSDictionary * stripeDict = @{@"stripeCardToken": paymentMethod.tokenId};
- [[self sharedInstance] performRequestWithPath:[NSString stringWithFormat:@"/wallets/%@/payment_methods", walletId] andMethod:@"POST" andJSONDictionary:stripeDict andCompletion:^(NSError *error, NSDictionary *jsonDict) {
- if(!error){
- completion(nil, YES);
- MLLog(@"postPaymentMethod: %@", jsonDict);
- }
- else{
- MLLog(@"Error postPaymentMethod! %@", error.localizedDescription);
- completion(error, nil);
- }
- }];
- }
- /*
- Ensurepaymentmethod will prompt the user to enter credit card info (and whatever else they need to do) before executing an action
- This could also prompt the user to buy bits if needed
- Something similar should be done with ensure balance - maybe ensureBalanceIsAtLeast:(int)amount - prompting user to buy bits and or enter credit card info
- */
- /*
- 10/4/2016 - is there ever a case where we want to ensure payment info without buying bits? This whole thing should run through the buying bits flow
- */
- +(NSArray *) purchaseOptions {
- NSArray *buttonTitles = @[@"100 Coins for $0.99", @"500 Coins for $4.99", @"1000 Coins for $9.99", @"2500 Coins for $24.99", @"10000 Coins for $99.99"];
- return buttonTitles;
- }
- //here minimum bits will just be used to filter the bit options if the
- +(void) promptUserToBuyBits:(int)minimumBits withCompletion:(MLErrorCompletionBlock)completion{
- UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"Not Enough Coins"]
- message:@"Use Coins to unlock this post. This price was added by the creator of this post." delegate:self cancelButtonTitle: @"Not now"
- otherButtonTitles: @"Get Coins", nil];
- [alert show];
- NSLog(@"ml wallet api promptUserToBuyBits delegate: %@", alert.delegate);
- }
- +(void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
- if(buttonIndex == 0) {
- //[[NSNotificationCenter defaultCenter] postNotificationName:@"RestrictAccessToPayContentNotification" object:nil userInfo:nil];
- }
- else if(buttonIndex == 1){
- [self presentActionSheetWithPurchaseOptions];
- }
- }
- +(void) presentActionSheetWithPurchaseOptions {
- UIImage* coinImage = [UIImage imageNamed:@"coin_24dp_.png"];
- UIImageView* coinImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, coinImage.size.width, coinImage.size.height)];
- coinImageView.tag = 98765;
- [coinImageView setImage:coinImage];
- UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Get Coins"
- message:[NSString stringWithFormat:@"Use Coins to reward people and keep Portal ad-free. \nCash out rewards you receive at portal.xyz."]
- preferredStyle:UIAlertControllerStyleActionSheet];
- NSArray *buttonTitles = [self purchaseOptions];
- NSDictionary *attr = nil;
- UIColor *textColor = [UIColor colorWithRed:3/255.0f green:3/255.0f blue:3/255.0f alpha:1];
- attr = @{
- NSFontAttributeName: [UIFont systemFontOfSize:17 weight:UIFontWeightMedium],
- NSForegroundColorAttributeName: textColor
- };
- NSMutableAttributedString *title = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"\n\n\nGet Coins"] attributes:attr];
- [alert setValue:title forKey:@"attributedTitle"];
- NSDictionary *attr2 = nil;
- attr2 = @{
- NSFontAttributeName: [UIFont systemFontOfSize:13 weight:UIFontWeightRegular],
- NSForegroundColorAttributeName: textColor
- };
- NSMutableAttributedString *msg = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"Use Coins to reward people and keep Portal ad-free. \nCash out rewards you receive at portal.xyz."] attributes:attr2];
- [alert setValue:msg forKey:@"attributedMessage"];
- //[alert setValue: ivMyImageView forKey:@"accessoryView"];
- [alert.view addSubview:coinImageView];
- coinImageView.frame = CGRectMake(0, 16, coinImageView.image.size.width, coinImageView.image.size.height);
- coinImageView.center = CGPointMake([MLSkinHelper screenSizeSmallerDimension]/2 - 8, coinImageView.center.y); //for some reason this magic number works to keep the imageview centered in the alert
- NSLog(@"coin center %@. view frame %@", NSStringFromCGPoint(coinImageView.center), NSStringFromCGRect(coinImageView.superview.frame));
- MLCoinPurchaseTier purchaseTier = -1;
- int purchaseIndex = 1;
- for(NSString * s in buttonTitles){
- switch (purchaseIndex) {
- case 1:
- purchaseTier = MLCoinPurchaseTier1;
- break;
- case 2:
- purchaseTier = MLCoinPurchaseTier5;
- break;
- case 3:
- purchaseTier = MLCoinPurchaseTier10;
- break;
- case 4:
- purchaseTier = MLCoinPurchaseTier25;
- break;
- case 5:
- purchaseTier = MLCoinPurchaseTier60;
- break;
- default:
- break;
- }
- NSLog(@"presentActionSheetWithPurchaseOptions adding action with purchaseTier:%i and purchaseIndex:%i buttonTitle:%@", purchaseTier, purchaseIndex, s);
- UIAlertAction* action = [UIAlertAction actionWithTitle:s style:UIAlertActionStyleDefault
- handler:^(UIAlertAction * action) {
- [self makePurchaseAtTier:purchaseTier];
- }];
- [alert addAction:action];
- purchaseIndex++;
- }
- MLRootNavigationController *rootController = (MLRootNavigationController *)[[[[UIApplication sharedApplication] delegate] window] rootViewController];
- [alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
- [rootController dismissViewControllerAnimated:YES completion:^{
- }];
- }]];
- [rootController presentViewController:alert animated:YES completion:^{
- }];
- // UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault
- // handler:^(UIAlertAction * action) {}];
- //
- //
- // [self presentViewController:alert animated:YES completion:nil];
- //
- // NSDictionary *attr = nil;
- //
- // UIColor *textColor = [UIColor colorWithRed:10/255.0f green:91/255.0f blue:255/255.0f alpha:1];
- // attr = @{
- // NSFontAttributeName: [UIFont systemFontOfSize:13 weight:UIFontWeightSemibold],
- // NSForegroundColorAttributeName: textColor
- // };
- //
- // NSMutableAttributedString *msg = [[NSMutableAttributedString alloc] initWithString:@"New Title" attributes:attr];
- //
- //
- // NSArray *buttonTitles = [self purchaseOptions];
- //
- // UIActionSheet * actionSheet = [[UIActionSheet alloc] initWithTitle:msg delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle: nil otherButtonTitles:nil];
- //
- // for(NSString * s in buttonTitles){
- // [actionSheet addButtonWithTitle:s];
- // }
- // [actionSheet promiseInView:nil].then(^(NSNumber *seletedButtonIndex){
- //
- // int buttonIndex = [seletedButtonIndex intValue];
- //
- // NSString* btnTitle = [actionSheet buttonTitleAtIndex:buttonIndex];
- //
- // MLLog(@"Clicked button at index %i", buttonIndex);
- //
- // MLCoinPurchaseTier purchaseTier = -1;
- //
- // switch (buttonIndex) {
- // case 0:
- // break;
- //
- // case 1:
- // purchaseTier = MLCoinPurchaseTier1;
- // break;
- // case 2:
- // purchaseTier = MLCoinPurchaseTier5;
- // break;
- // case 3:
- // purchaseTier = MLCoinPurchaseTier10;
- // break;
- // case 4:
- // purchaseTier = MLCoinPurchaseTier25;
- // break;
- // case 5:
- // purchaseTier = MLCoinPurchaseTier60;
- // break;
- // default:
- // break;
- // }
- //
- // [self makePurchaseAtTier:purchaseTier];
- //
- // });
- }
- #pragma mark - Custom Credit Card Form
- +(void) makePurchaseAtTier:(MLCoinPurchaseTier) tier {
- NSLog(@"");
- if(tier >= 0){
- #ifdef PORTAL_PREVIEW
- [MLHelper showTempAlertWithString:@"In App Purchases are disabled in Preview"];
- return;
- #endif
- [MLWalletAPI purchaseCoinsAtTierLevel:tier withCompletion:^(NSError *error, MLWalletEvent *wallet) {
- if(!error){
- [MLHelper showTempAlertWithString:[NSString stringWithFormat:@"Successfully purchased coins at tier level %i", tier]];
- [[NSNotificationCenter defaultCenter] postNotificationName:kTipNotification object:nil userInfo:@{@"success":@YES}];
- [MLSoundEffects playSoundEffectOfType:MLSoundEffectTypePurchaseCoins];
- //completion(error);
- //[self redraw];
- }
- else {
- [[NSNotificationCenter defaultCenter] postNotificationName:kTipNotification object:nil userInfo:@{@"success":@NO}];
- [MLHelper showTempAlertWithString:@"Error purchasing Coins"];
- //completion(error);
- }
- }];
- }
- else{
- [[NSNotificationCenter defaultCenter] postNotificationName:kPurchaseNotification object:nil userInfo:@{@"success":@NO}];
- NSError * error = [NSError errorWithDomain:@"com.masslab.portal" code:101 userInfo:@{@"localizedDescription":@"Didn't buy bits in wallet"}];
- NSLog(@"error at purchaseCoinsAtTierLevel: %@", error);
- //completion(error);
- }
- }
- +(void)ensureBalanceMinimum:(int)bitsRequired before:(MLErrorCompletionBlock)completion{
- [self getBalanceForCurrentUserWithCompletion:^(NSError *error, NSDecimalNumber *balanceInDollars) {
- int balanceInBits = [MLWalletAPI convertDollarsToBits:balanceInDollars];
- BOOL hasCash = balanceInBits >= bitsRequired; //check balance
- if(hasCash){
- completion(nil);
- }
- else{
- [self promptUserToBuyBits:bitsRequired withCompletion:^(NSError *error) {
- NSLog(@"ensure balance minimum prompt bits");
- //[MLHelper showTempAlertWithString:[NSString stringWithFormat:@"You need to buy at least %i bits", bitsRequired - balanceInBits]];
- //NSError * error = [NSError errorWithDomain:@"com.masslab.com" code:101 userInfo:@{@"localizedDecscription":@"Not enough bits in wallet"}];
- completion(error);
- }];
- }
- }];
- }
- +(void)changePaymentMethodWithCompletion:(MLErrorCompletionBlock)completion{
- AppDelegate * del = (AppDelegate *)[[UIApplication sharedApplication] delegate];
- MLNavigationStackController * stackController = [del currentStackController];
- MLLog(@"show stripe %@", [self class]);
- MLStripePaymentModel *content = [MLStripePaymentModel new];
- content.contentDescription.type = MLContentTypePayment;
- [content.contentDescription.properties setValue:[NSNumber numberWithBool:YES] forKey:@"hidesPlayerView"];
- [stackController presentControllerForModel:content withCompletion:^(NSError *error, MLNavigationCallbackState state) {
- NSLog(@"MLWalletAPI Callback in pop of controller in ensurePaymentMethodBefore");
- if(state == MLNavigationCallbackStateSubmitted){
- completion(nil);
- }
- else{
- completion(error);
- }
- }];
- }
- /*
- +(void)ensurePaymentMethodBefore:(MLErrorCompletionBlock)completion{
- [self checkForCurrentUserPaymentMethodsAndCustomerId:^(NSError *error, MLWallet *wallet, BOOL hasPaymentMethod, BOOL hasStripeCustomerId) {
- if(!error && wallet && hasPaymentMethod && hasStripeCustomerId){
- completion(nil);
- }
- else if (!hasPaymentMethod){
- [self changePaymentMethodWithCompletion:completion];
- }
- else{
- NSLog(@"SOMETHING ELSE IS WRONG WITH THE WALLET - has paymentMethod");
- }
- }];
- //stackController presentControllerForModel:<#(MLModel *)#> withCompletion:<#^(NSError *error, MLNavigationCallbackState state)completion#>
- }
- */
- #pragma mark -
- #pragma mark Payouts
- +(void) getPayoutRecipientsForWallet: (MLWallet *) wallet withCompletion: (MLMultiplePayoutRecipientsCompletionBlock) completion {
- NSLog(@"MLWalletAPI 2.0: getAcquisitionSourcesForWallet: %@", wallet.objectId);
- NSNumber *walletId = [NSNumber numberWithInteger:[[[wallet.objectId componentsSeparatedByString:@"/"] lastObject] integerValue]];
- NSString * collectionPath = [NSString stringWithFormat:@"%@/payout_recipients", wallet.objectId];
- [[self sharedInstance] performRequestWithPath:collectionPath andMethod:@"GET" andCompletion:^(NSError *error, id jsonDict) {
- if(jsonDict){
- NSLog(@"MLWalletAPI 2.0: getPayoutRecipientsForWallet: %@ json dict is %@", wallet.objectId, jsonDict);
- NSArray *recipients = [NSArray arrayWithArray:jsonDict];
- NSMutableArray * sourceModels = [NSMutableArray new];
- if (recipients.count > 0) {
- MLLog(@"found payment methods");
- for(NSDictionary * d in recipients){
- MLPayoutRecipient *pr = [MLPayoutRecipient instanceFromJSON:d withObjectId:[NSString stringWithFormat:@"%@/payout_recipients/%@", kWalletServerAddress,[d valueForKey:@"id"]]];
- NSLog(@"Populating getPayoutRecipientsForWallet with ID %@", pr.objectId);
- pr.wallet = wallet;
- [sourceModels addObject:pr];
- }
- }
- completion(nil, sourceModels);
- }
- else{
- //handle request error
- completion(error, nil);
- MLLog(@"Error getPayoutRecipientsForWallet! %@", error.localizedDescription);
- }
- }];
- }
- +(void)makePayoutRecipientForWallet:(MLWallet*)wallet withAccountIdentifier:(NSString*)accountIdentifier andCompletion:(MLPayoutRecipientCompletionBlock)completion{
- NSLog(@"MLWalletAPI 2.0: makePayoutRecipientForWallet: %@", wallet.objectId);
- MLPayoutRecipient * pr = [MLPayoutRecipient new];
- pr.clearinghouse = @"PayPal";
- pr.wallet = wallet;
- pr.accountIdentifier = accountIdentifier;
- [pr saveWithCompletion:^(NSError *error, MLModel *model) {
- if(!error){
- NSLog(@"MLWalletAPI 2.0: makePayoutRecipientForWallet: %@ no error", wallet.objectId);
- NSLog(@"MLPayoutRecipient: saveWithCompletion %@", model.objectId);
- completion(nil, (MLWalletAcquisitionSource*)model);
- }
- else{
- NSLog(@"MLWalletAPI 2.0: makePayoutRecipientForWallet: %@ error %@ ", wallet.objectId, error);
- completion(error, nil);
- }
- }];
- }
- +(void)getPayoutRecipientForWallet:(MLWallet *)wallet withAccountIdentifier:(NSString*)accountIdentifier withCompletion:(MLPayoutRecipientCompletionBlock)completion{
- NSLog(@"MLWalletAPI 2.0 PayoutRequest getPayoutRecipientForWallet");
- [self getPayoutRecipientsForWallet:wallet withCompletion:^(NSError *error, NSMutableArray *payoutRecipients) {
- if(!error){
- NSLog(@"MLWalletAPI 2.0: getPayoutRecipientForWallet: %@ no error %i payout recipients", wallet.objectId, [payoutRecipients count]);
- MLPayoutRecipient * recipientWithAccountIdentifier;
- //check for inapppurchase acquisition source
- for(MLPayoutRecipient * pr in payoutRecipients){
- if([pr.accountIdentifier isEqualToString:accountIdentifier]){
- recipientWithAccountIdentifier = pr;
- }
- }
- if(recipientWithAccountIdentifier){
- NSLog(@"MLWalletAPI 2.0: getPayoutRecipientForWallet: %@ withAccountIdentifier:%@ found %@", wallet.objectId, accountIdentifier, recipientWithAccountIdentifier.objectId);
- completion(nil, recipientWithAccountIdentifier);
- }
- else{
- NSLog(@"MLWalletAPI 2.0: getPayoutRecipientForWallet: %@ did not find payout recipient with accountIdentifier now will make a new one", wallet.objectId);
- //need to create acquisition source
- [self makePayoutRecipientForWallet:wallet withAccountIdentifier:accountIdentifier andCompletion:completion];
- }
- }
- else{
- NSLog(@"MLWalletAPI 2.0: getPayoutRecipientForWallet: %@ error getting Payout recipients %@", wallet.objectId, error);
- completion(error, nil);
- }
- }];
- }
- +(void) requestPayoutOfAmount:(int)amountInCoins toPaypalAccount:(NSString*)paypalAccount{
- NSLog(@"MLWalletAPI 2.0 PayoutRequest request payout of amount %i to paypalAccount %@", amountInCoins, paypalAccount);
- [self getCurrentUserWalletsWithCompletion:^(NSError *error, NSArray *wallets) {
- if(!error){
- MLWallet * currentUserWallet = [wallets firstObject];
- [self getPayoutRecipientForWallet:currentUserWallet withAccountIdentifier:paypalAccount withCompletion:^(NSError *error, MLPayoutRecipient *payoutRecipient) {
- if(!error){
- NSLog(@"MLWalletAPI 2.0 getPayoutRecipientForWallet: no error %@", payoutRecipient.objectId);
- NSDecimalNumber * amountInDollars = [MLWalletAPI convertBitsToDollars:amountInCoins];
- MLPayoutRequest * r = [payoutRecipient payoutRequestForAmountInDollars:amountInDollars];
- [r saveWithCompletion:^(NSError *error, MLModel *model) {
- if(!error){
- NSLog(@"MLWalletAPI 2.0 PayoutRequest success! %@", model.objectId);
- }
- else{
- NSLog(@"MLWalletAPI 2.0 PayoutRequest error! %@", error);
- }
- }];
- }
- else{
- }
- }];
- }
- else{
- [MLHelper showTempAlertWithString:@"Could not fetch wallet ub request payout of amount"];
- }
- }];
- }
- #pragma mark -
- #pragma mark Utility
- +(void)performRequestWithPath:(NSString*)path andMethod:(NSString*)method andCompletion:(MLWalletJSONResultsCompletionBlock) completion{
- [[self sharedInstance] performRequestWithPath:path andMethod:method andCompletion:completion];
- }
- -(void)performRequestWithPath:(NSString*)path andMethod:(NSString*)method andCompletion:(MLWalletJSONResultsCompletionBlock) completion{
- [self performRequestWithPath:path andMethod:method andJSONDictionary:nil andCompletion:completion];
- }
- -(void)performRequestWithPath:(NSString*)path andMethod:(NSString*)method andJSONDictionary:(NSDictionary*)jsonDict andCompletion:(MLWalletJSONResultsCompletionBlock) completion{
- NSLog(@"MLWalletAPI perform request with path %@ and method %@ and dictionary %@", path, method, jsonDict);
- if(![path hasPrefix:@"http"]){
- path = [kWalletServerAddress stringByAppendingPathComponent:path];
- }
- MLLog(@"About to request %@ with method %@ and dictionary %@", path, method, jsonDict);
- NSMutableURLRequest * req = [self requestWithPath:path andMethod:method andBody:jsonDict ? [NSJSONSerialization dataWithJSONObject:jsonDict options:nil error:nil] : nil];
- [req setValue:[MLApplication authorizationHeaderString] forHTTPHeaderField:@"Authorization"];
- [self performRequest:req forJSONDictionaryWithCompletion:completion];
- }
- -(NSMutableURLRequest*)requestWithPath:(NSString*)path andMethod:(NSString*)method{
- return [self requestWithPath:path andMethod:method andBody:nil];
- }
- -(NSMutableURLRequest*)requestWithPath:(NSString*)path andMethod:(NSString*)method andBody:(NSData*)body{
- //constructing request
- MLLog(@"MLWalletAPI: requestWithPath:%@ andMethod:%@",path, method);
- NSURL * url = [NSURL URLWithString:path];
- NSMutableURLRequest * mur = [[NSMutableURLRequest alloc] initWithURL:url];
- [mur setHTTPMethod:method];
- [mur setValue:@"application/hal+json, application/json;q=0.8" forHTTPHeaderField:@"Accept"];
- if(body){
- [mur setHTTPBody:body];
- }
- [mur setValue:[MLApplication authorizationHeaderString] forHTTPHeaderField:@"Authorization"];
- return mur;
- }
- -(void)performRequest:(NSMutableURLRequest*)request
- forJSONDictionaryWithCompletion:(MLWalletJSONResultsCompletionBlock) completion{
- NSLog(@"MLWalletAPI: url %@", request.URL);
- NSLog(@"MLWalletAPI: headers %@", request.allHTTPHeaderFields);
- NSLog(@"MLWalletAPI: body %@", request.HTTPBody);
- [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
- if(connectionError){
- NSLog(@"Connection error! %li %@ %@", connectionError.code, connectionError.localizedDescription, request.URL);
- }
- NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
- NSLog(@"MLWalletAPI: response status code: %ld for %@", (long)[httpResponse statusCode], request.URL);
- NSLog(@"MLWalletAPI: performRequest: %@ %i Got json back %lu %@", request.URL, httpResponse.statusCode, [data length], [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
- if(httpResponse.statusCode >= 400 && httpResponse.statusCode < 500){
- connectionError = [NSError errorWithDomain:@"com.masslab.portal" code:httpResponse.statusCode userInfo:@{@"localizedDescription" : [NSString stringWithFormat:@"Http error in MLWalletAPI perform request %@", request.URL]}];
- completion(connectionError, nil);
- return;
- }
- NSLog(@"response %@ %@", response, [self class]);
- NSLog(@"data %@ %@", data, [self class]);
- if(data.length < 3){
- MLLog(@"response is empty!");
- completion(nil, nil);
- return;
- }
- NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data
- options:kNilOptions
- error:&connectionError];
- NSLog(@"json %@ %@", json, [self class]);
- completion(connectionError, json);
- }];
- }
- +(int)convertCentsToBits:(int)cents{
- NSDecimalNumber * amountInDollars = [self convertCentsToDollars:cents];
- return [self convertDollarsToBits:amountInDollars];
- }
- //99c -> 25 Coins = 50c in the system 1 coin is actually 2c
- +(int)convertBitsToCents:(int)bits{
- NSDecimalNumber * amountInDollars = [self convertBitsToDollars:bits];
- //100 for pennies per dollar, nothing to do with the bits to dollar conversion rate
- return [[amountInDollars decimalNumberByMultiplyingBy:[NSDecimalNumber decimalNumberWithString:@"100"]] intValue];
- }
- +(int)convertDollarsToBits:(NSDecimalNumber *)dollars{
- return [[dollars decimalNumberByMultiplyingBy:[NSDecimalNumber decimalNumberWithString:@"200"]] intValue];
- //return [[dollars decimalNumberByMultiplyingBy:[NSDecimalNumber decimalNumberWithString:@"50"]] intValue];
- }
- +(NSDecimalNumber*)convertBitsToDollars:(int)bits{
- NSLog(@"convert %i bits to dollars", bits);
- //we just want to divide by 50
- NSDecimalNumber * amount = [NSDecimalNumber decimalNumberWithMantissa:bits exponent:0 isNegative:NO];
- amount = [amount decimalNumberByDividingBy:[NSDecimalNumber decimalNumberWithString:@"200"]];
- //old amount = [amount decimalNumberByDividingBy:[NSDecimalNumber decimalNumberWithString:@"50"]];
- NSLog(@"Converting bits to dollars %@", amount);
- return amount;
- }
- +(NSDecimalNumber*)convertCentsToDollars:(int)cents{
- //100 for pennies per dollar, nothing to do with the bits to dollar conversion rate
- return [[NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:@"%i", cents]] decimalNumberByDividingBy:[NSDecimalNumber decimalNumberWithString:@"100"]];
- }
- +(NSDictionary*)amountDictionaryFromBits:(int)bits{
- NSDecimalNumber * d = [self convertBitsToDollars:bits];
- return [self amountDictionaryFromDollars:d];
- }
- +(NSDictionary*)amountDictionaryFromDollars:(NSDecimalNumber*)d{
- MLUnpackedDecimalNumber updn = [d unpack];
- return @{@"currencyCodeA":@"USD", @"mantissa":[NSNumber numberWithInt:updn.mantissa], @"exponent":[NSNumber numberWithInt:updn.exponent]};
- }
- +(NSDecimalNumber*)convertAmountDictionaryToDollars:(NSDictionary*)dictionary{
- return [NSDecimalNumber decimalNumberWithMantissa:[[dictionary objectForKey:@"mantissa"] integerValue] exponent:[[dictionary objectForKey:@"exponent"] integerValue] isNegative:NO];
- }
- @end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement