medusa-qikink
v0.0.5
Published
A starter for Medusa plugins.
Maintainers
Readme
Compatibility
Compatible with Medusa >= 2.4.0.
Features
- Token: Obtain Qikink
access_tokenusing Client ID and client secret. - Create order: POST order payload to Qikink (
/api/order/create). - List orders: GET all orders from Qikink.
- Get order: GET a single order by
id(optionalfrom_date,to_date). - Product mapping: Map Qikink SKU to Medusa product variant (admin-only CRUD). Admin UI: "Add Qikink Variant" / "Update Qikink Variant" on the Product Variant details page (widget in overflow context).
- Order mapping: Map Qikink order to Medusa order with status (store + admin: create, list, get, update status).
All credentials and base URL come from config options (env vars or plugin options in medusa-config.ts).
Configuration
Environment variables
Set these in your environment (or in .env). All Qikink env access is centralized in src/config.ts; do not use process.env elsewhere.
| Variable | Description |
| -------- | ----------- |
| QIKINK_API_URL | Base URL (e.g. https://sandbox.qikink.com or https://api.qikink.com). If you set https://sandbox.qikink.com/v1, the plugin strips /v1 so paths are https://sandbox.qikink.com/api/token, etc. |
| QIKINK_CLIENT_ID | Your Qikink Client ID (from dashboard.qikink.com → Integration → Custom API). |
| QIKINK_CLIENT_SECRET | Your Qikink client secret. |
| QIKINK_RATE_LIMIT_REQUESTS_PER_MINUTE | Optional. Max Qikink API requests per minute (default 30). Set to 0 to disable. |
Plugin options (optional override)
In medusa-config.ts you can pass options to override env:
const { defineConfig } = require("medusa/config")
module.exports = defineConfig({
projectConfig: {
// ...
},
plugins: [
{
resolve: "medusa-qikink",
options: {
apiUrl: process.env.QIKINK_API_URL,
clientId: process.env.QIKINK_CLIENT_ID,
clientSecret: process.env.QIKINK_CLIENT_SECRET,
},
},
],
})Plugin options take precedence over environment variables.
Token caching and rate limiting
Token caching: The client caches the Qikink access token per config (
apiUrl+clientId). The first call togetToken()for a given config fetches the token; later calls return the cached token until it is close to expiry. If the API response includesexpires_in(seconds), that value is used; otherwise the token is treated as valid for 1 hour. The token is refreshed 30 seconds before expiry. This reduces token API calls when multiple requests (store orders, admin refresh, order-placed subscriber) use the same config.Rate limiting: To avoid exceeding Qikink’s API limit (e.g. 30 requests per minute), set
QIKINK_RATE_LIMIT_REQUESTS_PER_MINUTEin the environment or passrateLimitRequestsPerMinutein plugin options. Default is 30; use0to disable. When the limit is exceeded, the client throwsQikinkRateLimitErrorand API routes return 429 with the message"Rate limit exceeded. Try again later. You can access api N times per minute. Please try again after 60 seconds."
Store API endpoints
The Qikink APIs are exposed on the store so any client (storefront, mobile app, etc.) can use them.
| Method | Path | Description |
|--------|------|-------------|
| POST | /store/qikink/token | Get Qikink access token. Returns { access_token, ... }. |
| GET | /store/qikink/orders | List all Qikink orders. |
| GET | /store/qikink/orders?id=... | Get single order. Optional query: from_date, to_date. |
| POST | /store/qikink/orders | Create a Qikink order. Body: Qikink create-order JSON (order_number, qikink_shipping, gateway, total_order_value, line_items, shipping_address, etc.). |
See Qikink API documentation for request/response shapes and rate limits (e.g. 30 requests per minute).
Mapping modules (database + APIs)
Register the plugin modules in your Medusa app so migrations and APIs are available.
In medusa-config.ts add the modules from the plugin:
module.exports = defineConfig({
projectConfig: { /* ... */ },
plugins: [{ resolve: "medusa-qikink", options: { /* ... */ } }],
modules: [
// ... your other modules
require("medusa-qikink/modules/qikink-product-mapping"),
require("medusa-qikink/modules/qikink-order-mapping"),
],
})Then run migrations: npx medusa db:migrate.
Admin-only – Product mapping (Qikink SKU ↔ Medusa variant):
| Method | Path | Description |
|--------|------|-------------|
| GET | /admin/qikink-product-mapping | List mappings (query: qikink_sku_id, variant_id, limit, offset, order, order_direction). |
| POST | /admin/qikink-product-mapping | Create mapping. Body: { "qikink_sku_id": string, "variant_id": "uuid" }. Returns 409 if duplicate. |
| GET | /admin/qikink-product-mapping/:id | Get one mapping. |
| DELETE | /admin/qikink-product-mapping/:id | Delete mapping. |
Admin routes require an authenticated admin user.
Admin UI – Qikink variant mapping (Product Variant details):
- On the Product Variant details page, a "Qikink Variant" widget is shown below the variant content.
- Add Qikink Variant: Opens a modal to enter Qikink SKU ID and create a mapping for the current variant (order creation uses
search_from_my_products: 1, so Qikink looks up the product by SKU). - Delete Qikink Variant: If a mapping exists, the widget shows the current Qikink SKU and a "Delete Qikink Variant" button; a confirmation prompt then removes the mapping.
- Success toasts: "Qikink variant mapping created successfully." / "Qikink variant mapping removed."
- Database enforces unique
qikink_sku_idand uniquevariant_idper mapping.
Store (public) – Order mapping (Qikink order ↔ Medusa order + status):
| Method | Path | Description |
|--------|------|-------------|
| GET | /store/qikink-order-mapping | List mappings (query: qikink_order_id, medusa_order_id, status, limit, offset, order, order_direction). |
| GET | /store/qikink-order-mapping/:id | Get one mapping. |
Admin – Order mapping (list, get, refresh from Qikink):
| Method | Path | Description |
|--------|------|-------------|
| GET | /admin/qikink-order-mapping | List mappings (query: qikink_order_id, medusa_order_id, status, limit, offset, order, order_direction). Admin only. |
| GET | /admin/qikink-order-mapping/:id | Get one mapping. Admin only. |
| POST | /admin/qikink-order-mapping/refresh | Sync status from Qikink into mappings. Query: order_id (optional) – if set, refresh only that Qikink order; otherwise list only our mappings that are not in terminal status (completed, canceled, returned), then fetch each from Qikink by id and update. Optional limit (default 500, max 1000) and concurrency (default 20, max 100). Response: updated, processed, total_eligible, limit. Admin only. |
Admin UI – Qikink Orders: A dedicated section in the admin sidebar (Qikink Orders) lists all order mappings (Medusa order ID, Qikink order ID, status, created date). Use the "Refresh status" button to sync status from Qikink; the refresh API is also called when you open the page.
Order mappings are created automatically by the plugin: on order.placed, a subscriber checks whether any line item variant is in qikink_product_mapping; if so, it creates the Qikink order (with Qikink SKUs) and then creates a qikink_order_mapping record. There is no public POST to create mappings. Used by both storefront and admin.
Getting Started
Visit the Quickstart Guide to set up a server.
Visit the Plugins documentation to learn more about plugins and how to create them.
Visit the Docs to learn more about our system requirements.
What is Medusa
Medusa is a set of commerce modules and tools that allow you to build rich, reliable, and performant commerce applications without reinventing core commerce logic. The modules can be customized and used to build advanced ecommerce stores, marketplaces, or any product that needs foundational commerce primitives. All modules are open-source and freely available on npm.
Learn more about Medusa’s architecture and commerce modules in the Docs.
Community & Contributions
The community and core team are available in GitHub Discussions, where you can ask for support, discuss roadmap, and share ideas.
Join our Discord server to meet other community members.
