API Documentation

Complete REST API documentation.

POST /auth/api-key/create

Generate JWT access token using API key.


curl -X POST https://api.softstore.app/api/v1/auth/api-key/create \
-H "X-API-KEY: YOUR_API_KEY"
Response Schema
access_token string
expires_in integer
POST /products

Request Overview

This endpoint allows sellers to create a new product in their inventory. The product will be attached to the authenticated seller account.

Important: Product name and UUID must be unique per seller account. The system automatically validates category existence, product quantity, pricing limits and feature formatting.

Request Parameters

Parameter Type Required Description
id_categories integer Yes Existing category identifier
name string Yes Product title (3-255 chars)
meta_title string Yes SEO meta title
meta_description string Yes SEO meta description
tags string Yes Comma-separated tags list
text_page string Yes Full product description (minimum 10 chars)
price integer Yes Product price (1 - 9,999,999)
count integer Yes Available stock quantity
uuid string Yes External product identifier (must be unique)
features string Yes Minimum 3 comma-separated features
discount integer No Optional product discount
api_key string No Optional external API integration key

Response Parameters

Field Type Description
status string Response status
message string Success confirmation message
id string Generated internal product ID

Validation Rules

  • Category ID must exist in available categories list
  • Product name must be unique
  • UUID must be unique
  • Features field requires minimum 3 values
  • Price cannot be less than 1
  • Stock count cannot be negative
  • Text description must contain at least 10 characters

Request Example


curl -X POST https://api.softstore.app/api/v1/products \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
    "id_categories": 1,
    "name": "Windows 11 Pro Key",
    "meta_title": "Windows License",
    "meta_description": "Official activation key",
    "tags": "windows,key,microsoft",
    "text_page": "Official Windows activation key",
    "price": 500,
    "count": 100,
    "uuid": "ext-123456",
    "features": "Lifetime activation,Instant delivery,Official key"
}'

$response = $api->createProduct([
    'id_categories' => $categoryId,
    'name' => 'Test Product ' . rand(1000,9999),
    'meta_title' => 'Test Meta Title',
    'meta_description' => 'Test Meta Description',
    'tags' => 'test,api,product',
    'text_page' => 'This is a test product description',
    'price' => rand(100,1000),
    'count' => rand(1,1000),
    'uuid' => 'ext-' . uniqid(),
    'features' => 'Feature 1,Feature 2,Feature 3'
]);

print_r($response);

const response = await fetch(
    'https://api.softstore.app/api/v1/products',
    {
        method: 'POST',
        headers: {
            Authorization: 'Bearer YOUR_JWT_TOKEN',
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            id_categories: 1,
            name: "Windows 11 Pro Key",
            meta_title: "Windows License",
            meta_description: "Official key",
            tags: "windows,key",
            text_page: "Official product description",
            price: 500,
            count: 100,
            uuid: "ext-123456",
            features: "Feature 1,Feature 2,Feature 3"
        })
    }
);

console.log(await response.json());

Success Response


{
    "status": "success",
    "data": {
        "message": "Product created",
        "id": "69f8bd078449b"
    }
}

Error Responses


{
    "status": "error",
    "message": "Field 'name' is required"
}

{
    "status": "error",
    "message": "Product with this UUID already exists"
}

{
    "status": "error",
    "message": "Invalid category id"
}
POST /products/update/{id}

Request Overview

This endpoint updates an existing product that belongs to the authenticated seller. Only the product owner can update product data.

Important: Some fields trigger product moderation after update. Product status may be changed to wait automatically.

Headers


Authorization: Bearer YOUR_JWT_TOKEN
Content-Type: application/json
Accept: application/json

URL Parameters

Parameter Type Required Description
id string Yes Product internal ID

Fields Without Moderation

Updating these fields does not trigger moderation.

Field Type Description
price integer Product price
discount integer Product discount percentage
count integer Available stock quantity
api_key string External API integration key
api_url string External API URL

Fields That Trigger Moderation

Updating these fields will automatically send the product back to moderation.

Field Type Description
name string Product name
meta_title string SEO title
meta_description string SEO description
tags string Product tags
text_page string Product description
uuid string External product UUID
features string Comma-separated product features
id_categories integer Product category ID

Restricted Fields

The following fields cannot be updated:
  • rating
  • status_moderation

Request Example


curl -X POST https://api.softstore.app/api/v1/products/update/69f46db161e76 \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
    "price": 999,
    "discount": 15,
    "count": 200,
    "api_key": "new-api-key",
    "api_url": "https://example.com/api",
    "name": "Updated Product Name",
    "text_page": "Updated product description",
    "tags": "updated,test,product",
    "features": "Feature A,Feature B,Feature C",
    "id_categories": 8
}'

$response = $api->updateProduct('69f46db161e76', [

    'price' => rand(100,999),
    'discount' => rand(0,30),
    'count' => rand(1,500),
    'api_key' => 'new-api-key',
    'api_url' => 'https://example.com/api',

    'name' => 'Updated Product',
    'text_page' => 'Updated description',
    'tags' => 'update,test',
    'features' => 'Feature 1,Feature 2,Feature 3',
    'id_categories' => 8
]);

print_r($response);

