Search Unity

Unacceptable behavior change with developerPayload from Unity IAP v1.19

Discussion in 'Unity IAP' started by iyc, Jul 30, 2018.

  1. iyc

    iyc

    Joined:
    Jul 29, 2014
    Posts:
    11
    @nicholasr
    Hi there,

    From Unity IAP v1.19, there was a big behavior change with developerPayload of GooglePlay, that developerPayload field is encoded by Unity IAP to JSON form.

    This behavior change is not acceptable for our payment system, because we embed original transaction ID to developerPayload and check the receipt at the server. This system is shared for other games not using Unity IAP, so we can not change to parse JSON form specified by Unity IAP.

    Please provide option not to encode developerPayload. We can not update SDK anymore.
     
  2. ap-unity

    ap-unity

    Unity Technologies

    Joined:
    Aug 3, 2016
    Posts:
    1,519
    @iyc

    I apologize for the inconvenience this change has caused.

    As a workaround, you could add some code to manually deconstruct the receipt and decode the developerPayload. Then you could reconstruct the receipt in the format your server accepts. This isn't ideal, but hopefully it will get you to a place where you are able to continue using Unity IAP.

    If you have a project that has upgraded to v1.19 and you need to return it to the previous behavior, you can find previous versions available for download here:
    https://forum.unity.com/threads/unity-iap-previous-versions.527432/

    I will pass your feedback along to the IAP team.
     
  3. iyc

    iyc

    Joined:
    Jul 29, 2014
    Posts:
    11
    @ap-unity
    Thanks for your help!
    The problem is that if you manually falsified the receipt, it will fail validating receipt at server, because of inconsistency of provided signature. We need a option not to change given developerPayload.

    Since our project decided to stay at v1.18, we are not hurrying for new updates, but maybe we there is a point that we need to update Unity IAP because of store changes, we hopefully new option is provided at future releases.
     
  4. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    @iyc I don't quite follow. You are not manually falsifying the receipt (only decoding it), can you elaborate?
     
    m_takemura likes this.
  5. iyc

    iyc

    Joined:
    Jul 29, 2014
    Posts:
    11
    @JeffDUnity3D Our server program that verify the receipt and signature are checking below conditions.
    1. Provided receipt and signature pair are valid
    2. developerPayload is in specified format
    As server program is shared by many services, I can't customize these conditions. So if I don't falsified the receipt, it will return an error with invalid format of developerPayload. But if I falsified the receipt, it will return an error with invalid receipt and signature pair.

    In conclusion, I need developerPayload in our format without falsifying, to pass validator of server program.
     
  6. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Sorry I'm not clear on what you mean by falsifying? You are only decoding, not falsifying. As ap-unity mentioned previously, you could add some code to manually deconstruct the receipt and decode the developerPayload. Then you could reconstruct the receipt in the format your server accepts. This would be done on the client, not the server, so your server would also work with other services.
     
  7. iyc

    iyc

    Joined:
    Jul 29, 2014
    Posts:
    11
    @JeffDUnity3D Yes, I can decode the receipt, modify developerPayload and reconstruct the receipt again. But if I do that, than server doesn't accept the modified receipt because the signature I get with the receipt doesn't match. The signature of the receipt will guarantee that receipt is not modified by anyone. For security reason, server must check the signature, so that client can't modify the receipt.

    Document guide of checking signature on the server: https://developer.android.com/google/play/billing/billing_integrate#billing-security
     
  8. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    I don't believe that is correct. WE (Unity) are encoding it. When you decode it, you should be putting it back into the original format that a receipt service would expect. I will confirm with the IAP team here.
     
  9. iyc

    iyc

    Joined:
    Jul 29, 2014
    Posts:
    11
    It's not a problem of either I can reconstruct the receipt or not. It's a problem of modifying the receipt will break the signature provided by Google Play. Do you mean that Unity IAP is modifying the developerPayload after getting the receipt and signature from Google Play?
     
  10. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Two possible options - If we are modifying the payload, simply decode it and your server will be happy. If Google is encoding it, then we have no control over it. Your receipt service should accept the receipt in the same format as Google returns it. Have you tried decoding it and passing it?
     
  11. iyc

    iyc

    Joined:
    Jul 29, 2014
    Posts:
    11
    Oh, It seem that you are misunderstanding the issue. I have an issue with the format of developerPayload itself, not the whole receipt.

    Our server expect like kind of this format. Just to simplify, only developerPayload and orderId are shown.

    Code (JavaScript):
    1. {
    2.     "developerPayload": "SOME_SPECIAL_ID",
    3.     "orderId": "ORDER_ID"
    4. }
    But Unity IAP is encoding value of developerPayload to other format like this.

    Code (JavaScript):
    1. {
    2.     "developerPayload": "{\"developerPayload\":\"BASE64_ENCODED_SOME_SPECIAL_ID\",\"is_free_trial\":false,\"has_introductory_price_trial\":false}",
    3.     "orderId": "ORDER_ID"
    4. }
    Yes I tried decoding later format receipt and encoded to former format receipt, but failed to verify signature on the server, since I modified the receipt. For this behavior, I am thinking of Unity IAP is modifying developerPayload before passing to Google Play, is it correct? Google Play will generate signature with passed developerPayload, so you can not modify the receipt returned by Google Play.
     
  12. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    I meant to simply decode BASE64_ENCODED_SOME_SPECIAL_ID from your second example, and use it as SOME_SPECIAL_ID in the first example. Perhaps this is what you've tried?
     
  13. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    I heard from the IAP team regarding this issue, apologies on the confusion. Unfortunately there is no work around at this time. We may include an update for this behavior with developerPayload in a future release, but it has not been decided at this time.
     
  14. iyc

    iyc

    Joined:
    Jul 29, 2014
    Posts:
    11
    Yes I tried it on client app, sending the modified receipt to the server, but rejected for invalid signature. Only workaround is to add support of Unity IAP to server program, but the server is shared with various services and seems to be hard.

    I am glad to hear that. Since I am not hurrying for updates now, I will wait for updates. But in future we maybe need to update for external factor, I hope it will be fixed at some point.