openapi: '3.0.3'

info:
  title: SanctusPay API
  description: >
    The SanctusPay API provides endpoints for merchants to authenticate, create and
    manage payment intents, tokenize card data, retrieve transactions, and handle
    refunds. This documentation describes each endpoint, its request/response
    parameters, and how to integrate with SanctusPay from various merchant systems.
  version: 0.1.0

servers:
  - url: 'https://test.api.us.sanctuspay.com'
  - url: 'https://live.api.us.sanctuspay.com'

paths:
  /auth/token:
    post:
      summary: Obtain a New Authentication Token
      tags:
        - Auth
      description: >
        Use this endpoint to generate a new JWT (JSON Web Token) by providing valid
        client credentials (`client_id` and `client_secret`). The returned token must
        be included in the `Authorization` header as `Bearer <token>` for subsequent
        calls to authenticate and authorize access to the SanctusPay API.
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                client_id:
                  description: Your unique `client_id` assigned by SanctusPay.
                  type: string
                client_secret:
                  description: Your unique `client_secret` associated with your `client_id`.
                  type: string
              required:
                - client_id
                - client_secret
      responses:
        200:
          description: A successfully generated access token.
          content:
            application/json:
              schema:
                type: object
                properties:
                  access_token:
                    description: Your newly generated JWT access token.
                    type: string
                    format: JWT
                  expiry:
                    description: The UNIX timestamp (UTC) at which this token expires.
                    type: integer
                    format: timestamp
                required:
                  - access_token
                  - expiry

  /intents/card:
    post:
      summary: Create a Card Tokenization Intent
      tags:
        - Intents
      description: >
        Creates a new intent for card tokenization. This process securely collects card
        details that can later be used for transactions without needing to store raw
        card data on your systems.
      security:
        - BearerAuth: [ ]
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                external_id:
                  description: >
                    A unique identifier (e.g., UUID) from the merchant side to reference
                    this tokenization request. This helps correlate the newly generated
                    card token with a specific user or account in your system.
                  type: string
                  example: "496de72d-d4a4-45eb-b426-3d04d2078a85"
              required:
                - external_id
      responses:
        200:
          description: New card tokenization intent created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IntentResponse'

  /intents/payment:
    post:
      summary: Create a Payment Transaction Intent
      tags:
        - Intents
      description: >
        Creates a new intent for a payment authorization. An intent helps prepare
        and track the details required before finalizing a transaction (capture).
      security:
        - BearerAuth: [ ]
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                external_id:
                  description: >
                    A unique identifier from your system to reference this payment
                    intent. Useful for idempotency and for correlating the future
                    transaction within your internal systems.
                  type: string
                  example: "496de72d-d4a4-45eb-b426-3d04d2078a85"
                redirect_urls:
                  description: >
                    The URLs to which the checkout page should redirect the user after
                    a successful or failed payment. The unique transaction ID will be
                    included in the redirect parameters so you can store or retrieve
                    payment details via the API. In case of a lost connection during
                    processing, you can still retrieve the transaction using your
                    external ID.
                  type: object
                  properties:
                    success:
                      description: The desired redirect URL on successful payment.
                      type: string
                      format: URL
                      example: https://www.example.com/success?trx_id=XYZ&order_id=ZYX
                    failure:
                      description: The desired redirect URL on failed payment.
                      type: string
                      format: URL
                      example: https://www.example.com/failure?trx_id=XYZ&order_id=ZYX
                  required:
                    - success
                    - failure
                order:
                  $ref: "#/components/schemas/OrderRequest"
              required:
                - external_id
                - redirect_urls
                - order
      responses:
        200:
          description: New payment intent created.
          content:
            application/json:
              schema:
                type: object
                properties:
                  intent_id:
                    format: string
                    example: "int_01J5XCMDXCFXCAQ1BV8HVG6644"
                  reference_id:
                    description: >
                      Merchant's external reference ID. Typically used to link the
                      transaction to a specific order or consumer in your system.
                    type: string
                    example: "496de72d-d4a4-45eb-b426-3d04d2078a85"
                required:
                  - intent_id
                  - reference_id

  /transaction:
    get:
      summary: Get Transaction Details by Either order_id or external_id
      tags:
        - Transactions
      description: >
        Retrieves the details of a specific transaction by using either the `external_id`
        or the `order_id`. You must indicate which identifier type you are passing.
      security:
        - BearerAuth: [ ]
      parameters:
        - in: query
          name: type
          schema:
            enum:
              - external_id
              - order_id
          description: Indicates whether the provided `id` is the `external_id` or the `order_id`.
          required: true
        - in: query
          name: id
          schema:
            type: string
          description: The value of the `external_id` or the `order_id` being used.
          required: true
      responses:
        200:
          description: The requested transaction details.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TrxResponse'

  /transactions:
    get:
      summary: List Transactions
      tags:
        - Transactions
      description: >
        Retrieves a paginated list of transactions filtered by date range and optional
        criteria such as type and status. Sorting options are also available.
      security:
        - BearerAuth: [ ]
      parameters:
        - in: query
          name: from_date
          description: >
            The start date for transaction records (DD/MM/YYYY). The time is assumed
            to be 00:00:00 on the given date.
          schema:
            type: string
            example: 01/01/2024
          required: true
        - in: query
          name: to_date
          description: >
            The end date for transaction records (DD/MM/YYYY). The time is assumed
            to be 00:00:00 on the given date.
          schema:
            type: string
            example: 31/12/2024
          required: true
        - in: query
          name: offset
          description: >
            The pagination offset (zero-based). Determines the starting point of
            returned records. If negative number is provided, zero is assumed.
          schema:
            type: integer
            example: 0
          required: true
        - in: query
          name: limit
          description: >
            The maximum number of records to return in one request.   
            If value provided is equal or lower that 10, then 10 is assumed.  
            If value provided is higher than 100, then 100 is assumed.
          schema:
            type: integer
            example: 10
          required: true
        - in: query
          name: order_by
          description: >
            The field by which to sort the results (e.g., `created_at`, `updated_at`).
            Defaults to `updated_at`.
          schema:
            type: string
            default: updated_at
            enum:
              - type
              - status
              - order_amount
              - created_at
              - updated_at
        - in: query
          name: order_dir
          description: >
            The sorting direction, either ascending (`ASC`) or descending (`DESC`).
            Defaults to `ASC`.
          schema:
            type: string
            default: ASC
            enum:
              - ASC
              - DESC
        - in: query
          name: filter_type
          description: >
            Filter the result by transaction type (`PAYMENT`, `REFUND`, or `CHARGEBACK`).
          schema:
            type: string
            enum:
              - PAYMENT
              - REFUND
              - CHARGEBACK
        - in: query
          name: filter_status
          description: >
            Filter the result by transaction status (`AUTHORIZED`, `DECLINED`, `VOIDED`,
            `EXPIRED`, `CAPTURED`, etc.).
          schema:
            type: string
            enum:
              - AUTHORIZED
              - DECLINED
              - VOIDED
              - EXPIRED
              - PARTIAL_CAPTURED
              - CAPTURED
              - PARTIAL_SETTLED
              - SETTLED
      responses:
        200:
          description: A paginated list of transactions matching the provided criteria.
          content:
            application/json:
              schema:
                type: object
                properties:
                  offset:
                    description: The offset of the current transaction list.
                    type: integer
                    example: 0
                  limit:
                    description: The number of records returned in this request.
                    type: integer
                    example: 10
                  amount:
                    description: The total number of records matching the filter.
                    type: integer
                    example: 1
                  result:
                    description: The list of returned transaction objects.
                    type: array
                    items:
                      $ref: '#/components/schemas/TrxResponse'
                required:
                  - offset
                  - limit
                  - amount
                  - result
    post:
      summary: Create a Transaction
      tags:
        - Transactions
      description: >
        Initiates a new transaction authorization (`authorize`) or an authorization with immediate
        capture (`authcap`). The operation type determines how the transaction will be
        processed.
      security:
        - BearerAuth: [ ]
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                operation:
                  description: >
                    The operation to perform. Use `authorize` for authorization-only,
                    or `authcap` to authorize and immediately capture.
                  type: string
                  enum:
                    - authorize
                    - authcap
                  example: authcap
                external_id:
                  description: >
                    A unique identifier (e.g., UUID) for this transaction in your system.
                    Also used for idempotency validation. It can match the `order_id` or
                    be a separate unique value.
                  type: string
                  example: "496de72d-d4a4-45eb-b426-3d04d2078a85"
                order:
                  $ref: "#/components/schemas/OrderRequest"
                token:
                  type: string
                  description: >
                    A pre-generated card token (from a tokenization process) representing
                    secure card data. If you provide this token, you do not need to pass
                    raw card fields.
                  example: "tkn_01J5XCMDXCFXCAQ1BV8HVG6644_215626ca92fcc591fd2491b483c9d496"
                card:
                  type: object
                  description: >
                    Raw card data to be used if a token is not available. Passing these
                    fields will perform authorization using the provided card details.
                  properties:
                    pan:
                      description: The primary account number (payment card number).
                      type: string
                    code:
                      description: The card security code (CVV or CVC).
                      type: string
                      format: ^[0-9]{3,4}$
                      example: "012"
                    expiry:
                      description: The card expiration date in the format `MMYYYY`.
                      type: string
                      format: ^(0[1-9]|1[0-2])([0-9]{4})$
                      example: "122030"
                    name:
                      description: The cardholder's name as printed on the card.
                      type: string
                      example: "John Doe"
                  required:
                    - pan
                    - code
                    - expiry
                    - name
              required:
                - operation
                - external_id
                - order
      responses:
        200:
          description: Details of the newly created transaction.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TrxResponse'

  /transactions/{trx_id}:
    get:
      summary: Retrieve a Transaction by Transaction ID
      tags:
        - Transactions
      description: >
        Fetch the details of a specific transaction using its unique `trx_id`.
      security:
        - BearerAuth: [ ]
      parameters:
        - in: path
          name: trx_id
          schema:
            type: string
            example: "trx_01J5XCMDXCFXCAQ1BV8HVG6644"
          required: true
          description: The unique transaction ID to be retrieved.
      responses:
        200:
          description: The details of the requested transaction.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TrxResponse'
    post:
      summary: Capture or Void a Transaction
      tags:
        - Transactions
      description: >
        Perform a capture or void operation on a previously authorized transaction.
        Specify an amount to partially capture or void. Full captures/voids will use
        the entire authorized amount.
      security:
        - BearerAuth: [ ]
      parameters:
        - in: path
          name: trx_id
          schema:
            type: string
            example: "trx_01J5XCMDXCFXCAQ1BV8HVG6644"
          required: true
          description: The unique ID of the transaction to capture or void.
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                external_id:
                  description: >
                    A unique identifier (e.g., UUID) for referencing this operation
                    in your system. Also used as an idempotency key for capture/void.
                  type: string
                  example: "496de72d-d4a4-45eb-b426-3d04d2078a85"
                operation:
                  description: The operation to perform, either `capture` or `void`.
                  type: string
                  enum:
                    - capture
                    - void
                  example: capture
                amount:
                  description: >
                    The amount to capture or void, in the smallest currency unit
                    (e.g., cents for USD).
                  type: integer
                  example: 5000
              required:
                - external_id
                - operation
                - amount
      responses:
        200:
          description: The transaction details after the capture or void operation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TrxResponse'

  /refunds:
    post:
      summary: Refund a Transaction
      tags:
        - Refunds
      description: >
        Initiates a refund for an already captured or settled transaction. Each refund
        is treated as a new transaction of type `REFUND`. Use `GET /transactions` to
        retrieve its details.
      security:
        - BearerAuth: [ ]
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                external_id:
                  description: >
                    A unique identifier (e.g., UUID) for this refund in your system.
                    Used for idempotency checks and correlating the refund internally.
                  type: string
                  example: "496de72d-d4a4-45eb-b426-3d04d2078a85"
                trx_id:
                  description: >
                    The unique ID of the original `PAYMENT` transaction that you
                    want to refund.
                  type: string
                  example: "trx_01J5XCMDXCFXCAQ1BV8HVG6644"
                amount:
                  description: >
                    The amount to refund, in the smallest currency unit (e.g., cents for USD).
                  type: integer
                  example: 5000
              required:
                - external_id
                - trx_id
                - amount
      responses:
        200:
          description: Details of the new refund transaction.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TrxResponse"

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

  schemas:
    OrderRequest:
      type: object
      properties:
        order_id:
          description: A unique identifier for your order (e.g., invoice or cart ID).
          type: string
          example: "496de72d-d4a4-45eb-b426-3d04d2078a85"
        order_amount:
          description: >
            The total amount of the order (in the smallest currency unit, e.g., cents
            for USD). For instance, $100.00 would be `10000`.
          type: integer
          example: 10000
        order_currency:
          description: >
            The three-letter currency code in which you want to process the order
            (e.g., USD, EUR).
          type: string
          enum:
            - USD
            - EUR
          example: USD
        order_items:
          type: array
          items:
            properties:
              item_title:
                description: Short description/title of the item (max 32 characters).
                type: string
                example: "Lorem ipsum donet"
              item_id:
                description: The unique reference or SKU for the item.
                type: string
              item_qty:
                description: The quantity of this particular item.
                type: integer
                example: 2
              item_price:
                description: >
                  The price per unit of this item (in the smallest currency unit).
                  For example, $19.99 would be `1999`.
                type: integer
            required:
              - item_title
              - item_id
              - item_qty
              - item_price
        card_holder:
          description: Details about the card holder, including name, email, and address.
          type: object
          properties:
            first_name:
              description: Card holder's first name.
              type: string
            middle_name:
              description: Card holder's middle name(s) (if any).
              type: string
            last_name:
              description: Card holder's last name.
              type: string
            dob:
              description: >
                Card holder's date of birth in `dd/mm/yyyy` format
                (e.g., `07/08/2022` for August 7th 2022).
              type: string
              format: >-
                (^(((0[1-9]|1[0-9]|2[0-8])[\/](0[1-9]|1[012]))|
                ((29|30|31)[\/](0[13578]|1[02]))|
                ((29|30)[\/](0[4,6,9]|11)))[\/](19|[2-9][0-9])\d\d$)|
                (^29[\/]02[\/](19|[2-9][0-9])(00|04|08|12|16|20|24|28|32|36|40|44|48|52|56|
                60|64|68|72|76|80|84|88|92|96)$)
            email:
              description: A valid email address for the card holder.
              type: string
              format: email
            phone:
              description: >
                The card holder's phone number in E.164 format (e.g., +15615557689).
              type: string
            address_1:
              description: The first line of the card holder's address.
              type: string
            address_2:
              description: The second line of the address (optional).
              type: string
            postal_code:
              description: The postal code of the card holder's address.
              type: string
            city:
              description: The city of the card holder's address.
              type: string
            state:
              description: The state or region (optional).
              type: string
            country:
              description: The country of the card holder's address.
              type: string
          required:
            - first_name
            - last_name
            - dob
            - email
            - address_1
            - postal_code
            - city
            - country
      required:
        - order_id
        - order_amount
        - order_currency
        - card_holder

    IntentResponse:
      type: object
      properties:
        intent_id:
          format: string
          description: A unique identifier for the created intent.
          example: "int_01J5XCMDXCFXCAQ1BV8HVG6644"
        reference_id:
          description: >
            The external reference ID provided by the merchant. Useful for linking
            the future card token or payment to a specific customer/order in your system.
          type: string
          example: "496de72d-d4a4-45eb-b426-3d04d2078a85"
        valid_for:
          description: The amount of time (in milliseconds) for which this intent remains valid.
          type: integer
          example: 60000
      required:
        - intent_id
        - reference_id
        - valid_for

    TrxResponse:
      type: object
      properties:
        id:
          format: string
          description: The unique identifier for this transaction.
          example: "trx_01J5XCMDXCFXCAQ1BV8HVG6644"
        type:
          description: The type/category of this transaction.
          type: string
          enum:
            - PAYMENT
            - REFUND
            - CHARGEBACK
        status:
          description: The current status of the transaction (e.g., AUTHORIZED, DECLINED).
          type: string
          enum:
            - AUTHORIZED
            - DECLINED
            - VOIDED
            - PARTIAL_CAPTURED
            - PARTIAL_SETTLED
            - CAPTURED
            - SETTLED
            - EXPIRED
        order_amount:
          description: >
            The total order amount in the smallest currency unit (e.g., cents for USD).
            For instance, $100.00 would be `10000`.
          type: integer
          example: 10000
        order_currency:
          description: >
            The three-letter currency code of the transaction (e.g., USD, EUR).
          type: string
          enum:
            - USD
            - EUR
          example: USD
        amount_authorized:
          description: The total amount authorized for this transaction (in smallest currency unit).
          type: integer
          example: 10000
        amount_captured:
          description: The total amount captured (in smallest currency unit).
          type: integer
        amount_voided:
          description: The total amount voided (in smallest currency unit).
          type: integer
        amount_refunded:
          description: The total amount refunded (in smallest currency unit).
          type: integer
        external_id:
          description: >
            The merchant's external reference ID, used to match this transaction to
            records in your own system.
          type: string
          example: "496de72d-d4a4-45eb-b426-3d04d2078a85"
        updated_at:
          description: The date and time (UTC) when this transaction was last updated (ISO 8601 format).
          type: string
          format: ISO8601
          example: "2024-09-05T05:05:25Z"
      required:
        - id
        - type
        - status
        - order_amount
        - order_currency
        - amount_authorized
        - amount_captured
        - amount_voided
        - amount_refunded
        - external_id
        - updated_at
