Files
clinicpro/docs/api/payment.md
T
hamedandClaude Opus 4.8 3f31f42fa0 docs(api): document GET /api/v1/my/payments
Add the user payments-list endpoint to payment.md: permission, query
params (page/limit/status), and the paginated response shape.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 19:22:07 +03:30

6.7 KiB

Payment API

Prefix: /api/v1/payment, /api/v1/subscription-payment
Supported Gateways: mellat (Mellat Bank SOAP) | sep (SEP REST)


GET /api/v1/payment/config

دریافت تنظیمات عمومی پرداخت — برای نمایش وضعیت درگاه آزمایشی در frontend.

Permission: IS_AUTHENTICATED_FULLY

Response 200

{
  "success": true,
  "data": {
    "test_mode": true
  }
}
Field Type Description
test_mode boolean true = درگاه آزمایشی فعال است — backend از MockGateway استفاده می‌کند و پول واقعی کسر نمی‌شود

نکته: این endpoint هیچ اطلاعات حساسی (terminal_id، password، ...) را expose نمی‌کند. تنها یک boolean برای مصرف frontend است.


GET /api/v1/my/payments

List the authenticated user's own payments (derived from the token — there is no userId in the URL). Used by the public dashboard's transactions tab.

Permission: IS_AUTHENTICATED_FULLY

Query Parameters

Param Type Default Description
page integer 1 Page number
limit integer 20 Items per page (max 100)
status string Optional filter: pending / success / failed / cancelled / refunded

Response 200 (paginated)

{
  "success": true,
  "data": [
    {
      "uuid": "pay-uuid-...",
      "order_id": "ORD-84FB82E12A4A45CE",
      "amount_rials": 590000,
      "status": "success",
      "gateway": "mellat",
      "type": "appointment",
      "reference_id": "...",
      "appointment_uuid": "appt-uuid-...",
      "created_at": 1781521834
    }
  ],
  "meta": { "totalRecords": 1, "totalPages": 1, "currentPage": 1 }
}

Items at data (flat array), total at meta.totalRecords. Ordered by created_at DESC.

Errors

Code HTTP Description
ERR_AUTH_001 401 Missing token

POST /api/v1/payment/appointment

Initiate payment for an appointment. Returns a redirect URL to the payment gateway.

Permission: AUTH — must be the appointment owner (patient)

Request Body (application/json)

{
  "appointment_uuid": "appt-uuid-...",
  "gateway": "mellat",
  "frontend_address": "https://myapp.com/payment/result"
}
Field Type Required Description
appointment_uuid string (UUID) Appointment to pay for
gateway string "mellat" or "sep"
frontend_address string Redirect URL after payment (overrides default)

Response 200

{
  "success": true,
  "data": {
    "payment_uuid": "pay-uuid-...",
    "redirect_url": "https://bpm.shaparak.ir/pgwchannel/...",
    "order_id": "CLINICPRO-1717000000-ABC123"
  }
}

On successful callback for an appointment payment, the booking is transitioned pending → confirmed (its 15-minute expires_at is cleared) and a confirmation SMS is dispatched to the patient's mobile. If the booking already lapsed to expired before payment confirmed, it is not re-confirmed (the transition is rejected) — handle refund out of band.

Errors

Code HTTP Description
ERR_AUTH_001 401 Missing token
ERR_FORBIDDEN_001 403 Not the patient
ERR_PAYMENT_003 422 Appointment not in payable state
ERR_PAYMENT_002 422 Invalid amount
ERR_PAYMENT_001 503 Payment gateway unavailable

POST /api/v1/payment/callback/{gateway}

GET /api/v1/payment/callback/{gateway}

Payment gateway callback. Called by the bank after user completes (or cancels) payment.

Permission: PUBLIC — called by the gateway, not the user

Path Parameters

Param Type Description
gateway string mellat or sep

Request (varies by gateway)

Mellat POST fields:

ResCode=0&SaleOrderId=...&SaleReferenceId=...&RefId=...

SEP POST fields:

Status=2&RRN=...&RefNum=...&TerminalId=...&TraceNo=...

Response

  • If ResCode=0 (success): appointment confirmed, redirect to frontend_address?success=1&uuid=...
  • If failed: redirect to frontend_address?success=0&error=...

Notes

  • On success: appointment status → confirmed, wallet credited with doctor's share
  • Payment record stored with: order_id, amount_rials, status, gateway, ref_id

POST /api/v1/subscription-payment

Initiate a subscription / wallet top-up payment (not tied to a specific appointment).

Permission: AUTH

Request Body

{
  "gateway": "mellat",
  "amount_rials": 1000000,
  "frontend_address": "https://myapp.com/wallet/result"
}
Field Type Required Description
gateway string "mellat" or "sep"
amount_rials integer Amount in Rials (min: 10,000)
frontend_address string Redirect URL after payment

Response 200

{
  "success": true,
  "data": {
    "payment_uuid": "pay-uuid-...",
    "redirect_url": "https://bpm.shaparak.ir/pgwchannel/...",
    "order_id": "CLINICPRO-SUB-1717000000-XYZ"
  }
}

Errors

Code HTTP Description
ERR_AUTH_001 401 Missing token
ERR_PAYMENT_002 422 Invalid amount
ERR_PAYMENT_001 503 Gateway unavailable

POST/GET /api/v1/subscription-payment/callback/{gateway}

Callback for subscription payments. Same behavior as appointment callback but credits wallet instead.

Permission: PUBLIC


GET /api/v1/payment/{uuid}

Get payment status and details.

Permission: AUTH — must be the payment owner or ROLE_ADMIN

Path Parameters

Param Type Description
uuid string (UUID) Payment UUID

Response 200

{
  "success": true,
  "data": {
    "uuid": "pay-uuid-...",
    "order_id": "CLINICPRO-1717000000-ABC123",
    "amount_rials": 500000,
    "status": "paid",
    "gateway": "mellat",
    "ref_id": "123456789",
    "appointment_uuid": "appt-uuid-...",
    "created_at": 1717000000,
    "paid_at": 1717000120
  }
}

Payment Status Values:

Value Description
pending Created, not paid yet
paid Successfully paid
failed Gateway returned failure
cancelled User cancelled at gateway
refunded Refunded

Errors

Code HTTP Description
ERR_AUTH_001 401 Missing token
ERR_FORBIDDEN_001 403 Not the owner
ERR_NOT_FOUND_001 404 Payment not found