我正在尝试实施应用内购买,并按照文档进行了处理。
该应用已在商店中发布,并启用了应用内购买。我们的商店帐户有活跃的产品和订阅,但尝试购买约20个不同的帐户,我们在输入信用卡信息后获得"Your order could not be processed. Please try again".
。
我检查了商店的公钥和购买ID。使用Google测试ID,该应用程序可以运行。应用内购买工作大约6个月前。
这是我在设备日志中看到的2个错误:
- purchasefragment error purchaseerror type 2 subtype 0
- https://android.clients.google.com/fdfe/ees/commitPurchase
的意外回复代码500
我们已经在Xamarin中编写了应用程序并正在使用Xamarin.InAppBilling component。
private InAppBillingServiceConnection _serviceConnection;
private IEnumerable<Product> _availableProducts;
//public event EventHandler<PurchaseCanceledEventArgs> PurchaseCanceled;
public event EventHandler<PurchaseFailedEventArgs> PurchaseFailed;
public event EventHandler<PurchaseSucceededEventArgs> PurchaseSucceeded;
public void Buy(string productId)
{
if (_serviceConnection.Connected)
{
if (_availableProducts != null && _availableProducts.Any())
{
var product = _availableProducts.FirstOrDefault(x => x.ProductId.Equals(productId));
if (product != null)
{
_serviceConnection.BillingHandler.BuyProduct(product);
}
}
}
}
public PurchaseProduct GetProduct(string productId)
{
return null;
}
public bool HasSubscriptionFor(string productIdentifier)
{
if (_serviceConnection?.BillingHandler != null)
{
return _serviceConnection.BillingHandler.GetPurchases(ItemType.Subscription).Any(x => x.ProductId == productIdentifier);
}
return false;
}
public void RestorePreviousPurchases()
{
// Restore not required for google purchases (?)
}
public void Disconnect()
{
try
{
_serviceConnection?.Disconnect();
}
catch (Exception ex)
{
}
}
public void Connect(Activity activity)
{
try
{
_serviceConnection = new InAppBillingServiceConnection(activity, "our public key");
_serviceConnection.OnConnected += OnConnected;
_serviceConnection.Connect();
}
catch (Exception ex)
{
}
}
private async void OnConnected()
{
await Task.Run(async () =>
{
if (_serviceConnection?.BillingHandler != null)
{
_serviceConnection.OnInAppBillingError += OnInAppBillingError;
_serviceConnection.BillingHandler.OnProductPurchased += BillingHandlerOnOnProductPurchased;
_serviceConnection.BillingHandler.OnProductPurchasedError += BillingHandlerOnOnProductPurchasedError;
_serviceConnection.BillingHandler.BuyProductError += BillingHandlerOnBuyProductError;
// Test in sandbox mode only
//_availableProducts = await _serviceConnection.BillingHandler.QueryInventoryAsync(new List<string>
//{
// ReservedTestProductIDs.Purchased,
// ReservedTestProductIDs.Refunded,
// ReservedTestProductIDs.Canceled,
// ReservedTestProductIDs.Unavailable
//}, ItemType.Product);
var products = await _serviceConnection.BillingHandler.QueryInventoryAsync(_purchaseConfiguration.Products, ItemType.Product);
var subscriptions = await _serviceConnection.BillingHandler.QueryInventoryAsync(_purchaseConfiguration.Subscriptions, ItemType.Subscription);
_availableProducts = new List<Product>();
if (products?.Any() == true)
{
_availableProducts = _availableProducts.Concat(products);
}
if (subscriptions?.Any() == true)
{
_availableProducts = _availableProducts.Concat(subscriptions);
}
}
});
}
public void HandleResult(int requestCode, object resultCode, object data)
{
_serviceConnection.BillingHandler.HandleActivityResult(requestCode, (Result)resultCode, (Intent)data);
}
private void BillingHandlerOnBuyProductError(int responseCode, string sku)
{
PurchaseFailed?.Invoke(this, new PurchaseFailedEventArgs { Message = "BillingHandlerOnBuyProductError: " + sku });
}
private void BillingHandlerOnOnProductPurchasedError(int responseCode, string sku)
{
PurchaseFailed?.Invoke(this, new PurchaseFailedEventArgs { Message = "BillingHandlerOnBuyProductError: " + sku });
}
private void BillingHandlerOnOnProductPurchased(int response, Purchase purchase, string purchaseData, string purchaseSignature)
{
PurchaseSucceeded?.Invoke(this, new PurchaseSucceededEventArgs(purchase.ProductId));
}
private void OnInAppBillingError(InAppBillingErrorType error, string message)
{
if (!string.IsNullOrEmpty(message))
{
PurchaseFailed?.Invoke(this, new PurchaseFailedEventArgs { Message = message });
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="3.0.14" package="">
<uses-sdk android:minSdkVersion="17" android:targetSdkVersion="23" />
<application android:label="" android:icon="@drawable/ic_launcher" android:theme="@style/ApplicationBaseTheme" android:largeHeap="true" android:allowBackup="false">
<receiver android:name="com.google.android.gms.gcm.GcmReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="%PACKAGE_NAME%" />
</intent-filter>
</receiver>
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service android:name="com.pushwoosh.GCMInstanceIDListenerService" android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID" />
</intent-filter>
</service>
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id" />
<meta-data android:name="com.facebook.sdk.ApplicationName" android:value="@string/facebook_app_name" />
</application>
<uses-permission android:name="com.android.vending.BILLING" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<permission android:name="%PACKAGE_NAME%.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="%PACKAGE_NAME%.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!--for Samsung-->
<uses-permission android:name="com.sec.android.provider.badge.permission.READ"/>
<uses-permission android:name="com.sec.android.provider.badge.permission.WRITE"/>
<!--for htc-->
<uses-permission android:name="com.htc.launcher.permission.READ_SETTINGS"/>
<uses-permission android:name="com.htc.launcher.permission.UPDATE_SHORTCUT"/>
<!--for sony-->
<uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE"/>
<!--for apex-->
<uses-permission android:name="com.anddoes.launcher.permission.UPDATE_COUNT"/>
<!--for solid-->
<uses-permission android:name="com.majeur.launcher.permission.UPDATE_BADGE"/>
</manifest>