SoftStore Reseller API v2

Buyer/reseller REST API

Reseller API v2 is separate from Seller API v1. Use it to search public SoftStore products, buy from reseller balance, read buyer-side history, chats, favorites and order delivery status.

Authentication

Exchange an existing SoftStore seller API key for a Bearer token.

curl -X POST https://api.softstore.app/api/v2/auth/api-key/create \
  -H "X-API-KEY: YOUR_API_KEY"

Use protected methods with Authorization: Bearer ACCESS_TOKEN.

JSON Response Format

Success
{
  "ok": true,
  "data": {},
  "meta": {}
}
Error
{
  "ok": false,
  "code": "invalid_request",
  "message": "Human readable message",
  "error": {
    "code": "invalid_request",
    "details": {}
  }
}

API v2 returns one human-readable error message in the top-level message field. The nested error object is kept only for structured fields such as code and details. PHP SDK methods return this error as a regular array and Node.js SDK methods return it as a regular object, so 4xx API responses do not become fatal runtime errors.

Security Rules and Errors

POST/auth/api-key/create

Exchange the existing Seller API key for a short-lived Bearer token used by every protected Reseller API v2 method.

Exchange the existing Seller API key for a short-lived Bearer token used by every protected Reseller API v2 method.

Parameters

NameInTypeRequiredDescription
X-API-KEYheaderstringyesExisting SoftStore Seller API key.

Request Example

curl -X POST https://api.softstore.app/api/v2/auth/api-key/create \
  -H "X-API-KEY: YOUR_API_KEY"
<?php
$ch = curl_init('https://api.softstore.app/api/v2/auth/api-key/create');
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => ['X-API-KEY: YOUR_API_KEY']]);
echo curl_exec($ch);
const res = await fetch('https://api.softstore.app/api/v2/auth/api-key/create', { method: 'POST', headers: { 'X-API-KEY': 'YOUR_API_KEY' } });
console.log(await res.json());

Response Example

{
  "ok": true,
  "data": { "access_token": "ACCESS_TOKEN", "token_type": "Bearer" },
  "meta": {}
}
GET/balance

Returns the current reseller balance and default currency.

Returns the current reseller balance and default currency. Use it before buy requests to prevent insufficient-balance errors.

Request Example

curl "https://api.softstore.app/api/v2/balance" \
  -H "Authorization: Bearer ACCESS_TOKEN"
<?php
$token = 'ACCESS_TOKEN';
$ch = curl_init('https://api.softstore.app/api/v2/balance');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
echo curl_exec($ch);
const token = 'ACCESS_TOKEN';
const res = await fetch('https://api.softstore.app/api/v2/balance', {
  method: 'GET',
  headers: { Authorization: `Bearer ${token}` }
});
const data = await res.json();
console.log(data);

Response Example

{
  "ok": true,
  "data": { "balance": 7200, "currency": "RUB" },
  "meta": {}
}
GET/products/123

Returns a paginated public catalog for one seller.

Returns a paginated public catalog for one seller. Use this for storefront sync and seller-specific product browsing.

Parameters

NameInTypeRequiredDescription
seller_idpathintegeryesPublic seller identifier.
page / limitqueryintegernoPagination controls.

Request Example

curl "https://api.softstore.app/api/v2/products/123?page=1&limit=50" \
  -H "Authorization: Bearer ACCESS_TOKEN"
<?php
$token = 'ACCESS_TOKEN';
$ch = curl_init('https://api.softstore.app/api/v2/products/123?page=1&limit=50');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
echo curl_exec($ch);
const token = 'ACCESS_TOKEN';
const res = await fetch('https://api.softstore.app/api/v2/products/123?page=1&limit=50', {
  method: 'GET',
  headers: { Authorization: `Bearer ${token}` }
});
const data = await res.json();
console.log(data);

Response Example

{
  "ok": true,
  "data": [{ "product_id": "10001", "name": "Product", "count": 25 }],
  "meta": { "page": 1, "limit": 50 }
}
GET/product/PRODUCT_ID

