SUM over distinct rows with multiple joins
Since there can be multiple payments and multiple extras per item, you run into a &quot;proxy cross join&quot; between those two tables. Aggregate rows per item_id before joining to item and it should all be correct:
SELECT i.country         AS group_by
     , COUNT(*)          AS item_count
     , SUM(i.price)      AS cost
     , SUM(p.sum_amount) AS earned
     , SUM(e.sum_amount) AS extra_earned
FROM  items i
LEFT  JOIN (
   SELECT item_id, SUM(amount) AS sum_amount
   FROM   payments
   GROUP  BY 1
   ) p ON p.item_id = i.id
LEFT  JOIN (
   SELECT item_id, SUM(amount) AS sum_amount
   FROM   extras
   GROUP  BY 1
   ) e ON e.item_id = i.id
GROUP BY 1;

Consider the &quot;fishmarket&quot; example:

Two SQL LEFT JOINS produce incorrect result

To be precise, SUM(i.price) would be incorrect after joining to a single n-table, which multiplies each price by the number of related rows. Doing it twice just makes it worse - and also potentially computationally expensive.
Oh, and since we do not multiply rows in items now, we can just use the cheaper count(*) instead of count(DISTINCT i.id). (id being NOT NULL PRIMARY KEY.)
SQL Fiddle.
But if I want to filter by items.created?
Addressing your comment.
It depends. Can we apply the same filter to payments.created and extras.created?
If yes, then just add the filters in the subqueries as well. (Does not seem likely in this case.)
If no, but we are still selecting most items, the above query would still be most efficient. Some of the aggregations in the subqueries are eliminated in the joins, but that's still cheaper than more complex queries.
If no, and we are selecting a small fraction of items, I suggest correlated subqueries or LATERAL joins. Examples:

Multiple array_agg() calls in a single query