title: Xero OAuth2 Questions
body: <p>I have migrated my website to Xero 2.0 and it works, for creating Invoices. However after a few hours i have to reauthorise by clicking on the <a href="https://something.com/xero-oauth2/authorization.php" rel="nofollow noreferrer">https://something.com/xero-oauth2/authorization.php</a> file in the browser, reconnecting to the Xero account, otherwise my customers see something similar to the below ...</p>
  <p>Fatal error: Uncaught BadMethodCallException: Required parameter not passed: &quot;refresh_token&quot; in /var/www/vhosts/something.com/httpdocs/xero-oauth2/vendor/league/oauth2-client/src/Tool/RequiredParameterTrait.php:35 Stack trace: #0 /var/www/vhosts/something.com/httpdocs/xero-oauth2/vendor/league/oauth2-client/src/Tool/RequiredParameterTrait.php(53): League\OAuth2\Client\Grant\AbstractGrant-&gt;checkRequiredParameter('refresh_token', Array) #1 /var/www/vhosts/nasschools.org.uk/httpdocs/xero-oauth2/vendor/league/oauth2-client/src/Grant/AbstractGrant.php(76): League\OAuth2\Client\Grant\AbstractGrant-&gt;checkRequiredParameters(Array, Array) #2 /var/www/vhosts/something.com/httpdocs/xero-oauth2/vendor/league/oauth2-client/src/Provider/AbstractProvider.php(535): League\OAuth2\Client\Grant\AbstractGrant-&gt;prepareRequestParameters(Array, Array) #3 /var/www/vhosts/something.com/httpdocs/xero-oauth2/createInvoice.php(160): League\OAuth2\Client\Provider\AbstractProvider-&gt;getAccessToken(Object(League\OAuth2\Client\Grant\Refre in /var/www/vhosts/something.com/httpdocs/xero-oauth2/vendor/league/oauth2-client/src/Tool/RequiredParameterTrait.php on line 35</p>
  <p>Is there anything clearly wrong with this?</p>
  <pre><code>            &lt;?php 
  
              $storage = new StorageClass();
              $xeroTenantId = (string)$storage-&gt;getSession()['tenant_id'];
  
              if ($storage-&gt;getHasExpired()) {
                  $provider = new \League\OAuth2\Client\Provider\GenericProvider([
                      'clientId' =&gt; 'XXXXXX',
                      'clientSecret' =&gt; 'XXXXXX',
                      'redirectUri' =&gt; 'https://something.com/xero-oauth2/callback.php',
                      'urlAuthorize' =&gt; 'https://login.xero.com/identity/connect/authorize',
                      'urlAccessToken' =&gt; 'https://identity.xero.com/connect/token',
                      'urlResourceOwnerDetails' =&gt; 'https://api.xero.com/api.xro/2.0/Organisation'
                  ]);
  
                  $newAccessToken = $provider-&gt;getAccessToken('refresh_token', [
                      'refresh_token' =&gt; $storage-&gt;getRefreshToken()
                  ]);
  
                  // Save my token, expiration and refresh token
                  $storage-&gt;setToken(
                      $newAccessToken-&gt;getToken(),
                      $newAccessToken-&gt;getExpires(),
                      $xeroTenantId,
                      $newAccessToken-&gt;getRefreshToken(),
                      $newAccessToken-&gt;getValues()[&quot;id_token&quot;]);
              }
  
              // Configure OAuth2 access token for authorization: OAuth2
              $config = XeroAPI\XeroPHP\Configuration::getDefaultConfiguration()-&gt;setAccessToken((string)$storage-&gt;getSession()['token']);
              $config-&gt;setHost(&quot;https://api.xero.com/api.xro/2.0&quot;);        
  
              $apiInstance = new XeroAPI\XeroPHP\Api\AccountingApi(
                new GuzzleHttp\Client(),
                $config
              );
  
              $xero_tenant_id = $xeroTenantId; // string | Xero identifier for Tenant
  
              // \XeroAPI\XeroPHP\Models\Accounting\Invoices | Invoices with an array of invoice objects in body of request
              $summarize_errors = true; // bool | If false return 200 OK and mix of successfully created objects and any with validation errors
              $unitdp = 4; // int | e.g. unitdp=4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts
  
  
              $purchaseNumber = str_replace(&quot;&amp;&quot;, &quot;&amp;amp;&quot;, $_SESSION['purchasenumber']);
              $schoolOrGname = str_replace(&quot;&amp;&quot;, &quot;&amp;amp;&quot;, $_SESSION['schoolorgname1']);
              $billingEmail = str_replace(&quot;&amp;&quot;, &quot;&amp;amp;&quot;, $_SESSION['billingemail']);
              $billingAddress = str_replace(&quot;&amp;&quot;, &quot;&amp;amp;&quot;, $_SESSION['billingaddress']);
              $billingCity = str_replace(&quot;&amp;&quot;, &quot;&amp;amp;&quot;, $_SESSION['billingcity']);
              $billingPostalCode = str_replace(&quot;&amp;&quot;, &quot;&amp;amp;&quot;, $_SESSION['billingpostcode']);
              $billingFullName = str_replace(&quot;&amp;&quot;, &quot;&amp;amp;&quot;, $_SESSION['billingfullname']);
              $date = str_replace(&quot;&amp;&quot;, &quot;&amp;amp;&quot;, $_SESSION['now']);
              $dueDate = str_replace(&quot;&amp;&quot;, &quot;&amp;amp;&quot;, $_SESSION['thirty']);
              $eventTitle = str_replace(&quot;&amp;&quot;, &quot;&amp;amp;&quot;, $_SESSION['eventtitle']);
              $eventPrice = str_replace(&quot;&amp;&quot;, &quot;&amp;amp;&quot;, $_SESSION['eventprice']);
  
  
              $address = new Address();
              $address-&gt;setAddressType('POBOX');
              $address-&gt;setAddressLine1($billingAddress);
              $address-&gt;setCity($billingCity);
              $address-&gt;setPostalCode($billingPostalCode);
              $address-&gt;setAttentionTo($billingFullName);
  
              $contact = new Contact();
              $contact-&gt;setName($schoolOrGname)
                  -&gt;setContactStatus('ACTIVE')
                  -&gt;setEmailAddress($billingEmail)
                  -&gt;setAddresses([$address]);
  
              $lineItem = new LineItem();
              $lineItem-&gt;setDescription($eventTitle)
                  -&gt;setQuantity(1)
                  -&gt;setAccountCode(4002)
                  -&gt;setUnitAmount($eventPrice)
                  -&gt;setTaxAmount(0)
                  -&gt;setTaxType('NONE');
  
              $invoice = new Invoice();
              $invoice-&gt;setDate($date)
                  -&gt;setDueDate($dueDate)
                  -&gt;setLineAmountTypes('Exclusive')
                  -&gt;setType('ACCREC')
                  -&gt;setReference($_SESSION['purchasenumber'])
                  -&gt;setStatus('AUTHORISED')
                  -&gt;setContact($contact)
                  -&gt;setLineItems([$lineItem]);
  
              try {
                  $result = $apiInstance-&gt;createInvoices($xero_tenant_id, $invoice, $summarize_errors, $unitdp);
                  header(&quot;Location: https://something.com/order-confirmation/&quot;);
              } catch (Exception $e) {
  
                  print_r($e);
                  echo '&lt;br/&gt;&lt;br/&gt;Exception when calling AccountingApi-&gt;createInvoices: ', $e-&gt;getMessage(), PHP_EOL;
              }
              ?&gt;
  </code></pre>