Skip to content

POST/v1/charges20094ms

Payments infrastructure that reads like your codebase.

Ledgerline is one API for charges, refunds, and payouts. Every endpoint returns predictable JSON, every error tells you what to fix, and the docs are the same request you're about to run, not a rewrite of it.

Have questions first? Talk to us

POSTapi.ledgerline.dev/v1/charges
curl https://api.ledgerline.dev/v1/charges \  -H "Authorization: Bearer sk_live_51H8x9K2eZv" \  -H "Content-Type: application/json" \  -d '{    "amount": 4200,    "currency": "usd",    "source": "tok_visa",    "description": "Order #8842"  }'
200 OKResponse94ms
{  "id": "ch_1N3x9K2eZvKYlo2C",  "object": "charge",  "amount": 4200,  "currency": "usd",  "status": "succeeded",  "created": 1717430400,  "receipt_url": "https://ledgerline.dev/r/ch_1N3x9K"}

Running on Ledgerline

  • Northbeam Freight
  • Faircove
  • Anvic Robotics
  • Perigee Systems
  • Wrenfield
  • Solano Studio

POST/v1/charges

Take a payment in one request

POST an amount, a currency, and a payment source to /v1/charges and get a settled charge back. No redirect flow to babysit, no polling loop: the response tells you whether the money moved.

ResponseJSON
{  "id": "ch_1N3x9K2eZvKYlo2C",  "object": "charge",  "amount": 4200,  "currency": "usd",  "status": "succeeded",  "created": 1717430400,  "receipt_url": "https://ledgerline.dev/r/ch_1N3x9K"}

POST/webhooks/ledgerline

Get told the moment something changes

Ledgerline signs every webhook with a secret only you and we know. Verify the signature, switch on the event type, and you're done. No separate library to trust, just HMAC-SHA256 you can read in one line.

Verify a webhookNode.js
import { verifyWebhook } from "@ledgerline/node";app.post("/webhooks/ledgerline", (req, res) => {  const event = verifyWebhook(    req.rawBody,    req.headers["ledgerline-signature"],    process.env.LEDGERLINE_WEBHOOK_SECRET  );  if (event.type === "charge.succeeded") {    fulfillOrder(event.data.object);  }  res.status(200).send();});

POST/v1/refunds

Refunds are a first-class object

A refund isn't a flag on the original charge. It's its own record, with its own id and its own place in the ledger. Partial refunds, multiple refunds against one charge, all of it queryable later.

Issue a refundcURL
curl https://api.ledgerline.dev/v1/refunds \  -H "Authorization: Bearer sk_live_51H8x9K2eZv" \  -d "charge=ch_1N3x9K2eZvKYlo2C" \  -d "amount=4200"

402card_error

Errors explain themselves

Every failure ships a machine-readable code and a sentence a human can act on. "insufficient_funds" tells your support team exactly what to say, before they've read a single log line.

A declined chargeJSON
{  "error": {    "type": "card_error",    "code": "insufficient_funds",    "message": "The card has insufficient funds.",    "charge": "ch_1N3xAb2eZvKYlo9D"  }}

See it move money.