POS Endpoints
POS endpoints with context-calculated pricing
@narisolutions/medusa-plugin-pos
Medusa v2 plugin that adds the product endpoints any POS (Point of Sale) app needs. Built by Nari Solutions.
Without these custom endpoints, a POS talking to Medusa's generic API has two problems: stock isn't checked automatically when adding items to a cart, and prices come back raw — not context-calculated. This plugin's Copy to clipboard/pos/* endpoints return live inventory quantities per variant and context-calculated prices (Copy to clipboard?currency_code=), plus a Copy to clipboard?custom_fields= option to choose exactly which product fields you fetch.
Requirements
- Medusa v2 ≥ 2.15.0 (Copy to clipboard
@medusajs/frameworkand Copy to clipboard@medusajs/medusaare peer dependencies) - Node.js ≥ 20
Installation
1yarn add @narisolutions/medusa-plugin-pos
Setup
Add the plugin to your Copy to clipboardmedusa-config.ts:
12345678910111213import PosPlugin from "@narisolutions/medusa-plugin-pos"export default defineConfig({plugins: [PosPlugin({defaultCurrencyCode: "usd", // optional — used when ?currency_code= is omittedrateLimit: { // optional — per-IP rate limitingwindowMs: 60_000, // 1 minute windowmax: 100, // max requests per window},}),],})
API Documentation
- Copy to clipboard
docs/endpoints.md— endpoint reference with rationale and retirement criteria - Copy to clipboard
openapi.yaml— OpenAPI 3.1 spec (parameters, schemas, status codes)
Endpoints
All endpoints require an admin bearer token (Copy to clipboardAuthorization: Bearer <token>).
GET Copy to clipboard/pos/products/:sales_channel_id
Returns all published products for a sales channel, with inventory quantities per variant.
Query param Type Description Copy to clipboardcurrency_code string Include Copy to clipboardcalculated_price for each variant Copy to clipboardcustom_fields string Comma-separated extra fields appended to the default field list
The default field list covers core product/variant fields. Fields like Copy to clipboardtranslations.* are not included by default — opt in via Copy to clipboard?custom_fields=translations.*.
Response: array of product objects.
GET Copy to clipboard/pos/product-by-barcode/:sales_channel_id/:ean
Looks up a single product by barcode value, with inventory quantities.
The Copy to clipboard:ean path parameter is matched first against the variant Copy to clipboardbarcode field, then falls back to the Copy to clipboardean field. This means physical barcodes stored in Copy to clipboardbarcode work out of the box — Copy to clipboardean is the fallback for stores that populate that field instead.
Query param Type Description Copy to clipboardcurrency_code string Include Copy to clipboardcalculated_price for each variant Copy to clipboardcustom_fields string Comma-separated extra fields appended to the default field list (e.g. Copy to clipboardtranslations.*)
Response: single product object. Returns Copy to clipboard404 if no variant matches either field.
GET Copy to clipboard/pos/health
Returns Copy to clipboard{ "status": "ok" }. Requires auth. Use for backend health checks from your POS.
Authentication
Obtain a bearer token from the Medusa admin auth endpoint:
12POST /auth/user/emailpass{ "email": "...", "password": "..." }
Use the returned token as Copy to clipboardAuthorization: Bearer <token> on all Copy to clipboard/pos/* requests.
Frontend usage (example)
12345const res = await fetch(`/pos/products/${salesChannelId}?currency_code=usd`,{ headers: { Authorization: `Bearer ${token}` } })const products = await res.json()
12345const res = await fetch(`/pos/product-by-barcode/${salesChannelId}/${ean}?currency_code=usd`,{ headers: { Authorization: `Bearer ${token}` } })const product = await res.json()
Plugin options
Option Type Default Description Copy to clipboarddefaultCurrencyCode Copy to clipboardstring Copy to clipboardundefined Fallback currency code when Copy to clipboard?currency_code= is not passed Copy to clipboardrateLimit.windowMs Copy to clipboardnumber — Rate limit window in milliseconds Copy to clipboardrateLimit.max Copy to clipboardnumber — Max requests per IP per window
License
Apache-2.0

