You have a server-side app
Provider keys can be stored safely on the server.
Provider API docs
Official Datamoll SDKs
Connect the Datamoll catalog and order creation through a server-side SDK for Node.js, Python, or PHP. The SDK helps create duplicate-safe orders, recover them after timeout or failure, and store request_id for support, without Provider keys on the client.
Scenarios
Provider keys can be stored safely on the server.
Catalog and checkout work inside your store, bot, or panel.
request_id, recovery, and reconciliation help investigate failures.
Choose
Node.js / TypeScript
Use it when the partner project already runs on Node: Next.js API routes, NestJS, Express, Telegraf, grammY, Discord.js, or background workers.
Python async
Use it when the server-side app is Aiogram, FastAPI, asyncio workers, or scheduled jobs that sync catalog and reconcile orders.
PHP
Use it when the partner cannot move checkout into a separate Node/Python service and needs Datamoll inside the existing PHP server-side app.
npm config set @datamoll:registry https://docs.datamollcore.com/npm/
npm install @datamoll/provider-sdk
Configure the Datamoll npm scope once in the project or CI environment. The package name stays the same for the later public npm release.
pip install "datamoll-provider-sdk @ https://docs.datamollcore.com/downloads/datamoll_provider_sdk-0.3.0-py3-none-any.whl#sha256=7361dba98de770d43d567b15f6a0e25e825633b36368fda2172637aa7c836f0d"
Python currently installs from a checksum-pinned wheel. After PyPI publication, the command becomes pip install datamoll-provider-sdk.
composer config repositories.datamoll composer https://docs.datamollcore.com/composer
composer require datamoll/provider-sdk:0.3.0
PHP 7.4 or newer. Configure the Composer repository once. The package name is already the future Packagist-style name.
Quickstart
The goal of the first integration is not just to call the API. It is to create an order that can be recovered after a failure and explained to support.
Load DATAMOLL_PROVIDER_API_KEY and DATAMOLL_PROVIDER_API_SECRET from server environment variables or secret storage.
Use language, only_in_stock, and updated_since to keep localized product data in your own catalog.
Send your stable local order id as external_order_id. The SDK uses it for idempotency, HTTP 202 polling, and timeout recovery.
Persist Datamoll order_id, external_order_id, request_id, and delivery status with your local order.
The helper treats HTTP 202 as accepted, honors Retry-After, and polls the same external_order_id.
import { DatamollProviderClient } from "@datamoll/provider-sdk";
const apiKey = process.env.DATAMOLL_PROVIDER_API_KEY;
const apiSecret = process.env.DATAMOLL_PROVIDER_API_SECRET;
if (!apiKey || !apiSecret) {
throw new Error("Set DATAMOLL_PROVIDER_API_KEY and DATAMOLL_PROVIDER_API_SECRET");
}
const datamoll = new DatamollProviderClient({
apiKey,
apiSecret,
defaultLanguage: "ru",
});
const localOrderId = "partner-order-10001";
const { data: catalog } = await datamoll.listCatalog({
language: "ru",
only_in_stock: true,
});
const order = await datamoll.createOrderWithRecovery({
product_id: catalog.items[0].product_id,
quantity: 1,
external_order_id: `store-${localOrderId}`,
});
await saveDatamollOrder(localOrderId, order.data, order.requestId);
Use this inside a server route, background worker, or bot service method. Do not import it into browser code.
import asyncio
import os
from datamoll_provider import DatamollProviderClient
async def main():
async with DatamollProviderClient(
api_key=os.environ["DATAMOLL_PROVIDER_API_KEY"],
api_secret=os.environ["DATAMOLL_PROVIDER_API_SECRET"],
default_language="ru",
) as datamoll:
local_order_id = "partner-order-10001"
catalog = await datamoll.list_catalog({
"language": "ru",
"only_in_stock": True,
})
order = await datamoll.create_order_with_recovery({
"product_id": catalog.data["items"][0]["product_id"],
"quantity": 1,
"external_order_id": f"store-{local_order_id}",
})
await save_datamoll_order(local_order_id, order.data, order.request_id)
asyncio.run(main())
For Aiogram, keep the client in your service layer and call it from handlers through your own order service.
use Datamoll\Provider\DatamollProviderClient;
require __DIR__ . "/vendor/autoload.php";
$apiKey = getenv("DATAMOLL_PROVIDER_API_KEY") ?: null;
$apiSecret = getenv("DATAMOLL_PROVIDER_API_SECRET") ?: null;
if ($apiKey === null || $apiSecret === null) {
throw new RuntimeException("Set DATAMOLL_PROVIDER_API_KEY and DATAMOLL_PROVIDER_API_SECRET");
}
$localOrderId = "partner-order-10001";
$datamoll = DatamollProviderClient::fromArray([
"apiKey" => $apiKey,
"apiSecret" => $apiSecret,
"defaultLanguage" => "ru",
]);
$catalog = $datamoll->listCatalog([
"language" => "ru",
"only_in_stock" => true,
]);
$order = $datamoll->createOrderWithRecovery([
"product_id" => $catalog->data["items"][0]["product_id"],
"quantity" => 1,
"external_order_id" => "store-" . $localOrderId,
]);
saveDatamollOrder(
$localOrderId,
$order->data,
$order->requestId,
);
Use this in a server-side controller, plugin hook, or cron job. Keep delivery data out of public logs.
Coverage
Categories, products, languages, stock filters, delta sync, and full-sync guidance for disabled products.
Idempotent order creation with automatic HTTP 202 polling and timeout recovery by external order id.
Read completed and historical orders for local status repair.
Balance and transaction history for partner-side reconciliation.
Forward a buyer's dispute in one call, follow Datamoll's decisions and match refunds to your balance.
Typed API errors with request_id, retry-after, status, and API error code.
Production
Provider keys, order payloads, and delivered account lines must stay on the server. Browser and mobile clients call the partner server.
Use one immutable local order id for Datamoll checkout. Do not generate a new value on every retry.
Save request_id next to local order and dispute records. It is the fastest path to support correlation.
SDK polling retries 429 pages with retry-after, uses a 60s fallback only for malformed proxy responses, and pauses near rate-limit reset. Keep the loop in workers with max sleep/retry caps.
Raw delivered account lines belong only in the delivery path. Keep analytics, error logs, and public support messages sanitized.
Keep the Datamoll external_order_id on each sale. When a buyer opens a dispute, pass their lines to forwardDispute: the SDK finds the delivered lines, skips foreign ones and never opens a line twice. Disputes are optional.