const response = await fetch(
    'https://api.softstore.app/api/v1/products/update/69f46db161e76',
    {
        method: 'POST',
        headers: {
            Authorization: 'Bearer YOUR_JWT_TOKEN',
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            price: 999,
            discount: 15,
            count: 300,
            name: "Updated Product",
            text_page: "Updated product description",
            tags: "update,test",
            features: "Feature 1,Feature 2,Feature 3"
        })
    }
);

console.log(await response.json());

Success Response


{
    "status": "success",
    "data": {
        "message": "Product updated",
        "moderation": true
    }
}

Error Responses


{
    "status": "error",
    "message": "Product not found or access denied"
}

{
    "status": "error",
    "message": "Invalid price"
}

{
    "status": "error",
    "message": "UUID already exists"
}

{
    "status": "error",
    "message": "No fields to update"
}
DELETE /products/{id}

Request Overview

This endpoint permanently deletes an existing product from the authenticated seller inventory.

Warning: Product deletion is permanent and cannot be undone.

Headers


Authorization: Bearer YOUR_JWT_TOKEN
Accept: application/json

URL Parameters

Parameter Type Required Description
id string Yes Internal product ID returned after product creation

Response Parameters

Field Type Description
status string Response status
message string Deletion confirmation message

Validation Rules

  • User must be authenticated via JWT token
  • Product must exist
  • Product must belong to authenticated seller
  • Deleted products cannot be restored

Request Example


curl -X DELETE https://api.softstore.app/api/v1/products/69f8bd078449b \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Accept: application/json"

$productId = "69f8bd078449b";

$response = $api->deleteProduct($productId);

print_r($response);

const productId = "69f8bd078449b";

const response = await fetch(
    `https://api.softstore.app/api/v1/products/${productId}`,
    {
        method: 'DELETE',
        headers: {
            Authorization: 'Bearer YOUR_JWT_TOKEN',
            Accept: 'application/json'
        }
    }
);

console.log(await response.json());

Success Response


{
    "status": "success",
    "data": {
        "message": "Product deleted"
    }
}

Error Responses


{
    "status": "error",
    "message": "Unauthorized"
}
 
{
    "status": "error",
    "message": "Product not found"
}

{
    "status": "error",
    "message": "Delete failed or access denied"
}
GET /products/info/{id}

Request Overview

Retrieve full information about a specific product that belongs to the authenticated seller account.

Important: The system returns product details only if the product exists and belongs to the authenticated seller.

Headers


Authorization: Bearer YOUR_JWT_TOKEN
Accept: application/json

URL Parameters

Parameter Type Required Description
id string Yes Internal product identifier

Response Parameters

Field Type Description
status string Response status
product.id string Internal product ID
product.name string Product name
product.price integer Product price
product.count integer Available stock quantity
product.discount integer Applied discount percentage
product.uuid string External product UUID
product.status_moderation string Moderation status
product.created_at datetime Creation date

Validation Rules

  • User must be authenticated
  • Product must exist
  • Product must belong to authenticated seller
  • Invalid product ID returns error

Request Example


curl -X GET https://api.softstore.app/api/v1/products/info/69f8bd078449b \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Accept: application/json"

$productId = "69f8bd078449b";

$response = $api->getProductInfo($productId);

print_r($response);

const productId = "69f8bd078449b";

const response = await fetch(
    `https://api.softstore.app/api/v1/products/info/${productId}`,
    {
        method: 'GET',
        headers: {
            Authorization: 'Bearer YOUR_JWT_TOKEN',
            Accept: 'application/json'
        }
    }
);

console.log(await response.json());

Success Response


{
    "status": "success",
    "data": {
        "product": {
            "id": "69f8bd078449b",
            "name": "Windows 11 Pro Key",
            "price": 500,
            "count": 100,
            "discount": 10,
            "uuid": "ext-123456",
            "status_moderation": "approved",
            "created_at": "2026-05-05 12:30:00"
        }
    }
}

Error Responses


{
    "status": "error",
    "message": "Unauthorized"
}

{
    "status": "error",
    "message": "Product not found"
}

{
    "status": "error",
    "message": "Access denied"
}
GET /products

Request Overview

Returns a paginated list of products that belong to the authenticated seller account.

Important: This endpoint supports pagination and filtering. Use query parameters to optimize large product inventories.

Headers


Authorization: Bearer YOUR_JWT_TOKEN
Accept: application/json

Query Parameters

Parameter Type Required Description
page integer No Pagination page number (default: 1)
limit integer No Items per page (default: 20)
status string No Filter by moderation status
category integer No Filter by category ID
search string No Search products by name

Response Parameters

Field Type Description
status string Response status
products array List of seller products
products[].id string Product internal ID
products[].name string Product title
products[].price integer Product price
products[].count integer Available quantity
products[].status_moderation string Moderation status
pagination.total integer Total products count
pagination.page integer Current page
pagination.limit integer Current limit

Validation Rules

  • User must be authenticated
  • Page value must be greater than 0
  • Limit value must be within allowed range
  • Invalid filters may return empty result

Request Example


curl -X GET "https://api.softstore.app/api/v1/products?page=1&limit=20" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Accept: application/json"

$response = $api->getProducts([
    'page' => 1,
    'limit' => 20,
    'status' => 'approved'
]);

