Webhooks & Callbacks

Korba Xchange notifies your server the moment a transaction changes state — no polling required. Configure a callback URL in your dashboard and we will deliver a signed GET request with the transaction outcome directly to your endpoint.

Overview

When a transaction is initiated you supply a callback_url. Once the transaction reaches a terminal state — either SUCCESS or FAILED — Korba Xchange fires a GET request to that URL, appending the outcome as query parameters.

Callbacks are delivered at least once. If your endpoint returns a non-2xx response we will retry with exponential back-off. Design your handler to be idempotent — processing the same callback twice should have no adverse side-effect.

Callback Format

Korba Xchange appends three query parameters to your callback_url. The base URL you provide is left intact; parameters are joined with ? (or & if your URL already contains query parameters).

Callback URL pattern
{callback_url}?transaction_id={UNIQUE_ID}&status={SUCCESS|FAILED}&message={DETAILS}

Callback Parameters

Parameter Values Description
transaction_id string The unique transaction reference you supplied when creating the transaction. Use this to match the callback to a record in your database.
status SUCCESS FAILED Terminal outcome of the transaction. SUCCESS means funds were transferred; FAILED means the transaction did not complete.
message string A human-readable detail string describing the outcome — e.g. "Transaction processed successfully" or a failure reason.

Example Callback

Below is what a successful callback looks like when delivered to your endpoint:

Live example GET request
GET https://webhook.site/1c4d4a5d
    ?transaction_id=UNIQUE_ID
    &status=SUCCESS
    &message=Transaction+processed+successfully

Webhook Security

Webhooks include an additional security layer: the callback carries an X-Callback-Token HTTP header containing a pre-shared secret that you configure in your XCheckout settings on the dashboard.

Always validate this header before processing the callback. Reject any request where the token is absent or does not match your configured value — this prevents replay attacks from third parties who might discover your callback URL.

Always verify the X-Callback-Token. Skipping this check means any party who knows your callback URL can trigger false-positive order fulfillment in your system. Treat the token as a secret — rotate it immediately if it is ever exposed.
XCheckout callback headers
X-Callback-Token: your-configured-secret-token
Content-Type:     application/x-www-form-urlencoded

Example Handler

The snippets below show minimal production-ready callback handlers that verify the callback token (for XCheckout), look up the transaction, and update its status idempotently.

# Django view — GET /callbacks/korba/
import logging
from django.conf import settings
from django.http  import HttpResponse, HttpResponseForbidden
from django.views import View

logger = logging.getLogger(__name__)

class KorbaCallbackView(View):
    def get(self, request):
        # 1. Verify XCheckout callback token (XCheckout integrations only)
        token = request.headers.get("X-Callback-Token")
        if token != settings.KORBA_CALLBACK_TOKEN:
            logger.warning("Rejected callback — invalid token")
            return HttpResponseForbidden()

        # 2. Extract parameters
        transaction_id = request.GET.get("transaction_id")
        status         = request.GET.get("status")
        message        = request.GET.get("message", "")

        logger.info(f"Callback: txn={transaction_id} status={status}")

        # 3. Idempotently update your record
        Order.objects.filter(
            transaction_id=transaction_id,
            payment_status="pending",
        ).update(payment_status=status.lower())

        # 4. Respond quickly — do heavy work in a background task
        return HttpResponse("OK", status=200)

Best Practices

  • Verify the callback token. For XCheckout integrations, always check the X-Callback-Token header before processing. Return 403 Forbidden immediately if the value is absent or wrong.
  • Respond quickly. Your endpoint should return an HTTP 200 within a few seconds. Offload any heavy processing — sending emails, generating receipts — to a background queue after responding.
  • Make your handler idempotent. Callbacks may be delivered more than once. Use the transaction_id as a natural idempotency key: only act when the record is in a pending state, and ignore subsequent callbacks for the same reference.
  • Log every callback. Store the raw query parameters and timestamp for each incoming callback. This is invaluable during incident investigation and reconciliation.
  • Use HTTPS. Your callback URL must use https://. Korba Xchange will not deliver callbacks to plain HTTP endpoints in production.
  • Cross-check with the Transaction Status API. For high-value transactions, confirm the callback by calling the Transaction Status endpoint independently before fulfilling an order.