Returns full public product data including price, stock, seller fields, text description, delivery flags and bulk discount data when available.

Returns full public product data including price, stock, seller fields, text description, delivery flags and bulk discount data when available.

Parameters

NameInTypeRequiredDescription
product_idpathstringyesSoftStore product identifier.

Request Example

curl "https://api.softstore.app/api/v2/product/PRODUCT_ID" \
  -H "Authorization: Bearer ACCESS_TOKEN"
<?php
$token = 'ACCESS_TOKEN';
$ch = curl_init('https://api.softstore.app/api/v2/product/PRODUCT_ID');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
echo curl_exec($ch);
const token = 'ACCESS_TOKEN';
const res = await fetch('https://api.softstore.app/api/v2/product/PRODUCT_ID', {
  method: 'GET',
  headers: { Authorization: `Bearer ${token}` }
});
const data = await res.json();
console.log(data);

Response Example

{
  "ok": true,
  "data": { "product_id": "PRODUCT_ID", "name": "Product", "price": 999, "count": 10, "h2h": 1 },
  "meta": {}
}
POST/buy

Creates a buyer-side order from reseller balance.

Creates a buyer-side order from reseller balance. The method validates stock, H2H availability, seller restrictions and blocked categories before charging balance. If the product has comment_status=1, pass a valid comment. When product regex is configured, the complete comment must match it; otherwise API returns 422 comment_regex_mismatch.

Parameters

NameInTypeRequiredDescription
product_idbodystringyesProduct identifier to buy.
quantitybodyintegeryesUnits to purchase. Must be positive and available in stock.
commentbodystringconditionalBuyer activation data, max 200 chars. Required when product comment_status is enabled. HTML/script/control chars are rejected.

Request Example

curl -X POST "https://api.softstore.app/api/v2/buy" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"product_id":"PRODUCT_ID","quantity":1,"comment":"buyer_login@example.com"}'
<?php
$token = 'ACCESS_TOKEN';
$payload = ['product_id' => 'PRODUCT_ID', 'quantity' => 1, 'comment' => 'buyer_login@example.com'];
$ch = curl_init('https://api.softstore.app/api/v2/buy');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $token,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode($payload),
]);
echo curl_exec($ch);
const token = 'ACCESS_TOKEN';
const res = await fetch('https://api.softstore.app/api/v2/buy', {
  method: 'POST',
  headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({ product_id: 'PRODUCT_ID', quantity: 1, comment: 'buyer_login@example.com' })
});
const data = await res.json();
console.log(data);

Response Example

{
  "ok": true,
  "data": { "order_id": "123", "product_id": "PRODUCT_ID", "quantity": 1, "total": 999, "currency": "RUB", "h2h": 1 },
  "meta": {}
}
POST/gift

Creates a Gift code for a product from reseller balance.

Creates an H2H Gift purchase. The product must be active, moderated, in stock, H2H-deliverable and have gift_available=1. First release limitation: quantity/count must be 1. The successful response contains gift_code; the same code is sent to the order chat and buyer email.

Parameters

NameInTypeRequiredDescription
product_idbodystringyesProduct identifier linked to the Gift.
quantity / countbodyintegernoMust be 1 in the first release.

Request Example

curl -X POST "https://api.softstore.app/api/v2/gift" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"product_id":"PRODUCT_ID","quantity":1}'
<?php
$token = 'ACCESS_TOKEN';
$payload = ['product_id' => 'PRODUCT_ID', 'quantity' => 1];
$ch = curl_init('https://api.softstore.app/api/v2/gift');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $token,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode($payload),
]);
echo curl_exec($ch);
const token = 'ACCESS_TOKEN';
const res = await fetch('https://api.softstore.app/api/v2/gift', {
  method: 'POST',
  headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({ product_id: 'PRODUCT_ID', quantity: 1 })
});
const data = await res.json();
console.log(data);

Response Example

