AdonisJS provider for Shopify API integration
npm install @mixxtor/adonisjs-shopifyThis package provides a ready-to-use Shopify REST API client, making it easy to interact with the Shopify API with full TypeScript support and type inference for REST resources.
``bash`
npm install @mixxtor/adonisjs-shopify
First, add the package to your AdonisJS project:
`bash`
node ace configure @mixxtor/adonisjs-shopify
Add your Shopify app credentials to .env:
`env`
SHOPIFY_API_KEY=your_api_key
SHOPIFY_API_SECRET=your_api_secret
SHOPIFY_API_VERSION=2025-01
SHOPIFY_HOST_NAME=your-app-domain.com
SHOPIFY_SCOPES=read_products,write_products,read_orders
The package provider should be automatically registered in adonisrc.ts:
`typescript`
// adonisrc.ts
export default defineConfig({
providers: [
// ... other providers
() => import('@mixxtor/adonisjs-shopify/providers/shopify_provider'),
],
})
Create config/shopify.ts:
`typescript
import { defineConfig } from '@mixxtor/adonisjs-shopify'
import { RestResources } from '@shopify/shopify-api/rest/admin/2025-07'
import env from '#start/env'
// Extend the container types for proper REST resource type inference
declare module '@mixxtor/adonisjs-shopify/types' {
interface ShopifyRestResources extends RestResources {}
}
const shopifyConfig = defineConfig({
/**
* Shopify configurations
* @see https://github.com/Shopify/shopify-app-js/blob/main/packages/apps/shopify-api/docs/reference/shopifyApi.md
*/
app: {
apiKey: env.get('SHOPIFY_API_KEY'),
apiSecretKey: env.get('SHOPIFY_API_SECRET'),
apiVersion: env.get('SHOPIFY_API_VERSION', '2025-01'),
hostName: env.get('SHOPIFY_HOST_NAME'),
scopes: env.get('SHOPIFY_SCOPES', '').split(','),
scopes: env.get('SHOPIFY_API_SCOPES', 'read_products')?.split(','),
hostScheme: 'https',
hostName: env.get('SHOPIFY_HOST_NAME'),
isEmbeddedApp: true,
isPrivateApp: false,
// Add other Shopify configuration options as needed
},
/**
* A list of additional Shopify apps (e.g., for development or testing)
* whose credentials are also accepted when validating requests.
*/
trusted_app: env.get('SHOPIFY_API_TRUSTED_APPS'),
/**
* Defines the Shopify webhook topics that this app should register,
* along with their corresponding handler URLs.
*/
webhooks: {
[SHOPIFY.WEBHOOK_TOPICS.SHOP_UPDATE]: 'https://myapp.com/webhooks/shops/update', // Updates shop information if any change is made from Shopify
[SHOPIFY.WEBHOOK_TOPICS.APP_UNINSTALLED]: 'https://myapp.com/webhooks/shops/uninstall', // Uninstalls the app
},
})
export default shopifyConfig
`
For easier access across your app, export the service in start/service.ts:
`typescript
import app from '@adonisjs/core/services/app'
export const shopify = await app.container.make('shopify')
`
#### 1. Container-based Service (Recommended)
`typescript
// In your services/controllers
import { inject } from '@adonisjs/core'
import type { ShopifyService } from '@mixxtor/adonisjs-shopify/types'
@inject()
export default class ProductService {
constructor(private shopify: ShopifyService) {}
async getProducts(session: Session) {
// Full type inference for Product class
const products = await this.shopify.api.rest.Product.all({ session })
return products.data
}
async createProduct(session: Session, productData: any) {
const product = new this.shopify.api.rest.Product({ session })
product.title = productData.title
product.body_html = productData.description
await product.save()
return product
}
}
`
#### 2. Direct Service Import
`typescript
// Alternative: Import service directly
import shopify from '@mixxtor/adonisjs-shopify/services/main'
export default class ShopController {
async index({ session }: HttpContext) {
const products = await shopify.api.rest.Product.all({
session: session.shopifySession,
})
return products.data
}
}
`
`typescript
import { inject } from '@adonisjs/core'
import type { HttpContext } from '@adonisjs/core/http'
@inject()
export default class AuthController {
constructor(private shopify: ShopifyService) {}
async redirect({ request, response }: HttpContext) {
const shop = request.input('shop')
const authUrl = await this.shopify.auth.begin({
shop,
callbackPath: '/auth/callback',
isOnline: false,
})
return response.redirect(authUrl)
}
async callback({ request, response }: HttpContext) {
const authResult = await this.shopify.auth.callback({
rawRequest: request.request,
rawResponse: response.response,
})
if (authResult.session) {
// Store session and redirect to app
return response.redirect('/dashboard')
}
return response.badRequest('Authentication failed')
}
}
`
`typescript
import type { HttpContext } from '@adonisjs/core/http'
export default class WebhookController {
async handle({ request, response }: HttpContext) {
try {
const isValid = await shopify.webhooks.validate({
rawBody: request.raw(),
rawRequest: request.request,
})
if (!isValid.valid) {
return response.unauthorized()
}
const topic = request.header('x-shopify-topic')
const payload = request.body()
// Handle webhook based on topic
switch (topic) {
case 'orders/create':
await this.handleOrderCreate(payload)
break
case 'products/update':
await this.handleProductUpdate(payload)
break
}
return response.ok()
} catch (error) {
return response.internalServerError()
}
}
}
`
- ✅ Full IntelliSense support for all Shopify REST resources
- ✅ Type-safe API calls with proper parameter validation
- ✅ Auto-completion for methods and properties
- ✅ TypeScript error detection for invalid resources/methods
- ✅ Built-in OAuth authentication flow
- ✅ Webhook validation and handling
- ✅ Session management
All resources from @shopify/shopify-api/rest/admin/2025-07:
- Product, Variant, CollectionCustomer
- , Order, DraftOrderInventory
- , Location, FulfillmentServiceWebhook
- , ScriptTag, AssetShop
- , Country, Province`
- And 60+ more resources with full type support...
MIT