# Paziresh24 / Hamdast Widget Documentation (full) Base URL: https://developers.paziresh24.com Console: https://hamdast.paziresh24.com/console SDK: https://hamdast.paziresh24.com/sdk/hamdast.js OpenAPI bundle: https://developers.paziresh24.com/openapi-bundle.json TypeScript: https://developers.paziresh24.com/hamdast.d.ts Starter repo: https://github.com/paziresh24/widget-starter ## pages/apps/quickstart.mdx # شروع سریع یک ابزارک ساده که لیست نوبت‌های پزشک را نشان می‌دهد. ### ساخت ابزارک 1. وارد [کنسول همدست](https://hamdast.paziresh24.com/console) شوید. 2. **ابزارک جدید** بسازید (نوع: ابزارک برای پزشکان). 3. scope `provider.appointment.read` را فعال کنید. 4. از صفحه **اتصال به API**، `app_key` و کلید توسعه‌دهنده (`x-api-key`) را کپی کنید. ### کد فرانت‌اند ```js window.hamdast.initialize(); const sessionToken = await window.hamdast.getSessionToken(); const res = await fetch("/api/appointments", , body: JSON.stringify(), }); ``` در بک‌اند، `session_token` را به `access_token` تبدیل کنید و API نوبت‌ها را صدا بزنید. جزئیات در [احراز هویت](/authorization). ### تست ابزارک را روی HTTPS deploy کنید، URL را در کنسول ثبت کنید و در پنل پزشک نصب کنید. **SDK:** [نصب](/apps/sdk/install) ## pages/authorization/index.mdx # احراز هویت اولین قدم برای اتصال به api‌های پذیرش۲۴، پیاده‌سازی دریافت access_token در ابزارک شماست. بدین منظور ابتدا ابزارک خود را بسازید و پس از آن با انجام مراحل پایین دسترسی‌های لازم را از او بگیرید و سپس می‌توانید به عنوان وکیل کاربر به منابع تحت مالکیت او دسترسی داشته باشید. ## پیش‌نیازها * ساخت ابزارک در [کنسول همدست](https://hamdast.paziresh24.com/console) * تعیین دسترسی‌های لازم در صفحه **اتصال به API** (`/console/apps//authorization`) * [SDK همدست را در فرانت‌اند لود کرده‌اید.](/apps/sdk/install) * `app_key` اپ را در `initialize` ست کرده‌اید. * `x-api-key` را در بک‌اند خود نگهداری می‌کنید. ## دریافت دسترسی ### گرفتن `session_token` در فرانت‌اند در فرانت‌اند، با SDK توکن سشن را بگیرید: ```js showLineNumbers window.hamdast.initialize(); const sessionToken = await window.hamdast.getSessionToken(); ``` > خروجی این مرحله `session_token` است. ### تبدیل `session_token` به `access_token` در بک‌اند در این مرحله، بک‌اند شما باید `session_token` را به `access_token` تبدیل کند. الگوی endpoint به شکل زیر است: ```http POST https://hamdast.paziresh24.com/api/v1/apps//oauth/access_token ``` > - app_key: کلید اپ شما در مسیر URL > - x-api-key: کلید توسعه‌دهنده (فقط در بک‌اند) > - session_token: توکن سشنی که از SDK گرفته‌اید نمونه درخواست: ```terminal curl --request POST "https://hamdast.paziresh24.com/api/v1/apps/YOUR_APP_KEY/oauth/access_token" \ --header "Content-Type: application/json" \ --header "x-api-key: YOUR_DEVELOPER_API_KEY" \ --data '' ``` در صورت موفقیت، پاسخ نمونه: ```json ``` ### استفاده از `access_token` در درخواست‌های بعدی بعد از دریافت توکن دسترسی، آن را در هدر درخواست‌های بعدی قرار دهید: ```http Authorization: Bearer ``` ## خطاهای رایج | خطا | توضیح | راهکار | | - | - | - | | `USER_CLOSED_POPUP` | کاربر پنجره را بسته است | `getSessionToken()` را دوباره اجرا کنید | | `INVALID_SESSION_TOKEN` | سشن‌توکن نامعتبر یا منقضی شده | یک `session_token` جدید بگیرید و دوباره تبدیل کنید | | `DEVELOPER_NOT_AUTHORIZED` | کلید توسعه‌دهنده برای اپ مجاز نیست | `x-api-key` و دسترسی اپ را بررسی کنید | | 403 از API | scope نادرست یا تأییدنشده | scope را در کنسول فعال کنید | | `window.hamdast is undefined` | SDK لود نشده | اسکریپت را در `index.html` قبل از استفاده بگذارید | ## نکات امنیتی * `x-api-key` را فقط در بک‌اند نگهداری کنید. * تبدیل توکن را فقط در بک‌اند انجام دهید. * توکن‌ها را در لاگ عمومی چاپ نکنید. ## pages/authorization/scopes.mdx # دسترسی‌ها مشخص کردن دسترسی‌ها به کاربر این اطمینان را می‌دهد که اپلیکیشن شما فقط به اطلاعاتی که مشخص کرده‌اید دسترسی دارد. > لیست به‌روز scopeها در کنسول → **اتصال به API**. جدول scope→API: [llms.txt](/llms.txt) در جدول زیر دسترسی‌های رایج آمده است: #### پزشک | نام دسترسی | توضیحات | |-------------------------------|----------------------------------------------------------------| | provider.profile.read | دسترسی مشاهده اطلاعات پزشک، تخصص ها و مراکز درمانی... | | provider.profile.write | دسترسی ویرایش اطلاعات پزشک، تخصص ها و مراکز درمانی... | | provider.appointment.read | دسترسی مشاهده نوبت های پزشک | | provider.appointment.write | دسترسی حذف نوبت های پزشک | | provider.management.read | دسترسی مشاهده ساعت کاری و مرخصی های پزشک | | provider.management.write | دسترسی تنظیم ساعت کاری و مرخصی های پزشک | | provider.prescription.read | دسترسی جستجوی دارو و خدمات قابل تجویز در کاتالوگ بیمه | | provider.rasan.read | دسترسی مشاهده موجودی پیامک پزشک (rasan) | | provider.rasan.write | دسترسی ارسال پیامک به نام پزشک (rasan) | #### کاربر (نقش بیمار) | نام دسترسی | توضیحات | |-------------------------------|----------------------------------------------------------------| | user.profile.read | دسترسی مشاهده اطلاعات کاربر | | user.profile.write | دسترسی ویرایش اطلاعات کاربر | | user.appointment.read | دسترسی مشاهده نوبت های کاربر | | user.appointment.write | دسترسی حذف نوبت های کاربر | ## ai-docs/architecture.md # معماری ابزارک ## اصطلاحات | اصطلاح | معنی | |--------|------| | ابزارک | اپلیکیشن وب شما | | همدست | پلتفرم مدیریت ابزارک‌ها (hamdast.paziresh24.com) | | پذیرش۲۴ | پنل پزشک/بیمار که ابزارک داخل آن embed می‌شود | | window.hamdast | SDK جاوااسکریپت برای ارتباط iframe با پنل | ## فلوی کلی 1. پزشک ابزارک را در پنل باز می‌کند 2. iframe ابزارک شما لود می‌شود 3. hamdast.initialize + getSessionToken 4. session_token به بک‌اند شما 5. بک‌اند: POST oauth/access_token → access_token 6. بک‌اند: API با Bearer token 7. پاسخ JSON به فرانت ## لایه‌ها ### فرانت‌اند (iframe) - SDK: https://hamdast.paziresh24.com/sdk/hamdast.js - فقط app_key — هرگز x-api-key ### بک‌اند - تبدیل session_token → access_token - فراخوانی apigw.paziresh24.com ### API Gateway - Authorization: Bearer ## دو نوع ابزارک - **پزشک:** scopeهای provider.* — navigation با hamdast.redirect - **افزونه بیمار:** ادامه فرایند با hamdast.flow.dispatch ## امنیت - x-api-key فقط بک‌اند - تبدیل token فقط بک‌اند - HTTPS اجباری - scope حداقلی ## ai-docs/portal-guide.md # راهنمای کنسول همدست کنسول: https://hamdast.paziresh24.com/console ## مسیرها | مسیر | کاربرد | |------|--------| | /console | داشبورد | | /console/apps/new | ساخت ابزارک | | /console/apps//authorization | app_key، x-api-key، scopeها | | /console/apps//edit | URL ابزارک | | /console/apps//webhooks | وب‌هوک | | /console/apps//monetization | کسب درآمد | | /console/sandbox | تست (در حال توسعه) | ## ویزارد ساخت 1. ابزارک برای پزشکان 2. نام + app_key 3. scopeها 4. URL HTTPS 5. بازبینی ## app_key vs app_id - app_key: slug — در SDK و OAuth - app_id: شناسه داخلی — فقط URLهای کنسول ## Sandbox API سندباکس هنوز کامل نیست. برای تست واقعی، deploy کنید و در پنل پزشک نصب کنید. ## ai-docs/scope-mapping.md # نقشه scope به API لیست رسمی scopeها در کنسول → اتصال به API (داینامیک). برخی «نیاز به تأیید» دارند. ## پزشک (provider) | Hamdast scope | سرویس | endpoint | |---------------|-------|----------| | provider.profile.read | profile | GET /open-platform/v1/profile/information | | provider.profile.write | profile | PUT /open-platform/v1/profile/information | | provider.appointment.read | booking | GET /open-platform/v1/booking/appointments | | provider.appointment.write | booking | DELETE /open-platform/v1/booking/appointments/ | | provider.management.read | booking | GET /open-platform/v1/booking/work-hours, GET .../vacations/ | | provider.management.write | booking | POST/PUT work-hours, POST vacations | | provider.prescription.read | prescription | GET /v1/rx/services/search | | provider.rasan.read | rasan | GET /v1/rasan/balance | | provider.rasan.write | rasan | POST /v1/rasan/messages | ## بیمار (user) | Hamdast scope | سرویس | endpoint | |---------------|-------|----------| | user.profile.read | user-profile | GET /v1/user/information | | user.profile.write | user-profile | ویرایش پروفایل | | user.appointment.read | booking | نوبت‌های کاربر | | user.appointment.write | booking | حذف نوبت | ## x-scopes در OpenAPI در booking.json ممکن است x-scopes: ["view-calendar"] ببینید. این نام داخلی API است. در getSessionToken از scopeهای Hamdast (provider.*) استفاده کنید. ## ai-docs/troubleshooting.md # خطاهای رایج ## احراز هویت | خطا | راهکار | |-----|--------| | USER_CLOSED_POPUP | getSessionToken() دوباره | | INVALID_SESSION_TOKEN | token جدید | | DEVELOPER_NOT_AUTHORIZED | x-api-key و مالکیت اپ | | 403 API | scope فعال و تأییدشده | ## SDK undefined ```html ``` initialize قبل از getSessionToken. SDK در index.html نه bundle. ## iframe از hamdast.redirect.dispatch نه window.location. برای بیمار: hamdast.flow.dispatch. ## CORS فرانت → بک‌اند شما → API پذیرش۲۴. API مستقیم از مرورگر صدا نزنید. ## Sandbox هنوز به API وصل نیست. deploy + نصب در پنل. ## Monetization URLها از نه app_id داخلی. x-api-key فقط بک‌اند. ## ai-docs/sdk-reference.md # مرجع SDK همدست ```html ``` TypeScript: /hamdast.d.ts ## initialize() پیش‌نیاز: SDK لود شده. ## getSessionToken() خروجی: session token (string) خطا: USER_CLOSED_POPUP پیش‌نیاز: initialize، scope فعال در کنسول ## redirect.dispatch() پیش‌نیاز: iframe پنل پزشک ## flow.dispatch(action) actions: BOOKING.RECEIPT, BOOKING.ONLINE_VISIT_CHANNEL پیش‌نیاز: افزونه فرایند بیمار ## payment.pay() رویدادها: HAMDAST_PAYMENT_SUCCESS, HAMDAST_PAYMENT_CANCEL, HAMDAST_PAYMENT_ERROR ## payment.subscribe() رویدادها: HAMDAST_PAYMENT_SUBSCRIBE_SUCCESS, HAMDAST_PAYMENT_SUBSCRIBE_CANCEL ## payment.payForDoctorService() ``` payable = amount + amount × 0.3 × 0.1 // amount: ریال، بدون VAT دستی ``` رویدادها: HAMDAST_PAYMENT_DOCTOR_SERVICE_SUCCESS, CANCEL, ERROR موفقیت: `` — monetization/verify لازم نیست پیش‌نیاز: iframe پروفایل پزشک تبدیل session_token به access_token در بک‌اند با x-api-key — متد SDK نیست. ## rasan.activate() Activate provider SMS. Independent of `getSessionToken` — not a separate auth flow. Call from the widget frontend when needed. If SMS is already active, it resolves immediately; otherwise the provider is asked to confirm. Events: HAMDAST_RASAN_ACTIVATE_SUCCESS, HAMDAST_RASAN_ACTIVATE_CANCEL, HAMDAST_RASAN_ACTIVATE_ERROR Success example: `` After activation, use `getSessionToken` with `provider.rasan.read` / `provider.rasan.write` and `https://openapi.paziresh24.com/v1/rasan/*`. ## rasan.charge() Opens the shared SMS top-up modal (fixed packages + custom count). Payment goes through the platform `rasan` app, then credit is applied on Kavenegar. ```js const result = await hamdast.rasan.charge(); // result.event === "HAMDAST_RASAN_CHARGE_SUCCESS" ``` ## ai-docs/webhooks.md # Webhook verify (Svix) ```js const wh = new Webhook(process.env.WEBHOOK_SECRET); app.post("/webhooks/paziresh24", (req, res) => ; try catch }); ``` Console: /console/apps//webhooks ## ai-docs/cookbook/appointments-list.md # لیست نوبت‌ها نمایش نوبت‌های پزشک. ## مشخصات | مورد | مقدار | |------|-------| | Scope | `provider.appointment.read` | | Endpoint (از طریق apigw) | `GET https://apigw.paziresh24.com/open-platform/v1/booking/appointments` | | Endpoint (مستقیم، بدون apigw) | `GET https://openapi.paziresh24.com/v1/booking/appointments` | | Query params | `center_id` (الزامی), `date` (الزامی، `YYYY-MM-DD`) | | Auth | `Authorization: Bearer ` | | SDK | `initialize`, `getSessionToken` | هویت پزشک (و اینکه به کدام مرکزها دسترسی دارد) مستقیماً از روی `access_token` تشخیص داده می‌شود؛ نیازی به ارسال جداگانه‌ی `user_id` یا هدر مشابه نیست — همه‌چیز از توکن حل می‌شود. ## فرانت‌اند ```js window.hamdast.initialize(); const sessionToken = await window.hamdast.getSessionToken(); const res = await fetch("/api/appointments", , body: JSON.stringify(), }); const appointments = await res.json(); ``` ## بک‌اند ```js // POST /api/appointments async function exchangeToken(sessionToken) /oauth/access_token`, , body: JSON.stringify(), } ); const = await res.json(); return access_token; } async function getAppointments(accessToken, centerId, date) ` }, }); return res.json(); } ``` ## ai-docs/cookbook/doctor-service-payment.md # پرداخت سرویس پزشک ```js const = await window.hamdast.payment.payForDoctorService(, }); // HAMDAST_PAYMENT_DOCTOR_SERVICE_SUCCESS | CANCEL | ERROR ``` | | | |--|--| | `amount` | ریال، پایه (بدون VAT دستی) | | `payload` | اختیاری | | verify monetization | لازم نیست | | refund (server) | `POST .../billing/provider-service/refund` + `x-api-key` | | محل | پروفایل پزشک | | docs | `/apps/sdk/doctor-service-payment` | ``` payable = amount + amount × 0.3 × 0.1 ``` ```js await fetch( `https://hamdast.paziresh24.com/api/v1/apps/$/billing/provider-service/refund`, , body: JSON.stringify(), }, ); ``` ## ai-docs/cookbook/hami-widget-bot.md # Hami widget bot messaging Send Hami messages to a Paziresh24 user from your widget backend (bot account per app). ## Prerequisites 1. Console → **اتصال به API** → **بات حامی**: save bot mobile (resolves `user_id`). 2. Scope **`app.hami.messaging`** enabled and verified for your app. 3. **`x-api-key`** (developer) and **`app_id`** (app id) on every request — server only. No `getSessionToken` required for send; auth is platform API key + app id. ## Create conversation ```http POST https://openapi.paziresh24.com/v1/hami/conversations x-api-key: YOUR_DEVELOPER_API_KEY app_id: YOUR_APP_ID Content-Type: application/json ``` ## Send message ```http POST https://openapi.paziresh24.com/v1/hami/messages x-api-key: YOUR_DEVELOPER_API_KEY app_id: YOUR_APP_ID Content-Type: application/json ``` ## Notes - One chat per `(app, user_id)` via stable `reference_id` on create-or-get. - Hami ticket title: **`ابزارک `** (set by platform on create). - Appointment chat API (`/open-platform/v1/chats//messages`) is separate — booking context only. See also `hamdast/portal/docs/hami-widget-bot-messaging.md` in the Hamdast monorepo. ## ai-docs/cookbook/patient-flow-addon.md # افزونه فرایند بیمار هدایت بیمار به مرحله بعد پس از تکمیل کار در ابزارک. ## مشخصات | مورد | مقدار | |------|-------| | SDK | `flow.dispatch` | | پیش‌نیاز | ابزارک در فرایند نوبت‌دهی بیمار فعال باشد | | API | معمولاً لازم نیست (مگر داده سفارشی ذخیره کنید) | ## نمونه: هدایت به قبض نوبت ```js async function handleFormSubmit(formData) ); window.hamdast.flow.dispatch("BOOKING.RECEIPT"); } ``` ## نمونه: هدایت به چنل ویزیت آنلاین ```js window.hamdast.flow.dispatch("BOOKING.ONLINE_VISIT_CHANNEL"); ``` ## actions موجود | action | کاربرد | |--------|--------| | `BOOKING.RECEIPT` | صفحه قبض نوبت | | `BOOKING.ONLINE_VISIT_CHANNEL` | چنل گفتگوی ویزیت آنلاین | ## ai-docs/cookbook/payment.md # پرداخت در ابزارک دریافت پرداخت از کاربر بدون خروج از پنل. ## مشخصات | مورد | مقدار | |------|-------| | SDK | `payment.pay`, `payment.subscribe` | | بک‌اند | verify با `x-api-key` | | راهنما | | برای هزینه خدمت روی پروفایل پزشک → `payment.payForDoctorService` — `/apps/sdk/doctor-service-payment`. ## پرداخت با محصول از پیش تعریف‌شده ```js const = await window.hamdast.payment.pay(, }); if (event === "HAMDAST_PAYMENT_SUCCESS") , body: JSON.stringify(), }); } ``` ## verify در بک‌اند ```js await fetch( `https://hamdast.paziresh24.com/api/v1/apps/$/monetization/verify`, , body: JSON.stringify(), } ); ``` ## اشتراک ```js const = await window.hamdast.payment.subscribe(); ``` محصولات و پلن‌ها را در کنسول همدست → **کسب درآمد** تعریف کنید. ## ai-docs/cookbook/profile-edit.md # ویرایش پروفایل خواندن و به‌روزرسانی اطلاعات پزشک. ## مشخصات | مورد | مقدار | |------|-------| | Scope خواندن | `provider.profile.read` | | Scope نوشتن | `provider.profile.write` | | API | | | Endpoint خواندن | `GET /open-platform/v1/profile/information` | | Endpoint نوشتن | `PUT /open-platform/v1/profile/information` | ## فرانت‌اند ```js window.hamdast.initialize(); const sessionToken = await window.hamdast.getSessionToken(); // خواندن const profile = await fetch("/api/profile", , body: JSON.stringify(), }).then((r) => r.json()); // ویرایش await fetch("/api/profile", , body: JSON.stringify(, }), }); ``` ## بک‌اند ```js async function callProfileApi(accessToken, method, body) `, "Content-Type": "application/json", }, body: body ? JSON.stringify(body) : undefined, } ); return res.json(); } ``` ## ai-docs/cookbook/redirect-panel.md # هدایت به پنل باز کردن صفحات داخلی پنل پذیرش۲۴ از داخل ابزارک. ## مشخصات | مورد | مقدار | |------|-------| | SDK | `redirect.dispatch` | | پیش‌نیاز | ابزارک داخل iframe پنل پزشک | ## نمونه‌ها ```js // صفحه نوبت‌ها window.hamdast.redirect.dispatch(); // ساعت کاری window.hamdast.redirect.dispatch(); // پروفایل در تب جدید window.hamdast.redirect.dispatch(); ``` مسیرها بدون دامنه نوشته می‌شوند — SDK خودش با `paziresh24.com` ترکیب می‌کند. ## ai-docs/cookbook/sms.md # Provider SMS (Rasan) Send SMS and read SMS credit for a provider. ## Prerequisites 1. Enable `provider.rasan.read` and `provider.rasan.write` for your app in the Hamdast console (approval may be required). 2. Activate SMS from the frontend before the first send. 3. To top up credit: `await hamdast.rasan.charge()` (shared packages; not per-app). ## 1) Activate SMS (frontend SDK) This method is **not** authentication and does not depend on `getSessionToken`. If SMS is already active, it resolves immediately; otherwise the provider is asked to confirm. ```js hamdast.initialize(); const result = await hamdast.rasan.activate(); // result.event === "HAMDAST_RASAN_ACTIVATE_SUCCESS" ``` If the provider cancels: `HAMDAST_RASAN_ACTIVATE_CANCEL`. ## 2) OAuth ```js const session_token = await hamdast.getSessionToken(); ``` Exchange `session_token` for `access_token` on your backend with `x-api-key`. ## 3) Balance ```http GET https://openapi.paziresh24.com/v1/rasan/balance Authorization: Bearer ``` Example response: ```json ``` If SMS is not activated: `409` with code `SMS_NOT_ACTIVATED`. ## 4) Send SMS ```http POST https://openapi.paziresh24.com/v1/rasan/messages Authorization: Bearer Content-Type: application/json ``` Example response: ```json ``` Errors: | Code | Meaning | |------|---------| | `SMS_NOT_ACTIVATED` (409) | Call `hamdast.rasan.activate()` from the frontend first | | `INSUFFICIENT_SMS_CREDIT` (402) | Provider SMS credit is too low | | `403` | Scope missing or not approved | ## Suggested flow 1. `hamdast.rasan.activate()` when the user needs SMS 2. `getSessionToken()` 3. Backend: exchange + `POST /v1/rasan/messages` ## ai-docs/cookbook/work-hours.md # ساعت کاری و مرخصی مشاهده برنامه کاری پزشک. ## مشخصات | مورد | مقدار | |------|-------| | Scope | `provider.management.read` | | API | | | Endpoints | `GET /open-platform/v1/booking/work-hours`, `GET .../vacations/` | ## فرانت‌اند ```js window.hamdast.initialize(); const sessionToken = await window.hamdast.getSessionToken(); const workHours = await fetch("/api/work-hours", , body: JSON.stringify(), }).then((r) => r.json()); ``` ## بک‌اند ```js const accessToken = await exchangeToken(sessionToken); const workHoursRes = await fetch( "https://apigw.paziresh24.com/open-platform/v1/booking/work-hours", ` } } ); const workHours = await workHoursRes.json(); // مراکز را از medical-centers بگیرید، سپس: // GET .../vacations/ ``` برای ویرایش ساعت کاری scope `provider.management.write` لازم است.