question

John Peterson avatar image
John Peterson asked

iOS sandbox receipt validation is failing.

Dear PlayFab community,

I am having some trouble with validating a Sandbox iOS receipt using Unity IAP and iOS.

The iOS event that's triggered when attempting to validate is:

{
    "EventName": "player_receipt_validation",
    "PaymentProvider": "iTunes Sandbox",
    "PaymentType": "ReceiptValidation",
    "ReceiptContent": "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",
    "Valid": false,
    "Error": "InvalidBundleID",
    "EntityId": "121BD68E8A8B5E87",
    "EventNamespace": "com.playfab",
    "EntityType": "player",
    "Source": "PlayFab",
    "TitleId": "44B1",
    "EventId": "9023c388355c4890891f48757e615f9a",
    "SourceType": "BackEnd",
    "Timestamp": "2018-07-25T03:30:51.9365555Z",
    "History": null,
    "CustomTags": null,
    "Reserved": null,
    "PlayFabEnvironment": {
        "Vertical": "master",
        "Cloud": "main",
        "Application": "mainserver",
        "Commit": "48e3b14"
    }
}

Note specifically:

    "Valid": false,
    "Error": "InvalidBundleID",

I have triple-checked that I'm using the correct BundleID in PlayFab, and that it corresponds to the ProductID for the IAP on iTunesConnect. My test user successfully completed the purchase on the device.

I am not having the same issues on Android with Google Play:

{
    "EventName": "player_receipt_validation",
    "PaymentProvider": "Google Play",
    "PaymentType": "ReceiptValidation",
    "ReceiptContent": "{\"orderId\":\"GPA.3304-4256-7912-59329\",\"packageName\":\"net.digitalmonsoon.letterheroes\",\"productId\":\"net.digitalmonsoon.letterheroes.booster.major.06\",\"purchaseTime\":1532480733135,\"purchaseState\":0,\"developerPayload\":\"{\\\"developerPayload\\\":\\\"\\\",\\\"is_free_trial\\\":false,\\\"has_introductory_price_trial\\\":false,\\\"is_updated\\\":false}\",\"purchaseToken\":\"cmoabmmpapflonbmcnhpjkbl.AO-J1OxqWk_MIw64vgB_slbpOSP_rsjPp8B7yh4QZYJFCZJNCS59yJnX7149N0i17ShRf7I7PJXcfB3EQEMztZIERcMJwNtocfh41FGDJEWwBNRRcEr8N2llQjP4lP29BeIdR4xwKRwAGO5b8PYW5an3k8ysOBledFgWU9DxuFnKmoU53CRSqHgFnCtOACjS8pg4bnjeNrAe\"}",
    "Valid": true,
    "Error": null,
    "EntityId": "A4D08305FCAFFD7B",
    "EventNamespace": "com.playfab",
    "EntityType": "player",
    "Source": "PlayFab",
    "TitleId": "44B1",
    "EventId": "19a257e97dfa4bf5a996e0e415a67133",
    "SourceType": "BackEnd",
    "Timestamp": "2018-07-25T01:05:36.6257271Z",
    "History": null,
    "CustomTags": null,
    "Reserved": null,
    "PlayFabEnvironment": {
        "Vertical": "master",
        "Cloud": "main",
        "Application": "mainserver",
        "Commit": "48e3b14"
    }
}

My C# code to manage the Unity IAP aspects is as follows:

Product product = args.purchasedProduct; // args is of type PurchaseEventArgs and is passed into the function.

if ((product != null) && (product.hasReceipt))
{
   /*
   Get the embedded receipt data.

   Example of args.purchasedProduct.receipt:

   Apple Sandbox:

   {"Store":"AppleAppStore","TransactionID":"1000000377486512","Payload":"<SOME REALLY LONG UUENCODED STRING>"}

   Google Play Sandbox:

   (Raw string form.)
   {\"Store\":\"GooglePlay\",\"TransactionID\":\"GPA.3351-5231-4193-03133\",\"Payload\":\"{\\\"json\\\":\\\"{\\\\\\\"orderId\\\\\\\":\\\\\\\"GPA.3351-5231-4193-03133\\\\\\\",\\\\\\\"packageName\\\\\\\":\\\\\\\"net.digitalmonsoon.letterheroes\\\\\\\",\\\\\\\"productId\\\\\\\":\\\\\\\"net.digitalmonsoon.letterheroes.bundle.02\\\\\\\",\\\\\\\"purchaseTime\\\\\\\":1523490394536,\\\\\\\"purchaseState\\\\\\\":0,\\\\\\\"purchaseToken\\\\\\\":\\\\\\\"iahicnndbljhpjdeiemhjpma.AO-J1Ox-FveuvUV4KQxSm-nkXqOgyMnAHNaGtCYNOVQHGVO6up11XJU2ntUG814pA_Nz5bVESQCbxZ3S8tYrGZiSCjXd-sL ...
   */
   PlayFab.Json.JsonObject receipt = Utility.MakeObjectFromJsonSimple(product.receipt);

   #if UNITY_IOS
   PlayFabClientAPI.ValidateIOSReceipt
   (
      new ValidateIOSReceiptRequest
         {
         CurrencyCode  =                 product.metadata.isoCurrencyCode,
         PurchasePrice = Decimal.ToInt32(product.metadata.localizedPrice * 100),
         ReceiptData   = (string)(receipt["Payload"])
         },
      (ValidateIOSReceiptResult result) =>
   #endif
   #if UNITY_ANDROID
   PlayFab.Json.JsonObject payload = Utility.MakeObjectFromJsonSimple((string)(receipt["Payload"]));

   PlayFabClientAPI.ValidateGooglePlayPurchase
   (
      new ValidateGooglePlayPurchaseRequest
         {
            CurrencyCode  =                  product.metadata.isoCurrencyCode,
            PurchasePrice = Decimal.ToUInt32(product.metadata.localizedPrice * 100),
            ReceiptJson   = (string)(payload["json"]),
            Signature     = (string)(payload["signature"])
         },
      (ValidateGooglePlayPurchaseResult result) =>
   #endif

   ...
}

I have successfully made purchases with iOS in sandbox mode before. As far as I know, this code hasn't changed since I was successful.

I'd appreciate any help anyone can provide!

unity3dIn-Game EconomyPlayer Inventory
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

1 Answer

·
John Peterson avatar image
John Peterson answered

Bah...turned out the PlayFab Add-On for Apple was using an older "iOS App Bundle ID". I was thinking of BundleID as the in-game economy bundle for my purchase instead of the app itself. <blush>

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.