> For the complete documentation index, see [llms.txt](https://docs.xpayconnect.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.xpayconnect.io/documentation/eng/orders/receipt-upload.md).

# Receipt Upload

> Method: **POST**
>
> Path: **/merchant/receipt/upload**
>
> Formats: **multipart/form-data** (file) or **application/json** (URL)

A receipt can be attached to **any order** — after the client has made a payment.

This is a **direct method without a form**: the merchant uploads the receipt themselves via the API. The alternative is to redirect the client to the [`form_url`](/documentation/eng/orders/create.md) returned in the order creation response, where they pay and attach the receipt on our form. Both paths lead to the same result; choose direct upload if the merchant collects the receipt themselves.

Two ways to submit the receipt are supported: as a **file** (multipart) or as a **URL** (JSON) — for example, if the receipt has already been uploaded to a third-party service.

## Authorization

Like all other requests — via two headers (see [Authorization](/documentation/eng/concepts/auth.md)). The `x-api-key` signature is computed over **the request body**:

| Header             | Value                                                                                      |
| ------------------ | ------------------------------------------------------------------------------------------ |
| **client-api-key** | API key in plain text                                                                      |
| **x-api-key**      | SHA-256 hash of the string `<API_KEY>\|<request_body>` (for multipart — the body is empty) |

* **multipart**: the body is formally empty (the file in `multipart/form-data` is not included in the signature) → hash of `<API_KEY>\|`.
* **JSON**: the body is `JSON.stringify({orderId, receiptUrl})` → hash of `<API_KEY>\|{"orderId":"…","receiptUrl":"…"}`.

## Request Parameters

**Common:**

| Field       | Type             | Description                                                                                                                                                                    |
| ----------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **orderId** | string, required | The order's `purchaseId` (what the merchant passed as `order_id` during creation) **or** `internalId` (`lux…`, the one returned in the creation response) — either is accepted |

**multipart/form-data:**

| Field       | Type           | Description                                                                                             |
| ----------- | -------------- | ------------------------------------------------------------------------------------------------------- |
| **receipt** | file, required | Receipt file. **PDF, JPEG, PNG** are allowed, maximum **5 MB**. The format is validated by file content |

**application/json:**

| Field          | Type             | Description                                                                                                                                                              |
| -------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **receiptUrl** | string, required | Public HTTP(S) URL available for download. Maximum **5 MB**, allowed formats **PDF, JPEG, PNG**. Private and local addresses are not supported. Download timeout is 15 s |

## Request Examples

### multipart (file)

```bash
API_KEY="YOUR_API_KEY"
# Signature over empty body: sha256("<API_KEY>|")
X_API_KEY=$(printf '%s|' "$API_KEY" | shasum -a 256 | cut -d' ' -f1)

curl -X POST https://api.xpayconnect.io/merchant/receipt/upload \
  -H "client-api-key: $API_KEY" \
  -H "x-api-key: $X_API_KEY" \
  -F "orderId=lux019d0c56-..." \
  -F "receipt=@/path/to/check.pdf"
```

### JSON (URL)

```bash
API_KEY="YOUR_API_KEY"
BODY='{"orderId":"MERCHANT-ORDER-42","receiptUrl":"https://files.example.com/receipts/abc.pdf"}'
X_API_KEY=$(printf '%s|%s' "$API_KEY" "$BODY" | shasum -a 256 | cut -d' ' -f1)

curl -X POST https://api.xpayconnect.io/merchant/receipt/upload \
  -H "client-api-key: $API_KEY" \
  -H "x-api-key: $X_API_KEY" \
  -H "Content-Type: application/json" \
  -d "$BODY"
```

## Response

```json
{
    "success": true,
    "purchaseId": "MERCHANT-ORDER-42",
    "internalId": "lux019d0c56-..."
}
```

| Field          | Type    | Description                                                                                                                                         |
| -------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| **success**    | boolean | `true` on successful receipt upload                                                                                                                 |
| **purchaseId** | string  | The order's `external_id` — what the merchant passed as `order_id` during creation (if nothing was passed, this contains the order's `internal_id`) |
| **internalId** | string  | The order's internal ID (`lux…`), always generated by the system. Used in the payment form URL and in webhooks                                      |

## Errors

| Code    | Reason                                                                                                                                                                                                                                                                                                               |
| ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **400** | `orderId` not provided; `receipt` file or `receiptUrl` not provided; unsupported format (not PDF/JPEG/PNG); file exceeds 5 MB; content does not match the declared format; for JSON: `receiptUrl` is invalid / download timed out / host is forbidden (private/localhost) / returned non-2xx (codes `RECEIPT_URL_*`) |
| **401** | Missing or invalid authorization header (`client-api-key` / `x-api-key`)                                                                                                                                                                                                                                             |
| **403** | The order belongs to a different merchant (`ORDER_FORBIDDEN`)                                                                                                                                                                                                                                                        |
| **404** | Order not found (`ORDER_NOT_FOUND`)                                                                                                                                                                                                                                                                                  |
| **409** | A receipt for this order is already under review by support (`MODERATION_IN_PROGRESS`)                                                                                                                                                                                                                               |
| **500** | Internal server error                                                                                                                                                                                                                                                                                                |
