Xamarin.InAppBilling Android错误:无法处理您的订单。请再试一次
我正在尝试实现应用内购买,并严格遵守了文档 应用已在商店中发布,并启用了应用内购买。我们的商店帐户有活动产品和订阅,但尝试使用约20个不同的帐户购买时,我们都会收到Xamarin.InAppBilling Android错误:无法处理您的订单。请再试一次,xamarin,xamarin.android,google-play,in-app-purchase,google-apps-marketplace,Xamarin,Xamarin.android,Google Play,In App Purchase,Google Apps Marketplace,我正在尝试实现应用内购买,并严格遵守了文档 应用已在商店中发布,并启用了应用内购买。我们的商店帐户有活动产品和订阅,但尝试使用约20个不同的帐户购买时,我们都会收到“无法处理您的订单。请在输入信用卡信息后重试”。 我三次检查了商店的公钥和购买ID。使用谷歌测试ID,该应用程序可以正常工作。应用内购买在6个月前起作用 以下是我在设备日志中看到的两个错误: purchasefragment错误purchaseerror类型2子类型0 的意外响应代码500 我们已经用Xamarin编写了应用程序,
“无法处理您的订单。请在输入信用卡信息后重试”。
我三次检查了商店的公钥和购买ID。使用谷歌测试ID,该应用程序可以正常工作。应用内购买在6个月前起作用
以下是我在设备日志中看到的两个错误:
- purchasefragment错误purchaseerror类型2子类型0
- 的意外响应代码500
专用InAppBillingService连接\u服务连接;
私人可数产品;
//已取消公共事件事件处理程序购买;
公共事件EventHandler PurchaseFailed;
公共事件EventHandler PurchaseSuccessed;
公共作废购买(字符串productId)
{
if(_serviceConnection.Connected)
{
if(_availableProducts!=null&&u availableProducts.Any())
{
var product=_availableProducts.FirstOrDefault(x=>x.ProductId.Equals(ProductId));
如果(产品!=null)
{
_serviceConnection.BillingHandler.BuyProduct(产品);
}
}
}
}
public PurchaseProduct GetProduct(字符串productId)
{
返回null;
}
公共bool HasSubscriptionFor(字符串productIdentifier)
{
if(_serviceConnection?.BillingHandler!=null)
{
return _serviceConnection.BillingHandler.GetPurchases(ItemType.Subscription).Any(x=>x.ProductId==productIdentifier);
}
返回false;
}
公共无效恢复以前的购买()
{
//谷歌购买不需要恢复(?)
}
公共空间断开连接()
{
尝试
{
_serviceConnection?.Disconnect();
}
捕获(例外情况除外)
{
}
}
公共void Connect(活动)
{
尝试
{
_serviceConnection=新的InAppBillingServiceConnection(活动,“我们的公钥”);
_serviceConnection.OnConnected+=未连接;
_serviceConnection.Connect();
}
捕获(例外情况除外)
{
}
}
私有异步void OnConnected()
{
等待任务。运行(异步()=>
{
if(_serviceConnection?.BillingHandler!=null)
{
_serviceConnection.OnInAppBillingError+=OnInAppBillingError;
_serviceConnection.BillingHandler.OnProductPurchased+=BillingHandlerOnOnOnOnOnProductPurchased;
_serviceConnection.BillingHandler.OnProductPurchasedError+=BillingHandlerOnOnNonProductPurchasederRor;
_serviceConnection.BillingHandler.BuyProductError+=BillingHandlerOnBuyProductError;
//仅在沙箱模式下测试
//_availableProducts=Wait\u serviceConnection.BillingHandler.QueryInventoryAsync(新列表
//{
//ReservedTestProductId.已购买,
//ReservedTestProductId.已退款,
//ReservedTestProductId。已取消,
//ReservedTestProductId。不可用
//},ItemType.Product);
var products=wait _serviceConnection.BillingHandler.QueryInventoryAsync(_purchaseConfiguration.products,ItemType.Product);
var subscriptions=wait _serviceConnection.BillingHandler.QueryInventoryAsync(_purchaseConfiguration.subscriptions,ItemType.Subscription);
_availableProducts=新列表();
如果(产品?.Any()==true)
{
_availableProducts=\u availableProducts.Concat(产品);
}
if(订阅?.Any()==true)
{
_availableProducts=\u availableProducts.Concat(订阅);
}
}
});
}
public void HandleResult(int请求代码、对象结果代码、对象数据)
{
_serviceConnection.BillingHandler.HandleActivityResult(请求代码,(结果)结果代码,(意图)数据);
}
私有无效BillingHandlerOnBuyProductError(int响应代码,字符串sku)
{
PurchaseFailed?.Invoke(这是新的PurchaseFailedEventArgs{Message=“BillingHandlerOnBuyProductError:”+sku});
}
私有作废账单HandlerOnNonProductPurchaseDerror(int响应代码,字符串sku)
{
PurchaseFailed?.Invoke(这是新的PurchaseFailedEventArgs{Message=“BillingHandlerOnBuyProductError:”+sku});
}
private void BillingHandlerOnOnNonProductPurchased(整数响应、购买购买、字符串购买数据、字符串购买签名)
{
PurchaseSuccessed?.Invoke(这是新的PurchaseSucceedeEventArgs(purchase.ProductId));
}
私有void OnInAppBillingError(InAppBillingErrorType错误,字符串消息)
{
如果(!string.IsNullOrEmpty(消息))
{
PurchaseFailed?.Invoke(这是新的PurchaseFailedEventArgs{Message=Message});
}
}
如果日志是从真实日志粘贴的,请检查打字错误。上面写着“aBdroid”。响应代码500可能是“内部服务器错误”(如果是网络响应),您的应用程序是否设置为已发布?还是它仍然准备发布?它需要被发布,InApp的购买才能生效,如果它仍然是Alpha版本,那么
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>