openapi: 3.0.3
info:
  title: 'RsomPay External API Documentation'
  description: 'RsomPay External B2B Partner API — invoices, transactions, settlements, and refunds for integration partners (scope=external clients only). Scoped internal source-of-truth for this repo; the partner-facing narrative docs are hand-maintained in the sibling external-api-docs/ project.'
  version: 1.0.0
servers:
  -
    url: 'http://127.0.0.1:8000'
tags:
  -
    name: Invoices
    description: "\nCreate, look up, and refund invoices on behalf of your customers (parents/students, in the\nschool-vertical case). Every invoice created here also carries a hosted checkout link\n(`payment_url`) — see the payment-flow section of the integration guide."
  -
    name: Settlements
    description: "\nRead-only settlement/payout status for reconciliation. Settlement batches are created and\nprocessed internally by RsomPay — this panel only exposes their status and constituent\ntransactions, scoped to your own client."
components:
  securitySchemes:
    default:
      type: http
      scheme: bearer
      description: 'Sanctum personal access token of type <code>client-external-api</code>, minted for a <code>Client</code> with <code>scope=external</code>. See EXTERNAL_API_INTEGRATION_GUIDE.md (external-api-docs project) for onboarding.'
security:
  -
    default: []
paths:
  /api/external/v1/transactions:
    get:
      summary: 'List customer transactions'
      operationId: listCustomerTransactions
      description: 'Paginated payment history for one customer, across all their invoices with this client.'
      parameters:
        -
          in: query
          name: customer_id
          description: 'value must not be greater than 255 characters.'
          example: b
          required: true
          schema:
            type: string
            description: 'value must not be greater than 255 characters.'
            example: b
        -
          in: query
          name: page
          description: 'value must be at least 1.'
          example: 22
          required: false
          schema:
            type: integer
            description: 'value must be at least 1.'
            example: 22
            nullable: true
        -
          in: query
          name: per_page
          description: 'value must be at least 1. value must not be greater than 100.'
          example: 7
          required: false
          schema:
            type: integer
            description: 'value must be at least 1. value must not be greater than 100.'
            example: 7
            nullable: true
      responses: {  }
      tags:
        - Invoices
  /api/external/v1/invoices:
    post:
      summary: 'Create invoice'
      operationId: createInvoice
      description: "Idempotent by `external_id` per client — calling this again with the same `external_id`\nreturns the previously created invoice instead of creating a duplicate."
      parameters: []
      responses:
        201:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  status: true
                  message: 'Mission completed successfully'
                  data:
                    external_id: INV-PARTNER-001
                    reference_number: INV-42-000123
                    customer:
                      id: CUST-9
                      fullname: 'عميل تجريبي'
                      email: customer@example.com
                      phone: '+966501234567'
                    status: issued
                    confirmation_status: pending_confirmation
                    amount: 103.5
                    currency_code: SAR
                    due_date: null
                    issued_date: '2026-08-02'
                    payment_url: 'https://payment.rsompay.com/pay/checkout/9f2b3c1a-...'
                    notification_url: 'https://partner.example.com/webhooks/rsom'
                    return_url: 'https://partner.example.com/payment/return'
                    totals:
                      subtotal: 100
                      discount_total: 10
                      tax_total: 13.5
                      grand_total: 103.5
                    items:
                      -
                        description: خدمة
                        item_type: null
                        quantity: 1
                        unit_price: 100
                        discount_amount: 10
                        tax_rate: 15
                        tax_amount: 13.5
                        total_amount: 103.5
                        reference_id: LINE-1
                    created_at: '2026-08-02 10:00:00'
                    updated_at: '2026-08-02 10:00:00'
                properties:
                  status:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: 'Mission completed successfully'
                  data:
                    type: object
                    properties:
                      external_id:
                        type: string
                        example: INV-PARTNER-001
                      reference_number:
                        type: string
                        example: INV-42-000123
                      customer:
                        type: object
                        properties:
                          id:
                            type: string
                            example: CUST-9
                          fullname:
                            type: string
                            example: 'عميل تجريبي'
                          email:
                            type: string
                            example: customer@example.com
                          phone:
                            type: string
                            example: '+966501234567'
                      status:
                        type: string
                        example: issued
                      confirmation_status:
                        type: string
                        example: pending_confirmation
                      amount:
                        type: number
                        example: 103.5
                      currency_code:
                        type: string
                        example: SAR
                      due_date:
                        type: string
                        example: null
                        nullable: true
                      issued_date:
                        type: string
                        example: '2026-08-02'
                      payment_url:
                        type: string
                        example: 'https://payment.rsompay.com/pay/checkout/9f2b3c1a-...'
                      notification_url:
                        type: string
                        example: 'https://partner.example.com/webhooks/rsom'
                      return_url:
                        type: string
                        example: 'https://partner.example.com/payment/return'
                      totals:
                        type: object
                        properties:
                          subtotal:
                            type: integer
                            example: 100
                          discount_total:
                            type: integer
                            example: 10
                          tax_total:
                            type: number
                            example: 13.5
                          grand_total:
                            type: number
                            example: 103.5
                      items:
                        type: array
                        example:
                          -
                            description: خدمة
                            item_type: null
                            quantity: 1
                            unit_price: 100
                            discount_amount: 10
                            tax_rate: 15
                            tax_amount: 13.5
                            total_amount: 103.5
                            reference_id: LINE-1
                        items:
                          type: object
                          properties:
                            description:
                              type: string
                              example: خدمة
                            item_type:
                              type: string
                              example: null
                              nullable: true
                            quantity:
                              type: integer
                              example: 1
                            unit_price:
                              type: integer
                              example: 100
                            discount_amount:
                              type: integer
                              example: 10
                            tax_rate:
                              type: integer
                              example: 15
                            tax_amount:
                              type: number
                              example: 13.5
                            total_amount:
                              type: number
                              example: 103.5
                            reference_id:
                              type: string
                              example: LINE-1
                      created_at:
                        type: string
                        example: '2026-08-02 10:00:00'
                      updated_at:
                        type: string
                        example: '2026-08-02 10:00:00'
      tags:
        - Invoices
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                external_id:
                  type: string
                  description: 'value must not be greater than 255 characters.'
                  example: b
                notification_url:
                  type: string
                  description: 'Must be a valid URL. Must match the regex /^https:\/\//i. value must not be greater than 2048 characters.'
                  example: 'http://bailey.com/'
                return_url:
                  type: string
                  description: 'Must be a valid URL. Must match the regex /^https:\/\//i. value must not be greater than 2048 characters.'
                  example: 'http://rempel.com/sunt-nihil-accusantium-harum-mollitia'
                currency_code:
                  type: string
                  description: 'value must not be greater than 8 characters.'
                  example: khwaykcm
                  nullable: true
                due_date:
                  type: string
                  description: 'value must be a valid date.'
                  example: '2026-08-02T23:52:06'
                  nullable: true
                issued_date:
                  type: string
                  description: 'value must be a valid date.'
                  example: '2026-08-02T23:52:06'
                  nullable: true
                payment_method:
                  type: string
                  description: ''
                  example: mada
                  enum:
                    - mada
                    - credit_card
                    - apple_pay
                    - tamara
                  nullable: true
                notes:
                  type: string
                  description: 'value must not be greater than 2000 characters.'
                  example: 'y'
                  nullable: true
                customer:
                  type: object
                  description: ''
                  example: []
                  properties:
                    id:
                      type: string
                      description: 'value must not be greater than 255 characters.'
                      example: b
                    fullname:
                      type: string
                      description: 'value must not be greater than 255 characters.'
                      example: 'n'
                    email:
                      type: string
                      description: 'value must be a valid email address. value must not be greater than 255 characters.'
                      example: ashly64@example.com
                      nullable: true
                    phone:
                      type: string
                      description: 'value must not be greater than 32 characters.'
                      example: v
                      nullable: true
                  required:
                    - id
                    - fullname
                items:
                  type: array
                  description: 'value must have at least 1 items.'
                  example:
                    - []
                  items:
                    type: object
                    properties:
                      description:
                        type: string
                        description: 'value must not be greater than 255 characters.'
                        example: 'Eius et animi quos velit et.'
                      item_type:
                        type: string
                        description: 'value must not be greater than 32 characters.'
                        example: v
                        nullable: true
                      quantity:
                        type: number
                        description: 'value must be at least 0.001.'
                        example: 42
                        nullable: true
                      unit_price:
                        type: number
                        description: 'value must be at least 0.01.'
                        example: 37
                      discount_amount:
                        type: number
                        description: 'value must be at least 0.'
                        example: 9
                        nullable: true
                      tax_rate:
                        type: number
                        description: 'value must be at least 0.'
                        example: 52
                        nullable: true
                      reference_id:
                        type: string
                        description: 'value must not be greater than 128 characters.'
                        example: i
                        nullable: true
                    required:
                      - description
                      - unit_price
              required:
                - external_id
                - notification_url
                - return_url
                - customer
                - items
  /api/external/v1/invoices/by-reference:
    get:
      summary: 'Get invoice by reference'
      operationId: getInvoiceByReference
      description: "Look up by either `external_id` (your own id) or `reference_number` (RsomPay's), at least\none is required. `payment_url` is regenerated fresh on every call if the previous checkout\nsession expired — safe to re-fetch instead of caching the original link."
      parameters:
        -
          in: query
          name: external_id
          description: 'value must not be greater than 255 characters.'
          example: b
          required: false
          schema:
            type: string
            description: 'value must not be greater than 255 characters.'
            example: b
            nullable: true
        -
          in: query
          name: reference_number
          description: 'value must not be greater than 100 characters.'
          example: 'n'
          required: false
          schema:
            type: string
            description: 'value must not be greater than 100 characters.'
            example: 'n'
            nullable: true
      responses: {  }
      tags:
        - Invoices
  '/api/external/v1/invoices/{reference}/refund':
    post:
      summary: 'Refund invoice payment'
      operationId: refundInvoicePayment
      description: "Full refund if `amount` is omitted, partial refund otherwise (capped at the remaining\nrefundable balance). Only supported for completed Dhamen-gateway payments that haven't\nentered settlement yet."
      parameters: []
      responses: {  }
      tags:
        - Invoices
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                amount:
                  type: number
                  description: 'value must be at least 1.'
                  example: 16
                  nullable: true
                reason:
                  type: string
                  description: 'value must not be greater than 500 characters.'
                  example: 'n'
                  nullable: true
    parameters:
      -
        in: path
        name: reference
        description: "The invoice's `external_id` or `reference_number`."
        example: INV-PARTNER-001
        required: true
        schema:
          type: string
  /api/external/v1/settlements:
    get:
      summary: 'List settlements'
      operationId: listSettlements
      description: ''
      parameters:
        -
          in: query
          name: page
          description: 'value must be at least 1.'
          example: 16
          required: false
          schema:
            type: integer
            description: 'value must be at least 1.'
            example: 16
            nullable: true
        -
          in: query
          name: per_page
          description: 'value must be at least 1. value must not be greater than 100.'
          example: 22
          required: false
          schema:
            type: integer
            description: 'value must be at least 1. value must not be greater than 100.'
            example: 22
            nullable: true
        -
          in: query
          name: status
          description: 'value must not be greater than 32 characters.'
          example: g
          required: false
          schema:
            type: string
            description: 'value must not be greater than 32 characters.'
            example: g
            nullable: true
        -
          in: query
          name: date_from
          description: 'value must be a valid date.'
          example: '2026-08-02T23:52:06'
          required: false
          schema:
            type: string
            description: 'value must be a valid date.'
            example: '2026-08-02T23:52:06'
            nullable: true
        -
          in: query
          name: date_to
          description: 'value must be a valid date. value must be a date after or equal to <code>date_from</code>.'
          example: '2052-08-25'
          required: false
          schema:
            type: string
            description: 'value must be a valid date. value must be a date after or equal to <code>date_from</code>.'
            example: '2052-08-25'
            nullable: true
      responses:
        200:
          description: ''
          content:
            application/json:
              schema:
                type: object
                example:
                  status: true
                  message: 'Mission completed successfully'
                  data:
                    -
                      id: 42
                      reference: DHM-INS-12-0007
                      status: settled
                      period_from: '2026-07-01'
                      period_to: '2026-07-15'
                      currency_code: SAR
                      gross_total: 1500
                      fee_total: 75
                      net_total: 1425
                      transactions_count: 12
                      bank_transfer_reference: BANK-REF-001
                      settled_at: '2026-07-18 09:00:00'
                      created_at: '2026-07-16 08:00:00'
                  meta:
                    total: 1
                    per_page: 15
                    current_page: 1
                    last_page: 1
                properties:
                  status:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: 'Mission completed successfully'
                  data:
                    type: array
                    example:
                      -
                        id: 42
                        reference: DHM-INS-12-0007
                        status: settled
                        period_from: '2026-07-01'
                        period_to: '2026-07-15'
                        currency_code: SAR
                        gross_total: 1500
                        fee_total: 75
                        net_total: 1425
                        transactions_count: 12
                        bank_transfer_reference: BANK-REF-001
                        settled_at: '2026-07-18 09:00:00'
                        created_at: '2026-07-16 08:00:00'
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          example: 42
                        reference:
                          type: string
                          example: DHM-INS-12-0007
                        status:
                          type: string
                          example: settled
                        period_from:
                          type: string
                          example: '2026-07-01'
                        period_to:
                          type: string
                          example: '2026-07-15'
                        currency_code:
                          type: string
                          example: SAR
                        gross_total:
                          type: integer
                          example: 1500
                        fee_total:
                          type: integer
                          example: 75
                        net_total:
                          type: integer
                          example: 1425
                        transactions_count:
                          type: integer
                          example: 12
                        bank_transfer_reference:
                          type: string
                          example: BANK-REF-001
                        settled_at:
                          type: string
                          example: '2026-07-18 09:00:00'
                        created_at:
                          type: string
                          example: '2026-07-16 08:00:00'
                  meta:
                    type: object
                    properties:
                      total:
                        type: integer
                        example: 1
                      per_page:
                        type: integer
                        example: 15
                      current_page:
                        type: integer
                        example: 1
                      last_page:
                        type: integer
                        example: 1
      tags:
        - Settlements
  '/api/external/v1/settlements/{id}':
    get:
      summary: 'Get settlement detail'
      operationId: getSettlementDetail
      description: "Returns the batch plus its settled line items and a minimal transaction sub-object per item.\n404 if the settlement doesn't exist or doesn't belong to your client."
      parameters: []
      responses: {  }
      tags:
        - Settlements
    parameters:
      -
        in: path
        name: id
        description: "The settlement's internal id (from the list endpoint)."
        example: 42
        required: true
        schema:
          type: integer
