Updated to show new code / new error @ 10/12/2020 11:30
I need to copy invoices from my website to xero using their API. I managed to get this working using the OAuth 1 but now need to update to OAuth2.0.
I've installed xero-php-oauth2-starter which connects and works fine with the examples. e.g. if I click the example "Create one Contact" link, the demo contact is created in xero.
As such, I know the link is working.
I've been looking around trying to find an example of how to create an invoice using the API but am finding it incredibly hard to work out.
Below is what I currently have in my xero api folder:
<?php
ini_set('display_errors', 'On');
require __DIR__ . '/vendor/autoload.php';
require_once('storage.php');
// Use this class to deserialize error caught
use XeroAPI\XeroPHP\AccountingObjectSerializer;
// Storage Classe uses sessions for storing token > extend to your DB of choice
$storage = new StorageClass();
$xeroTenantId = (string)$storage->getSession()['tenant_id'];
if ($storage->getHasExpired()) {
$provider = new \League\OAuth2\Client\Provider\GenericProvider([
'clientId' => 'REMOVED',
'clientSecret' => 'REMOVED',
'redirectUri' => 'https://REMOVED/callback.php',
'urlAuthorize' => 'https://login.xero.com/identity/connect/authorize',
'urlAccessToken' => 'https://identity.xero.com/connect/token',
'urlResourceOwnerDetails' => 'https://api.xero.com/api.xro/2.0/Organisation'
]);
$newAccessToken = $provider->getAccessToken('refresh_token', [
'refresh_token' => $storage->getRefreshToken()
]);
// Save my token, expiration and refresh token
$storage->setToken(
$newAccessToken->getToken(),
$newAccessToken->getExpires(),
$xeroTenantId,
$newAccessToken->getRefreshToken(),
$newAccessToken->getValues()["id_token"] );
}
$config = XeroAPI\XeroPHP\Configuration::getDefaultConfiguration()->setAccessToken( (string)$storage->getSession()['token'] );
$apiInstance = new XeroAPI\XeroPHP\Api\AccountingApi(
new GuzzleHttp\Client(),
$config
);
$invoices = '{"invoices":[{
"type":"Invoice.TypeEnum.ACCREC",
"contact":{"contactID":"97af3783-0f32-42be-a06d-8c586c8aa8ec"},
"lineItems":[{
"description":"Acme Tires",
"quantity":2,
"unitAmount":20,
"accountCode":"000",
"taxType":"NONE",
"lineAmount":40
}],
"date":"2019-03-11",
"dueDate":"2018-12-10",
"reference":"Website Design",
"status":"Invoice.StatusEnum.DRAFT"
}]}';
foreach ($import as $invoice) {
//create contact
$xcontact = new XeroAPI\XeroPHP\Models\Accounting\Contact();
$xcontact->setName($contactname);
//create line item
$lineItems = array();
foreach ($invoice['invoiceLineItems'] as $line) {
$newLine = new XeroAPI\XeroPHP\Models\Accounting\LineItem();
$newLine->setDescription($invoice['message']."\n".$line['description']);
$newLine->setQuantity($line['quantity']);
$newLine->setUnitAmount($line['amount']);
$newLine->setAccountCode('200');
$lineItems[] = $newLine;
}
$xinvoice = new XeroAPI\XeroPHP\Models\Accounting\Invoice();
$xinvoice->setType("ACCREC");
$xinvoice->setStatus("AUTHORISED");
$xinvoice->setDate($invoice['invoiceDate']);
$xinvoice->setDueDate($invoice['dueDate']);
$xinvoice->setLineAmountTypes("NoTax");
$xinvoice->setContact($xcontact);
$xinvoice->setLineItems($lineItems);
$xinvoice->setInvoiceNumber("INV-0".$invoice['invoiceNumber']);
$xinvoices['Invoices'][] = $xinvoice;
}
$apiResponse = $apiInstance->createInvoices($xeroTenantId,$xinvoices);
$summarize_errors = false; // 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
?>
gives
Fatal error: Uncaught InvalidArgumentException: Missing the required parameter $invoices when calling createInvoices
which I can't seem to find any details on.
I've created the product "Acme Tires" in xero just incase that was causing the issue (I remember in auth 1 that it wouldn't work if the product wasn't listed first).
Any help would be greatly appreciated.