> ## Documentation Index
> Fetch the complete documentation index at: https://dev.nickel.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Send an Invoice and Get Paid

> Create an invoice, email it to your customer, and track the payment through to the invoice being settled

This is the core Nickel workflow, end to end: you create an invoice, email it to your customer, they pay on the hosted checkout page, and you confirm the money is on its way. No checkout code, no card handling on your side.

<Note>
  In the API, an invoice is a **payment link** — the endpoints and field names below say `paymentLink`. Same thing; this guide says "invoice" because that's what your customer sees.
</Note>

<Info>
  **Before you start**: You need a sandbox API key and a customer to bill. The [Quickstart](/guides/quickstart) covers both — this guide picks up the same example. Requests below use `https://rest.staging.nickel.com`.
</Info>

<Steps>
  <Step title="Create the customer">
    Every invoice belongs to a customer. Create one with [`POST /customer`](/api-reference/customer/create-a-customer) if they don't exist yet:

    ```bash theme={null}
    curl -X POST https://rest.staging.nickel.com/customer \
      -H "Authorization: Bearer $NICKEL_SANDBOX_KEY" \
      -H "Content-Type: application/json" \
      -d '{"name": "Acme Landscaping", "emails": ["ap@acmelandscaping.com"]}'
    ```

    ```json theme={null}
    {
      "id": "cmr9zja1s0000sf028pvdtpsh",
      "name": "Acme Landscaping",
      "emails": ["ap@acmelandscaping.com"],
      "achEnabled": null,
      "feePassthroughPercent": 50
    }
    ```

    `feePassthroughPercent` echoes your **organization's** setting, not anything you sent: it's the share of the card processing fee your customers cover. This sandbox organization passes 50% through (a new organization starts at 100) — you'll see that 50% again when we read the payment's charged amount below.

    <Note>
      If your account has QuickBooks Online connected, pass `"syncToQbo": true` to also create the customer in QuickBooks. See [QuickBooks](/concepts/quickbooks) for exactly what does and doesn't sync.
    </Note>
  </Step>

  <Step title="Create the invoice">
    Create the invoice with [`POST /paymentLink`](/api-reference/payment-link/create-a-new-payment-link). The `name` is what your customer sees — an invoice number works well:

    ```bash theme={null}
    curl -X POST https://rest.staging.nickel.com/paymentLink \
      -H "Authorization: Bearer $NICKEL_SANDBOX_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "INV-123",
        "customerId": "cmr9zja1s0000sf028pvdtpsh",
        "requestedAmountCents": 12055,
        "dueDate": "2026-08-01"
      }'
    ```

    <Warning>
      Amounts are always in **cents** — `12055` is \$120.55.
    </Warning>

    ```json theme={null}
    {
      "id": "cmr9zjev80002sf027g6f8pdd",
      "name": "INV-123",
      "status": "ACTIVE",
      "url": "https://nickel.staging.nickelpayments.com/pay/vKzQLZwb",
      "payments": [],
      "dueDate": "2026-08-01",
      "customerId": "cmr9zja1s0000sf028pvdtpsh",
      "requestedAmountCents": 12055,
      "completedAmountCents": 0,
      ...
    }
    ```

    A few optional fields let you control checkout per invoice — `creditCardEnabled` and `achEnabled` toggle payment methods, `amountEditable` lets the customer change the amount (useful for deposits), and `feePassthroughPercent` sets how much of the card processing fee the customer covers. Omit them to inherit your customer and organization settings.
  </Step>

  <Step title="Attach the invoice PDF (optional)">
    If you generate a PDF for the invoice, attach it so your customer can view and download it on the payment page. It's two calls: upload the file, then attach it by ID.

    Upload the PDF as `multipart/form-data` to [`POST /file`](/api-reference/file/upload-a-file) with `type=INVOICE_PDF` (PDFs up to 10MB):

    ```bash theme={null}
    curl -X POST https://rest.staging.nickel.com/file \
      -H "Authorization: Bearer $NICKEL_SANDBOX_KEY" \
      -F "file=@invoice-123.pdf" \
      -F "type=INVOICE_PDF"
    ```

    ```json theme={null}
    {
      "id": "cm4x2fj8t0001abcd1234wxyz",
      "key": "files/1751830000000-invoice-123.pdf",
      "type": "INVOICE_PDF",
      "createdAt": "2026-07-06T18:00:00.000Z"
    }
    ```

    Then attach it by sending the file's `id` — not the `key`, and not the file itself — to [`POST /paymentLink/{paymentLinkId}/uploadPdf`](/api-reference/payment-link/attach-a-previously-uploaded-pdf-to-a-payment-link) as JSON:

    ```bash theme={null}
    curl -X POST https://rest.staging.nickel.com/paymentLink/cmr9zjev80002sf027g6f8pdd/uploadPdf \
      -H "Authorization: Bearer $NICKEL_SANDBOX_KEY" \
      -H "Content-Type: application/json" \
      -d '{"fileId": "cm4x2fj8t0001abcd1234wxyz"}'
    ```

    The response is the updated invoice.

    <Note>
      Files can only be attached by the API key that uploaded them — use the same key for both calls.
    </Note>

    <Accordion title="Troubleshooting PDF attachment">
      | Response                                 | Cause                                                                                                                                        |
      | ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
      | `404` `File not found`                   | No file exists with that `fileId`. Check that you're passing the `id` from the `POST /file` response (not the `key` or a URL).               |
      | `403`                                    | The file was uploaded with a different API key than the one making this request. Upload and attach with the same key.                        |
      | `400` `fileId is required`               | The request body didn't include a `fileId` — this usually means the PDF was sent directly to this endpoint instead of to `POST /file` first. |
      | `400` `File must be of type INVOICE_PDF` | The file was uploaded with a different `type`. Re-upload it with `type=INVOICE_PDF`.                                                         |
    </Accordion>
  </Step>

  <Step title="Send it">
    Email the invoice to your customer with [`POST /paymentLink/{paymentLinkId}/send`](/api-reference/payment-link/send-a-payment-link-to-recipients). Nickel sends a payment request email with your branding and the link:

    ```bash theme={null}
    curl -X POST https://rest.staging.nickel.com/paymentLink/cmr9zjev80002sf027g6f8pdd/send \
      -H "Authorization: Bearer $NICKEL_SANDBOX_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "recipients": [{"email": "ap@acmelandscaping.com", "name": "Acme Landscaping"}],
        "sendSms": false
      }'
    ```

    ```json theme={null}
    { "message": "Payment link sent" }
    ```

    <Tip>
      Call this endpoint again to nudge a slow payer — Nickel automatically treats repeat sends to the same recipient as reminders. Omit `sendSms` to use your organization's SMS setting for recipients with a `phoneNumber`.
    </Tip>
  </Step>

  <Step title="Your customer pays">
    The email links to the hosted checkout page (the invoice's `url`). Your customer sees the invoice details and the attached PDF, and pays by card or bank transfer (ACH) — whichever you've left enabled. If you pass part of the card fee through, the checkout shows the customer their share as a line item before they confirm.

    You don't need to build anything for this step.
  </Step>

  <Step title="Get notified when the payment lands">
    Subscribe to [webhooks](/concepts/webhooks) and listen for `payment.made`. The event tells you which payment changed; fetch the full details with [`GET /payment/{paymentId}`](/api-reference/payment/returns-a-payment-by-id):

    ```bash theme={null}
    curl https://rest.staging.nickel.com/payment/cmr9zvqgk000csf025pyi3qfi \
      -H "Authorization: Bearer $NICKEL_SANDBOX_KEY"
    ```

    ```json theme={null}
    {
      "id": "cmr9zvqgk000csf025pyi3qfi",
      "status": "SUCCEEDED",
      "amountInCents": 12055,
      "chargedAmountInCents": 12230,
      "platformFeeInCents": 350,
      "fees": [{ "type": "CREDIT_CARD_FEE", "amountInCents": 350 }],
      "paymentMethod": {
        "type": "Card",
        "cardDetails": { "brand": "Visa", "last4": "1111", ... },
        ...
      },
      "estimatedDisbursementDate": "2026-07-08",
      "paymentLinkId": "cmr9zjev80002sf027g6f8pdd",
      "disbursement": null,
      "refunds": []
    }
    ```

    Reading the money fields: `amountInCents` is the invoice amount ($120.55), `platformFeeInCents` is the total processing fee ($3.50), and `chargedAmountInCents` is what the customer's card was actually charged (\$122.30 — the invoice plus their half of the fee, since this account passes 50% through).

    <Warning>
      Card payments show `SUCCEEDED` right away. Bank (ACH) payments sit in `PENDING` for a few business days first, and can still fail up to 60 days later if the customer's bank returns the debit. See [How Payments Work](/concepts/payments) before you treat ACH money as final.
    </Warning>
  </Step>

  <Step title="Confirm the invoice is settled">
    The invoice tracks its own progress — fetch it any time with [`GET /paymentLink/{paymentLinkId}`](/api-reference/payment-link/find-a-payment-link-by-id):

    ```json theme={null}
    {
      "id": "cmr9zjev80002sf027g6f8pdd",
      "name": "INV-123",
      "status": "COMPLETED",
      "requestedAmountCents": 12055,
      "completedAmountCents": 12055,
      "payments": [{ "id": "cmr9zvqgk000csf025pyi3qfi", "status": "SUCCEEDED", ... }],
      ...
    }
    ```

    `completedAmountCents` climbs as payments come in, and `status` flips from `ACTIVE` to `COMPLETED` when the invoice is fully paid.
  </Step>

  <Step title="Record offline payments (optional)">
    If the customer pays outside Nickel — a mailed check, cash — close the invoice with [`POST /paymentLink/{paymentLinkId}/markPaid`](/api-reference/payment-link/mark-a-payment-link-as-paid) (no request body). It returns the invoice with `status: "COMPLETED"`, and no money moves.
  </Step>
</Steps>

<Note>
  Payments on API-created invoices are **never** recorded in QuickBooks by Nickel, even with the integration connected — book them yourself without double-entry risk. Details in [QuickBooks](/concepts/quickbooks).
</Note>

## Where to go next

<Columns cols={2}>
  <Card title="Refund or void a payment" href="/guides/refunds" icon="rotate-left">
    Give money back the right way — and know when it's fee-free.
  </Card>

  <Card title="Track your payouts" href="/guides/payouts" icon="building-columns">
    Match Nickel payments to the deposits on your bank statement.
  </Card>

  <Card title="Webhook events" href="/concepts/webhooks" icon="bolt">
    Every event you can subscribe to, and how delivery works.
  </Card>

  <Card title="Charge customers automatically" href="/guides/autopay" icon="repeat">
    Skip the waiting — pay invoices from an authorization on file.
  </Card>
</Columns>
