POS Integration Microservice¶
This document focuses on the least-visible but most critical layer: how source systems send catalog, pricing, and stock updates into the platform.
Mission¶
Build one stable integration surface that can accept updates from:
- restaurant POS systems
- merchant admin dashboards
- warehouse ERP / WMS systems
- brand / seller APIs
- bulk import jobs
The rest of the platform should consume canonical internal events, not raw vendor payloads.
High-Level Components¶
flowchart TD
SOURCE[POS / ERP / Seller Source]
AUTH[Auth + Signature Verification]
RAW[Raw Payload Store]
DEDUPE[Idempotency + Replay Guard]
MAP[Source Mapping Resolver]
TRANSFORM[Payload Transformer]
VALIDATE[Canonical Validation]
COMMAND[Canonical Command Writer]
BUS[Kafka Topic]
SOURCE --> AUTH
AUTH --> RAW
RAW --> DEDUPE
DEDUPE --> MAP
MAP --> TRANSFORM
TRANSFORM --> VALIDATE
VALIDATE --> COMMAND
COMMAND --> BUS
Inbound Endpoints¶
Recommended endpoint families:
POST /v1/integrations/pos/:provider/webhooks/menuPOST /v1/integrations/pos/:provider/webhooks/inventoryPOST /v1/integrations/pos/:provider/webhooks/store-statusPOST /v1/integrations/erp/:provider/webhooks/stockPOST /v1/integrations/seller/:provider/import
Provider Types¶
Restaurant POS Providers¶
Examples:
- PetPooja
- UrbanPiper
- DotPe
- Posist
Typical data:
- menu item upserts
- addon groups
- item availability
- restaurant open / close
- order acceptance status
Dark Store ERP / WMS Providers¶
Examples:
- Unicommerce
- Vinculum
- Omuni
- in-house WMS
Typical data:
- stock deltas
- receiving events
- returns
- transfers
- pick-pack shortages
Seller / Brand Providers¶
Typical data:
- product feed
- image URLs
- base price
- attribute sheets
Adapter Pattern¶
Never let downstream services understand provider-specific payloads.
Each provider should expose:
verifySignature(headers, rawBody)parse(rawPayload)toCanonicalCommands(sourcePayload, mappingContext)
Canonical command examples:
UpsertCatalogItemUpsertMenuItemUpsertVariantUpdateStockLevelUpdateStoreStatusUpdatePrice
Idempotency Rules¶
Every inbound update must support at least one idempotency strategy:
- provider event ID
- provider entity version
- hash of
(provider, merchant, entity, timestamp, payload)
Store idempotency keys in a short-retention table or Redis.
Raw Payload Retention¶
Before transforming, persist:
- headers
- body
- provider
- tenant
- merchant/store mapping
- received timestamp
Use object storage for long retention and a relational table for metadata.
This is essential for:
- replay
- support
- dispute analysis
- onboarding new transforms
Canonical Validation¶
Required checks before writing commands:
- source merchant/store mapped
- source SKU / item mapped or allowed for new creation
- price format valid
- stock is numeric
- unit and currency valid
- category present or assignable
Validation failures should go to a dead-letter queue or review dashboard.
Event Topics¶
Recommended topics:
catalog.commandscatalog.eventspricing.eventsinventory.eventsstore-status.eventsintegration.failures
Commands and events should be separate.
Processing Model¶
Synchronous path¶
Do only:
- verify
- persist raw payload
- write canonical command / event
- return 200
Asynchronous path¶
Do later:
- deep normalization
- search reindex
- recommendation updates
- LLM enrichment
This keeps providers fast and reliable.
Store and Merchant Mapping¶
One of the hardest problems is identity mapping.
Maintain mapping tables for:
- provider merchant ID -> canonical merchant ID
- provider store ID -> canonical store ID
- provider SKU / item ID -> canonical item ID
- provider variant ID -> canonical variant ID
Without this, integrations fail at scale.
Failure Handling¶
For each inbound call:
- respond quickly
- never drop payloads silently
- classify failures as:
- auth failure
- mapping failure
- validation failure
- processing failure
- duplicate event
Expose a support screen or dashboard for failed events.
Security¶
Minimum controls:
- provider-specific API keys or signed headers
- IP allowlisting where possible
- HMAC verification
- raw-body signature validation
- audit logging
Recommended MVP¶
If you want to get one integration working fast:
- pick one provider
- implement webhook receiver
- store raw payloads
- map to canonical
UpdateStockLevelandUpsertCatalogItem - emit Kafka events
- update Redis-backed availability and catalog views
That is enough to prove the pattern before adding more providers.