تاجر جني
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
Wholesale API
Seller orders

API documentation

Everything you need to integrate with the Gini v2 Third-Party API.

Wholesale Seller Orders

The seller side of the Wholesale (B2B) API: list the orders other merchants have placed with you, inspect a single sale in full detail, and move it through its lifecycle — accept, deliver, or cancel. Every route is scoped to the calling signed merchant through its wholesaleSales relation, so an integration only ever sees and mutates its own sales. Writes run with webhook suppression, so a transition made here does not re-fire the merchant's own outbound webhook.

List seller orders

Returns the wholesale orders where the calling merchant is the seller, as a paginated collection, newest first. Pass an optional status to filter by lifecycle stage. List rows eager-load the buyer and the line items with their product only — item variant details are omitted here and appear on the single-order detail endpoint instead.

GET /api/v1.0/third-party/wholesale/orders/seller
Signed
Query parameters
Field Type Required Description
status string Optional Filter by lifecycle status. One of pending, accepted, delivered, cancelled.
page integer Optional Page number to retrieve. The page size is fixed at 15.
Response
{
    "data": [
        {
            "id": 4012,
            "status": "pending",
            "status_label": "Pending",
            "accepted_at": null,
            "delivered_at": null,
            "buyer_received_at": null,
            "total": "300000.000",
            "formatted_total": "IQD 300,000.000",
            "items": [
                {
                    "id": 9051,
                    "product": {
                        "id": 142,
                        "name": "Wireless Headphones",
                        "slug": "wireless-headphones",
                        "sku": "WH-2026-001",
                        "description": "Over-ear Bluetooth headphones",
                        "b2b_price": "150000.00",
                        "b2b_min_quantity": 2,
                        "quantity": 340,
                        "image": "https://s3.amazonaws.com/gini/products/142-1.jpg",
                        "images": [
                            "https://s3.amazonaws.com/gini/products/142-1.jpg",
                            "https://s3.amazonaws.com/gini/products/142-2.jpg"
                        ]
                    },
                    "quantity": 2,
                    "unit_price": "150000.000",
                    "formatted_unit_price": "IQD 150,000.000",
                    "total_price": "300000.000",
                    "formatted_total_price": "IQD 300,000.000"
                }
            ],
            "cancelled_by": null,
            "cancelled_at": null,
            "created_at": "2026-07-05 14:32",
            "buyer": {
                "id": 88,
                "business_name": "Baghdad Retail Co.",
                "logo_url": "https://s3.amazonaws.com/gini/merchants/88/logo.png",
                "business_phone": "+9647701234567"
            }
        }
    ],
    "links": {
        "first": "https://merchant.gini.iq/api/v1.0/third-party/wholesale/orders/seller?page=1",
        "last": "https://merchant.gini.iq/api/v1.0/third-party/wholesale/orders/seller?page=4",
        "prev": null,
        "next": "https://merchant.gini.iq/api/v1.0/third-party/wholesale/orders/seller?page=2"
    },
    "meta": {
        "current_page": 1,
        "last_page": 4,
        "per_page": 15,
        "total": 52
    }
}
Notes
  • Scoped to the signed merchant — only orders where you are the seller (wholesaleSales) are returned.
  • Ordered newest-first (latest created_at).
  • status is an optional filter; accepted values are pending, accepted, delivered and cancelled (the WholesaleOrderStatus enum). Anything else is rejected with a 422 validation error.
  • List rows load the buyer and items with their product only; the item variant is not loaded here, so list items have no variant key — fetch a single order to read variant attributes.
  • Paginated with a fixed page size of 15; navigate with the page query parameter. The response carries the standard data, links and meta blocks.
  • total and each item unit_price / total_price are decimal strings; formatted_total, formatted_unit_price and formatted_total_price mirror them pre-formatted in IQD.
  • Every request is HMAC-signed as the calling merchant.
Show seller order

Returns the full detail for a single wholesale sale owned by the calling merchant, including the line items with their product and — when the ordered line is a variant — the variant with its attribute values. The {id} path segment is the numeric wholesale order id; there is no route-model binding, so the order is looked up manually and scoped to the caller.

GET /api/v1.0/third-party/wholesale/orders/seller/{id}
Signed
Response
{
    "data": {
        "id": 4012,
        "status": "accepted",
        "status_label": "Accepted",
        "accepted_at": "2026-07-06 09:10",
        "delivered_at": null,
        "buyer_received_at": null,
        "total": "300000.000",
        "formatted_total": "IQD 300,000.000",
        "items": [
            {
                "id": 9051,
                "product": {
                    "id": 142,
                    "name": "Wireless Headphones",
                    "slug": "wireless-headphones",
                    "sku": "WH-2026-001",
                    "description": "Over-ear Bluetooth headphones",
                    "b2b_price": "150000.00",
                    "b2b_min_quantity": 2,
                    "quantity": 338,
                    "image": "https://s3.amazonaws.com/gini/products/142-1.jpg",
                    "images": [
                        "https://s3.amazonaws.com/gini/products/142-1.jpg",
                        "https://s3.amazonaws.com/gini/products/142-2.jpg"
                    ]
                },
                "variant": {
                    "id": 1167,
                    "sku": "WH-2026-001-BLK",
                    "b2b_price": "155000.00",
                    "quantity": 118,
                    "attributes": [
                        {
                            "id": 44,
                            "product_variant_id": 1167,
                            "product_attribute_id": 3,
                            "value": "Black",
                            "name": "Color"
                        }
                    ]
                },
                "quantity": 2,
                "unit_price": "150000.000",
                "formatted_unit_price": "IQD 150,000.000",
                "total_price": "300000.000",
                "formatted_total_price": "IQD 300,000.000"
            }
        ],
        "cancelled_by": null,
        "cancelled_at": null,
        "created_at": "2026-07-05 14:32",
        "buyer": {
            "id": 88,
            "business_name": "Baghdad Retail Co.",
            "logo_url": "https://s3.amazonaws.com/gini/merchants/88/logo.png",
            "business_phone": "+9647701234567"
        }
    }
}
Notes
  • Returns 404 with body {'message': 'Wholesale order not found.'} when the id does not exist or is not one of your sales.
  • The detail payload additionally loads each item variant (with its attribute values) on top of the product; variant is present only for lines ordered as a variant and is absent otherwise.
  • The nested product carries only the eager-loaded columns (id, name, slug, sku, description, b2b_price, b2b_min_quantity, quantity and image URLs); its category, seller client and variants blocks are not loaded on this endpoint.
  • status is the WholesaleOrderStatus backing string with a human status_label alongside it; cancelled_by is buyer, seller or null.
  • accepted_at, delivered_at, buyer_received_at and cancelled_at are Y-m-d H:i timestamps or null depending on the lifecycle stage.
