@thorprovider/medusa-extended
v1.2.1
Published
Thor Commerce multi-tenant admin extensions for Medusa v2
Readme
title: "@thorprovider/medusa-extended" purpose: "HTTP clients for custom Thor Commerce admin endpoints (dropshipper, multi-tenant) that extend the standard Medusa v2 API" lastReviewed: "2026-05-23"
@thorprovider/medusa-extended
Thor Commerce multi-tenant admin extensions for Medusa v2
HTTP clients for custom Thor endpoints that are not part of the Medusa standard API.
Packages exported
| Export | Description |
|---|---|
| MedusaAdminClient | Thin wrapper around the Medusa Admin REST API (/admin/*). Uses x-medusa-access-token. |
| DropshipperClient | Client for all dropshipping endpoints (/admin/thor/dropshipper/*). Uses Authorization: Bearer <jwt>. |
MedusaAdminClient
import { MedusaAdminClient } from '@thorprovider/medusa-extended';
const admin = new MedusaAdminClient({
baseUrl: process.env.MEDUSA_BACKEND_URL!,
apiKey: process.env.MEDUSA_API_KEY!,
});DropshipperClient
Covers all 53 methods across the dropshipping feature set. Both the ThorProvider admin (X) and the dropshipper panel (Y) use this same client — access control is enforced server-side.
Configuration
import { DropshipperClient } from '@thorprovider/medusa-extended';
const client = new DropshipperClient({
baseUrl: process.env.MEDUSA_BACKEND_URL!,
// JWT obtained from POST /auth/user/emailpass
token: jwtFromLogin,
debug: false, // optional — logs every request
});Authentication
Every request sends Authorization: Bearer <token>. The JWT is obtained from Medusa's native auth endpoint:
POST /auth/user/emailpass
{ "email": "...", "password": "..." }
→ { "token": "eyJ..." }Methods
Onboarding (Solo X — Admin role required)
| Method | Endpoint |
|---|---|
| onboardDropshipper(body) | POST /admin/thor/dropshipper/onboard |
Variant Costs (Solo X)
| Method | Endpoint |
|---|---|
| getVariantCosts(options?) | GET /admin/thor/dropshipper/variant-costs |
| createVariantCost(body) | POST /admin/thor/dropshipper/variant-costs |
| batchVariantCosts(body) | POST /admin/thor/dropshipper/variant-costs/batch |
| deleteVariantCost(id) | DELETE /admin/thor/dropshipper/variant-costs/:id |
Products & Prices (Solo Y)
| Method | Endpoint |
|---|---|
| getProducts(options?) | GET /admin/thor/dropshipper/products |
| updatePrices(body) | PUT /admin/thor/dropshipper/prices |
Orders (Y + X for set-payment-collector)
| Method | Endpoint |
|---|---|
| getOrders(options?) | GET /admin/thor/dropshipper/orders |
| getOrder(id) | GET /admin/thor/dropshipper/orders/:id |
| createOrder(body) | POST /admin/thor/dropshipper/orders |
| setPaymentCollector(id, body) | POST /admin/thor/dropshipper/orders/:id/set-payment-collector |
| cancelOrder(id) | POST /admin/thor/dropshipper/orders/:id/cancel |
| createOrderEdit(id, body?) | POST /admin/thor/dropshipper/orders/:id/edit |
| addOrderEditItem(id, body) | POST /admin/thor/dropshipper/orders/:id/edit/items |
| confirmOrderEdit(id) | POST /admin/thor/dropshipper/orders/:id/edit/confirm |
Order Notes (Y)
| Method | Endpoint |
|---|---|
| getOrderNotes(orderId) | GET /admin/thor/dropshipper/orders/:id/notes |
| createOrderNote(orderId, body) | POST /admin/thor/dropshipper/orders/:id/notes |
| deleteOrderNote(orderId, noteId) | DELETE /admin/thor/dropshipper/orders/:id/notes/:noteId |
Provider Categories (read-only — Medusa native)
| Method | Endpoint |
|---|---|
| getProviderCategories() | GET /admin/thor/dropshipper/categories/provider |
Custom Categories (Solo Y)
| Method | Endpoint |
|---|---|
| getCategories(options?) | GET /admin/thor/dropshipper/categories |
| createCategory(body) | POST /admin/thor/dropshipper/categories |
| updateCategory(id, body) | PUT /admin/thor/dropshipper/categories/:id |
| deleteCategory(id, options?) | DELETE /admin/thor/dropshipper/categories/:id — pass { force: true } to cascade-delete children |
| getCategoryMappings(options?) | GET /admin/thor/dropshipper/category-mappings — filter by product_id |
| createCategoryMapping(body) | POST /admin/thor/dropshipper/category-mappings |
| deleteCategoryMapping(id) | DELETE /admin/thor/dropshipper/category-mappings/:id |
Customers (Solo Y)
| Method | Endpoint |
|---|---|
| getCustomers(options?) | GET /admin/thor/dropshipper/customers |
| getCustomer(id) | GET /admin/thor/dropshipper/customers/:id |
| createCustomer(body) | POST /admin/thor/dropshipper/customers |
| getCustomerAddresses(customerId) | GET /admin/thor/dropshipper/customers/:id/addresses |
| createCustomerAddress(customerId, body) | POST /admin/thor/dropshipper/customers/:id/addresses |
| updateCustomerAddress(customerId, addressId, body) | POST /admin/thor/dropshipper/customers/:id/addresses/:addr_id |
| deleteCustomerAddress(customerId, addressId) | DELETE /admin/thor/dropshipper/customers/:id/addresses/:addr_id |
Account & Settlements (Solo Y — read-only)
| Method | Endpoint |
|---|---|
| getAccount() | GET /admin/thor/dropshipper/account |
| getPayable() | GET /admin/thor/dropshipper/account/payable |
| getReceivable() | GET /admin/thor/dropshipper/account/receivable |
| getSettlements(options?) | GET /admin/thor/dropshipper/settlements |
| getSettlement(id) | GET /admin/thor/dropshipper/settlements/:id |
Admin Settlements (Solo X)
| Method | Endpoint |
|---|---|
| getAdminSettlements(options?) | GET /admin/thor/dropshipper/admin/settlements |
| createSettlement(body) | POST /admin/thor/dropshipper/admin/settlements |
| confirmSettlement(id, body?) | POST /admin/thor/dropshipper/admin/settlements/:id/confirm |
| cancelSettlement(id, body?) | POST /admin/thor/dropshipper/admin/settlements/:id/cancel |
Admin Account Management (Solo X)
| Method | Endpoint |
|---|---|
| getAdminAccounts() | GET /admin/thor/dropshipper/admin/accounts |
| getAdminAccountBalance(id) | GET /admin/thor/dropshipper/admin/accounts/:id/balance |
| getAdminPriceLists() | GET /admin/thor/dropshipper/admin/price-lists |
| getUserChannel() | GET /admin/thor/dropshipper/admin/user-channel |
Promotions (Solo Y)
| Method | Endpoint |
|---|---|
| getPromotions(options?) | GET /admin/thor/dropshipper/promotions |
| createPromotion(body) | POST /admin/thor/dropshipper/promotions |
| getPromotion(id) | GET /admin/thor/dropshipper/promotions/:id |
| updatePromotion(id, body) | PUT /admin/thor/dropshipper/promotions/:id |
| deletePromotion(id) | DELETE /admin/thor/dropshipper/promotions/:id |
Dashboard (Solo Y)
| Method | Endpoint |
|---|---|
| getDashboardStats(options?) | GET /admin/thor/dropshipper/dashboard/stats |
Storefront (public — uses publishable API key)
| Method | Endpoint |
|---|---|
| getStorefrontCategories() | GET /store/thor/dropshipper-categories |
The storefront endpoint resolves the channel from the
x-publishable-api-keyheader, not from the JWT. When calling this method directly from a server context, pass the publishable key via a separate fetch or configure an HTTP proxy. The client itself always sendsAuthorization: Bearer— this method is included for completeness.
Error handling
All methods throw ProviderAPIError on non-2xx responses:
import { ProviderAPIError } from '@thorprovider/adapters';
try {
const result = await client.getProducts();
} catch (err) {
if (err instanceof ProviderAPIError) {
console.error(err.code); // e.g. "DROPSHIPPER_API_403"
}
}Endpoint reference
Full request/response contracts: docs/multitenant/dropshipping-api-contract.md
Operational detail and middleware breakdown: docs/multitenant/dropshipping-feature-reference.md
