Feels like a bug in the json package.
You can work around it with a custom Unmarshaller, like this, although it may be annoying if you've got a complex struct:
func (p *Product) UnmarshalJSON(b []byte) error {
m := map[string]string{}
err := json.Unmarshal(b, &m)
if err != nil {
return err
}
if priceStr, ok := m["price"]; ok {
p.Price, _ = strconv.Atoi(priceStr)
}
return nil
}