Without seeing the response for why you're receiving the 403, you should be able to get that from the response body for the cURL request, it's hard to trouble shoot this effectively. The most common issue is that there is an encoding failure in something in the URL. This can often times happen in the redirect_uri parameter. If you've already checked these values, can you reply with the details of the 403 error you're receiving?
On another note, we do offer a fully functional PHP implementation of OAuth 2.0 with our PHP wrapper library. We highly recommend using that as it can save you a lot of time in serializing payloads, implementing OAuth and other detail pieces that can consume lots of time. Let us know if there is something missing or a reason why you decided not to use that, we'd be very interested to understand how we can make it better. You can find our PHP wrapper here: https://github.com/constantcontact/php-sdk
Thanks for the reply. Yes, the 403 response after my cURL access token request is:
You don't have permission to access /oauth2/oauth/siteowner/authorize on this server.