Reminder: v201702 will be sunset on February 28, 2018.

DFP Sales Manager Reconciliation

This guide explains the reconciliation services and shows you how to retrieve and adjust your billing and delivery numbers.

Primer

Before you start working with the reconciliation services, it's important to have a solid understanding of the reconciliation process in DFP. In the API, this process is handled by the entities outlined below. This diagram shows their relationship. Reconciliation Entities

ReconciliationReport

The ReconciliationReport object represents the top level parent of a billing period's delivery data. ReconciliationReports have a read-only computed status of DRAFT, RECONCILED, or REVERTED. This status is derived from the status of the ReconciliationReport's orders. For example, if all the ReconciliationOrderReports are RECONCILED, then the ReconciliationReport status will be RECONCILED as well.

The ReconciliationReport's ID is required when retrieving ReconciliationReportRows or ReconciliationOrderReports.

Editable Fields
ReconciliationReport.notes

ReconciliationOrderReport

The ReconciliationOrderReport represents one order in a reconciliation report. Once you have reviewed and adjusted reconciliation information in the line items for the order, you can submit the ReconciliationOrderReport. If you need to revise the delivery or revenue data, you can revert the ReconciliationOrderReport.

Editable Fields
ReconciliationOrderReport.proposalGrossBillableRevenueManualAdjustment

ReconciliationLineItemReport

The ReconciliationLineItemReport contains the delivery and billing data for a single line item within a billing period. You can set the volume for a third party ad server, add a manual volume adjustment, or override the billable revenue entirely.

Editable Fields
ReconciliationLineItemReport.reconciliationSource
ReconciliationLineItemReport.thirdPartyVolume
ReconciliationLineItemReport.manualVolume
ReconciliationLineItemReport.billableRevenueOverrides

ReconciliationReportRow

The ReconciliationReportRow contains the delivery data at the creative level. It is uniquely identified by its reconciliation report, line item, and creative. It has a thirdPartyVolume field for entering delivery information from a third party ad server and a manualVolume field if you need to override the DFP or third party volumes.

Editable Fields
ReconciliationReportRow.billFrom
ReconciliationReportRow.thirdPartyVolume
ReconciliationReportRow.manualVolume
ReconciliationReportRow.comments

Retrieving delivery numbers for a billing period

To retrieve a particular month's reconciliation report, you can filter on the report's start date.

Java


  ReconciliationReportServiceInterface reconciliationReportService =
      dfpServices.get(session, ReconciliationReportServiceInterface.class);

  // Get the NetworkService.
  NetworkServiceInterface networkService =
      dfpServices.get(session, NetworkServiceInterface.class);

  // Get the first day of last month in your network's time zone.
  Network network = networkService.getCurrentNetwork();
  DateTime lastMonth = new DateTime(DateTimeZone.forID(network.getTimeZone()))
      .minusMonths(1).dayOfMonth().withMinimumValue();

  // Create a statement to select reconciliation reports.
  StatementBuilder statementBuilder = new StatementBuilder()
      .where("startDate = :startDate")
      .orderBy("id ASC")
      .limit(1)
      .withBindVariableValue("startDate", lastMonth.toString("YYYY-MM-dd"));

  // Get the reconciliation report.
  ReconciliationReportPage page =
      reconciliationReportService.getReconciliationReportsByStatement(
          statementBuilder.toStatement());

Python


# Initialize appropriate service.
reconciliation_report_service = client.GetService(
    'ReconciliationReportService', version='v201705')

first_of_the_month = date.today().replace(day=1)
last_month = first_of_the_month - timedelta(days=1)

# Create a statement to select reconciliation reports.
statement = (dfp.StatementBuilder()
             .Where('startDate = :startDate')
             .WithBindVariable('startDate', last_month))

# Retrieve a small amount of reconciliation reports at a time, paging
# through until all reconciliation reports have been retrieved.
while True:
  response = (
      reconciliation_report_service
      .getReconciliationReportsByStatement(
          statement.ToStatement()))
  if 'results' in response:
    for reconciliation_report in response['results']:
      # Print out some information for each reconciliation report.
      print(
          'Reconciliation report with ID "%d" and start date "%s" was found.'
          '\n' % (reconciliation_report['id'],
                  last_month.strftime('%Y-%m-01')))
    statement.offset += dfp.SUGGESTED_PAGE_LIMIT
  else:
    break

