Cheok Yan Cheng
Cheok Yan Cheng

Reputation: 42768

Correct steps after in-app purchase is successful

I tried the following code for in-app purchase. I'm using CurrentAppSimulator for testing purpose.

private async void history_Click(object sender, RoutedEventArgs e)
{
    bool OK = true;

    // Get the license info
    // The next line is commented out for testing.
    // licenseInformation = CurrentApp.LicenseInformation;

    // The next line is commented out for production/release.       
    LicenseInformation licenseInformation = CurrentAppSimulator.LicenseInformation;
    if (!licenseInformation.ProductLicenses["PremiumFeatures"].IsActive)
    {
        try
        {
            // The customer doesn't own this feature, so 
            // show the purchase dialog.

            await CurrentAppSimulator.RequestProductPurchaseAsync("PremiumFeatures", false);
            // the in-app purchase was successful
            OK = true;
        }
        catch (Exception)
        {
            // The in-app purchase was not completed because 
            // an error occurred.
            OK = false;
        }
    }
    else
    {
        // The customer already owns this feature.
        OK = true;
    }

    if (OK)
    {
        Frame.Navigate(typeof(HistoryPage));
    }
}

However, the dialog keep pop up, every time I perform history_Click, even I choose S_OK. I expect licenseInformation.ProductLicenses["PremiumFeatures"].IsActive should changed to true, after I buy the PremiumFeatures.

enter image description here

I guess, perhaps when the in-app purchase was successful, I need to turn on IsActive flag, so that it will not show me purchase dialog again.

        // the in-app purchase was successful
        OK = true;
        // Compile error!!!
        licenseInformation.ProductLicenses["PremiumFeatures"].IsActive = true;

OK. Seems like IsActive is a read only field. So, may I know, what is the correct way to handle purchase successful case?

Update :

After looking at Trial app and in-app purchase sample, I realize having the following code can have IsActive changed from false to true automatically, after purchasing successful. (But why it works?)

    private async Task LoadInAppPurchaseProxyFileAsync()
    {
        StorageFolder proxyDataFolder = await Package.Current.InstalledLocation.GetFolderAsync("data");
        StorageFile proxyFile = await proxyDataFolder.GetFileAsync("in-app-purchase.xml");
        licenseChangeHandler = new LicenseChangedEventHandler(InAppPurchaseRefreshScenario);
        CurrentAppSimulator.LicenseInformation.LicenseChanged += licenseChangeHandler;
        await CurrentAppSimulator.ReloadSimulatorAsync(proxyFile);

        // setup application upsell message
        ListingInformation listing = await CurrentAppSimulator.LoadListingInformationAsync();
        var product1 = listing.ProductListings["product1"];
        var product2 = listing.ProductListings["product2"];
        Product1SellMessage.Text = "You can buy " + product1.Name + " for: " + product1.FormattedPrice + ".";
        Product2SellMessage.Text = "You can buy " + product2.Name + " for: " + product2.FormattedPrice + ".";
    }

However, the "Is already bought" status is not persistence. If I close the app and start it again, it will thought my "Premium Feature" to "is not bought yet".

How am I suppose the make this behavior persistence?

Upvotes: 5

Views: 1802

Answers (5)

Arsen Y.M.
Arsen Y.M.

Reputation: 697

It is not necessary to check if the license IsActive immediately after the purchase. Instead, you can (you'd better) store the result of RequestProductPurchaseAsync, which is of type PurchaseResults and has a Status property. The latter in its turn is a ProductPurchaseStatus enum value, and if it is Succeeded, you can proceed without checking the license.

Upvotes: 0

Felix Haub
Felix Haub

Reputation: 1

I'm just gonna clear this out. When executing

  try {

        await CurrentAppSimulator.RequestProductPurchaseAsync("PremiumFeatures", false);
        OK = true

    }
    catch (Exception)
    {

        OK = false;
    }

OK will not only be true if the user bought the feature, it will also be true if he cancels the buy or he cant be identified or he disables his network connection. So this is the wrong way to check if the purchase was successfull. Basically Anobik was right, you have to check afterwards if the license is purchased so the right code would be:

if (!licenseInformation.ProductLicenses["PremiumFeatures"].IsActive)
{
    try
    {
        // The customer doesn't own this feature, so 
        // show the purchase dialog.

        await CurrentAppSimulator.RequestProductPurchaseAsync("PremiumFeatures", false);
                if (licenseInformation.ProductLicenses["PremiumFeatures"].IsActive)
                {
                    // the in-app purchase was successful
                     OK = true;
                    //Success in purchase use ur own code block
                }
                else
                {
                     OK = false;
                    //error in purchase use your own code block
                }

    }
    catch (Exception)
    {
        // The in-app purchase was not completed because 
        // an error occurred.
        OK = false;
    }
}
else
{
    // The customer already owns this feature.
    OK = true;
}

if (OK)
{
    Frame.Navigate(typeof(HistoryPage));
}

But still, if you compile you will see that it doesn't work. I think, this is because the CurrentAppSimulator will not make a permanent change to the license. I hope this is true :)

Upvotes: 0

Jerry Nixon
Jerry Nixon

Reputation: 31831

PLEASE READ

I would assume, based on your experience, that App.IsTrial is set to true. You cannot commit a purchase while the app is in trial mode or (for any other reason) is not active. Please note that I am referring to the App and not the feature/product. Once the app is active your purchase will succeed.

Upvotes: 8

Anobik
Anobik

Reputation: 4899

You are only missing one if else condition to handle the in app purchase

Here's the code

private async void history_Click(object sender, RoutedEventArgs e)
{
bool OK = true;

// Get the license info
// The next line is commented out for testing.
// licenseInformation = CurrentApp.LicenseInformation;

// The next line is commented out for production/release.       
LicenseInformation licenseInformation = CurrentAppSimulator.LicenseInformation;
if (!licenseInformation.ProductLicenses["PremiumFeatures"].IsActive)
{
    try
    {
        // The customer doesn't own this feature, so 
        // show the purchase dialog.

        await CurrentAppSimulator.RequestProductPurchaseAsync("PremiumFeatures", false);
                if (licenseInformation.ProductLicenses["PremiumFeatures"].IsActive)
                {
                    // the in-app purchase was successful
                     OK = true;
                    //Success in purchase use ur own code block
                }
                else
                {
                     OK = false;
                    //error in purchase use your own code block
                }

    }
    catch (Exception)
    {
        // The in-app purchase was not completed because 
        // an error occurred.
        OK = false;
    }
}
else
{
    // The customer already owns this feature.
    OK = true;
}

if (OK)
{
    Frame.Navigate(typeof(HistoryPage));
}

}

Upvotes: -1

ChristiaanV
ChristiaanV

Reputation: 5541

As far as I know it's not automatically updated when you click OK. It only returns the correct status like it should do in the Windows Store.

What I think is an option to do, but I haven't implemented it myself is to use ReloadSimulatorAsync(proxyFile) method. Before you call this method you have to update the in-app-purchase.xml yourself save it and pass the file to the ReloadSimulatorAsync method.

Personally I would use the manual update of the xml file. But I can't Judge about that for your application / application flow.

A good start for automating this process is the sample "In-app purchase" app which you can find here. If you look in the code file InAppPurchase.xaml.cs you will see already a bit of code for your own implementation.

Upvotes: 3

Related Questions