Skip to main content
Layer ingests revenue through Invoices & Payments and Payouts. This includes in-person sales made through a point of sale system, invoices sent through your software, ecommerce sales, and any other type of accounts receivable activity. For a complete accounting picture, you will also need to import your customers’ bank data.

Invoices and payments

Invoices and payments represent revenue collected by your business customers. This can be in-person sales made through a point of sale system, invoices sent through your software, ecommerce sales, or any other type of accounts receivable activity. To import invoices, make a call to the Create Invoice endpoint. This endpoint takes in the data on the sale your customer made, what was sold, any associated taxes, and how the sale was paid for.

Invoices without payments

Invoices can be created without any payments associated with them. Payments towards the invoice can then be recorded later on using the Record an Invoice Payment endpoint.
Request
curl -X POST https://sandbox.layerfi.com/v1/businesses/{business_id}/invoices \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "external_id": "019234",
    "sent_at": "2024-04-02T09:02:00Z",
    "due_at": "2023-04-02T09:02:00Z",
    "invoice_number": "1",
    "customer_external_id": "customer-john-doe",
    "line_items": [
      {
        "product": "Cleaner Solution Pro",
        "unit_price": 1299,
        "quantity": 2,
        "sales_taxes": [
          {
            "tax_account": {
              "type": "Tax_Name",
              "name": "CALIFORNIA_VAT"
            },
            "amount": 218
          }
        ]
      },
      {
        "product": "Full drain cleaning service",
        "unit_price": 25000,
        "quantity": 1
      }
    ],
    "additional_discount": 250
  }'
The API will respond with an Invoice object.
Response
{
  "data": {
    "type": "Invoice",
    "id": "6d0c298f-3e4e-4538-9a71-1d5359c22f71",
    "business_id": "83d8fb80-31ee-4d57-b684-44b4aaa5e01f",
    "external_id": "019234",
    "status": "SENT",
    "sent_at": "2024-04-02T09:02:00Z",
    "due_at": "2023-04-02T09:02:00Z",
    "paid_at": null,
    "voided_at": null,
    "invoice_number": "1",
    "customer": {
      "id": "a4c38874-8c01-4986-b8d0-4f159a52dd39",
      "external_id": "customer-john-doe",
      "individual_name": null,
      "company_name": null,
      "email": null,
      "mobile_phone": null,
      "office_phone": null,
      "address_string": null,
      "notes": null,
      "status": "ACTIVE"
    },
    "line_items": [
      {
        "id": "e6a491dd-9c22-4403-a54f-32d741a7ec67",
        "invoice_id": "6d0c298f-3e4e-4538-9a71-1d5359c22f71",
        "account_identifier": null,
        "description": null,
        "product": "Cleaner Solution Pro",
        "unit_price": 1299,
        "quantity": "2.00",
        "subtotal": 2598,
        "discount_amount": 0,
        "sales_taxes_total": 218,
        "sales_taxes": [
          {
            "tax_account": {
              "type": "Tax_Name",
              "name": "CALIFORNIA_VAT"
            },
            "amount": 218
          }
        ],
        "total_amount": 2816
      },
      {
        "id": "44f06385-3ef5-4517-8095-eeedaf2054ab",
        "invoice_id": "6d0c298f-3e4e-4538-9a71-1d5359c22f71",
        "account_identifier": null,
        "description": null,
        "product": "Full drain cleaning service",
        "unit_price": 25000,
        "quantity": "1.00",
        "subtotal": 25000,
        "discount_amount": 0,
        "sales_taxes_total": 0,
        "total_amount": 25000
      }
    ],
    "subtotal": 27598,
    "additional_discount": 250,
    "additional_sales_taxes_total": 0,
    "tips": 0,
    "tips_account": {
      "type": "StableName",
      "stable_name": "TIPS_REVENUE"
    },
    "total_amount": 27566,
    "outstanding_balance": 27566,
    "payment_allocations": [],
    "imported_at": "2024-04-19T02:23:59.902537Z",
    "updated_at": null,
    "transaction_tags": []
  }
}

Invoices with payments

