Каталог
Бараа, хувилбар, ангилал, багцыг токенгүй уншина. Монгол хайлт (?q=) дэлгүүрийнхтэй ижил хөдөлгүүрээр ажиллана.
Каталогийн endpoint-уудДэлгүүрийн каталог, захиалга, гарын үсэгтэй webhook, барааны feed ба OAuth апп — нэг REST /v1 гэрээ. Гэрээ нь OpenAPI 3.1 файл бөгөөд энэ хуудас түүний Монгол хураангуй.
POS, ERP, нягтлан бодох бүртгэл — нэг дэлгүүрийн захиалга, үнэ, үлдэгдлийг API түлхүүрээр холбоно.
Мерчантууд суулгадаг апп: OAuth-аар зөвшөөрөл авч, дэлгүүр бүрт тусдаа токеноор ажиллана.
Бараа, ангиллыг токенгүй уншиж, Google Merchant, Meta-д барааны feed-ээ өгнө.
Жишээнүүд бодит хост, бодит endpoint-оор бичигдсэн. demo-г өөрийн дэлгүүрийн нэрээр солиход л хангалттай.
Дэлгүүрийнхээ консолд Тохиргоо → Интеграц → «API түлхүүр» хэсэгт түлхүүр үүсгэж, хэрэгтэй эрхээ (scope) сонгоно. Түлхүүр зөвхөн нэг удаа харагдана — алдагдвал тэндээсээ шууд хүчингүй болгоно.
# Түлхүүрээ орчны хувьсагчид хадгална — кодонд бүү бич
export OPENSHOP_API_KEY="osk_live_…"Каталог токенгүй нээлттэй — дэлгүүрийн өөрийн хост дээр шууд уншина. Захиалга унших бол order:read эрхтэй түлхүүрээ Authorization толгойд тавина.
# Каталог — токенгүй, дэлгүүрийн өөрийн хост
curl "https://demo.openshop.mn/api/v1/shop/products?limit=5"
# Захиалга — order:read эрхтэй түлхүүрээр
curl "https://api.openshop.mn/v1/shop/orders?status=paid&limit=20" \
-H "Authorization: Bearer $OPENSHOP_API_KEY"Консолын мөн л Интеграц хэсэгт HTTPS хаягаа бүртгэж үйл явдлаа сонгоно. Хүсэлт бүрийн X-OpenShop-Signature толгойг түүхий биеийг задлахаас ӨМНӨ шалгана.
import crypto from "node:crypto";
// rawBody = задлаагүй Buffer (жишээ нь express.raw({ type: "application/json" }))
export function verifyOpenShop(secret, header, rawBody, nowMs = Date.now()) {
const parts = header.split(",").map((p) => p.trim().split("="));
const t = parts.find(([k]) => k === "t")?.[1];
const sigs = parts.filter(([k]) => k === "v1").map(([, v]) => v);
if (!t || sigs.length === 0) return false;
if (Math.abs(Math.floor(nowMs / 1000) - Number(t)) > 300) return false;
const expected = crypto
.createHmac("sha256", secret)
.update(t + ".")
.update(rawBody)
.digest("hex");
// Нууц солих 24 цагт толгойд хоёр v1 ирнэ — аль нэг нь таарвал хүчинтэй.
return sigs.some(
(s) =>
s.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(s), Buffer.from(expected)),
);
}Олон дэлгүүрт үйлчлэх апп бол app.openshop.mn → Хөгжүүлэгч хэсэгт апп бүртгэнэ. Мерчант таны аппыг суулгахдаа эрхүүдийг зөвшөөрч, та дэлгүүр тус бүрийн токен авна.
# 1) Мерчантыг зөвшөөрлийн хуудас руу илгээнэ (PKCE S256 заавал)
https://id.openshop.mn/oauth2/authorize?response_type=code
&client_id=app_…&redirect_uri=https://your.app/callback
&scope=order:read%20product:read&state=…
&code_challenge=…&code_challenge_method=S256
# 2) Буцаж ирсэн code-оо токеноор солино
curl -X POST https://id.openshop.mn/oauth2/token \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-d grant_type=authorization_code \
-d code=… -d redirect_uri=https://your.app/callback \
-d code_verifier=…Зөвхөн өнөөдөр ажиллаж буй зүйлсийг жагсаав. Бүх endpoint-ийн параметр, хариуны хэлбэр лавлагаанд бий.
Бараа, хувилбар, ангилал, багцыг токенгүй уншина. Монгол хайлт (?q=) дэлгүүрийнхтэй ижил хөдөлгүүрээр ажиллана.
Каталогийн endpoint-уудЗахиалгын жагсаалт, дэлгэрэнгүй, «хүргэсэн» төлөв. Худалдан авагчийн холбоо барих мэдээлэл тусдаа customer:read эрхээр.
ЭрхүүдЗахиалга, барааны үйл явдлыг гарын үсэгтэйгээр таны сервер рүү илгээж, алдвал дахин оролдоно.
Гарын үсэг ба дахин оролдлогоGoogle Merchant ба Meta Commerce Manager-т зориулсан CSV, XML feed — дэлгүүр бүрийн өөрийн хост дээр.
Feed-ийн форматОлон дэлгүүрт суулгадаг апп: authorization code + PKCE, эргэлддэг refresh токен, суулгац бүрийн webhook.
Апп бүтээхХувин бүрийн хязгаар, 429 + Retry-After, алдааны дугтуй {error, code} — салаалах нь зөвхөн code-оор.
Хязгаарын хүснэгтНэг дэлгүүр өөрийн системээ холбох бол API түлхүүр. Олон дэлгүүрт суулгадаг апп бол OAuth — түлхүүрийг гараар дамжуулахгүй.
Консолын Тохиргоо → Интеграц хэсгээс үүсгэнэ. Түлхүүр osk_live_… хэлбэртэй, нэг л удаа харагдана.
GET https://api.openshop.mn/v1/shop/orders
Authorization: Bearer osk_live_…https://{slug}.openshop.mn/api/v1/shop/* эсвэл https://api.openshop.mn/v1/shop/* — түлхүүр өөрөө дэлгүүрээ нэрлэдэг. Өөр дэлгүүрийн хост дээр 401 invalid_api_key.GET /shop/products*, /shop/categories*) токенгүй нээлттэй; product:write түлхүүртэй бол ноорог ч харагдана.POST /shop/checkout-д Idempotency-Key: 24 цагийн турш ижил хариу, өөр биетэй бол 422 idempotency_key_reuse.cost_mnt) ямар ч түлхүүрт буцахгүй.app.openshop.mn → Хөгжүүлэгч хэсэгт хөгжүүлэгчийн нөхцөл-ийг зөвшөөрч (ДАН-аар баталгаажсан байна) апп бүртгэнэ.
client_secret нэг удаа харагдана.osa_live_… (1 цаг) · osr_live_… — хэрэглэх бүрд шинэ хос; хуучныг дахин илгээвэл суулгацын бүх токен хүчингүй болно.POST /oauth2/revoke (RFC 7009). Мерчант аппыг салгамагц дараагийн хүсэлт 401 invalid_token.GET /shop/orders/export апп-д хаалттай — жагсаалт + webhook-оор синк хийнэ.Scope = консолын эрхийн нэр — API түлхүүр ба апп хоёуланд ижил хаалттай жагсаалт. Ажилтан, эрх, түлхүүр удирдах эрх ямар ч credential-д олгогдохгүй. Эрх дутвал 403 insufficient_scope + required_scope.
customer:read-гүй бол захиалгын худалдан авагчийн талбарууд null + pii_redacted: true. Мэдрэмтгий эрхийг апп хүсвэл хяналтад бичгээр үндэслэнэ.
Консолын Интеграц хэсэгт HTTPS хаягаа бүртгэж үйл явдлаа сонгоно. Бие нь хувийн мэдээлэлгүй нимгэн дугтуй — дэлгэрэнгүйг API-аас татна.
POST https://your.app/openshop-webhook
X-OpenShop-Event-Id: <үйл явдлын id — давхардлыг үүгээр шүү>
X-OpenShop-Delivery-Id: <оролдлого бүрд шинэ>
X-OpenShop-Event-Type: order.paid
X-OpenShop-Api-Version: 2026-09
X-OpenShop-Signature: t=1750000000,v1=06f35f44…
User-Agent: OpenShop-Webhooks/1.0 (+https://openshop.mn)
{"id":"evt_1","type":"order.paid","occurred_at":"…",
"created_at":"…","api_version":"2026-09",
"shop":{"slug":"demo"},
"data":{"order_id":"…","status":"paid","total_mnt":50000,
"discount_mnt":0,"paid_at":"…"}}v1 = HMAC-SHA256(secret, t + "." + rawBody), hex. Түүхий биеийг задлахаас өмнө шалгаж, t-г ±300 секундээр хязгаарла. Нууц солих 24 цагт толгойд хоёр v1 ирнэ — аль нэг таарвал хүчинтэй. Node.js, Go жишээ нь Алхам 3-т.
Тест вектор
X-OpenShop-Event-Id-ээр давхардлыг шүү. Дараалал баталгаагүй: order.expired-ийн дараа order.paid ирж болно — эцсийн төлөв нь GET /shop/orders/{id}.Тасалдлын дараа консолын «Бүх амжилтгүйг дахин илгээх» эсвэл POST /shop/webhooks/{id}/replay — амжилтгүй бүрд нэг шинэ оролдлого (ижил X-OpenShop-Event-Id), нэг хүсэлтэд ≤100, endpoint тус бүрд минутад 1.
Аппын webhook: суулгац бүрд эрхээр шүүгдсэн endpoint автоматаар үүсч, толгойд X-OpenShop-Installation-Id · X-OpenShop-Shop ирнэ. Салгахад app.uninstalled — тухайн дэлгүүрийн өгөгдлийг 30 хоногт устгана.
Дэлгүүр бүр өөрийн хост дээр токенгүй feed-тэй. Каталогийн «Scheduled fetch»-д холбоосыг нь л өгнө.
GET https://{slug}.openshop.mn/api/v1/shop/feed.csv
→ text/csv (UTF-8 BOM, RFC 4180)
GET https://{slug}.openshop.mn/api/v1/shop/feed.xml
→ RSS 2.0 + xmlns:g (Google Merchant)Кэш 5 минут, ETag → If-None-Match = 304. Зочны IP тус бүрд 30 хүсэлт/мин.
id = барааны UUID (Pixel-ийн content_ids-тэй ижил). 2+ хувилбар → хувилбар бүр мөр, item_group_id = барааны UUID."50000 MNT"; sale_price зөвхөн хямдрал идэвхтэй ба үнийн түүхээр батлагдсан үед — дэлгүүрийнхтэй ижил тооцоо.Хувин бүр тусдаа — нэг интегратор бусдыг хаахгүй. Алдааг текстээр биш, машин уншдаг code-оор салаална.
| Гадаргуу | Хязгаар | Хувин |
|---|---|---|
| API түлхүүртэй унших хүсэлт | 600 / мин | түлхүүр бүрд |
| API түлхүүртэй бичих хүсэлт | 120 / мин | түлхүүр бүрд |
| Апп токентой унших / бичих | 600 / 120 мин | суулгац бүрд |
| Нэг аппын бүх суулгац нийлээд | 6000 / мин | client_id |
| POST /oauth2/token (апп) | 60 / мин | client_id |
| POST /shop/checkout (токенгүй) | 30 / мин | зочны IP |
| GET /shop/feed.csv · feed.xml | 30 / мин | зочны IP |
| GET /shop/suggest | 120 / мин | зочны IP |
| POST /shop/orders/lookup | 10 / мин | зочны IP |
Түлхүүртэй хүсэлт X-RateLimit-Limit / Remaining / Reset толгойтой; хэтэрвэл 429 rate_limited + Retry-After.
HTTP 409
{"error": "Нөөц хүрэлцэхгүй байна.",
"code": "insufficient_stock", "remaining": 2}error = хэрэглэгчид харуулах Монгол текст (өөрчлөгдөж болно). code = гэрээ: шинэ нь нэмэгдэнэ, байгаа нь нэрээ солихгүй. Танихгүй код гарвал HTTP статусаар нь ханд.
Хасах өөрчлөлт = Deprecation + Sunset толгой, дор хаяж 6 сарын мэдэгдэл, дараа нь 410 endpoint_sunset. Одоогоор хуучирсан endpoint байхгүй.
Нэмэлт өөрчлөлт л v1 дотор гарна; эвдэх өөрчлөлт бол /v2.
2026-09-24
2026-09-22
2026-09-16
2026-09-08
Интерактив лавлагаа тусдаа хуудсанд ачаалагдана — энэ хуудас хөнгөн хэвээр.