I have implemented subscription purchase using Plugin.InAppBilling
package and its codes are below.
private async void PlanClicked(Object sender, EventArgs e)
{
UserDialogs.Instance.ShowLoading("");
if (IsBusy)
return;
IsBusy = true;
try
{
// check internet first with Essentials
if (Connectivity.NetworkAccess != NetworkAccess.Internet)
return;
// connect to the app store api
var connected = await CrossInAppBilling.Current.ConnectAsync();
if (!connected)
return;
UserDialogs.Instance.HideHud();
//try to make purchase, this will return a purchase, empty, or throw an exception
var purchase = await CrossInAppBilling.Current.PurchaseAsync(productId, ItemType.Subscription);
if (purchase == null)
{
//nothing was purchased
return;
}
if (purchase.State == PurchaseState.Purchased)
{
Debug.WriteLine("Purchase successfull");
Debug.WriteLine("Purchase token:>>" + purchase.PurchaseToken);
Debug.WriteLine("Purchase id:>>" + purchase.Id);
}
else
{
throw new InAppBillingPurchaseException(PurchaseError.GeneralError);
}
}
catch (InAppBillingPurchaseException purchaseEx)
{
// Handle all the different error codes that can occure and do a pop up
Debug.WriteLine("purchaseEx:>>" + purchaseEx);
}
catch (Exception ex)
{
// Handle a generic exception as something really went wrong
Debug.WriteLine("exception:>>" + ex);
}
finally
{
await CrossInAppBilling.Current.DisconnectAsync();
IsBusy = false;
}
}
After successful purchase I get the PurchaseToken
and ID
from app store and play store.
Now using this I need to fetch the subscription details of a user. Which App Store Developer API and Play Store Developer API are suit for this?
I tried using this API from Apple and this API from Play Store. Is this the correct API to fetch the subscription details?
When I try the Apple API I am getting the 401 Unauthorized
response.
Using below code I am generating the JWT token.
private string LoadPrivateKey()
{
string fileName = "API key (.p8 file)";
using var stream = FileSystem.OpenAppPackageFileAsync(fileName).Result;
using var reader = new StreamReader(stream);
var privateKey = reader.ReadToEnd();
// Remove the header and footer lines
privateKey = privateKey
.Replace("-----BEGIN PRIVATE KEY-----", string.Empty)
.Replace("-----END PRIVATE KEY-----", string.Empty)
.Replace("\n", string.Empty)
.Replace("\r", string.Empty);
return privateKey;
}
public async void JWTGenerator(Object sender, EventArgs e)
{
try
{
// Key ID from Apple Developer account
string keyId = "keyId";
// Team ID from Apple Developer account
string teamId = "teamId";
// Load your private key from the .p8 file
string privateKey = LoadPrivateKey();
// Call the GenerateToken method to create a JWT
string jwtToken = AppleApiTokenGenerator.GenerateToken(keyId, teamId, privateKey);
DisplayAlert("JWT Token", jwtToken, "OK");
}
catch (Exception ex)
{
Debug.WriteLine("JWTException:>" + ex);
}
}
public class AppleApiTokenGenerator
{
public static string GenerateToken(string keyId, string teamId, string privateKey)
{
byte[] privateKeyBytes = Convert.FromBase64String(privateKey);
var tokenHandler = new JwtSecurityTokenHandler();
var key = new SymmetricSecurityKey(Convert.FromBase64String(privateKey));
var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim(JwtRegisteredClaimNames.Iss, teamId),
new Claim(JwtRegisteredClaimNames.Aud, "https://api.storekit-sandbox.itunes.apple.com/inApps/v1/subscriptions/{transactionId}"),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
}),
Expires = DateTime.UtcNow.AddMinutes(20),
SigningCredentials = credentials
};
var token = tokenHandler.CreateToken(tokenDescriptor);
Console.WriteLine($"JWT token:{tokenHandler.WriteToken(token)}");
return tokenHandler.WriteToken(token);
}
}
The .P8 file we have added under the Recourses/Row and set the build action as a MauAsset.
Can anyone provide a solution or guidance?
Thanks in advance for your help!
You need to sign in to view this answers
Leave feedback about this