print_r($response);

const response = await fetch(
    'https://api.softstore.app/api/v1/products?page=1&limit=20',
    {
        method: 'GET',
        headers: {
            Authorization: 'Bearer YOUR_JWT_TOKEN',
            Accept: 'application/json'
        }
    }
);

console.log(await response.json());

Success Response


{
    "status": "success",
    "data": {
        "products": [
            {
                "id": "69f8bd078449b",
                "name": "Windows 11 Pro Key",
                "price": 500,
                "count": 100,
                "status_moderation": "approved"
            }
        ],
        "pagination": {
            "total": 150,
            "page": 1,
            "limit": 20
        }
    }
}

Error Responses


{
    "status": "error",
    "message": "Unauthorized"
}

{
    "status": "error",
    "message": "Invalid pagination parameters"
}
GET /products/categories

Request Overview

This endpoint returns the full list of available product categories that sellers can use when creating or updating products.

Important: Use category IDs from this endpoint when sending id_categories during product creation or update.

Headers


Authorization: Bearer YOUR_JWT_TOKEN
Accept: application/json

Response Parameters

Field Type Description
status string Response status
data array Array of available categories
id integer Category internal identifier
name string Category title
slug string Category URL slug
status string Category status

Business Logic

  • Returns only active categories
  • Inactive categories may be hidden from sellers
  • Category IDs are required for product creation
  • Use this endpoint before creating marketplace integrations

Request Example


curl -X GET https://api.softstore.app/api/v1/products/categories \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Accept: application/json"

$response = $api->getCategories();

print_r($response);

const response = await fetch(
    'https://api.softstore.app/api/v1/products/categories',
    {
        method: 'GET',
        headers: {
            Authorization: 'Bearer YOUR_JWT_TOKEN',
            Accept: 'application/json'
        }
    }
);

console.log(await response.json());

Success Response


{
    "status": "success",
    "data": [
        {
            "id": 1,
            "name": "Software Keys",
            "slug": "software-keys",
            "status": "active"
        },
        {
            "id": 2,
            "name": "Gaming Accounts",
            "slug": "gaming-accounts",
            "status": "active"
        },
        {
            "id": 3,
            "name": "Subscriptions",
            "slug": "subscriptions",
            "status": "active"
        }
    ]
}

Error Responses


{
    "status": "error",
    "message": "Unauthorized"
}

{
    "status": "error",
    "message": "Categories not found"
}
POST /products/moderation

Request Overview

This endpoint sends an existing product to manual moderation. Uploading or replacing the product image also returns the product to pending moderation. After submitting, moderators will review product content, image, pricing, category selection and marketplace compliance.

Important: Products already under moderation may not be submitted again until the current review process is completed.

Headers


Authorization: Bearer YOUR_JWT_TOKEN
Content-Type: application/json
Accept: application/json

Request Parameters

Parameter Type Required Description
id_product string Yes Internal product identifier

Response Parameters

Field Type Description
status string Response status
message string Moderation submission result
moderation_status string Current moderation state

Moderation Rules

  • Product must belong to authenticated seller
  • Product must exist
  • Product cannot already be under active moderation
  • A product must have an image before it can be sent to moderation
  • Uploading/replacing an image sets moderation back to pending
  • Moderators may reject invalid products
  • Rejected products can be fixed and resubmitted later

Request Example


curl -X POST https://api.softstore.app/api/v1/products/moderation \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
    "id_product": "69f8bd078449b"
}'

$response = $api->sendProductToModeration([
    'id_product' => '69f8bd078449b'
]);

print_r($response);

const response = await fetch(
    'https://api.softstore.app/api/v1/products/moderation',
    {
        method: 'POST',
        headers: {
            Authorization: 'Bearer YOUR_JWT_TOKEN',
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            id_product: "69f8bd078449b"
        })
    }
);

console.log(await response.json());

Success Response


{
    "status": "success",
    "data": {
        "message": "Product submitted for moderation",
        "moderation_status": "pending"
    }
}

Error Responses


{
    "status": "error",
    "message": "Unauthorized"
}

{
    "status": "error",
    "message": "Product not found"
}

{
    "status": "error",
    "message": "Product is already under moderation"
}

{
    "status": "error",
    "message": "Access denied"
}
GET /orders

Request Overview

This endpoint returns the full order history for the authenticated seller. It allows sellers to monitor all purchases made for their products. Buyer email addresses are intentionally not exposed in seller API responses or in the seller dashboard.

Important: Only orders related to the authenticated seller account will be returned.

Headers


Authorization: Bearer YOUR_JWT_TOKEN
Accept: application/json

Response Parameters

Field Type Description
id_order string Unique order identifier
id_product string Purchased product ID
amount string Total order amount
status_order string Current order status (wait / paid / canceled)
data_create string Order creation date
time_create string Order creation time
count string Purchased quantity

Business Logic

  • Returns only seller-owned orders
  • Does not expose buyer email addresses
  • Requires valid JWT authorization
  • Orders are returned as full history list
  • Use /orders/info/{id} for detailed order information

Request Example


curl -X GET https://api.softstore.app/api/v1/orders \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Accept: application/json"

$response = $api->getOrders();

print_r($response);

