Why do I get invalid_grant when requesting access token?

This signifies that the code is unrecognized or has already been used, or that the redirect_uri does not match the one given when requesting the user’s authorization.

code values expire after 10 minutes and can only be used once.

redirect_uri values must match exactly. Check for http and https mismatch or perhaps a trailing / on urls.