Extremely slow query on indexed column in Postgres
There is a subtle problem hidden in your ORDER BY clause:
ORDER BY updated_at DESC 

Would sort NULL values first. I assume you do not want that. Your column updated_at can be NULL (lacks a NOT NULL constraint). The missing constraint should probably be added. Your query should be fixed either way:
SELECT * 
FROM   orders 
WHERE  shop_id = 3828 
ORDER  BY updated_at DESC NULLS LAST
LIMIT  1;
The multicolumn index @Ste Bov mentioned should be adapted accordingly:
CREATE INDEX orders_shop_id_updated_at_idx ON orders (shop_id, updated_at DESC NULLS LAST);
Then you get a basic Index Scan instead of the (almost as fast) Index Scan Backward, and you won't get an additional index condition: Index Cond: (updated_at IS NOT NULL).
Related:

Unused index in range of dates query
Optimizing queries on a range of timestamps (two columns)

Asides
You can save a bit of wasted disk space by optimizing the sequence of columns for your big table (which makes everything a bit faster):
id                 | integer                     | not null default nextval( ...
shop_id            | integer                     |
sent               | boolean                     | default false
name               | varchar(255)                |
total_price        | double precision            |
recovered_at       | timestamp without time zone |
created_at         | timestamp without time zone |
updated_at         | timestamp without time zone |

See:

Configuring PostgreSQL for read performance

Add NOT NULL constraints to all columns that cannot be NULL.
Consider text or varchar instead of varchar(255), timestamptz instead of timestamp and integer for the price (as Cents) or numeric (for fractional numbers) which is an arbitrary precision type and stores your values exactly as given. Never use a lossy floating point type for a &quot;price&quot; or anything to do with money.