{
  "ok": true,
  "data": { "order_id": "ORDER_ID", "product_id": "PRODUCT_ID", "quantity": 1, "total": 999, "currency": "RUB", "h2h": 1, "gift": 1, "gift_code": "GIFT-0123456789ABCDEF" },
  "meta": {}
}
GET/history

Lists reseller buyer-side orders with filters for reconciliation, customer support and storefront order status sync.

Lists reseller buyer-side orders with filters for reconciliation, customer support and storefront order status sync.

Parameters

NameInTypeRequiredDescription
statusquerystringnoOrder status filter, for example paid, unpaid, dispute.
seller_idqueryintegernoFilter by seller.
product_idquerystringnoFilter by product.
date_from / date_toquerydatenoDate interval in YYYY-MM-DD format.
page / limitqueryintegernoPagination controls.

Request Example

curl "https://api.softstore.app/api/v2/history?status=paid&limit=50" \
  -H "Authorization: Bearer ACCESS_TOKEN"
<?php
$token = 'ACCESS_TOKEN';
$ch = curl_init('https://api.softstore.app/api/v2/history?status=paid&limit=50');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
echo curl_exec($ch);
const token = 'ACCESS_TOKEN';
const res = await fetch('https://api.softstore.app/api/v2/history?status=paid&limit=50', {
  method: 'GET',
  headers: { Authorization: `Bearer ${token}` }
});
const data = await res.json();
console.log(data);

Response Example

{
  "ok": true,
  "data": [{ "order_id": "123", "status": "paid", "total": 999 }],
  "meta": { "page": 1, "limit": 50 }
}
GET/order/ORDER_ID

Returns one reseller-owned order with current status, delivery data, dispute fields and linked chat identifiers when available.

Returns one reseller-owned order with current status, delivery data, dispute fields and linked chat identifiers when available.

Parameters

NameInTypeRequiredDescription
order_idpathstringyesOrder identifier returned by /buy or /history.

Request Example

curl "https://api.softstore.app/api/v2/order/ORDER_ID" \
  -H "Authorization: Bearer ACCESS_TOKEN"
<?php
$token = 'ACCESS_TOKEN';
$ch = curl_init('https://api.softstore.app/api/v2/order/ORDER_ID');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
echo curl_exec($ch);
const token = 'ACCESS_TOKEN';
const res = await fetch('https://api.softstore.app/api/v2/order/ORDER_ID', {
  method: 'GET',
  headers: { Authorization: `Bearer ${token}` }
});
const data = await res.json();
console.log(data);

Response Example

{
  "ok": true,
  "data": { "order_id": "ORDER_ID", "status": "paid", "delivery_text": "...", "chat_id": "CHAT_ID" },
  "meta": {}
}
GET/favorites

Lists reseller favorites.

Lists reseller favorites. Use POST on the same endpoint to add, remove or toggle a product in favorites.

Parameters

NameInTypeRequiredDescription
product_idbodystringPOST onlyProduct identifier.
actionbodystringPOST onlyOne of add, remove or toggle.

Request Example

curl "https://api.softstore.app/api/v2/favorites" \
  -H "Authorization: Bearer ACCESS_TOKEN"
<?php
$token = 'ACCESS_TOKEN';
$ch = curl_init('https://api.softstore.app/api/v2/favorites');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
echo curl_exec($ch);
const token = 'ACCESS_TOKEN';
const res = await fetch('https://api.softstore.app/api/v2/favorites', {
  method: 'GET',
  headers: { Authorization: `Bearer ${token}` }
});
const data = await res.json();
console.log(data);

Response Example

{
  "ok": true,
  "data": [{ "product_id": "PRODUCT_ID", "name": "Product" }],
  "meta": {}
}
GET/comment/PRODUCT_ID

Returns moderated public comments for a product.

Returns moderated public comments for a product. Useful before purchase and for storefront product detail pages.

Parameters

NameInTypeRequiredDescription
product_idpathstringyesProduct identifier.

Request Example

