KSeF Faktury
EN
Join the start list
Early access

The API is in early access: we hand out test keys (KSeF TEST) in batches to people on the launch list. Live mode comes later.

Request access

Guides

Corrections for refunds

A refund in your store becomes a correction invoice (KOR) with difference lines, linked to the KSeF number of the original invoice.

How a refund becomes a correction

When you refund goods or shipping, send the refund to POST /v1/invoices/{id}/corrections. The API creates a correction invoice (KOR, TypKorekty 2) with difference lines: returned items have negative quantities, and the correction refers to the original invoice's KSeF number. The queue waits until the original is accepted in KSeF, so you can send the refund right away.

POST /v1/invoices/{id}/corrections
curl -X POST https://app.ksefshop.pl/v1/invoices/inv_4fJ2kP9xQwErTy7uI0oPaSdF/corrections \
  -H "Authorization: Bearer $KSEF_API_KEY" \
  -H "Idempotency-Key: refund-RF-1" \
  -H "Content-Type: application/json" \
  -d '{
  "refund": {
    "external_id": "RF-1",
    "reason": "Zwrot towaru",
    "lines": [
      {
        "name": "Kubek ceramiczny 350 ml",
        "sku": "KUB-350",
        "quantity": 1,
        "unit_price": "49.00",
        "vat_rate": "23"
      }
    ],
    "shipping": {
      "price": "15.99"
    }
  }
}'

What to send

  • refund.external_id: your refund id. One refund, one correction: a repeat returns the existing correction with 200.
  • lines: returned lines with a positive quantity, the gross unit price and the VAT rate, as on the invoice.
  • shipping.price: refunded gross shipping; the VAT rate of the invoice's shipping applies.
  • reason: the reason printed on the correction, e.g. "Returned goods".

At least one of lines and shipping is required.

What the API does not do

Situation Response
Amount-only refund, no lines or shipping 422 order_unprocessable
A correction of a correction (cor_... in the path) 400 correction_requires_invoice
The original was rejected by KSeF correction skipped, original_rejected
An order without an invoice correction skipped, original_not_invoiced

Correction status

A correction has the same statuses as an invoice. Follow it through correction.accepted, correction.rejected and correction.skipped events, with GET /v1/invoices/cor_..., or in the original invoice's corrections field.

WooCommerce

Instead of refund, the WooCommerce plugin sends woocommerce_order plus woocommerce_refund (a WooCommerce REST API v3 refund). We derive the difference lines from _refunded_item_id.

KSeF Faktury

API early access

We hand out test keys in batches. Leave your email: we will write when your access is ready.