Invoicing on Behalf of Another Account

Invoicing on Behalf of Another Account

This is an advanced feature for platforms that run more than one account in the same account hierarchy. If you just need to bill your own customers, see the Invoices guide — you don't need this.

An account can let another account invoice its customers on its behalf — for example, a head-office account that bills the customers of its subsidiaries. Granting servicing access is a permission grant, so it is always made by the serviced account — the one whose customers will be invoiced.

Which grant you need depends on the customer's type, and the two are independent:

Customer typeWhat it isGrant
InternalLinked to a sub-account via backing_account — how a platform bills a sub-account as if it were a customerList each operator in servicing_accounts
ExternalAn ordinary end userThe descendant wildcard — the explicit list does not cover these

Granting access to internal customers

API reference

Use updateAccount on the serviced account, setting capabilities.billing.invoice.servicing_accounts to the operator accounts that should be allowed to invoice its internal customers. Only the fields you populate are updated; everything else is left unchanged.

curl -X POST https://api.synaptopay.com/v1/accounts/acct_SERVICED \
  -H "Authorization: Api-Key $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "account": {
      "capabilities": {
        "billing": {
          "invoice": {
            "servicing_accounts": ["accounts/acct_OPERATOR"]
          }
        }
      }
    }
  }'

Every listed account must belong to the same account hierarchy as the serviced account — that is, share the same top-level parent (parent_account_name) — and can't be the serviced account itself. To revoke the grant, send the same request with an empty servicing_accounts list (keep the surrounding invoice object so the backend treats it as an intentional empty list, not "leave unchanged").

Servicing external customers

servicing_accounts does not cover external customers, however you list them. To let sub-accounts invoice an account's external customers — say a ride-hailing platform where every driver bills the platform's riders — set all_descendants_service_external_customers on the account that owns them. Every account beneath it in the hierarchy may then invoice its external customers, and sub-accounts you add later are covered automatically, with no further calls.

The grant is all-or-nothing: there is no per-operator list for external customers.

Unlike servicing_accounts, this flag is set through the capabilities endpoint, where the field name is flat:

curl -X POST https://api.synaptopay.com/v1/accounts/acct_SERVICED/capabilities \
  -H "Authorization: Api-Key $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "billing_invoice_all_descendants_service_external_customers": true
  }'

It reads back on the account as capabilities.billing.invoice.all_descendants_service_external_customers. Omitting the field leaves it unchanged.

This grant is external-only. It does not cover internal customers, so it cannot be used for one sub-account to bill another. To let an operator bill an internal customer, list that operator explicitly in servicing_accounts. The two grants are independent: set the wildcard and list specific operators at the same time, and each governs its own customer type.

To revoke, send the same call with false — that drops the wildcard only; any operators still named in servicing_accounts keep their explicit grant.

How servicing works once granted

The mechanics below are the same under either grant.

The operator invoices the serviced account's customers using its own account: it creates the invoice under acct_OPERATOR and points the invoice's customer at the serviced customer, e.g. accounts/acct_SERVICED/customers/cus_X. The operator owns the resulting invoice (accounts/acct_OPERATOR/invoices/inv_Y) and collects it via its own MID — the customer simply lives under a different account. Customer resources themselves still belong to the serviced account and are addressed there.

The grant covers the billing-invoice surface on the public API, split two ways. On the serviced account's rows, the operator can call getCustomer, the invoice-item RPCs (createInvoiceItem, getInvoiceItem, deleteInvoiceItem), and createInvoice for a serviced customer. The invoices it raises are its own, so getInvoice, finalizeInvoice, payInvoice, voidInvoice, markInvoiceUncollectible, addInvoiceLine, and removeInvoiceLine act under acct_OPERATOR, not the serviced account.

Servicing invoices are collected like any other: finalize the invoice and send the customer its hosted_invoice_url, where they pay on Synapto's hosted page. The operator can't autopay a servicing invoice with the serviced customer's saved payment method — payInvoice requires the payment method and the invoice to sit on the same account, and here the invoice is the operator's while the method belongs to the serviced account. Nor can the operator save a method for the serviced customer: a setup intent or SETUP-mode checkout session needs payments.write on the account that owns the customer, so payment-method setup stays with the serviced account.

Listing differs by endpoint. listInvoices is strict by URL parent — it returns only invoices owned by the account in the URL, so the servicing invoices you raise appear under parent=accounts/acct_OPERATOR, never under the serviced account. listCustomers is scoped to what the caller can reach: called by the operator's own API key with parent=accounts/acct_OPERATOR, it merges the operator's own customers and the serviced customers it may bill into one result set, ordered by creation time and paged with next_page_token. Call it with the operator's own key — listing at another account's URL returns that account's customers, not a merged view.

For a worked example — a platform that lets its merchants bill platform-level customers — see Charging Platform Fees.


Did this page help you?