简体   繁体   中英

How to get separate price and currency information for an in-app purchase?

I am implementing in-app purchases for an app with support for several countries.

The In-App Billing Version 3 API claims that :

No currency conversion or formatting is necessary: prices are reported in the user's currency and formatted according to their locale.

This is actually true , since skuGetDetails() takes care of all necessary formatting. The response includes a field called price , which contains the

Formatted price of the item, including its currency sign. The price does not include tax.

However, I need the ISO 4217 currency code (retrievable if I know the store locale) and the actual non-formatted price (optimally in a float or decimal variable) so I can do further processing and analysis myself.

Parsing the return of skuGetDetails() is not a reliable idea, because many countries share the same currency symbols.

货币

How can I get the ISO 4217 currency code and non-formatted price of an in-app purchase with the In-App Billing Version 3 API?

Full information can be found here , but essentially in August 2014 this was resolved with:

The getSkuDetails() method

This method returns product details for a list of product IDs. In the response Bundle sent by Google Play, the query results are stored in a String ArrayList mapped to the DETAILS_LIST key. Each String in the details list contains product details for a single product in JSON format. The fields in the JSON string with the product details are summarized below

price_currency_code ISO 4217 currency code for price. For example, if price is specified in British pounds sterling, price_currency_code is "GBP".

price_amount_micros Price in micro-units, where 1,000,000 micro-units equal one unit of the currency. For example, if price is "€7.99", price_amount_micros is "7990000".

You can't, this is currently not supported. There is a feature request for it, but it may or may not get implemented.

https://code.google.com/p/marketbilling/issues/detail?id=93

You can. You need to modify SkuDetails.java like below.

Steps:

  1. Check their sample app for in-app billing.
  2. Modify the SkuDetails.java file as follows:
 import org.json.JSONException; import org.json.JSONObject; /** * Represents an in-app product's listing details. */ public class SkuDetails { String mItemType; String mSku; String mType; int mPriceAmountMicros; String mPriceCurrencyCode; String mPrice; String mTitle; String mDescription; String mJson; public SkuDetails(String jsonSkuDetails) throws JSONException { this(IabHelper.ITEM_TYPE_INAPP, jsonSkuDetails); } public SkuDetails(String itemType, String jsonSkuDetails) throws JSONException { mItemType = itemType; mJson = jsonSkuDetails; JSONObject o = new JSONObject(mJson); mSku = o.optString("productId"); mType = o.optString("type"); mPrice = o.optString("price"); mPriceAmountMicros = o.optInt("price_amount_micros"); mPriceCurrencyCode = o.optString("price_currency_code"); mTitle = o.optString("title"); mDescription = o.optString("description"); } public String getSku() { return mSku; } public String getType() { return mType; } public String getPrice() { return mPrice; } public String getTitle() { return mTitle; } public String getDescription() { return mDescription; } public int getPriceAmountMicros() { return mPriceAmountMicros; } public String getPriceCurrencyCode() { return mPriceCurrencyCode; } @Override public String toString() { return "SkuDetails:" + mJson; } } 

Here is my workaround :)

private static Locale findLocale(String price) {
    for (Locale locale : Locale.getAvailableLocales()){
        try {
            Currency currency = Currency.getInstance(locale);
            if (price.endsWith(currency.getSymbol())) 
                return locale;
        }catch (Exception e){

        }

    }
    return null;
}

Usage:

Locale locale = findLocale(price);
String currency = Currency.getInstance(locale).getCurrencyCode();
double priceClean = NumberFormat.getCurrencyInstance(locale).parse(price).doubleValue();

You can check this The Android developers in select countries can now offer apps for sale in multiple currencies through Google Wallet Merchant Center. To sell your apps in additional currencies, you will need to set the price of the app in each country/currency. A list of supported countries/currencies is available in our help center.

If you make an app available in local currency, Google Play customers will only see the app for sale in that currency. Customers will be charged in their local currency, but payment will be issued in the currency set in your Google Wallet Merchant Center account.

Another hardcoded workaround is to price items for countries with the same symbol, differently by a cent or so. When you retrieve the price of the item from google play upon purchasing and you know the retrieved currency symbol is one which is used in many countries ie. $. You then have a log of different prices on your backend server and correlate the purchase price with a specific country.

Very simple. SKU returns the currency code ("price_currency_code" field). With that code you can retrieve the symbol using the Currency class. See the code attached:

String currencyCode = skuObj.getString("price_currency_code");
currencySymbol = Currency.getInstance(currencyCode).getSymbol();

Here's a complete code:

ArrayList<String> skuList = new ArrayList<>();
skuList.add("foo");
skuList.add("bar");

final String[] prices = new String[skuList.size()];

Bundle querySkus = new Bundle();
querySkus.putStringArrayList("ITEM_ID_LIST", skuList);

Bundle skuDetails = _appActivity.mService.getSkuDetails(3, _appActivity.getPackageName(), "inapp", querySkus);

int response = skuDetails.getInt("RESPONSE_CODE");
if(response == 0) {
    ArrayList<String> responseList = skuDetails.getStringArrayList("DETAILS_LIST");

    int i = 0;
    for (String thisResponse : responseList) {
        JSONObject object = new JSONObject(thisResponse);
        String sku = object.getString("productId");
        final String priceCurrency = object.getString("price_currency_code");
        String priceAmountMicros = object.getString("price_amount_micros");
        float priceAmount = Float.parseFloat(priceAmountMicros) / 1000000.0f;
        String price = priceAmount + " " + priceCurrency;

        if(skuList.contains(sku)){
            prices[i] = price;
            i++;
        }
    }
}

From documentation:

price_currency_code ISO 4217 currency code for price. For example, if price is specified in British pounds sterling, price_currency_code is "GBP".

price_amount_micros Price in micro-units, where 1,000,000 micro-units equal one unit of the currency. For example, if price is "€7.99", price_amount_micros is "7990000". This value represents the localized, rounded price for a particular currency.

Now you just have to divide price_amount_micros by a 1000000 and concatenate it with currency.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM