The main area of concern is handling unexpected problems while sending
the Payment message, or receiving the corresponding PaymentACK message.
For example, in case of a transport layer failure or non-200 HTTP status
code while sending the Payment message, what should the wallet software
do next? Is it safe to re-send the Payment message? I'd propose that for
any transport failure or 500 status code, the client retries after a
delay (suggested at 30-60 seconds). For 400 status codes, the request
should not be repeated, and as such the user should be alerted and a
copy of the Payment message saved to be resent later.

Why does error handling have to be standardized?

I generally think that wallet software should be free to do whatever gives the user the best experience, so I'm in favor of restricting BIPs to things that must be standardized so that different implementations inter-operate.
 
For 300 (redirect and similar) status codes, is it considered safe to
follow redirects? I think we have to, but good to make it clear in the
specification.

Referencing whatever RFCs defines how to fetch URLs would be the best way to do this. Submit a pull request.
 

On the merchant's side; I think it would be useful for there to be
guidance for handling of errors processing Payment messages. I'd suggest
that Payment messages should have a fixed maximum size to avoid merchant
systems theoretically having to accept files of any size; 10MB would
seem far larger than in any way practical, and therefore a good maximum
size?

PaymentRequests are limited to 50,000 bytes. I can't think of a reason why Payment messages would need to be any bigger than that. Submit a pull request to the existing BIP.
 
A defined maximum time to wait (to avoid DDoS via connection
holding) might be useful too, although I'd need to do measurements to
find what values are tolerable.

Implementation detail that doesn't belong in the spec, in my humble opinion.
 
I would like to have the protocol state that merchant systems should
handle repeatedly receiving the same Payment message, and return an
equivalent (if not identical) PaymentACK to each. This is important in
case of a network failure while the client is sending the Payment
message, as outlined above.

I think this should be left to implementations to work out.
 
Lastly, I'm wondering about potential timing issues with transactions;
if a merchant system wants to see confirmation of a transaction before
sending a PaymentACK...

.... not a good idea. The user should get feedback right away. Poking a "pay now" button and then waiting more than a second or three to get "your payment has been received and is being processed" is terrible UI.


--
--
Gavin Andresen