My suggestion is to give the option to enter generic information but don't let that become the default.
* allow the user to enter a free-form address, normalize it and then prompt the user for confirmation that the normalization was correct.
* Allow the user to edit fields on the confirmation page.
* Log any differences between the normalization and what the user changes for further refinement of the normalization process.
* Don't require fields that may not be relevant to all addresses that you plan to capture.
* Allow some sort of contact avenue on the address confirmation page so that they can complain when the interface doesn't allow them to properly enter their address. (If people hit a brickwall while trying to submit their address, they are more likely to just give up if they have to hunt down contact information. At the very least, if there is an easy way for them to complain, you get some sort of feedback even if you lose them as a customer.)
Is there some huge performance advantage in having the state field be an Id into a states table? Perhaps it would make updates easier if they ever rename Washington?
Why not normalize the name? There must be lots of Johns in your DB
It makes more sense to normalize it at the beginning in order to give the user a chance to approve that it was processed correctly. You could just do the normalization at the point when you need to interact with the 3rd-party services, but then it's hidden in the back-end so you have to be confident in your normalization processing.
You could roll out a solution where the confirmation page is just there to allow the user to approve that normalization works on their free-form address, but still store it as a chuck of text in the database. Then when you are confident enough in your normalization process, you could just remove the user confirmation part.
Sure, there are other ways to normalize an address from freetext input, but they often require using a third party system from FedEx or UPS.