Getting Started
Build your first SaaS app
A working approval, OAuth, orders and webhook tutorial.
Use an authorized local/test environment with Marketplace enabled. This tutorial does not activate production gates.
- Sign in at
/en/developers/apply, complete the application and accept the terms. Ask your platform administrator to review it. Wait for approval before using/en/developers/dashboard. - Create an external app with a unique slug and bilingual listing. Save its Client ID and one-time Client Secret in your server environment.
- Run
examples/apps/basic-orders-appusing its README. SetEXAMPLE_APP_ORIGINto your HTTPS example origin andSAAS_PLATFORM_ORIGINto the platform origin. Use a local TLS reverse proxy; do not send secrets in browser JavaScript. - Create version
1.0.0in the portal. Register the exact${EXAMPLE_APP_ORIGIN}/callback, requestorders:readandwebhooks:manage, and declareorders.created. Fill the app, support and privacy URLs, then upload the app icon and at least one screenshot from your device (JPG, PNG, WebP or AVIF, up to 10 MB each; up to 8 screenshots). Submit for review. The administrator approves and then publishes the exact version. - Find the app in the merchant Marketplace and install it. Open the example’s
/connect; choose your store and approve the version’s requested scopes. The example binds state to an HttpOnly session, consumes PKCE once and exchanges the code with the client secret on the server. - The callback opens
/orders, which callsGET /api/v1/orders?limit=10with the installation token. No browser-supplied tenant ID becomes authority. The SDK offers bounded pagination for larger result sets. - Return to the example’s
/and press Register orders webhook. Its server callsPOST /api/v1/webhooksfororders.createdat its fixed HTTPS/webhookURL. The one-time signing secret remains on the server. Create a synthetic order through the merchant workflow, then inspect the real delivery status in Developer Dashboard. The receiver verifies raw bytes, event ID, timestamp and HMAC before parsing and deduplicates event IDs. - Uninstall the app in
/en/dashboard/apps. Reloading the example’s/ordersmust now fail. Reusing an authorization code or the revoked access token must also fail.
The example uses memory for sessions and deduplication and is deliberately a learning server. A restart loses those records. Use durable encrypted token storage and idempotent event processing in a real application. A webhook receiver needs an approved publicly reachable HTTPS endpoint; localhost is rejected by webhook SSRF protection.
For the CLI alternative, run dev login, then app create, add its returned id as app_id, and run app submit with this manifest structure (replace all example domains and assets):
{
"slug": "my-orders-app",
"version": "1.0.0",
"name_ar": "تطبيق الطلبات",
"name_en": "My orders app",
"description_ar": "عرض طلبات المتجر بعد موافقة التاجر",
"description_en": "Read store orders with explicit merchant consent",
"category": "business_tools",
"pricing_model": "free",
"app_url": "https://your-app.example",
"icon_url": "https://your-app.example/icon.png",
"privacy_url": "https://your-app.example/privacy",
"support_url": "https://your-app.example/support",
"redirect_urls": ["https://your-app.example/callback"],
"scopes": ["orders:read", "webhooks:manage"],
"webhook_events": ["orders.created"],
"screenshots": ["https://your-app.example/screenshot.png"]
}