PHP


    $reconciliationReportService =
        $dfpServices->get($session, ReconciliationReportService::class);

    $networkService = $dfpServices->get($session, NetworkService::class);
    $network = $networkService->getCurrentNetwork();

    // Create a statement to select reconciliation reports.
    $pageSize = StatementBuilder::SUGGESTED_PAGE_LIMIT;
    $statementBuilder = (new StatementBuilder())
        ->where('startDate = :startDate')
        ->orderBy('id ASC')
        ->limit($pageSize)
        ->withBindVariableValue(
            'startDate',
            DfpDateTimes::fromDateTime(
                new DateTime(
                    'first day of last month',
                    new DateTimeZone($network->getTimeZone())
                )
            )->getDate()
        );

    $page = $reconciliationReportService->getReconciliationReportsByStatement(
        $statementBuilder->toStatement());

From there, you can use the ReconciliationReport's ID to retrieve all the orders, line items, or creatives for that report. The following example code shows a filter to retrieve a single report's line items.

Java


  // Create a statement to select reconciliation line item reports.
  StatementBuilder statementBuilder = new StatementBuilder()
      .where("reconciliationReportId = :reconciliationReportId AND lineItemId != :lineItemId")
      .orderBy("lineItemId ASC")
      .limit(StatementBuilder.SUGGESTED_PAGE_LIMIT)
      .withBindVariableValue("reconciliationReportId", reconciliationReportId)
      .withBindVariableValue("lineItemId", 0);

Python


  # Create a statement to select reconciliation line item reports.
  statement = (dfp.StatementBuilder()
               .Where(('reconciliationReportId = :reconciliationReportId AND '
                       'lineItemId != :lineItemId'))
               .OrderBy('lineItemId', ascending=True)
               .WithBindVariable('reconciliationReportId',
                                 RECONCILIATION_REPORT_ID)
               .WithBindVariable('lineItemId', 0))

PHP


    // Create a statement to select reconciliation line item reports.
    $pageSize = StatementBuilder::SUGGESTED_PAGE_LIMIT;
    $statementBuilder = (new StatementBuilder())
        ->where('reconciliationReportId = :reconciliationReportId AND '
            . 'lineItemId != :lineItemId')
        ->orderBy('lineItemId ASC')
        ->limit($pageSize)
        ->withBindVariableValue(
            'reconciliationReportId', $reconciliationReportId)
        ->withBindVariableValue('lineItemId', 0);

Reconciling revenue at the line item level

You can use the ReconciliationLineItemReportService to enter delivery data from third party ad servers at the line item level. If you need to reconcile DFP's delivery numbers, you can use a manual volume as demonstrated here. This is analogous to editing the reconciled volume cell in the DFP UI.

Java


  // Set and use a manual volume for billing. This example splits the difference between DFP
  // and the third party volume.
  lineItemReport.setManualVolume(
      (lineItemReport.getDfpVolume() + lineItemReport.getThirdPartyVolume()) / 2);
  lineItemReport.setReconciliationSource(BillFrom.MANUAL);

  ReconciliationLineItemReport[] updatedLineItemReports =
      reconciliationLineItemReportService.updateReconciliationLineItemReports(
          new ReconciliationLineItemReport[] {lineItemReport});

Python


  # Set and use a manual volume for billing. This example splits the difference
  # between DFP and the third party volume.
  line_item_report['manualVolume'] = (line_item_report['dfpVolume'] +
                                      line_item_report['thirdPartyVolume']) / 2
  line_item_report['reconciliationSource'] = 'MANUAL'

  result = (reconciliation_line_item_report_service
            .updateReconciliationLineItemReports([line_item_report]))

PHP


    // Set and use a manual volume for billing. This example splits the
    // difference between DFP and the third party volume.
    $lineItemReport->setManualVolume(
        ($lineItemReport->getDfpVolume()
            + $lineItemReport->getThirdPartyVolume()) / 2);
    $lineItemReport->setReconciliationSource(BillFrom::MANUAL);

    // Update the reconciliation line item report on the server.
    $updatedLineItemReports = $reconciliationLineItemReportService
        ->updateReconciliationLineItemReports([$lineItemReport]);

