Invoice

Monthly invoices for a Google Ads account can be retrieved using the InvoiceService.

Prerequisites

  • Have monthly invoicing enabled for the Google Ads account. See the guides on account billing setups and budgets to learn how to manage billing using the Google Ads API.
  • If set, login-customer-id must specify the customer ID of a manager account that is managing the Google Ads account for which you're retrieving invoices.

Retrieving invoices

To retrieve invoices, you need to request the InvoiceService.ListInvoices method setting all the required fields in the ListInvoicesRequest: customer_id, billing_setup, issue_year, and issue_month.

Here is an example:

PHP

// Issues the request.
$response = $googleAdsClient->getInvoiceServiceClient()->listInvoices(
    $customerId,
    ResourceNames::forBillingSetup($customerId, $billingSetupId),
    // The year needs to be 2019 or later.
    date('Y', $lastMonth),
    MonthOfYear::value(strtoupper(date('F', $lastMonth)))
);

The response is a ListInvoicesResponse object that contains the list of matching Invoices, each of which contains a large set of fields such as:

  • IDs: payments_account_id, payments_profile_id.
  • Time: issue_date, due_date, service_date_range.
  • Amounts: subtotal_amount_micros, tax_amount_micros, total_amount_micros.
  • PDF: pdf_url. See downloading an invoice PDF for instructions.
  • History: corrected_invoice, replaced_invoices.

Getting budget details

An Invoice provides detailed information about related account budgets as a list of AccountBudgetSummary objects in the account_budget_summaries field:

  • IDs: customer, account_budget, purchase_order_number.
  • Time: billable_activity_date_range.
  • Amounts: subtotal_amount_micros, tax_amount_micros, total_amount_micros.

An Invoice also contains other fields when they are relevant:

  • Adjustments: adjustments_subtotal_amount_micros, adjustments_tax_amount_micros, adjustments_total_amount_micros.
  • Regulatory costs: regulatory_costs_subtotal_amount_micros, regulatory_costs_tax_amount_micros, regulatory_costs_total_amount_micros.

Understanding amounts

All the amounts provided in AccountBudgetSummary and Invoice objects are attributable during their service periods and are evaluated according to these rules:

AccountBudgetSummary Evaluation rule
subtotal_amount_micros $account\_budget\_subtotal$ (account budget's pretax)
tax_amount_micros $account\_budget\_tax$ (account budget's tax)
total_amount_micros
$account\_budget\_subtotal + account\_budget\_tax$
Invoice Evaluation rule
adjustments_subtotal_amount_micros $adjustments\_subtotal$ (adjustments' pretax)
regulatory_costs_subtotal_amount_micros $regulatory\_costs\_subtotal$ (regulatory costs' pretax)
adjustments_tax_amount_micros $adjustments\_tax$ (adjustments' tax)
regulatory_costs_tax_amount_micros $regulatory\_costs\_tax$ (regulatory costs' tax)
adjustments_total_amount_micros
$adjustments\_subtotal + adjustments\_tax$
regulatory_costs_total_amount_micros
$regulatory\_costs\_subtotal + regulatory\_costs\_tax$
subtotal_amount_micros $adjustments\_subtotal + \sum_{i=1}^n account\_budget\_subtotal_i$
tax_amount_micros $adjustments\_tax + regulatory\_costs\_tax + \sum_{i=1}^n account\_budget\_tax_i$
total_amount_micros
$subtotal + regulatory\_costs\_subtotal + tax$

Here is an example of how the retrieved invoices can be iterated on:

PHP

// Iterates over all invoices retrieved and prints their information.
foreach ($response->getInvoices() as $invoice) {
    /** @var Invoice $invoice */
    printf(
        "- Found the invoice '%s':" . PHP_EOL .
        "  ID (also known as Invoice Number): '%s'" . PHP_EOL .
        "  Type: %s" . PHP_EOL .
        "  Billing setup ID: '%s'" . PHP_EOL .
        "  Payments account ID (also known as Billing Account Number): '%s'" . PHP_EOL .
        "  Payments profile ID (also known as Billing ID): '%s'" . PHP_EOL .
        "  Issue date (also known as Invoice Date): %s" . PHP_EOL .
        "  Due date: %s" . PHP_EOL .
        "  Currency code: %s" . PHP_EOL .
        "  Service date range (inclusive): from %s to %s" . PHP_EOL .
        "  Adjustments: subtotal '%.2f', tax '%.2f', total '%.2f'" . PHP_EOL .
        "  Regulatory costs: subtotal '%.2f', tax '%.2f', total '%.2f'" . PHP_EOL .
        "  Replaced invoices: '%s'" . PHP_EOL .
        "  Amounts: subtotal '%.2f', tax '%.2f', total '%.2f'" . PHP_EOL .
        "  Corrected invoice: '%s'" . PHP_EOL .
        "  PDF URL: '%s'" . PHP_EOL .
        "  Account budgets:" . PHP_EOL,
        $invoice->getResourceName(),
        $invoice->getId(),
        InvoiceType::name($invoice->getType()),
        $invoice->getBillingSetup(),
        $invoice->getPaymentsAccountId(),
        $invoice->getPaymentsProfileId(),
        $invoice->getIssueDate(),
        $invoice->getDueDate(),
        $invoice->getCurrencyCode(),
        $invoice->getServiceDateRange()->getStartDate(),
        $invoice->getServiceDateRange()->getEndDate(),
        self::microToBase($invoice->getAdjustmentsSubtotalAmountMicros()),
        self::microToBase($invoice->getAdjustmentsTaxAmountMicros()),
        self::microToBase($invoice->getAdjustmentsTotalAmountMicros()),
        self::microToBase($invoice->getRegulatoryCostsSubtotalAmountMicros()),
        self::microToBase($invoice->getRegulatoryCostsTaxAmountMicros()),
        self::microToBase($invoice->getRegulatoryCostsTotalAmountMicros()),
        $invoice->getReplacedInvoices()
            ? implode(
                "', '",
                iterator_to_array($invoice->getReplacedInvoices()->getIterator())
            ) : 'none',
        self::microToBase($invoice->getSubtotalAmountMicros()),
        self::microToBase($invoice->getTaxAmountMicros()),
        self::microToBase($invoice->getTotalAmountMicros()),
        $invoice->getCorrectedInvoice() ?: 'none',
        $invoice->getPdfUrl()
    );
    foreach ($invoice->getAccountBudgetSummaries() as $accountBudgetSummary) {
        /** @var AccountBudgetSummary $accountBudgetSummary */
        printf(
            "  - Account budget '%s':" . PHP_EOL .
            "      Name (also known as Account Budget): '%s'" . PHP_EOL .
            "      Customer (also known as Account ID): '%s'" . PHP_EOL .
            "      Customer descriptive name (also known as Account): '%s'" . PHP_EOL .
            "      Purchase order number (also known as Purchase Order): '%s'" . PHP_EOL .
            "      Billing activity date range (inclusive): from %s to %s" . PHP_EOL .
            "      Amounts: subtotal '%.2f', tax '%.2f', total '%.2f'" . PHP_EOL,
            $accountBudgetSummary->getAccountBudget(),
            $accountBudgetSummary->getAccountBudgetName() ?: 'none',
            $accountBudgetSummary->getCustomer(),
            $accountBudgetSummary->getCustomerDescriptiveName() ?: 'none',
            $accountBudgetSummary->getPurchaseOrderNumber() ?: 'none',
            $accountBudgetSummary->getBillableActivityDateRange()->getStartDate(),
            $accountBudgetSummary->getBillableActivityDateRange()->getEndDate(),
            self::microToBase($accountBudgetSummary->getSubtotalAmountMicros()),
            self::microToBase($accountBudgetSummary->getTaxAmountMicros()),
            self::microToBase($accountBudgetSummary->getTotalAmountMicros())
        );
    }
}

Downloading an invoice PDF

Any invoice can be downloaded as a PDF file. Once you have retrieved the Invoice, you need to send an HTTP request for the URL that is stored in its pdf_url field. This request must be authenticated using the same Google account used to retrieve the invoice; that is, you need to specify an OAuth access token generated using the Google account in the Authorization: Bearer request header:

curl --request GET \
     --header "Authorization: Bearer access token" \
     Invoice.pdf_url > filename.pdf

The result is an invoice PDF content stored in the file filename.pdf.

Common error codes

Scenario Error Code
Missing or empty billing setup, issue year, or issue month. RequestError.REQUIRED_FIELD_MISSING
Can't parse given billing setup, issue year, or issue month. FieldError.INVALID_VALUE
Request is for invoices issued before January 1, 2019. InvoiceError.YEAR_MONTH_TOO_OLD
Request is for a customer who doesn't receive invoices. InvoiceError.NOT_INVOICED_CUSTOMER
User doesn't have permission to view invoices of the billing setup. AuthorizationError.ACTION_NOT_PERMITTED