const response = await fetch(
    'https://api.softstore.app/api/v1/orders',
    {
        method: 'GET',
        headers: {
            Authorization: 'Bearer YOUR_JWT_TOKEN',
            Accept: 'application/json'
        }
    }
);

console.log(await response.json());

Success Response


{
    "status": "success",
    "data": [
        {
            "id_order": "3fb0a629f15a0bdd7ce4b69f9a164911",
            "id_product": "69f362be33c2a",
            "amount": "9408",
            "status_order": "wait",
            "data_create": "2026-05-02",
            "time_create": "17:28:49",
            "count": "16"
        },
        {
            "id_order": "4b51c4d77809743fdd172713feb02300",
            "id_product": "777156470",
            "amount": "640",
            "status_order": "paid",
            "data_create": "2026-04-28",
            "time_create": "13:46:13",
            "count": "5"
        }
    ]
}

Error Responses


{
    "status": "error",
    "message": "Unauthorized"
}
GET /orders/info/{id}

Request Overview

This endpoint returns detailed information about a specific order. Sellers can only access orders that belong to their own account.

Important: If the order does not belong to the authenticated seller, access will be denied.

Headers


Authorization: Bearer YOUR_JWT_TOKEN
Accept: application/json

Path Parameters

Parameter Type Required Description
id string Yes Unique order identifier

Response Parameters

Field Type Description
id string Internal database ID
id_user string Registered buyer ID (if available)
guest_id string Guest buyer identifier
buyer_type string Buyer type (guest / registered)
id_product string Purchased product ID
id_seller string Seller identifier
id_order string Public order identifier
status_order string Order status
data_create string Order creation date
time_create string Order creation time
amount string Total payment amount
count string Purchased quantity
payment_system string Payment provider name

Business Logic

  • Seller can only access their own orders
  • Order must exist
  • Requires valid JWT token
  • Returns order payment and delivery metadata without buyer email

Request Example


curl -X GET https://api.softstore.app/api/v1/orders/info/4b51c4d77809743fdd172713feb02300 \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Accept: application/json"

$response = $api->infoOrder(
    '4b51c4d77809743fdd172713feb02300'
);

print_r($response);

const orderId = "4b51c4d77809743fdd172713feb02300";

const response = await fetch(
    `https://api.softstore.app/api/v1/orders/info/${orderId}`,
    {
        method: 'GET',
        headers: {
            Authorization: 'Bearer YOUR_JWT_TOKEN',
            Accept: 'application/json'
        }
    }
);

console.log(await response.json());

Success Response


{
    "status": "success",
    "data": {
        "id": "94",
        "id_user": "0",
        "guest_id": "70df52e8ca9741105f5d3ccaee808edd",
        "buyer_type": "guest",
        "id_product": "777156470",
        "id_seller": "1774966755",
        "id_order": "4b51c4d77809743fdd172713feb02300",
        "email": "ads@frogs-wallet.biz",
        "status_order": "paid",
        "data_create": "2026-04-28",
        "time_create": "13:46:13",
        "amount": "640",
        "count": "5",
        "payment_system": "cyberpay"
    }
}

Error Responses


{
    "status": "error",
    "message": "Unauthorized"
}

{
    "status": "error",
    "message": "Order not found or access denied"
}
POST /orders/delivery/{token}

Overview

This endpoint allows sellers to deliver digital products after receiving a successful payment webhook notification.

Important: The {token} is automatically generated by SoftStore and included inside webhook notification payload.

Delivery Flow


1. Customer purchases product
↓
2. Payment completed
↓
3. SoftStore sends webhook to seller API
↓
4. Seller receives delivery_url
↓
5. Seller sends digital product to delivery_url
↓
6. Buyer receives product via email

Webhook Notification Example


{
  "id_order": "030a3c6f15f2744e58f2e24fd40d3466",
  "id_product": "69f36497dc78f",
  "payment_status": "paid",
  "signature": "df595764abc185bbf31c5c6334cfade65379feb6",
  "delivery_url": "https://api.softstore.app/api/v1/orders/delivery/TOKEN",
  "token": "d487c01d834dcb296c4f7b5a02e0b0d9df320bb153778d6c20cd26e2c50b40bf"
}

Request Body

Field Type Required Description
text string Yes Product delivery message / activation key / credentials
download string (https url) No Optional download link for digital file delivery

Delivery Types

Text Delivery:
Product keys, credentials, license codes, instructions
Download Delivery:
Files, archives, software installers, ebooks etc.

Request Examples


curl -X POST \
https://api.softstore.app/api/v1/orders/delivery/TOKEN_HERE \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
  "text":"Windows 11 activation key: XXXXX-XXXXX",
  "download":"https://cdn.example.com/windows.zip"
}'

$response = $api->deliverOrder($token, [
    'text' => 'Windows license key: XXXXX',
    'download' => 'https://cdn.example.com/file.zip'
]);

print_r($response);

await fetch(deliveryUrl, {
    method: "POST",
    headers: {
        "Authorization": "Bearer YOUR_JWT_TOKEN",
        "Content-Type": "application/json"
    },
    body: JSON.stringify({
        text: "Your license key: XXXXX",
        download: "https://cdn.example.com/file.zip"
    })
});

Success Response


