Skip to main content
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.
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.
Before you start: You need a sandbox API key and a customer to bill. The Quickstart covers both — this guide picks up the same example. Requests below use https://rest.staging.nickel.com.
1

Create the customer

Every invoice belongs to a customer. Create one with POST /customer if they don’t exist yet:
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"]}'
{
  "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.
If your account has QuickBooks Online connected, pass "syncToQbo": true to also create the customer in QuickBooks. See QuickBooks for exactly what does and doesn’t sync.
2

Create the invoice

Create the invoice with POST /paymentLink. The name is what your customer sees — an invoice number works well:
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"
  }'
Amounts are always in cents12055 is $120.55.
{
  "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.
3

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 with type=INVOICE_PDF (PDFs up to 10MB):
curl -X POST https://rest.staging.nickel.com/file \
  -H "Authorization: Bearer $NICKEL_SANDBOX_KEY" \
  -F "file=@invoice-123.pdf" \
  -F "type=INVOICE_PDF"
{
  "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 as JSON:
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.
Files can only be attached by the API key that uploaded them — use the same key for both calls.
ResponseCause
404 File not foundNo file exists with that fileId. Check that you’re passing the id from the POST /file response (not the key or a URL).
403The file was uploaded with a different API key than the one making this request. Upload and attach with the same key.
400 fileId is requiredThe 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_PDFThe file was uploaded with a different type. Re-upload it with type=INVOICE_PDF.
4

Send it

Email the invoice to your customer with POST /paymentLink/{paymentLinkId}/send. Nickel sends a payment request email with your branding and the link:
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
  }'
{ "message": "Payment link sent" }
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.
5

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.
6

Get notified when the payment lands

Subscribe to webhooks and listen for payment.made. The event tells you which payment changed; fetch the full details with GET /payment/{paymentId}:
curl https://rest.staging.nickel.com/payment/cmr9zvqgk000csf025pyi3qfi \
  -H "Authorization: Bearer $NICKEL_SANDBOX_KEY"
{
  "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),platformFeeInCentsisthetotalprocessingfee(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).
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 before you treat ACH money as final.
7

Confirm the invoice is settled

The invoice tracks its own progress — fetch it any time with GET /paymentLink/{paymentLinkId}:
{
  "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.
8

Record offline payments (optional)

If the customer pays outside Nickel — a mailed check, cash — close the invoice with POST /paymentLink/{paymentLinkId}/markPaid (no request body). It returns the invoice with status: "COMPLETED", and no money moves.
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.

Where to go next

Refund or void a payment

Give money back the right way — and know when it’s fee-free.

Track your payouts

Match Nickel payments to the deposits on your bank statement.

Webhook events

Every event you can subscribe to, and how delivery works.

Charge customers automatically

Skip the waiting — pay invoices from an authorization on file.