For instances where invoices are immediately paid, such as when using a point of sale device for in-person sales or online merchandise sales, you can also include payment information directly in the creation of the invoice. This looks very similar to the above example with the addition of payment information.
Request
curl -X POST https://sandbox.layerfi.com/v1/businesses/863ed926-e30d-40f4-8e7e-b0d5387ce4fb/invoices \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "external_id": "234988",
    "sent_at": "2024-05-12T14:13:07Z",
    "due_at": "2024-06-12T14:13:07Z",
    "invoice_number": "2",
    "customer_external_id": "customer-john-doe",
    "line_items": [
      {
        "product": "Cleaner Solution Pro",
        "unit_price": 1299,
        "quantity": 1,
        "sales_taxes": [
          {
            "amount": 114
          }
        ]
      },
      {
        "product": "Cleanout snake",
        "unit_price": 18000,
        "quantity": 1
      }
    ],
    "additional_sales_taxes": [
      {
        "amount": 1291
      }
    ],
    "payments": [
      {
        "external_id": "239872",
        "method": "CREDIT_CARD",
        "amount": 20704,
        "processor": "MY_PROCESSOR"
      }
    ]
  }'
In this case, the API will respond with the same created invoice, but with the invoice marked as fully or partially paid and the payment information included.
Response
{
  "data": {
    "type": "Invoice",
    "id": "d01c9839-0378-4d44-b409-a0ae1e5dbb59",
    "business_id": "83d8fb80-31ee-4d57-b684-44b4aaa5e01f",
    "external_id": "234988",
    "status": "PAID",
    "sent_at": "2024-05-12T14:13:07Z",
    "due_at": "2024-06-12T14:13:07Z",
    "paid_at": "2024-04-19T02:24:00.009658Z",
    "voided_at": null,
    "invoice_number": "2",
    "customer": {
      "id": "a4c38874-8c01-4986-b8d0-4f159a52dd39",
      "external_id": "customer-john-doe",
      "individual_name": null,
      "company_name": null,
      "email": null,
      "mobile_phone": null,
      "office_phone": null,
      "address_string": null,
      "notes": null,
      "status": "ACTIVE"
    },
    "line_items": [
      {
        "id": "fd60aa16-a0a6-40de-a814-b01836acfd36",
        "invoice_id": "d01c9839-0378-4d44-b409-a0ae1e5dbb59",
        "account_identifier": null,
        "description": null,
        "product": "Cleaner Solution Pro",
        "unit_price": 1299,
        "quantity": "1.00",
        "subtotal": 1299,
        "discount_amount": 0,
        "sales_taxes_total": 114,
        "sales_taxes": [
          {
            "tax_account": {
              "type": "AccountId",
              "id": "ba1a5e91-d04a-4c67-919e-f09a20d6e151"
            },
            "amount": 114
          }
        ],
        "total_amount": 1413
      },
      {
        "id": "4dd7708a-cad4-46e6-b5ff-34248a0b141e",
        "invoice_id": "d01c9839-0378-4d44-b409-a0ae1e5dbb59",
        "account_identifier": null,
        "description": null,
        "product": "Cleanout snake",
        "unit_price": 18000,
        "quantity": "1.00",
        "subtotal": 18000,
        "discount_amount": 0,
        "sales_taxes_total": 0,
        "total_amount": 18000
      }
    ],
    "subtotal": 19299,
    "additional_discount": 0,
    "additional_sales_taxes_total": 1291,
    "additional_sales_taxes": [
      {
        "tax_account": {
          "type": "AccountId",
          "id": "ba1a5e91-d04a-4c67-919e-f09a20d6e151"
        },
        "amount": 1291
      }
    ],
    "tips": 0,
    "total_amount": 20704,
    "outstanding_balance": 0,
    "payment_allocations": [
      {
        "invoice_id": "d01c9839-0378-4d44-b409-a0ae1e5dbb59",
        "payment_id": "4d769e05-a101-4a16-8de5-6c37fbcec088",
        "amount": 20704,
        "transaction_tags": []
      }
    ],
    "imported_at": "2024-04-19T02:24:00.009658Z",
    "updated_at": null,
    "transaction_tags": []
  }
}

Payouts

A Payout represents a processor deposit that moves funds from a payment processor, such as Stripe, to one of your business customers’ bank accounts. Payouts are used to reconcile bank transactions that represent processor deposits with the underlying processor activity they contain, such as invoice payments and refunds. Matching bank transactions to payouts prevents revenue from being double-counted: first from the invoice payment, and second from categorizing the bank transaction as revenue.