Accept a seller order

Accepts a pending order the caller is selling. Stock is decremented at acceptance (not at placement), the variant/product row is locked to prevent over-selling, and the buyer is notified. Takes no request body.

POST /api/v1.0/third-party/wholesale/orders/seller/{id}/accept
Signed
Response
{
    "data": null
}
Notes
  • Takes no request body — the order is identified by the {id} path segment.
  • On success returns 200 with body {'data': null}; there is no order payload, so re-fetch via GET /orders/seller/{id} to read the new state.
  • Only a pending order can be accepted; any other status returns 422 with {'message': 'Only pending orders can be accepted.'}.
  • Stock is decremented inside a transaction with the variant/product row locked FOR UPDATE; if stock is insufficient the whole accept rolls back with 422 and {'message': 'Insufficient stock for product.'} (or the variant wording for a variant line).
  • Returns 404 with {'message': 'Wholesale order not found.'} when the id is not one of your sales.
  • On success the buyer receives an OrderAccepted notification, and the write runs with webhook suppression so it does not re-fire your own outbound webhook.
Mark a seller order as delivered

Marks an accepted order as delivered and notifies the buyer. The buyer separately confirms physical receipt later through their own flow (which sets buyer_received_at) — that is not part of this call. Takes no request body.

POST /api/v1.0/third-party/wholesale/orders/seller/{id}/deliver
Signed
Response
{
    "data": null
}
Notes
  • Takes no request body — the order is identified by the {id} path segment.
  • On success returns 200 with body {'data': null}; re-fetch via GET /orders/seller/{id} to read the new state.
  • Only an accepted order can be marked delivered; any other status returns 422 with {'message': 'Only accepted orders can be marked as delivered.'}.
  • Returns 404 with {'message': 'Wholesale order not found.'} when the id is not one of your sales.
  • delivered_at is stamped and the buyer receives an OrderDelivered notification. The buyer later confirms physical receipt through their own endpoint, which sets buyer_received_at.
  • Runs with webhook suppression, so delivering via this API does not re-fire your own outbound webhook.
Cancel a seller order

Cancels a pending order from the seller side and notifies the buyer. Sellers may only cancel while the order is still pending — once accepted, stock has been committed and only the buyer can cancel. Takes no request body.

POST /api/v1.0/third-party/wholesale/orders/seller/{id}/cancel
Signed
Response
{
    "data": null
}
Notes
  • Takes no request body — the order is identified by the {id} path segment.
  • On success returns 200 with body {'data': null}; re-fetch via GET /orders/seller/{id} to read the new state.
  • Sellers may only cancel a pending order; any other status returns 422 with {'message': 'Sellers can only cancel pending orders.'}. Once an order is accepted only the buyer can cancel it.
  • Returns 404 with {'message': 'Wholesale order not found.'} when the id is not one of your sales.
  • Cancelling stamps cancelled_at and sets cancelled_by to seller; because a pending order never decremented stock, none is restored. The buyer receives an OrderCancelled notification.
  • Runs with webhook suppression, so cancelling via this API does not re-fire your own outbound webhook.
List your buyers

Every merchant that has ever ordered from your wholesale catalogue, with their lifetime figures. Read-only and derived from your orders — there is no buyers record to create or edit.

GET /api/v1.0/third-party/wholesale/buyers
Signed
Query parameters
Field Type Required Description
search string Optional Match the buyer business name.
sort string Optional spend (default), orders, recent or name. name sorts ascending; the rest descending.
per_page integer Optional Results per page, 1–100. Defaults to 15.
Response
{
    "data": [
        {
            "buyer_id": 812,
            "business_name": "Baghdad Wholesale Co",
            "business_phone": "+9647701234567",
            "state_label": "Baghdad",
            "orders_count": 14,
            "delivered_count": 11,
            "lifetime_spend": 4250000,
            "last_order_at": "2026-09-02 11:30:00"
        }
    ],
    "meta": {
        "current_page": 1,
        "last_page": 1,
        "per_page": 15,
        "total": 1
    }
}
Notes
  • lifetime_spend counts DELIVERED orders only — a cancelled order still raises orders_count but contributes nothing to spend.
  • This list has meta but no links, because the rows are a GROUP BY rather than a model query.
  • Scoped to you as the seller: you only ever see merchants who have ordered from you.