App revenue by country
worked examples on synthetic data.
Three labeled revenue datasets, the country table each one produces and the rule behind every number.
How every example is counted
- Revenue is added under the country the revenue provider puts on the purchase: country_code from RevenueCat, countryCode from Superwall.
- Installs are counted under the country stamped on first_open, which comes from the request IP.
- A country's share is its revenue divided by the total revenue in the range.
- Gross adds up the positive prices. Net takes each charge after store commission and tax, and refunds reduce it.
- Sandbox purchases are not counted.
Every device, user, country and amount is synthetic. The counts come from the same engine as the dashboard's Acquisition card. Setup is in the RevenueCat docs and the Superwall docs.
App revenue by country: install country vs store country
Synthetic data 12 installs in DE, US and BR in one week, plus a purchase from an older install. Installs follow the IP country at first open, revenue follows the store country on the purchase.
| Country | Share | Revenue | Installs | |
|---|---|---|---|---|
| 🇺🇸 United States | 45.0% | $90.00 | 4 | |
| 🇩🇪 Germany | 35.0% | $70.00 | 5 | |
| 🇫🇷 France | 10.0% | $20.00 | — | |
| 🇧🇷 Brazil | 0.0% | — | 3 | |
| No country | 10.0% | $20.00 | — | |
| Total | 100.0% | $200.00 | 12 |
- Germany has 5 installs and $70.00. One of those five devices bought with a US store country, so its $10.00 sits in the US row, which has 4 installs and $90.00.
- Brazil has 3 installs and no purchase, so its revenue shows as a dash, the same mark the dashboard uses for zero.
- France has revenue and no installs. The buyer installed before the week began, so only the renewal falls in the range.
- One purchase arrived without a country. It counts in the $200.00 total and in the Other tier, in no country row, so it shows as No country.
- The sandbox purchase (environment SANDBOX) is not counted anywhere.
Event log (22 events)
| Time (UTC) | Device | User | Event | Country | Props |
|---|---|---|---|---|---|
| 09-04 00:00 | d_a_fr1 | u_a_fr1 | first_open | 🇫🇷 France | |
| 09-07 01:00 | d_a_de1 | u_a_de1 | first_open | 🇩🇪 Germany | |
| 09-07 01:20 | none | u_a_de1 | rc_initial_purchase | 🇩🇪 Germany | {"price":10,"proceeds":7,"price_in_purchased_currency":10,"currency":"USD","commission_percentage":0.3,"tax_percentage":0,"product_id":"pro.monthly","store":"APP_STORE","environment":"PRODUCTION","transaction_id":"tx_a_01","original_transaction_id":"tx_a_01"} |
| 09-07 12:40 | d_a_us1 | u_a_us1 | first_open | 🇺🇸 United States | |
| 09-07 13:00 | none | u_a_us1 | rc_initial_purchase | 🇺🇸 United States | {"price":10,"proceeds":7,"price_in_purchased_currency":10,"currency":"USD","commission_percentage":0.3,"tax_percentage":0,"product_id":"pro.monthly","store":"APP_STORE","environment":"PRODUCTION","transaction_id":"tx_a_04","original_transaction_id":"tx_a_04"} |
| 09-08 00:20 | d_a_br1 | u_a_br1 | first_open | 🇧🇷 Brazil | |
| 09-08 12:00 | d_a_de2 | u_a_de2 | first_open | 🇩🇪 Germany | |
| 09-08 12:20 | none | u_a_de2 | rc_initial_purchase | 🇺🇸 United States | {"price":10,"proceeds":7,"price_in_purchased_currency":10,"currency":"USD","commission_percentage":0.3,"tax_percentage":0,"product_id":"pro.monthly","store":"APP_STORE","environment":"PRODUCTION","transaction_id":"tx_a_02","original_transaction_id":"tx_a_02"} |
| 09-08 23:40 | d_a_us2 | u_a_us2 | first_open | 🇺🇸 United States | |
| 09-09 00:00 | none | u_a_us2 | rc_initial_purchase | 🇺🇸 United States | {"price":60,"proceeds":42,"price_in_purchased_currency":60,"currency":"USD","commission_percentage":0.3,"tax_percentage":0,"product_id":"pro.annual","store":"APP_STORE","environment":"PRODUCTION","transaction_id":"tx_a_05","original_transaction_id":"tx_a_05"} |
| 09-09 11:20 | d_a_br2 | u_a_br2 | first_open | 🇧🇷 Brazil | |
| 09-09 23:00 | d_a_de3 | u_a_de3 | first_open | 🇩🇪 Germany | |
| 09-09 23:20 | none | u_a_de3 | rc_initial_purchase | 🇩🇪 Germany | {"price":60,"proceeds":42,"price_in_purchased_currency":60,"currency":"USD","commission_percentage":0.3,"tax_percentage":0,"product_id":"pro.annual","store":"APP_STORE","environment":"PRODUCTION","transaction_id":"tx_a_03","original_transaction_id":"tx_a_03"} |
| 09-10 10:40 | d_a_us3 | u_a_us3 | first_open | 🇺🇸 United States | |
| 09-10 11:00 | none | u_a_us3 | rc_initial_purchase | 🇺🇸 United States | {"price":10,"proceeds":7,"price_in_purchased_currency":10,"currency":"USD","commission_percentage":0.3,"tax_percentage":0,"product_id":"pro.monthly","store":"APP_STORE","environment":"PRODUCTION","transaction_id":"tx_a_06","original_transaction_id":"tx_a_06"} |
| 09-10 11:20 | none | u_a_fr1 | rc_renewal | 🇫🇷 France | {"price":20,"proceeds":14,"price_in_purchased_currency":20,"currency":"USD","commission_percentage":0.3,"tax_percentage":0,"product_id":"pro.quarterly","store":"APP_STORE","environment":"PRODUCTION","transaction_id":"tx_a_07","original_transaction_id":"tx_a_07"} |
| 09-10 22:20 | d_a_br3 | u_a_br3 | first_open | 🇧🇷 Brazil | |
| 09-11 07:20 | none | u_a_x1 | rc_initial_purchase | none | {"price":20,"proceeds":14,"price_in_purchased_currency":20,"currency":"USD","commission_percentage":0.3,"tax_percentage":0,"product_id":"pro.quarterly","store":"APP_STORE","environment":"PRODUCTION","transaction_id":"tx_a_08","original_transaction_id":"tx_a_08"} |
| 09-11 10:00 | d_a_de4 | u_a_de4 | first_open | 🇩🇪 Germany | |
| 09-11 21:40 | d_a_us4 | u_a_us4 | first_open | 🇺🇸 United States | |
| 09-12 03:20 | none | u_a_test | rc_initial_purchase | 🇺🇸 United States | {"price":10,"proceeds":7,"price_in_purchased_currency":10,"currency":"USD","commission_percentage":0.3,"tax_percentage":0,"product_id":"pro.monthly","store":"APP_STORE","environment":"SANDBOX","transaction_id":"tx_a_09","original_transaction_id":"tx_a_09"} |
| 09-12 09:20 | d_a_de5 | u_a_de5 | first_open | 🇩🇪 Germany |
Gross vs net app revenue by country, with local currency and refunds
Synthetic data Purchases in five countries and four currencies, plus one refund in Germany. The same events read two ways.
| Country | Gross | Net | Refunds | Paid locally |
|---|---|---|---|---|
| 🇺🇸 United States | $80.00 | $56.00 | — | USD 80.00 |
| 🇩🇪 Germany | $70.00 | $7.00 | $60.00 | EUR 63.00 |
| 🇯🇵 Japan | $60.00 | $42.00 | — | JPY 9000 |
| 🇬🇧 United Kingdom | $40.00 | $28.00 | — | GBP 32.00 |
| 🇫🇷 France | $20.00 | $14.00 | — | EUR 18.00 |
| Total | $270.00 | $147.00 | $60.00 |
- Gross adds up the positive prices, $270.00. The refund does not reduce it.
- Net adds up what is left after the store commission and tax, 30% and 0% here, and the refund is subtracted. That gives $147.00.
- The $60.00 refund in Germany takes its net from $49.00 to $7.00.
- Each event keeps the price and currency the buyer paid in, as the log shows. ActivationPal adds up the price the provider sends and does no currency conversion.
Event log (11 events)
| Time (UTC) | Device | User | Event | Country | Props |
|---|---|---|---|---|---|
| 09-07 05:00 | none | u_c_us1 | rc_initial_purchase | 🇺🇸 United States | {"price":60,"proceeds":42,"price_in_purchased_currency":60,"currency":"USD","commission_percentage":0.3,"tax_percentage":0,"product_id":"pro.annual","store":"APP_STORE","environment":"PRODUCTION","transaction_id":"tx_c_01","original_transaction_id":"tx_c_01"} |
| 09-07 15:00 | none | u_c_de1 | rc_initial_purchase | 🇩🇪 Germany | {"price":60,"proceeds":42,"price_in_purchased_currency":54,"currency":"EUR","commission_percentage":0.3,"tax_percentage":0,"product_id":"pro.annual","store":"APP_STORE","environment":"PRODUCTION","transaction_id":"tx_c_de1","original_transaction_id":"tx_c_de1"} |
| 09-08 01:00 | none | u_c_fr1 | rc_initial_purchase | 🇫🇷 France | {"price":10,"proceeds":7,"price_in_purchased_currency":9,"currency":"EUR","commission_percentage":0.3,"tax_percentage":0,"product_id":"pro.monthly","store":"APP_STORE","environment":"PRODUCTION","transaction_id":"tx_c_05","original_transaction_id":"tx_c_05"} |
| 09-08 11:00 | none | u_c_us2 | rc_initial_purchase | 🇺🇸 United States | {"price":10,"proceeds":7,"price_in_purchased_currency":10,"currency":"USD","commission_percentage":0.3,"tax_percentage":0,"product_id":"pro.monthly","store":"APP_STORE","environment":"PRODUCTION","transaction_id":"tx_c_02","original_transaction_id":"tx_c_02"} |
| 09-08 21:00 | none | u_c_gb1 | rc_initial_purchase | 🇬🇧 United Kingdom | {"price":20,"proceeds":14,"price_in_purchased_currency":16,"currency":"GBP","commission_percentage":0.3,"tax_percentage":0,"product_id":"pro.quarterly","store":"APP_STORE","environment":"PRODUCTION","transaction_id":"tx_c_07","original_transaction_id":"tx_c_07"} |
| 09-09 07:00 | none | u_c_de2 | rc_initial_purchase | 🇩🇪 Germany | {"price":10,"proceeds":7,"price_in_purchased_currency":9,"currency":"EUR","commission_percentage":0.3,"tax_percentage":0,"product_id":"pro.monthly","store":"APP_STORE","environment":"PRODUCTION","transaction_id":"tx_c_04","original_transaction_id":"tx_c_04"} |
| 09-09 22:00 | none | u_c_de1 | rc_cancellation | 🇩🇪 Germany | {"price":-60,"proceeds":-42,"price_in_purchased_currency":-54,"currency":"EUR","commission_percentage":0.3,"tax_percentage":0,"product_id":"pro.annual","store":"APP_STORE","environment":"PRODUCTION","transaction_id":"tx_c_de1","original_transaction_id":"tx_c_de1","cancel_reason":"CUSTOMER_SUPPORT"} |
| 09-10 14:40 | none | u_c_jp1 | rc_initial_purchase | 🇯🇵 Japan | {"price":60,"proceeds":42,"price_in_purchased_currency":9000,"currency":"JPY","commission_percentage":0.3,"tax_percentage":0,"product_id":"pro.annual","store":"APP_STORE","environment":"PRODUCTION","transaction_id":"tx_c_09","original_transaction_id":"tx_c_09"} |
| 09-11 05:40 | none | u_c_us3 | rc_initial_purchase | 🇺🇸 United States | {"price":10,"proceeds":7,"price_in_purchased_currency":10,"currency":"USD","commission_percentage":0.3,"tax_percentage":0,"product_id":"pro.monthly","store":"APP_STORE","environment":"PRODUCTION","transaction_id":"tx_c_03","original_transaction_id":"tx_c_03"} |
| 09-12 08:20 | none | u_c_fr2 | rc_initial_purchase | 🇫🇷 France | {"price":10,"proceeds":7,"price_in_purchased_currency":9,"currency":"EUR","commission_percentage":0.3,"tax_percentage":0,"product_id":"pro.monthly","store":"APP_STORE","environment":"PRODUCTION","transaction_id":"tx_c_06","original_transaction_id":"tx_c_06"} |
| 09-12 16:40 | none | u_c_gb2 | rc_initial_purchase | 🇬🇧 United Kingdom | {"price":20,"proceeds":14,"price_in_purchased_currency":16,"currency":"GBP","commission_percentage":0.3,"tax_percentage":0,"product_id":"pro.quarterly","store":"APP_STORE","environment":"PRODUCTION","transaction_id":"tx_c_08","original_transaction_id":"tx_c_08"} |
App revenue by country FAQ
How do you see app revenue by country?
Connect the RevenueCat or Superwall webhook. Each purchase carries its store country, so the Acquisition card's country tab lists installs and revenue per country and the tier tab rolls them into the five pricing tiers.
Why does a country have installs but no revenue?
Installs follow the IP country at first open and revenue follows the store country on the purchase. A traveller, a VPN or a different storefront moves the money to another row, as in the first example.
Is app revenue by country gross or net?
The dashboard shows either. Gross adds up the positive prices. Net takes each charge after store commission and tax, so refunds reduce it. To project revenue from typed numbers, use the app revenue calculator.
More free tools
- App Store account auditPortfolio similarity, review signals and listing concerns, with evidence.Open →
- App revenue calculator12 months of subscription revenue from installs, conversion and price.Open →
- Funnel calculatorStep conversion, drop-off and a chart from the users at each step.Open →
- Funnel analysis examplesWorked mobile funnels on labeled synthetic events, with the counting rules.Open →
- ARPU calculatorGross and net average revenue per user from revenue and users.Open →
- Cohort analysis toolA retention heatmap from weekly cohort sizes and users still active.Open →
- App Store keyword checkerPopularity and difficulty for any keyword, in any country.Open →
- Country pricing tiersEvery country in five pricing tiers, with the discount for each.Open →