title: MailChimp OAuth2 Access Token
body: <p>This question is similar to others that have already been asked, but the answers haven't helped and there's a key piece that I think is missing.  I'm at step 4 of the MailChimp OAuth2 flow, which requires an out-of-band post to the authorize url (<a href="http://developer.mailchimp.com/documentation/mailchimp/guides/how-to-use-oauth2/" rel="nofollow noreferrer">see here</a>).  It keeps returning the error: invalid_grant, which I understand can indicate a number of different errors.  Here's my code (I'm using Yii2).</p>
  
  <pre><code>// Controller action (authorize)
  public function actionMailchimpAuthorize()
  {
      $redirect_uri = Url::toRoute(['controller/mailchimp-token'], 'https');
      $base_uri = 'https://login.mailchimp.com/oauth2/authorize';
      $params = '?response_type=code&amp;client_id=' . Model::CLIENT_ID . '&amp;redirect_uri=' . urlencode($redirect_uri);
      $authorize_uri = $base_uri . $params;
  
      return $this-&gt;render('mailchimpAuthorize', [
          'authorize_uri' =&gt; $authorize_uri,
      ]);
  }
  
  // Controller action (token)
  public function actionMailchimpToken($code=NULL)
  {
          $redirect_uri = Url::toRoute(['controller/mailchimp-token'], 'https');
          $token_uri = 'https://login.mailchimp.com/oauth2/token';
          $params = [
              'grant_type' =&gt; 'authorization_code',
              'client_id' =&gt; Model::CLIENT_ID,
              'client_secret' =&gt; Model::CLIENT_SECRET,
              'redirect_uri' =&gt; urlencode($redirect_uri),
              'code' =&gt; $code,
          ];
          $user_agent = 'oauth2-draft-v10';
          $headers = ['Accept: application/json'];
          $res = Utility::post($token_uri, $params, $user_agent, $headers);
          var_dump($res);
  }
  
  // Utility
   public function post($url, $params, $user_agent = NULL, $headers = NULL)
  {
          $ch = curl_init($url);  
          curl_setopt($ch, CURLOPT_ENCODING, "");
          curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
          curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
          $post = http_build_query($params);
          curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
          isset($user_agent) ? curl_setopt($ch, CURLOPT_USERAGENT, $user_agent) : NULL;
          isset($headers) ? curl_setopt($ch, CURLOPT_HTTPHEADER, $headers) : NULL;
          $res = curl_exec($ch);
          curl_close($ch);
          return $res;   
  }
  </code></pre>
  
  <p>Answers here on SO make a big deal about the redirect URIs matching.  But there are three places to enter a return uri: In Mailchimp when you register the app, in the authorization url, and the token url.  Do all three need to macth exactly, or only the auth and token URIs?  I've tried various combinations to no avail. My problem may be something different, but this the only thing that I'm unclear about (I think). As with many before me, I'm going crazy with this one.</p>