jamesmontemagno / InAppBillingPlugin

Cross-platform In App Billing Plugin for .NET
MIT License
651 stars 152 forks source link

InAppBillingPurchase.PurchaseToken comes from the deprecated SKPaymentTransaction.transactionReceipt field. #191

Closed brianrak closed 5 years ago

brianrak commented 5 years ago

Version Number of Plugin: 2.0.0 Device Tested On: iPhone 6 (iOS 12) Version of VS: 15.8.9 Version of Xamarin: 4.0.11.770

Steps to reproduce the Behavior

  1. Use CrossInAppBilling.Current.PurchaseAsync to make a purchase.
  2. Submit the data provided in InAppBillingPurchase.PurchaseToken to Apple for validation.
  3. Note that what is returned is an "iOS 6 style" receipt.

Expected Behavior

The provided receipt data should not come from a deprecated field.

Actual Behavior

The provided receipt data is an "iOS 6 style" receipt which comes from SKPaymentTransaction.transactionReceipt.

Also, possibly because this field is deprecated, InAppBillingPurchase.PurchaseToken is sometimes null.

Code snippet

See: https://github.com/jamesmontemagno/InAppBillingPlugin/blob/master/src/Plugin.InAppBilling.iOS/InAppBillingImplementation.cs, line 204.

var purchase = new InAppBillingPurchase
{
    TransactionDateUtc = reference.AddSeconds(p.TransactionDate.SecondsSinceReferenceDate),
    Id = p.TransactionIdentifier,
    ProductId = p.Payment?.ProductIdentifier ?? string.Empty,
    State = p.GetPurchaseState(),
    PurchaseToken = p.TransactionReceipt?.GetBase64EncodedString(NSDataBase64EncodingOptions.None) ?? string.Empty
};

Other

I would like to suggest that the "iOS 7 style" receipt be attached to PurchaseToken, even though it contains information about much more than the current transaction. The InAppBillingPurchase object contains the right information to drill into the appropriate part of the receipt data returned from Apple upon Validation.

jamesmontemagno commented 5 years ago

We actually use the new way to validate with this date via the IInAppBillingVerifyPurchase and call taht new code.

PurchaseToken isn't used for validation.

You implement and pass in the interface and this code gets called: https://github.com/jamesmontemagno/InAppBillingPlugin/blob/master/src/Plugin.InAppBilling.iOS/InAppBillingImplementation.cs#L215-L229

See: https://jamesmontemagno.github.io/InAppBillingPlugin/SecuringPurchases.html

brianrak commented 5 years ago

Thank you for the reply!

I was aware of the option to use the overload that takes an implementation of IInAppBillingVerifyPurchase, but I thought I read in your documentation that InAppBillingPurchase.PurchaseToken contains the base64 receipt data (for iOS) or purchase token (for Android) as well. I had chosen to put the entire InAppBillingPurchase object, as returned from PurchaseAsync, in a queue for processing, since it comes wrapped up in a nice package with other useful data.

If that is not correct, then what is the purpose of PurchaseToken? Is it a vestige of a legacy approach?