Importing payouts

Create payouts with the Create Payout endpoint, or use Bulk Create Payouts to create or update multiple payouts in a single request. If processor is set (e.g. STRIPE), every linked payment and refund must also use this processor value. Use the Update Payout endpoint to modify a payout after it has been created. external_id is your idempotency key. Re-posting the same external_id returns the existing payout unchanged. The bulk endpoint uses upsert semantics: if a payout with the same external_id already exists, it will be updated; otherwise, a new payout is created.

Linking payments and refunds

Attach existing invoice payments and refunds by Layer ID or your external ID:
{
  "payments": [
    { "invoice_payment_id": "<invoice_payment_id>" }
  ],
  "refunds": [
    { "refund_payment_id": "<refund_payment_id>" }
  ]
}

Other transactions

Use other_transactions for line items that are not represented as invoice payments or refunds (e.g. Merchant Cash Advance fees, tax withholding, or other fees).

Stripe Instant Payouts

Instant payouts from Stripe should be imported as two Payout objects in Layer: one payout for the instant cash movement, and one following payout that reconciles the itemized payment activity when Stripe includes it in a later payout. Normal Stripe payouts are itemized around the specific transactions included in the payout. Instant payouts are amount-based, so Layer represents the instant transfer separately from the later itemized payout that contains the payment.

Process Steps

The expected process steps are:
  1. Import the invoice and payment.
  2. Create the instant payout with no payments or refunds, plus one CREDIT transaction to STRIPE_CLEARING.
  3. Create the following payout with the original payment attached, plus one DEBIT transaction from STRIPE_CLEARING.
After both payout objects are imported, the STRIPE_CLEARING entries will offset each other.

1. Import the payment

First, import the sale and its Stripe payment. In the example payout below, there is an invoice for 12500 cents, with one credit card payment for the same amount and no fee.
{
  "external_id": "invoice-instant-payout",
  "sent_at": "2023-12-05T00:00:00Z",
  "due_at": "2023-12-05T00:00:00Z",
  "customer_external_id": "customer-instant-payout",
  "line_items": [
    {
      "description": "Test Service",
      "quantity": 1,
      "unit_price": 12500,
      "product": "Test Product"
    }
  ],
  "payments": [
    {
      "external_id": "payment-instant-payout",
      "amount": 12500,
      "fee": 0,
      "processor": "STRIPE",
      "method": "CREDIT_CARD"
    }
  ]
}

2. Create the instant payout

Create a payout for the instant transfer itself. Note the example payout below has the amount that Stripe deposited, but does not yet attach the invoice payment.
{
  "external_id": "payout-instant",
  "paid_out_amount": 12500,
  "fee": 0,
  "processor": "STRIPE",
  "completed_at": "2023-12-05T00:00:00Z",
  "payments": [],
  "refunds": [],
  "other_transactions": [
    {
      "amount": 12500,
      "direction": "CREDIT",
      "account": {
        "type": "StableName",
        "stable_name": "STRIPE_CLEARING"
      },
      "description": "Stripe payout payout-instant",
      "external_id": "pbt-payout-instant-funding"
    }
  ]
}

3. Create the following payout

When Stripe later reports the itemized payout that includes the payment, create a second payout. In the example payout below, the paid_out_amount of 0, references the invoice payment created earlier and includes the opposite STRIPE_CLEARING transaction.
{
  "external_id": "payout-following",
  "paid_out_amount": 0,
  "fee": 0,
  "processor": "STRIPE",
  "completed_at": "2023-12-06T00:00:00Z",
  "payments": [
    {
      "invoice_payment_id": "<invoice_payment_id>"
    }
  ],
  "refunds": [],
  "other_transactions": [
    {
      "amount": 12500,
      "direction": "DEBIT",
      "account": {
        "type": "StableName",
        "stable_name": "STRIPE_CLEARING"
      },
      "description": "Stripe payout payout-instant",
      "external_id": "pbt-payout-instant-reconciliation"
    }
  ]
}
The example now has both payouts present, with the following payout including the original payment. The STRIPE_CLEARING account will net to zero after the CREDIT and DEBIT transactions are applied.