{
  "status": "success",
  "data": {
    "message": "Product delivered successfully",
    "id_order": "030a3c6f15f2744e58f2e24fd40d3466",
    "delivered": true
  }
}

Error Responses

HTTP Error Description
401 Unauthorized Invalid JWT token
404 Order not found Invalid delivery token
409 Order already delivered Product already sent
422 Invalid download URL Only HTTPS links allowed
GET /seller

Request Overview

This endpoint returns full information about the authenticated seller account. It allows marketplace sellers to retrieve profile information, financial balance, API settings, moderation status and public store details.

Important: This endpoint only returns data for the authenticated seller. JWT authorization is required.

Headers


Authorization: Bearer YOUR_JWT_TOKEN
Accept: application/json

Response Parameters

Field Type Description
id integer Internal seller record ID
id_user integer Telegram/User account identifier
name string Store name
balance integer Current seller balance
img string Seller profile image URL
description string Store description
api_url string Connected external API URL
data_create string Account registration date
rating integer Seller marketplace rating
api_key string Seller API key
status_moderation integer Seller moderation status

Business Logic

  • JWT token must be valid
  • Seller account must exist
  • Only current authenticated seller data is returned
  • API key is returned for integration usage
  • Balance reflects current available funds

Request Example


curl -X GET https://api.softstore.app/api/v1/seller \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Accept: application/json"

createApiKey();

// get seller info
$response = $api->getSellerInfo();

print_r($response);

const response = await fetch(
    'https://api.softstore.app/api/v1/seller',
    {
        method: 'GET',
        headers: {
            Authorization: 'Bearer YOUR_JWT_TOKEN',
            Accept: 'application/json'
        }
    }
);

console.log(await response.json());

Success Response


{
    "status": "success",
    "data": {
        "id": 1,
        "id_user": 1774966755,
        "name": "My shop 777",
        "balance": 19056,
        "img": "https://img.softstore.app/uploads/example.png",
        "description": "Best shop ever 777",
        "api_url": "https://api.soft-shop.com",
        "data_create": "10.04.2026",
        "rating": 0,
        "api_key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "status_moderation": 0
    }
}

Error Responses


{
    "status": "error",
    "message": "Unauthorized"
}

{
    "status": "error",
    "message": "Seller not found"
}
POST /seller/profile

Request Overview

This endpoint allows sellers to update their store profile information. Only specific fields are allowed for editing. The system validates all incoming data before saving changes.

Important: Only name, description and api_url fields can be updated.

Headers


Authorization: Bearer YOUR_JWT_TOKEN
Content-Type: application/json
Accept: application/json

Allowed Request Parameters

Parameter Type Required Description
name string No Store name (3-100 characters)
description string No Store description (10-1000 characters)
api_url string No External API URL

Validation Rules

  • Name must contain 3 to 100 characters
  • Name cannot contain dangerous symbols
  • Description must contain 10 to 1000 characters
  • HTML/script tags are automatically sanitized
  • API URL must be valid
  • Unknown fields are rejected
  • Empty update requests are rejected

Restricted Fields

The following fields cannot be updated through this endpoint:
  • balance
  • rating
  • api_key
  • status_moderation
  • id_user

Request Example


curl -X POST https://api.softstore.app/api/v1/seller/profile \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
    "name": "My New Store Name",
    "description": "Updated store description for customers",
    "api_url": "https://example-api.com"
}'

createApiKey();

// update seller profile
$response = $api->updateSellerProfile([
    'name' => 'Updated Store Name',
    'description' => 'Updated description text',
    'api_url' => 'https://example-api.com'
]);

print_r($response);

const response = await fetch(
    'https://api.softstore.app/api/v1/seller/profile',
    {
        method: 'POST',
        headers: {
            Authorization: 'Bearer YOUR_JWT_TOKEN',
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            name: "Updated Store Name",
            description: "Updated description text",
            api_url: "https://example-api.com"
        })
    }
);

console.log(await response.json());

Success Response


{
    "status": "success",
    "data": {
        "id": 1,
        "name": "Updated Store Name",
        "description": "Updated description text",
        "api_url": "https://example-api.com"
    }
}

Error Responses


{
    "status": "error",
    "message": "Unauthorized"
}

{
    "status": "error",
    "message": "Invalid JSON"
}

{
    "status": "error",
    "message": "Name must be between 3 and 100 characters"
}

{
    "status": "error",
    "message": "Description too short (min 10)"
}

{
    "status": "error",
    "message": "Invalid API URL"
}

{
    "status": "error",
    "message": "Field 'balance' is not allowed"
}

{
    "status": "error",
    "message": "No valid data to update"
}

{
    "status": "error",
    "message": "Profile not updated"
}
POST /products/img

Request Overview

This endpoint uploads a product image for an existing product. Images are uploaded using multipart/form-data. The image will be linked to the authenticated seller product.

Important: Product must belong to the authenticated seller. Only valid image formats are accepted.

Headers


Authorization: Bearer YOUR_JWT_TOKEN
Content-Type: multipart/form-data

Form Data Parameters

Parameter Type Required Description
img file Yes Product image file
id_product string Yes Product internal ID

Validation Rules

  • JWT token must be valid
  • Product must exist
  • Product must belong to authenticated seller
  • Image file is required
  • Only image MIME types are accepted
  • Invalid uploads are rejected

