1

更新以显示新代码/新错误 @ 10/12/2020 11:30

我需要使用他们的 API 将发票从我的网站复制到 xero。我设法使用 OAuth 1 使其正常工作,但现在需要更新到 OAuth2.0。

我已经安装了 xero-php-oauth2-starter,它可以与示例连接并正常工作。例如,如果我单击示例“创建一个联系人”链接,演示联系人将在 xero 中创建。

因此,我知道该链接有效。

我一直在四处寻找如何使用 API 创建发票的示例,但发现它非常难以解决。

以下是我目前在我的 xero api 文件夹中的内容:

<?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

?>

Fatal error: Uncaught InvalidArgumentException: Missing the required parameter $invoices when calling createInvoices

我似乎找不到任何细节。

我已经在 xero 中创建了产品“Acme Tires”,以防万一这是导致问题的原因(我记得在 auth 1 中,如果产品没有首先列出,它将无法工作)。

任何帮助将不胜感激。

4

1 回答 1

1

使用新的 PHP SDK,您需要传递一个 Invoice 对象数组。

下面基于预先存在的数组 ($import) 的内容创建发票。

您会看到需要将行项目放入一个数组中,然后将其插入到发票对象中。然后将发票本身插入到传递给 API 的数组中。

<?php
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);
?>

更新:

$apiInstance 将在之前创建,例如。

$apiInstance = new XeroAPI\XeroPHP\Api\AccountingApi(
    new GuzzleHttp\Client(),
    $config
  );

$import 是原始脚本中的一个数组,其中包含我要导入的原始数据。您需要将其替换为您自己的数据。

更新 2:

要使用您的原始数据,您需要删除

foreach ($import as $invoice) {

环形。并用您自己的数据替换对 $invoice 的引用。

例如:

//create contact
    $xcontact = new XeroAPI\XeroPHP\Models\Accounting\Contact();
    $xcontact->setName($contactname);

会成为:

//create contact
    $xcontact = new XeroAPI\XeroPHP\Models\Accounting\Contact();
    $xcontact->setContactId("97af3783-0f32-42be-a06d-8c586c8aa8ec");
于 2020-12-10T10:30:59.787 回答