curl "https://api.softstore.app/api/v2/comment/PRODUCT_ID" \
  -H "Authorization: Bearer ACCESS_TOKEN"
<?php
$token = 'ACCESS_TOKEN';
$ch = curl_init('https://api.softstore.app/api/v2/comment/PRODUCT_ID');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
echo curl_exec($ch);
const token = 'ACCESS_TOKEN';
const res = await fetch('https://api.softstore.app/api/v2/comment/PRODUCT_ID', {
  method: 'GET',
  headers: { Authorization: `Bearer ${token}` }
});
const data = await res.json();
console.log(data);

Response Example

{
  "ok": true,
  "data": [{ "rating": 5, "text": "Fast delivery" }],
  "meta": {}
}
GET/chat/CHAT_ID

Reads messages for an order chat owned by the reseller.

Reads messages for an order chat owned by the reseller. Private chats for unrelated orders return forbidden or not found.

Parameters

NameInTypeRequiredDescription
chat_idpathstringyesChat identifier from order details.

Request Example

curl "https://api.softstore.app/api/v2/chat/CHAT_ID" \
  -H "Authorization: Bearer ACCESS_TOKEN"
<?php
$token = 'ACCESS_TOKEN';
$ch = curl_init('https://api.softstore.app/api/v2/chat/CHAT_ID');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
echo curl_exec($ch);
const token = 'ACCESS_TOKEN';
const res = await fetch('https://api.softstore.app/api/v2/chat/CHAT_ID', {
  method: 'GET',
  headers: { Authorization: `Bearer ${token}` }
});
const data = await res.json();
console.log(data);

Response Example

{
  "ok": true,
  "data": [{ "message_id": "1", "from": "buyer", "message": "Hello" }],
  "meta": {}
}
POST/chat/CHAT_ID

Sends a buyer-side message to a reseller-owned order chat.

Sends a buyer-side message to a reseller-owned order chat.

Parameters

NameInTypeRequiredDescription
chat_idpathstringyesChat identifier.
messagebodystringyesMessage text.

Request Example

curl -X POST "https://api.softstore.app/api/v2/chat/CHAT_ID" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"message":"Hello"}'
<?php
$token = 'ACCESS_TOKEN';
$payload = ['message' => 'Hello'];
$ch = curl_init('https://api.softstore.app/api/v2/chat/CHAT_ID');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $token,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode($payload),
]);
echo curl_exec($ch);
const token = 'ACCESS_TOKEN';
const res = await fetch('https://api.softstore.app/api/v2/chat/CHAT_ID', {
  method: 'POST',
  headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({ message: 'Hello' })
});
const data = await res.json();
console.log(data);

Response Example

{
  "ok": true,
  "data": { "message_id": "2", "sent": true },
  "meta": {}
}
POST/dispute

Opens or closes a dispute for a reseller-owned order and attaches the message to the dispute workflow.

Opens or closes a dispute for a reseller-owned order and attaches the message to the dispute workflow.

Parameters

NameInTypeRequiredDescription
order_idbodystringyesOrder identifier.
actionbodystringyesopen or close.
messagebodystringnoReason or comment for the dispute.

Request Example

curl -X POST "https://api.softstore.app/api/v2/dispute" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"order_id":"ORDER_ID","action":"open","message":"Delivery issue"}'
<?php
$token = 'ACCESS_TOKEN';
$payload = ['order_id' => 'ORDER_ID', 'action' => 'open', 'message' => 'Delivery issue'];
$ch = curl_init('https://api.softstore.app/api/v2/dispute');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $token,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode($payload),
]);
echo curl_exec($ch);
const token = 'ACCESS_TOKEN';
const res = await fetch('https://api.softstore.app/api/v2/dispute', {
  method: 'POST',
  headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({ order_id: 'ORDER_ID', action: 'open', message: 'Delivery issue' })
});
const data = await res.json();
console.log(data);

Response Example

{
  "ok": true,
  "data": { "order_id": "ORDER_ID", "dispute": true, "status": "dispute" },
  "meta": {}
}