Request Example


curl -X POST https://api.softstore.app/api/v1/products/img \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-F "img=@product-image.png" \
-F "id_product=69f8bd078449b"

createApiKey();

// upload image
$response = $api->uploadProductImage(
    '69f8bd078449b',
    '/home/user/product-image.png'
);

print_r($response);

const formData = new FormData();

formData.append('img', fileInput.files[0]);
formData.append('id_product', '69f8bd078449b');

const response = await fetch(
    'https://api.softstore.app/api/v1/products/img',
    {
        method: 'POST',
        headers: {
            Authorization: 'Bearer YOUR_JWT_TOKEN'
        },
        body: formData
    }
);

console.log(await response.json());

Success Response


{
    "status": "success",
    "data": {
        "message": "Product image uploaded",
        "url": "https://img.softstore.app/uploads/products/example.png"
    }
}

Error Responses


{
    "status": "error",
    "message": "Unauthorized"
}

{
    "status": "error",
    "message": "Image file required"
}

{
    "status": "error",
    "message": "Product not found or access denied"
}

{
    "status": "error",
    "message": "Invalid image format"
}
POST /seller/img

Request Overview

This endpoint allows sellers to upload or update their profile image. The uploaded image becomes the public avatar/logo of the seller store.

Important: Only authenticated sellers can upload profile images. Previous image may be replaced automatically.

Headers


Authorization: Bearer YOUR_JWT_TOKEN
Content-Type: multipart/form-data

Form Data Parameters

Parameter Type Required Description
img file Yes Seller profile image file

Validation Rules

  • JWT token must be valid
  • Image file is required
  • Only valid image formats are allowed
  • Invalid uploads will be rejected
  • Old profile image may be replaced automatically

Request Example


curl -X POST https://api.softstore.app/api/v1/seller/img \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-F "img=@seller-avatar.png"

createApiKey();

// upload seller image
$response = $api->uploadSellerImage(
    '/home/user/seller-avatar.png'
);

print_r($response);

const formData = new FormData();

formData.append('img', fileInput.files[0]);

const response = await fetch(
    'https://api.softstore.app/api/v1/seller/img',
    {
        method: 'POST',
        headers: {
            Authorization: 'Bearer YOUR_JWT_TOKEN'
        },
        body: formData
    }
);

console.log(await response.json());

Success Response


{
    "status": "success",
    "data": {
        "message": "Profile image uploaded",
        "url": "https://img.softstore.app/uploads/sellers/avatar.png"
    }
}

Error Responses


{
    "status": "error",
    "message": "Unauthorized"
}

{
    "status": "error",
    "message": "Image file required"
}

{
    "status": "error",
    "message": "Invalid image format"
}

{
    "status": "error",
    "message": "Upload failed"
}
POST /payout

Request Overview

Create a withdrawal request from seller internal balance. This endpoint requires Google Authenticator OTP verification.

Important: Funds are immediately reserved after successful payout creation.

Headers


Authorization: Bearer YOUR_JWT_TOKEN
Content-Type: application/json
Accept: application/json

Request Parameters

Parameter Type Required Description
amount integer Yes Payout amount (min: 1000)
payment_system string Yes usdt / card / payment_account
wallet string Yes Wallet address / card number / bank account
cod string Yes 6-digit Google Authenticator OTP code

Validation Rules

  • JWT token must be valid
  • Seller account must exist
  • Amount must be between 1000 and 1000000
  • Seller balance must be sufficient
  • OTP code must be valid
  • Only supported payout systems allowed

Request Example


curl -X POST https://api.softstore.app/api/v1/payout \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
    "amount": 5000,
    "payment_system": "usdt",
    "wallet": "TRC20_WALLET_ADDRESS",
    "cod": "123456"
}'

 [
            'method' => 'POST',
            'header' => [
                'Authorization: Bearer YOUR_JWT_TOKEN',
                'Content-Type: application/json'
            ],
            'content' => json_encode([
                'amount' => 5000,
                'payment_system' => 'usdt',
                'wallet' => 'TRC20_WALLET_ADDRESS',
                'cod' => '123456'
            ])
        ]
    ])
);

echo $response;

const response = await fetch(
    'https://api.softstore.app/api/v1/payout',
    {
        method: 'POST',
        headers: {
            Authorization: 'Bearer YOUR_JWT_TOKEN',
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            amount: 5000,
            payment_system: 'usdt',
            wallet: 'TRC20_WALLET_ADDRESS',
            cod: '123456'
        })
    }
);

console.log(await response.json());

Success Response


{
    "status": "success",
    "data": {
        "id_order": "6fa81a21b1d44e9"
    }
}

Error Responses


{
    "status": "error",
    "message": "Unauthorized"
}

{
    "status": "error",
    "message": "Invalid OTP code"
}

{
    "status": "error",
    "message": "Insufficient balance"
}
GET /payout/history

Request Overview

Retrieve full payout history for the authenticated seller. Returns withdrawal transactions created from seller balance.

Important: Only payouts created by the authenticated seller are returned.

Headers


Authorization: Bearer YOUR_JWT_TOKEN
Accept: application/json

Request Parameters

