> ## Documentation Index
> Fetch the complete documentation index at: https://docs.khaime.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Transaction

> Look up a transaction's current status on demand, instead of relying solely on webhooks.

## Intro

Look up a single transaction by its durable id — the same id echoed as `data.id` in the `payment.succeeded` / `payment.failed` webhook and returned as `transaction_id` from [Create Charge](/api-reference/payments/create-charge). Unlike [Get Session](/api-reference/payments/get-session), this id never expires.

## Context

Webhooks remain the recommended way to confirm payment outcomes — this endpoint exists for businesses that don't want to depend on webhook delivery alone (a webhook can be delayed, or your receiving endpoint can be temporarily down). Call it any time after a charge has been created to check current status, or use it to reconcile your own records against Khaime's.

The response is the exact same payment object shape delivered in the `payment.succeeded` / `payment.failed` webhook `data` field — whichever way you receive it, the fields match. It's deliberately scoped to that field set (not a full internal record dump): amounts, gateway reference, product, customer, and metadata — not the underlying business/customer/order joins an internal record would carry.

## Hows

### Path parameters

<ParamField path="transaction_id" type="integer" required>
  The transaction id — from `transaction_id` in a [Create Charge](/api-reference/payments/create-charge) response, or `data.id` in a payment webhook.
</ParamField>

### Response

```json theme={null}
{
  "success": true,
  "message": "Transaction retrieved successfully",
  "data": {
    "object": "payment",
    "id": "481920",
    "status": "succeeded",
    "payment_type": "one_time",
    "gateway": "paystack",
    "gateway_reference": "T123456789",
    "session_id": "intent_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "amounts": {
      "customer_paid": { "amount": 500000, "currency": "NGN" },
      "merchant_gross": { "amount": 500000, "currency": "NGN" },
      "merchant_net": { "amount": 485000, "currency": "NGN" },
      "fees": {
        "platform_fee": { "amount": 0, "currency": "NGN" },
        "gateway_fee": { "amount": 15000, "currency": "NGN" },
        "total": { "amount": 15000, "currency": "NGN" }
      }
    },
    "product": { "id": "501", "title": "Premium Plan", "type": "digital" },
    "customer": {
      "email": "customer@example.com",
      "first_name": "John",
      "last_name": "Doe"
    },
    "metadata": { "wc_order_id": "123" },
    "created_at": "2026-08-20T10:15:00.000Z",
    "paid_at": "2026-08-20T10:15:32.000Z"
  }
}
```

`status` is one of `succeeded`, `failed`, `refunded`, or `disputed` — it reflects the transaction's current state, not just its outcome at creation time, so a transaction that was refunded after payment shows `refunded` here rather than `succeeded`.

### Error codes

| Status | Error Code          | Cause                                                                                                                             |
| ------ | ------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `404`  | `ORDER_NOT_FOUND`   | `transaction_id` doesn't exist, or doesn't belong to your business (or an active sub-merchant, if you're a marketplace operator). |
| `422`  | `VALIDATION_FAILED` | `transaction_id` is missing or not a positive integer.                                                                            |
| `401`  | —                   | Invalid or missing API key.                                                                                                       |

<RequestExample>
  ```bash cURL theme={null}
  curl https://api.khaime.com/api/v1/partner/transactions/481920 \
    -H "X-API-Key: pk_sandbox_your_key"
  ```
</RequestExample>

## Whys

The response reuses the exact webhook-payload builder rather than a separate serializer, so this endpoint and your webhook handler can never drift apart — whichever one your integration reads from, the fields mean the same thing. Ownership follows the same rule as [Refunds](/payments/refunds): scoped to your business, or to an active sub-merchant if you operate a marketplace, since looking up payment details is the same trust boundary as reversing them.

## Why nots

* This is not a general transaction-search endpoint — it takes a single known `transaction_id`, not filters like date range or customer. Use your own records (built from webhooks or Create Charge responses) to know which id to look up.
* It does not return the full internal record — no linked business/order/customer table joins, only the fields already defined in the partner webhook payload shape.
* A suspended or pending sub-merchant's transactions can't be looked up through this endpoint by the marketplace operator until the sub-merchant is active again — same restriction as refunds.
