PHP code example of iperson1337 / nct-client-bundle
1. Go to this page and download the library: Download iperson1337/nct-client-bundle library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
use Iperson1337\NctClientBundle\Exception\NctProductNotFoundException;
use Iperson1337\NctClientBundle\NctClient;
final class NtinLookup
{
public function __construct(private readonly NctClient $nct) {}
public function ntinFor(string $gtin): ?string
{
try {
$card = $this->nct->fetchProductByGtin($gtin);
// nct.gov.kz returns `ntin_code`; the portal returns `ntin`
return $card['ntin'] ?? $card['ntin_code'] ?? null;
} catch (NctProductNotFoundException) {
return null; // no card for this GTIN — a regular outcome, not a failure
}
}
}
$cards = $this->nct->portal()->fetchProductsByTin('4870001302818'); // GET /v2/products/{tin}
use Iperson1337\NctClientBundle\Request\ProductRequestPayload;
$portal = $this->nct->portal();
$payload = new ProductRequestPayload(
oktru: '10.51.11',
autoPublication: false,
attributes: [
['code' => 'gtin', 'value' => '4870001302818'],
['code' => 'name_ru', 'value' => 'Молоко 2,5% 1 л'],
],
);
$requestId = (int) $portal->submitProductRequest($payload->toArray())['id']; // POST …/requests → draft
$portal->submitToModeration($requestId); // PUT …/{id}/moderation (new, underRevision)
$portal->cancelRequest($requestId); // PUT …/{id}/cancel (onModeration → cancelled)
$portal->updateProductRequest($requestId, $payload->toArray()); // PUT …/{id} (new, underRevision, cancelled)
$portal->publishRequest($requestId); // PUT …/{id}/publish (readyToPublish)
$portal->deleteProductRequest($requestId); // DELETE …/{id} (new only)
$draft = $portal->createEditRequest('0200212305195'); // POST …/requests/{ntin}/edit-product
$requestId = (int) $draft['productRequestId'];
$body = ProductRequestPayload::fromArray($draft); // same shape as PUT …/requests/{id}
// `oktru` may come back null for old cards — set a current category code before sending.
$portal->updateProductRequest($requestId, $body->toArray());
if (!$payload->matchesStoredJson($request->getRequestBody())) {
$portal->updateProductRequest($requestId, $payload->toArray());
}
use Iperson1337\NctClientBundle\Attribute\AttributeDefinition;
use Iperson1337\NctClientBundle\Dictionary\DictionaryItem;
foreach ($portal->fetchAttributes() as $row) { // GET …/requests/attributes
if (AttributeDefinition::missingRequiredFields($row) !== []) {
continue;
}
$definition = AttributeDefinition::fromPortalRow($row);
// $definition->code, ->dataType ('string'|'text'|'number'|'boolean'|'dictionary'|'multiDictionary'|'date'),
// ->isRequired, ->maxLength, ->pattern, ->dictionaryCode, ->dictionaryValues …
}
$gov = $portal->fetchGovAttributes('10.51.11'); // mainAttributes + additionalAttributes per ОКТРУ
$dictionaries = $portal->fetchDictionaries(); // GET …/dictionaries
$roots = $portal->fetchDictionaryRoots('MEASURE_UNIT'); // tree dictionaries
$children = $portal->fetchDictionaryChildren('MEASURE_UNIT', (int) $roots[0]['id']);
$page = $portal->fetchDictionaryItems('TNVED', page: 1, size: 100); // any dictionary, paged (size 1..100)
foreach ($roots as $row) {
if (DictionaryItem::missingRequiredField($row) === null) {
$item = DictionaryItem::fromRow($row); // externalId, code, nameRu, nameKk, parentId, level, hasChild, isDeleted
}
}
$gov = $this->nct->gov();
$cards = $gov->searchByGtin($gtin); // every card with this code, incl. deactivated duplicates; [] if none
$cards = $gov->searchByTins(['4870235770032', '0200093179779']); // up to 100 NTIN/GTIN per request
$page = $gov->searchByName('Молоко', limit: 100, offset: 0); // ['count', 'next', 'previous', 'last_modified', 'result' => [...]]
$card = $gov->findActiveCard($gtin); // first card with ntin_isdeactivated === false; null if all are deactivated
$ntin = $gov->lookupNtin($gtin); // ['gtin' => …, 'ntin_code' => string|null]; throws if there are no cards
$full = $gov->fetchProduct((int) $card['id']); // GET /api/core/products/{id}; category.full_code holds ОКТРУ
$auth = $gov->login('username', 'password'); // POST /api/auth/login/ — raw response with the JWT
$jwt = $auth['access'] ?? $auth['token']; // key name depends on the portal's response
$count = $gov->countChangedProducts($jwt, from: 1743596160)['count'];
$page = $gov->exportProducts($jwt, from: 1743596160, limit: 1000, offset: 0);
foreach ($page['result'] as $card) {
// id, name_ru, name_kk, gtin, ntin_code, is_social, modified, status, is_markedeac, measure,
// product_type (1 goods, 2 work, 3 service), ntin_isdeactivated, ntin_deactivationreason, ntin_duplicateofproduct
}
// next call: from = the largest `modified` received