Parameter Type Required Description
No This endpoint does not require request body parameters

Response Parameters

Field Type Description
id_order string Payout transaction identifier
type string Transaction type (out)
amount integer Payout amount
status string Payout processing status
payment_system string Selected payout payment method
date_create date Creation date
time_create time Creation time

Validation Rules

  • User must be authenticated
  • Seller account must exist
  • Only own payout history is accessible

Request Example


curl -X GET https://api.softstore.app/api/v1/payout/history \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Accept: application/json"

createApiKey();

// get payout history
$response = $api->getPayoutHistory();

print_r($response);

const response = await fetch(
    'https://api.softstore.app/api/v1/payout/history',
    {
        method: 'GET',
        headers: {
            Authorization: 'Bearer YOUR_JWT_TOKEN',
            Accept: 'application/json'
        }
    }
);

console.log(await response.json());

Success Response


{
    "status": "success",
    "data": [
        {
            "id_order": "6fa81a21b1d44e9",
            "type": "out",
            "amount": 5000,
            "status": "wait",
            "payment_system": "usdt",
            "date_create": "2026-05-17",
            "time_create": "14:25:11"
        }
    ]
}

Error Responses


{
    "status": "error",
    "message": "Unauthorized"
}

{
    "status": "error",
    "message": "Seller not found"
}
POST Seller Webhook Notifications

Overview

SoftStore automatically sends webhook notifications to your api_url after successful payment.

Configure your webhook URL via: POST /seller/profile

Incoming Webhook Payload


{
  "id_order": "030a3c6f15f2744e58f2e24fd40d3466",
  "id_product": "69f36497dc78f",
  "payment_status": "paid",
  "signature": "df595764abc185bbf31c5c6334cfade65379feb6",
  "delivery_url": "https://api.softstore.app/api/v1/orders/delivery/TOKEN",
  "token": "d487c01d834dcb296c4f7b5a02e0b0d9df320bb153778d6c20cd26e2c50b40bf"
}

Signature Verification

Signature formula:


sha1( sha1(api_key) + id_order)

PHP Example


$payload = json_decode(
    file_get_contents('php://input'),
    true
);

$apiKey = "YOUR_SECRET_API_KEY";

$expected = sha1(
    sha1($apiKey) . $payload['id_order']
);

if ($expected !== $payload['signature']) {
    http_response_code(403);
    exit('Invalid signature');
}

$deliveryUrl = $payload['delivery_url'];

echo "Webhook verified";

Node.js Example


const crypto = require("crypto");

app.post("/webhook", (req, res) => {

    const payload = req.body;


     // sha1(apiKey)
        const hashedApiKey = crypto
            .createHash("sha1")
            .update(API_KEY)
            .digest("hex");

    const expected = crypto
        .createHash("sha1")
        .update(hashedApiKey + payload.id_order)
        .digest("hex");

    if (expected !== payload.signature) {
        return res.status(403).json({
            error: "Invalid signature"
        });
    }

    const deliveryUrl = payload.delivery_url;

    console.log("Valid webhook:", deliveryUrl);

    res.json({
        success: true
    });
});

Recommended Flow


Receive webhook
↓
Validate signature
↓
Get delivery_url
↓
Generate product/license/file
↓
Send product to delivery_url
↓
Customer receives order

Webhook Errors

Error Description
Invalid signature Webhook request is not trusted
Missing delivery_url Webhook payload corrupted
Product generation failed Seller internal delivery logic failed
POST Webhook Processing + Product Delivery

Overview

After successful payment SoftStore automatically sends an HTTP webhook request to your configured api_url.

Your server must:

  • Receive webhook notification
  • Validate webhook signature
  • Request full order details
  • Generate digital product/license
  • Send product to customer
Configure webhook URL using: POST /seller/profile

Recommended Flow


Buyer pays product
↓
SoftStore confirms payment
↓
Webhook sent to seller api_url
↓
Seller validates signature
↓
Seller requests GET /orders/info/{id}
↓
Seller generates product/license
↓
Seller sends product via POST /orders/delivery/{token}
↓
Buyer receives product by email

Incoming Webhook Payload


{
  "id_order": "030a3c6f15f2744e58f2e24fd40d3466",
  "id_product": "69f36497dc78f",
  "payment_status": "paid",
  "signature": "df595764abc185bbf31c5c6334cfade65379feb6",
  "delivery_url": "https://api.softstore.app/api/v1/orders/delivery/TOKEN",
  "token": "d487c01d834dcb296c4f7b5a02e0b0d9df320bb153778d6c20cd26e2c50b40bf"
}

Signature Verification

Verify webhook authenticity before processing:


sha1(
    sha1(api_key) + id_order
)

Get Order Information

Before delivering product you can request full order details:


GET /orders/info/{id_order}

This allows you to identify:

  • Purchased product ID
  • Quantity
  • Customer email
  • Order metadata

{
  "status": "success",
  "data": {
    "id_order": "030a3c6f15f2744e58f2e24fd40d3466",
    "id_product": "69f36497dc78f",
    "count": 3
  }
}

Webhook Implementation Example


<?php

require_once "SellerApi.php";

$apiKey = "YOUR_API_KEY";

/*
|--------------------------------------------------------------------------
| Receive webhook
|--------------------------------------------------------------------------
*/