The values of certain revenue fields depend on your network, proposal, and line item settings. For more information, see the reference documentation.

Overriding billable revenue

If adjusting delivery isn't sufficient, you can also manually override the billable revenue. To do so, set the billableRevenueOverride. This represents either the gross or net value when reconciling a proposal line item, depending on the pricing model.

Reconciling revenue at the creative level

You can use the ReconciliationReportRowService to enter delivery data from third party ad servers or manual volumes at the creative level. Instead of a unique ID, ReconciliationReportRows are uniquely identified by their reconciliationReportId, lineItemId, and creativeId.

Java


  // Get the ReconciliationReportRowService.
  ReconciliationReportRowServiceInterface reconciliationReportRowService =
      dfpServices.get(session, ReconciliationReportRowServiceInterface.class);

  // Create a statement to select reconciliation report rows.
  StatementBuilder statementBuilder = new StatementBuilder()
      .where("id = :reconciliationReportRowId AND "
          + "reconciliationReportId = :reconciliationReportId")
      .orderBy("id ASC")
      .limit(StatementBuilder.SUGGESTED_PAGE_LIMIT)
      .withBindVariableValue("reconciliationReportRowId", reconciliationReportRowId)
      .withBindVariableValue("reconciliationReportId", reconciliationReportId);

  // Get reconciliation report rows by statement.
  ReconciliationReportRowPage page =
      reconciliationReportRowService.getReconciliationReportRowsByStatement(
          statementBuilder.toStatement());

  ReconciliationReportRow row = Iterables.getOnlyElement(Arrays.asList(page.getResults()));

  // Set a comment on the reconciliation report row.
  row.setComments("Third party volume didn't match DFP - we agreed to split the difference");

  // Set and use a manual volume for billing.
  row.setManualVolume((row.getDfpVolume() + row.getThirdPartyVolume()) / 2);
  row.setReconciliationSource(BillFrom.MANUAL);

  ReconciliationReportRow[] updatedRows =
      reconciliationReportRowService.updateReconciliationReportRows(
          new ReconciliationReportRow[] {row});

Python


  # Initialize appropriate service.
  reconciliation_report_row_service = (client.GetService(
      'ReconciliationReportRowService', version='v201705'))

  # Create a statement to select reconciliation report rows.
  statement = (dfp.StatementBuilder()
               .Where(('id = :reconciliationReportRowId AND '
                       'reconciliationReportId = :reconciliationReportId'))
               .OrderBy('id', ascending=True)
               .WithBindVariable('reconciliationReportRowId',
                                 RECONCILIATION_REPORT_ROW_ID)
               .WithBindVariable('reconciliationReportId',
                                 RECONCILIATION_REPORT_ID))

  # Get reconciliation report rows by statement.
  page = (reconciliation_report_row_service
          .getReconciliationReportRowsByStatement(statement.ToStatement()))

  row = page['results'][0]

  # Set a comment on the reconciliation report row.
  row['comments'] = ('Third part volume didn\'t match DFP - we agreed to split '
                     'the difference')

  # Set and use a manual volume for billing.
  row['manualVolume'] = (row['dfpVolume'] + row['thirdPartyVolume']) / 2
  row['reconciliationSource'] = 'MANUAL'

  updated_rows = (reconciliation_report_row_service
                  .updateReconciliationReportRows([row]))

PHP


    $reconciliationReportRowService = $dfpServices->get(
        $session, ReconciliationReportRowService::class);

    // Create a statement to select the reconciliation report rows to update.
    $pageSize = StatementBuilder::SUGGESTED_PAGE_LIMIT;
    $statementBuilder = (new StatementBuilder())
        ->where('reconciliationReportId = :reconciliationReportId AND id = '
            . ':reconciliationReportRowId')
        ->orderBy('id ASC')
        ->limit($pageSize)
        ->withBindVariableValue(
            'reconciliationReportId', $reconciliationReportId)
        ->withBindVariableValue(
            'reconciliationReportRowId', $reconciliationReportRowId);

    $page = $reconciliationReportRowService
        ->getReconciliationReportRowsByStatement(
            $statementBuilder->toStatement());
    $row = $page->getResults()[0];

    // Set a comment on the reconciliation report row.
    $row->setComments('Third party volume didn\'t match DFP - we agreed to '
        . 'split the difference');

    // Set and use a manual volume for billing.
    $row->setManualVolume(
        ($row->getDfpVolume() + $row->getThirdPartyVolume()) / 2);
    $row->setReconciliationSource(BillFrom::MANUAL);

    // Update the reconciliation report rows on the server.
    $updatedRows =
        $reconciliationReportRowService->updateReconciliationReportRows([$row]);

