Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Continue to improve error reporting.

  • Loading branch information...
commit 9e81aec7d1e5276892d1cba1c720c207268d268c 1 parent 209473f
Stan Chang Khin Boon authored

Showing 1 changed file with 66 additions and 15 deletions. Show diff stats Hide diff stats

  1. +66 15 CargoBay/CargoBay.m
81 CargoBay/CargoBay.m
@@ -248,8 +248,16 @@ static BOOL CBValidatePurchaseInfoMatchesReceipt(NSDictionary *purchaseInfo, NSD
248 248 }
249 249
250 250 // Make sure the transaction details actually match the purchase info
251   -static BOOL CBValidateTransactionMatchesPurchaseInfo(SKPaymentTransaction *theTransaction, NSDictionary *thePurchaseInfoDictionary) {
  251 +static BOOL CBValidateTransactionMatchesPurchaseInfo(SKPaymentTransaction *theTransaction, NSDictionary *thePurchaseInfoDictionary, NSError * __autoreleasing *theError) {
252 252 if ((!theTransaction) || (!thePurchaseInfoDictionary)) {
  253 + if (theError != NULL) {
  254 + NSDictionary *theUserInfo =
  255 + [NSDictionary dictionaryWithObjectsAndKeys:
  256 + @"Transaction does not match purchase info because either transaction or purchase info is invalid.", NSLocalizedDescriptionKey,
  257 + @"Either transaction or purchase info is invalid.", NSLocalizedFailureReasonErrorKey,
  258 + nil];
  259 + *theError = [NSError errorWithDomain:CargoBayErrorDomain code:CargoBayErrorTransactionDoesNotMatchesPurchaseInfo userInfo:theUserInfo];
  260 + }
253 261 return NO;
254 262 }
255 263
@@ -257,6 +265,14 @@ static BOOL CBValidateTransactionMatchesPurchaseInfo(SKPaymentTransaction *theTr
257 265 NSString *theTransactionProductIdentifier = theTransaction.payment.productIdentifier;
258 266 NSString *thePurchaseInfoDictionaryProductIdentifier = thePurchaseInfoDictionary[@"product-id"];
259 267 if (![theTransactionProductIdentifier isEqualToString:thePurchaseInfoDictionaryProductIdentifier]) {
  268 + if (theError != NULL) {
  269 + NSDictionary *theUserInfo =
  270 + [NSDictionary dictionaryWithObjectsAndKeys:
  271 + [NSString stringWithFormat:@"Transaction does not match purchase info because transaction's product ID (%@) does not match purchase info's product ID (%@).", theTransactionProductIdentifier, thePurchaseInfoDictionaryProductIdentifier], NSLocalizedDescriptionKey,
  272 + [NSString stringWithFormat:@"Transaction's product ID (%@) does not match purchase info's product ID (%@).", theTransactionProductIdentifier, thePurchaseInfoDictionaryProductIdentifier], NSLocalizedFailureReasonErrorKey,
  273 + nil];
  274 + *theError = [NSError errorWithDomain:CargoBayErrorDomain code:CargoBayErrorPurchaseInfoDoesNotMatchReceipt userInfo:theUserInfo];
  275 + }
260 276 return NO;
261 277 }
262 278 }
@@ -265,6 +281,14 @@ static BOOL CBValidateTransactionMatchesPurchaseInfo(SKPaymentTransaction *theTr
265 281 NSInteger theTransactionQuantity = theTransaction.payment.quantity;
266 282 NSInteger thePurchaseInfoDictionaryQuantity = [thePurchaseInfoDictionary[@"quantity"] integerValue];
267 283 if (theTransactionQuantity != thePurchaseInfoDictionaryQuantity) {
  284 + if (theError != NULL) {
  285 + NSDictionary *theUserInfo =
  286 + [NSDictionary dictionaryWithObjectsAndKeys:
  287 + [NSString stringWithFormat:@"Transaction does not match purchase info because transaction's quantity (%d) does not match purchase info's quantity (%d).", theTransactionQuantity, thePurchaseInfoDictionaryQuantity], NSLocalizedDescriptionKey,
  288 + [NSString stringWithFormat:@"Transaction's quantity (%d) does not match purchase info's quantity (%d).", theTransactionQuantity, thePurchaseInfoDictionaryQuantity], NSLocalizedFailureReasonErrorKey,
  289 + nil];
  290 + *theError = [NSError errorWithDomain:CargoBayErrorDomain code:CargoBayErrorPurchaseInfoDoesNotMatchReceipt userInfo:theUserInfo];
  291 + }
268 292 return NO;
269 293 }
270 294 }
@@ -273,6 +297,14 @@ static BOOL CBValidateTransactionMatchesPurchaseInfo(SKPaymentTransaction *theTr
273 297 NSString *theTransactionTransactionIdentifier = theTransaction.transactionIdentifier;
274 298 NSString *thePurchaseInfoDictionaryTransactionIdentifier = thePurchaseInfoDictionary[@"transaction-id"];
275 299 if (![theTransactionTransactionIdentifier isEqualToString:thePurchaseInfoDictionaryTransactionIdentifier]) {
  300 + if (theError != NULL) {
  301 + NSDictionary *theUserInfo =
  302 + [NSDictionary dictionaryWithObjectsAndKeys:
  303 + [NSString stringWithFormat:@"Transaction does not match purchase info because transaction's transaction ID (%@) does not match purchase info's transaction ID (%@).", theTransactionTransactionIdentifier, thePurchaseInfoDictionaryTransactionIdentifier], NSLocalizedDescriptionKey,
  304 + [NSString stringWithFormat:@"Transaction's transaction ID (%@) does not match purchase info's transaction ID (%@).", theTransactionTransactionIdentifier, thePurchaseInfoDictionaryTransactionIdentifier], NSLocalizedFailureReasonErrorKey,
  305 + nil];
  306 + *theError = [NSError errorWithDomain:CargoBayErrorDomain code:CargoBayErrorPurchaseInfoDoesNotMatchReceipt userInfo:theUserInfo];
  307 + }
276 308 return NO;
277 309 }
278 310 }
@@ -282,6 +314,14 @@ static BOOL CBValidateTransactionMatchesPurchaseInfo(SKPaymentTransaction *theTr
282 314 NSString *thePurchaseInfoDictionaryBundleID = thePurchaseInfoDictionary[@"bid"];
283 315 NSString *theAppBundleID = [NSBundle mainBundle].bundleIdentifier;
284 316 if (![thePurchaseInfoDictionaryBundleID isEqualToString:theAppBundleID]) {
  317 + if (theError != NULL) {
  318 + NSDictionary *theUserInfo =
  319 + [NSDictionary dictionaryWithObjectsAndKeys:
  320 + [NSString stringWithFormat:@"Transaction does not match purchase info because purchase info's bundle ID (%@) does not match the app bundle ID (%@).", thePurchaseInfoDictionaryBundleID, theAppBundleID], NSLocalizedDescriptionKey,
  321 + [NSString stringWithFormat:@"Purchase info's bundle ID (%@) does not match the app bundle ID (%@).", thePurchaseInfoDictionaryBundleID, theAppBundleID], NSLocalizedFailureReasonErrorKey,
  322 + nil];
  323 + *theError = [NSError errorWithDomain:CargoBayErrorDomain code:CargoBayErrorPurchaseInfoDoesNotMatchReceipt userInfo:theUserInfo];
  324 + }
285 325 return NO;
286 326 }
287 327 }
@@ -290,18 +330,28 @@ static BOOL CBValidateTransactionMatchesPurchaseInfo(SKPaymentTransaction *theTr
290 330 NSString *thePurchaseInfoDictionaryBundleVersion = thePurchaseInfoDictionary[@"bvrs"];
291 331 NSString *theAppBundleVersion = [NSBundle mainBundle].infoDictionary[(__bridge NSString *)kCFBundleVersionKey];
292 332 if (![thePurchaseInfoDictionaryBundleVersion isEqualToString:theAppBundleVersion]) {
  333 + if (theError != NULL) {
  334 + NSDictionary *theUserInfo =
  335 + [NSDictionary dictionaryWithObjectsAndKeys:
  336 + [NSString stringWithFormat:@"Transaction does not match purchase info because purchase info's bundle version (%@) does not match the app bundle version (%@).", thePurchaseInfoDictionaryBundleVersion, theAppBundleVersion], NSLocalizedDescriptionKey,
  337 + [NSString stringWithFormat:@"Purchase info's bundle version (%@) does not match the app bundle version (%@).", thePurchaseInfoDictionaryBundleVersion, theAppBundleVersion], NSLocalizedFailureReasonErrorKey,
  338 + nil];
  339 + *theError = [NSError errorWithDomain:CargoBayErrorDomain code:CargoBayErrorPurchaseInfoDoesNotMatchReceipt userInfo:theUserInfo];
  340 + }
293 341 return NO;
294 342 }
295 343 }
296 344
297 345 // Optionally check the requestData.
298 346 {
299   - // `theTransaction.payment.requestData` is reserved for future use as stated
300   - // in the document (iOS 6). It is mentioned that the default value will be nil.
301   - // If the value is not nil, it will be rejected by the Apple App Store.
302   - // We could check for nil. But Apple might decides to populate this field
303   - // in the future, which will break our code by then. So I think the wisest
304   - // choice would be to avoid doing anything to this field all together for now.
  347 + /*
  348 + `theTransaction.payment.requestData` is reserved for future use as stated
  349 + in the document (iOS 6). It is mentioned that the default value will be nil.
  350 + If the value is not nil, it will be rejected by the Apple App Store.
  351 + We could check for nil. But Apple might decides to populate this field
  352 + in the future, which will break our code by then. So I think the wisest
  353 + choice would be to avoid doing anything to this field all together for now.
  354 + */
305 355 }
306 356
307 357 // Optionally check the dates.
@@ -315,6 +365,14 @@ static BOOL CBValidateTransactionMatchesPurchaseInfo(SKPaymentTransaction *theTr
315 365 NSDate *thePurchaseInfoDictionaryPurchaseDate = [theDateFormatter dateFromString:[thePurchaseInfoDictionaryPurchaseDateString stringByReplacingOccurrencesOfString:@"Etc/" withString:@""]];
316 366
317 367 if (![theTransactionTransactionDate isEqualToDate:thePurchaseInfoDictionaryPurchaseDate]) {
  368 + if (theError != NULL) {
  369 + NSDictionary *theUserInfo =
  370 + [NSDictionary dictionaryWithObjectsAndKeys:
  371 + [NSString stringWithFormat:@"Transaction does not match purchase info because transaction's transaction date (%@) does not match purchase info's purchase date (%@).", theTransactionTransactionDate, thePurchaseInfoDictionaryPurchaseDate], NSLocalizedDescriptionKey,
  372 + [NSString stringWithFormat:@"Transaction's transaction date (%@) does not match purchase info's purchase date (%@).", theTransactionTransactionDate, thePurchaseInfoDictionaryPurchaseDate], NSLocalizedFailureReasonErrorKey,
  373 + nil];
  374 + *theError = [NSError errorWithDomain:CargoBayErrorDomain code:CargoBayErrorPurchaseInfoDoesNotMatchReceipt userInfo:theUserInfo];
  375 + }
318 376 return NO;
319 377 }
320 378 }
@@ -958,14 +1016,7 @@ - (BOOL)isTransactionAndItsReceiptValid:(SKPaymentTransaction *)theTransaction e
958 1016 // }
959 1017
960 1018 // Ensure the transaction itself is legit
961   - if (!CBValidateTransactionMatchesPurchaseInfo(theTransaction, thePurchaseInfoDictionary)) {
962   - if (theError != NULL) {
963   - NSDictionary *theUserInfo =
964   - [NSDictionary dictionaryWithObjectsAndKeys:
965   - @"Transaction does not match purchase info", NSLocalizedDescriptionKey,
966   - nil];
967   - *theError = [NSError errorWithDomain:CargoBayErrorDomain code:CargoBayErrorTransactionDoesNotMatchesPurchaseInfo userInfo:theUserInfo];
968   - }
  1019 + if (!CBValidateTransactionMatchesPurchaseInfo(theTransaction, thePurchaseInfoDictionary, theError)) {
969 1020 return NO;
970 1021 }
971 1022

0 comments on commit 9e81aec

Please sign in to comment.
Something went wrong with that request. Please try again.