$payload = json_decode(
    file_get_contents("php://input"),
    true
);

if (!$payload) {
    http_response_code(400);
    exit("Invalid payload");
}

/*
|--------------------------------------------------------------------------
| Verify signature
|--------------------------------------------------------------------------
*/

$expected = sha1(
    sha1($apiKey) . $payload['id_order']
);

if ($expected !== $payload['signature']) {
    http_response_code(403);
    exit("Invalid signature");
}

/*
|--------------------------------------------------------------------------
| Create API client
|--------------------------------------------------------------------------
*/

$api = new SellerApi(
    "https://api.softstore.app/api/v1",
    $apiKey
);

$api->createApiKey();

/*
|--------------------------------------------------------------------------
| Get full order info
|--------------------------------------------------------------------------
*/

$orderInfo = $api->infoOrder(
    $payload['id_order']
);

print_r($orderInfo);

/*
|--------------------------------------------------------------------------
| Deliver product
|--------------------------------------------------------------------------
*/

$response = $api->deliverOrder(
    $payload['token'],
    [
        "text" => "Windows License Key: XXXXX",

        "download" =>
            "https://cdn.yoursite.com/file.zip"

        // or:
        // "download" => false
    ]
);

print_r($response);

http_response_code(200);
echo "Delivered";

const express = require("express");
const crypto = require("crypto");
const axios = require("axios");

const app = express();

app.use(express.json());

const API_KEY = "YOUR_API_KEY";


app.post("/webhook", async (req, res) => {

    try {

        const payload = req.body;

        /*
        --------------------------------------
        Verify signature
        --------------------------------------
        */

        const hashedApiKey = crypto
            .createHash("sha1")
            .update(API_KEY)
            .digest("hex");

        const expected = crypto
            .createHash("sha1")
            .update(
                hashedApiKey + payload.id_order
            )
            .digest("hex");

        if (expected !== payload.signature) {
            return res.status(403).send(
                "Invalid signature"
            );
        }

        /*
        --------------------------------------
        Get JWT token
        --------------------------------------
        */

        const auth = await axios.post(
            "https://api.softstore.app/api/v1/auth/api-key/create",
            {},
            {
                headers: {
                    "X-API-KEY": API_KEY
                }
            }
        );

        const jwt =
            auth.data.data.access_token;

        /*
        --------------------------------------
        Get order details
        --------------------------------------
        */

        const orderInfo = await axios.get(
            `https://api.softstore.app/api/v1/orders/info/${payload.id_order}`,
            {
                headers: {
                    Authorization:
                        `Bearer ${jwt}`
                }
            }
        );

        console.log(orderInfo.data);

        /*
        --------------------------------------
        Deliver product
        --------------------------------------
        */

        const response = await axios.post(
            `https://api.softstore.app/api/v1/orders/delivery/${payload.token}`,
            {
                text:
                    "Windows License Key: XXXXX",

                download:
                    "https://cdn.yoursite.com/file.zip"

                // or:
                // download: false
            },
            {
                headers: {
                    Authorization:
                        `Bearer ${jwt}`
                }
            }
        );

        console.log(response.data);

        return res.status(200).send(
            "Delivered"
        );

    } catch (error) {

        console.error(
            error.response?.data
        );

        return res.status(500).send(
            "Delivery error"
        );
    }

});

app.listen(3000, () => {
    console.log(
        "Webhook server started"
    );
});

Successful Delivery Response


{
  "status": "success",
  "data": {
    "message": "Product delivered successfully",
    "id_order": "030a3c6f15f2744e58f2e24fd40d3466",
    "delivered": true
  }
}

Delivery Errors

HTTP Code Error Description
401 Unauthorized Missing or invalid JWT token
403 Access denied Order belongs to another seller
404 Order not found Invalid delivery token
409 Order already delivered Product already sent
422 Invalid download URL Only HTTPS links allowed
SDK Official SDK Libraries

Overview

Official SDK libraries help sellers integrate with SoftStore faster without writing raw API requests manually.

Available SDKs include authentication, product management, order management, webhook processing, and automatic digital product delivery.

Recommended for automated marketplaces, license systems, subscription services, game stores, SaaS sellers, and digital product platforms.

Available SDK Libraries

Generate Additional SDKs

Need another language?

Export our OpenAPI schema and generate your own SDK using:

  • Java
  • Python
  • Go
  • C#
  • Ruby
  • Swift
  • Kotlin
  • TypeScript
Use Swagger Codegen or OpenAPI Generator with our exported schema file.

Quick Start Examples


<?php

require_once "SellerApi.php";

$api = new SellerApi(
    "https://api.softstore.app/api/v1",
    "YOUR_API_KEY"
);

$response = $api->createApiKey();

print_r($response);

const SellerSDK = require("./seller-sdk");

const api = new SellerSDK(
    "https://api.softstore.app/api/v1",
    "YOUR_API_KEY"
);

async function init() {
    const response = await api.createApiKey();
    console.log(response);
}

init();

Included Features

Feature Supported
JWT Authentication
Create Products
Update Products
Delete Products
Order Management
Webhook Processing
Automatic Delivery
Image Uploads

JWT API Playground

Test authenticated requests directly from documentation.