In the IAP sandbox test, consumables and non-consumables cannot be purchased again after being purchased once. As a result, the payment page cannot be displayed. In onActivityResult, the IAP SDK returns code
ORDER_PRODUCT_OWNED 60051
Is this a general problem or am I doing something wrong?
60051 means A user failed to purchase a product because the user already owns the product. and @Disavowed has given the explanation and solution. https://developer.huawei.com/consumer/en/doc/development/HMS-References/iap-ExceptionHandlingAndGeneralErrorCodes-v4
Here is the code on how to consume the product.
/**
* Consume the unconsumed purchase with type 0 after successfully delivering the product, then the Huawei payment server will update the order status and the user can purchase the product again.
* @param inAppPurchaseData JSON string that contains purchase order details.
*/
private void consumeOwnedPurchase(final Context context, String inAppPurchaseData) {
Log.i(TAG, "call consumeOwnedPurchase");
IapClient mClient = Iap.getIapClient(context);
Task<ConsumeOwnedPurchaseResult> task = mClient.consumeOwnedPurchase(createConsumeOwnedPurchaseReq(inAppPurchaseData));
task.addOnSuccessListener(new OnSuccessListener<ConsumeOwnedPurchaseResult>() {
@Override
public void onSuccess(ConsumeOwnedPurchaseResult result) {
// Consume success
Log.i(TAG, "consumeOwnedPurchase success");
Toast.makeText(context, "Pay success, and the product has been delivered", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
Log.e(TAG, e.getMessage());
Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show();
if (e instanceof IapApiException) {
IapApiException apiException = (IapApiException)e;
Status status = apiException.getStatus();
int returnCode = apiException.getStatusCode();
Log.e(TAG, "consumeOwnedPurchase fail,returnCode: " + returnCode);
} else {
// Other external errors
}
}
});
}
/**
* Create a ConsumeOwnedPurchaseReq instance.
* @param purchaseData JSON string that contains purchase order details.
* @return ConsumeOwnedPurchaseReq
*/
private ConsumeOwnedPurchaseReq createConsumeOwnedPurchaseReq(String purchaseData) {
ConsumeOwnedPurchaseReq req = new ConsumeOwnedPurchaseReq();
// Parse purchaseToken from InAppPurchaseData in JSON format.
try {
InAppPurchaseData inAppPurchaseData = new InAppPurchaseData(purchaseData);
req.setPurchaseToken(inAppPurchaseData.getPurchaseToken());
} catch (JSONException e) {
Log.e(TAG, "createConsumeOwnedPurchaseReq JSONExeption");
}
return req;
}