تاجر جني
Which API?
Merchant API For merchants: manage your own catalogue, orders and finances through the v2 Third-Party API. Application API For partner apps: browse Gini merchants and products, send customers to checkout and follow their orders.

New: Application API docs

Pick the API you are reading here — the Merchant API for your own store, the Application API for partner apps.

Merchant dashboard
API reference
Orders

Application API

For partner applications: browse merchants and products, hand customers a checkout link, and follow the orders it creates.

Orders

Orders created through your application — and only those. Read them, cancel a pending one, and fetch the reasons a cancellation accepts.

List orders

Orders created through your application, newest first. Items have the same shape as order details.

GET /api/third-party/v1/applications/orders
Signed
Query parameters
Field Type Required Description
status string Optional One of pending, accepted, delivery_handoff, received, in_warehouse, on_the_way, delayed, delivered, rejected, cancelled, expired, returned, rwa, refunded.
customer_id string Optional The customer's SuperQi id (sguid), not Gini's internal user id. Customers without SuperQi have none and cannot be filtered this way.
external_id string Optional Orders whose checkout token carried this external_id. Resolved inside your scope.
from_date date Optional Placed on or after, e.g. 2026-06-01.
to_date date Optional Placed on or before. Must be ≥ from_date.
page integer Optional Default 1.
page_size integer Optional Default 20, max 100.
Notes
  • Every filter is applied inside your application's scope — none can surface another application's orders.
Order details

One order created through your application. Any other order — another application's, an organic Gini order, an unknown id — is a plain 404 {"message": "Order not found"}, so ids cannot be probed.

GET /api/third-party/v1/applications/orders/{id}
Signed
Response
{
    "data": {
        "id": 265552,
        "status": "accepted",
        "is_pre_order": false,
        "payment": {
            "method": "cash_on_delivery",
            "status": "pending"
        },
        "shipping": {
            "method": "delivery",
            "cost": 5000
        },
        "amounts": {
            "total": "280000",
            "discount_total": null,
            "promo_code": null
        },
        "merchant": {
            "id": 1519,
            "name": "الجواد للاجهزة الكهربائية"
        },
        "items": [
            {
                "product_id": 285209,
                "variant_id": null,
                "name": "بلي شتيشن 4",
                "quantity": 1,
                "unit_price": "280000",
                "discount_unit_price": "0",
                "total_price": "280000",
                "discount_total_price": "0"
            }
        ],
        "placed_at": "2026-06-17T13:12:55+00:00",
        "accepted_at": "2026-06-17T14:02:11+00:00",
        "shipped_at": null,
        "delivered_at": null,
        "cancelled_at": null,
        "refunded_at": null
    }
}
Notes
  • amounts.total is a string; the other amounts are numbers.
  • cancelled_at covers cancellation, rejection and expiry. refunded_at covers both return flows.
  • Each timestamp is the last time the order reached that state, so an order delivered twice reports the second delivery.
  • No customer PII — no name, phone or address.
  • Deliberately excluded: code, the delivery PIN (holding it would let an application confirm a delivery that never happened), and promocode, the campaign code itself (it could be replayed). amounts.promo_code still gives the discount applied.
Cancel an order

Cancels an order your application created. This is a POST — sign the body.

POST /api/third-party/v1/applications/orders/{id}/cancel
Signed
Body parameters
Field Type Required Description
reject_reason_id integer Optional One of /reject-reasons (see Cancellation reasons below).
reject_reason_notes string Optional Max 1000.
Request
POST /orders/9182/cancel
{ "reject_reason_id": 3, "reject_reason_notes": "Customer changed their mind" }

Cancelling runs the same path as a customer cancelling in the app: the payment is reversed for the order's method (Aqsati cancellation, e-payment refund; nothing to reverse for cash or post-paid), stock is restored, and the customer and merchant are notified. The customer is taken from the order itself — you act on behalf of whoever placed it.

Status Body Meaning
200 { "data": { … } } Cancelled. The updated order, same shape as GET /orders/{id}.
400 { "key": "errors.validation.reject_reason_id.exists", … } reject_reason_id is not one of /reject-reasons.
404 {"message": "Order not found"} Not found, or not yours.
422 { "key": "errors.order_status_not_pending", … } Past pending — accepted, shipped, delivered, already cancelled.
422 { "key": "errors.order_not_self_cancellable", … } Paid with ratibi or dots, which have no automatic reversal. Contact Gini.
Cancellation reasons

The reference list for reject_reason_id. No parameters, not paginated — fetch once and cache.

GET /api/third-party/v1/applications/reject-reasons
Signed
Response
{
    "data": [
        {
            "id": 1,
            "title": "غيرت رأيي"
        },
        {
            "id": 2,
            "title": "طلبت بالخطأ"
        }
    ]
}
Notes
  • It returns exactly the reasons the cancel endpoint accepts: customer-side, active reasons only. Anything it withholds is rejected.
  • reject_reason_id stays optional — cancelling without one is valid.