Submit or revert an order's delivery numbers

Once you have verified and reconciled an order's delivery data, you can submit the ReconciliationOrderReport.

Java


  // Get the ReconciliationOrderReportService.
  ReconciliationOrderReportServiceInterface reconciliationOrderReportService =
      dfpServices.get(session, ReconciliationOrderReportServiceInterface.class);

  // Create a statement to select reconciliation order reports.
  StatementBuilder statementBuilder = new StatementBuilder()
      .where("id = :id")
      .orderBy("id ASC")
      .limit(1)
      .withBindVariableValue("id", reconciliationOrderReportId);

  // Create action to submit reconciliation order reports.
  com.google.api.ads.dfp.axis.v201711.SubmitReconciliationOrderReports action =
      new com.google.api.ads.dfp.axis.v201711.SubmitReconciliationOrderReports();

  // Perform action.
  UpdateResult result =
      reconciliationOrderReportService.performReconciliationOrderReportAction(
          action, statementBuilder.toStatement());

Python

  # Initialize appropriate service.
  reconciliation_order_report_service = (client.GetService(
      'ReconciliationOrderReportService', version='v201705'))

  # Create a statement to select reconciliation order reports.
  statement = (dfp.StatementBuilder()
               .Where('id = :id')
               .OrderBy('id', ascending=True)
               .Limit(1)
               .WithBindVariable('id', RECONCILIATION_ORDER_REPORT_ID))

  # Perform action.
  result = (reconciliation_order_report_service
            .performReconciliationOrderReportAction(
                {'xsi_type': 'SubmitReconciliationOrderReports'},
                statement.ToStatement()))

PHP


    $reconciliationOrderReportService =
        $dfpServices->get($session, ReconciliationOrderReportService::class);

    // Create a statement to select the reconciliation order reports to submit.
    $pageSize = StatementBuilder::SUGGESTED_PAGE_LIMIT;
    $statementBuilder = (new StatementBuilder())
        ->where('id = :id')
        ->orderBy('id ASC')
        ->limit($pageSize)
        ->withBindVariableValue('id', $reconciliationOrderReportId);

    // Create and perform action.
    $action = new SubmitReconciliationOrderReportsAction();
    $result = $reconciliationOrderReportService
        ->performReconciliationOrderReportAction(
            $action, $statementBuilder->toStatement());

If you need to adjust the data further, you can also revert the order report with the RevertReconciliationOrderReports action.

FAQ

Can I use the reconciliation services for reporting?

We strongly encourage you to use the ReportService to retrieve read-only delivery and revenue data. You can read more about creating billing and reconciliation reports in the DFP help center. The reconciliation services should primarily be used to review and reconcile delivery information.

What's the difference between a ReconciliationLineItemReport and a ReconciliationReportRow?

The ReconciliationReportRow deals with delivery data at the creative level, whereas the ReconciliationLineItemReport works at the line item level.

How do I submit a ReconciliationReport?

You cannot submit a ReconciliationReport directly. A ReconciliationReport's status will be RECONCILED once all of its ReconciliationOrderReports are submitted.

The volume fields don't have units. What do they represent?

The units of the volume fields depend on the rate type of the LineItem or ProposalLineItem. For example if the RateType is CPC, it represents clicks; if the rate type is CPM, it represents impressions; if the rate type is CPD, it represents line item days.

I set a manual volume, but the reconciled volume didn't change. What gives?

In addition to setting a manual volume, you must also set which volume you want to bill from.

What's the difference between the data pulled by the reconciliation services and the ReportService?

The reconciliation services provide volume and revenue data based on the proposal's local timezone. The ReportService provides data based on network timezone.

Enviar comentarios sobre…

DoubleClick for Publishers
DoubleClick for Publishers
¿Necesitas ayuda? Visita nuestra página de asistencia.