Skip to main content

Developer Quickstart: QrX Public API and Webhooks

H
Written by Hayko

Developer Quickstart: QrX Public API and Webhooks

The QrX Public API lets merchants and developers create and manage Payment on Delivery transactions, shipping labels, products, returns and webhooks. It is a REST API with JSON, Bearer authentication and signed webhooks. The complete reference, generated live from the API, is at qrx.eu/api.

The Basics

  • Base URL: https://api.qr-x.net

  • Format: JSON requests and responses. Errors use application/problem+json with a machine-readable code and a readable message.

  • Specification: OpenAPI, with code samples in cURL, Node.js, C#, PHP and Python, a "try it" console and a ready-made Postman collection.

  • Access: you need an approved QrX merchant account. Sign up at portal.qr-x.app or request access through qrx.eu/api.

Step 1: Get an API Key and an Access Token

  1. In PortalX, open Settings, Merchant channels, and create an API key for the sales channel you want to connect. Each channel has its own key.

  2. Exchange the key for an access token: POST /api/v1/auth/token with the header QrX-MerchantChannel-API-Key: YOUR_KEY. The response contains accessToken and expiresIn (3600 seconds).

  3. Send Authorization: Bearer <accessToken> on every other call. Request a new token when it expires.

Keep the API key on your server. Never put it in a browser, a mobile app or a public repository.

Step 2: Create a Transaction

POST /api/v1/transactions creates a Payment on Delivery transaction. The body contains the amount, currency, locale, orderDetails (order id, customer name, email, phone, address and order lines) and optionally a parcel block to choose a shipping method and sender and create the carrier label in the same call. Use the reference endpoints (/api/v1/reference/carriers, countries, locales, shipping-methods, senders) to get valid values.

The response returns the transactionId, the QR code value (a link on go.qr-x.app) and image, and, when you asked for a label, the shipping labels with tracking number. For UPS Payment on Delivery the label set includes the QrX payment label.

Important: HTTP 201 means QrX accepted the transaction. It is not proof of payment. The payment session with the PSP can be created in the background, and the customer pays later at the door.

Step 3: Follow the Outcome

  • GET /api/v1/transactions/{id}/status returns whether the transaction is paid or open.

  • POST /api/v1/transactions/{id}/ship stores tracking details from your own system.

  • POST /api/v1/transactions/{id}/cancel cancels an eligible open transaction with a reason. A cancelled transaction can no longer be paid, labelled or fulfilled.

Step 4: Subscribe to Webhooks

Webhooks are the reliable way to keep your system in sync, because payment processing can complete or fail after your request has returned.

  • Create a webhook with POST /api/v1/webhooks: a name, your HTTPS targetUrl, the eventTypes you want (for example transaction/created and transaction/paid) and an API version.

  • Get the current list of event types and API versions with GET /api/v1/webhooks/event-types.

  • transaction/edited is sent when the products of an unpaid pay-at-door order change (a line removed, a new quantity or a line added), also when the amount stays the same. It holds eventId (use it to deduplicate), transactionId, orderId, shopOrderId, editId, oldAmount, newAmount, currency, paymentLinkChanged and the removedLines, changedLines and addedLines with SKU, name, old and new quantity and totals.

  • Each delivery has the headers X-QrX-Event, X-QrX-Delivery-Id and X-QrX-Signature. The signature has the form sha256=<hex>: an HMAC-SHA256 of the raw body with your webhook signing secret. Verify it before trusting the event.

  • Respond with a 2xx status quickly and process the event afterwards. Handle duplicates safely, because retries and redeliveries can happen.

  • Use the endpoints to send a test webhook, list deliveries, redeliver or cancel a delivery, re-enable a disabled webhook and rotate the signing secret.

Warehouse Stock

With QrX warehouse stock you can read stock levels, stock items and locations with GET /api/v1/stock/levels, /items and /locations, and book a correction with POST /api/v1/stock/adjust. The webhook events stock/adjusted and stock/low tell you when stock changes or runs low. See "Stock and Warehouse API" and "Stock and Warehouse Webhooks".

Test Mode

Set testMode: true when creating a transaction to test the full flow. Test transactions use sandbox or test configuration where available, never create a real payment or payout, and must not be treated as real orders. Labels for test accounts are created in the carrier's sandbox.

Idempotency

Commands on returns (such as approve, reject, record resolution or post a message) require an Idempotency-Key header of at most 200 characters. Reuse the same key when you retry the same command to receive its stored result; use a new key for a new command. For transactions, use your own order id and webhooks to avoid creating the same order twice. POST /api/v1/stock/adjust requires an Idempotency-Key header too.

Rate Limits

Limits apply per merchant API key or channel, for example 60 token requests per minute and 300 transaction commands per minute. A 429 response includes Retry-After and RateLimit-Reason. Wait at least Retry-After seconds before retrying, and reuse your access token.

Building for Other Merchants?

If you build an app, WMS or platform used by many merchants, use QrX Connect so merchants can link their QrX channel without pasting an API key. See "QrX Connect: connecting your platform with OAuth".

When to Contact Our Support Team

Contact QrX support at [email protected] for API access, production incidents, leaked credentials or signature problems you cannot explain. Include the environment, channel, transaction id, webhook delivery id and a sanitized request, never the key, token or secret. See also "API and Webhook Troubleshooting".

Did this answer your question?