openapi: "3.0.2"
info:
  version: 1.0.0
  title: Customer Service
  description: |
    The Customer Service is responsible for customer registration and customer data management.
    ## Change Log:
    - 1.0.0 (2023-05-31):
      - Initial version with Customer Events webhook

    ## Source
    [Download openapi yaml](customer-service-v1.x.x-ext2.yaml)
  contact:
    name: Tech Support
    email: techsupport@zastrpay.com
    url: https://zastrpay.com
servers:
  - url: https://api.example.com/customer-service/v1
tags:
  - name: customer-event
    description: Customer Event
    x-displayName: Customer Event

security:
  - ApiKeyAuth: []

paths:
  /customer-events/subscriptions/{eventSubscriptionId}:
    put:
      tags:
        - customer-event
      summary: Subscribe to Customer events
      operationId: subscribeToCustomerEvents
      parameters:
        - name: eventSubscriptionId
          in: path
          required: true
          description: The unique id of this subscription, which can be used for unsubscribing later on.
          schema:
            type: string
            example: 40c7fe9f-3bf9-464a-8d3a-937db20f5dae
      requestBody:
        required: true
        content:
          application/json:
            schema:
              allOf:
                - $ref: "#/components/schemas/NewEventSubscription"
                - type: object
                  properties:
                    eventTypes:
                      description: the list of event types to which subscriber would like to listen for
                      type: array
                      minItems: 1
                      items:
                        $ref: "#/components/schemas/CustomerEventType"
                  required:
                    - callbackUrl
                    - apiKey
                    - eventTypes
      responses:
        "201":
          description: Subscription created
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/EventSubscription"
                  - type: object
                    properties:
                      eventTypes:
                        type: array
                        items:
                          $ref: "#/components/schemas/CustomerEventType"
        "400":
          description: Validation failed
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/Error"
                  - type: object
                    properties:
                      code:
                        type: string
                        enum:
                          - Validation
        "500":
          description: Unexpected technical error
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/Error"
                  - type: object
                    properties:
                      code:
                        type: string
                        enum:
                          - GeneralErrorOccurred
      # callbacks:
      #   onEvent:
      #     "{$request.body#/callbackUrl}":
      #       post:
      #         requestBody:
      #           description: Contents of the callback message
      #           required: true
      #           content:
      #             application/json:
      #               schema:
      #                 $ref: "#/components/schemas/CustomerEvent"
      #         responses:
      #           "200":
      #             description: Your server returns this code if it accepts the callback
    patch:
      tags:
        - customer-event
      summary: Update the subscription to Customer events
      parameters:
        - name: eventSubscriptionId
          in: path
          required: true
          description: The unique id of this subscription, which can be used for unsubscribing later on.
          schema:
            type: string
            example: 40c7fe9f-3bf9-464a-8d3a-937db20f5dae
      requestBody:
        required: true
        content:
          application/json:
            schema:
              allOf:
                - $ref: "#/components/schemas/UpdateEventSubscription"
                - type: object
                  properties:
                    eventTypes:
                      description: the list of event types to which subscriber would like to listen for
                      type: array
                      minItems: 1
                      items:
                        $ref: "#/components/schemas/CustomerEventType"
                  required:
                    - callbackUrl
                    - apiKey
                    - eventTypes
      responses:
        "200":
          description: Webhook updated
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/EventSubscription"
                  - type: object
                    properties:
                      eventTypes:
                        type: array
                        items:
                          $ref: "#/components/schemas/CustomerEventType"
        "400":
          description: Validation failed
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/Error"
                  - type: object
                    properties:
                      code:
                        type: string
                        enum:
                          - Validation
        "403":
          description: Operation forbidden
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/Error"
                  - type: object
                    properties:
                      code:
                        type: string
                        enum:
                          - InvalidTriggeredBy

        "404":
          description: Subscription not found
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/Error"
                  - type: object
                    properties:
                      code:
                        type: string
                        enum:
                          - SubscriptionNotFound

        "409":
          description: Subscription was updated in the meantime, get and retry
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/Error"
                  - type: object
                    properties:
                      code:
                        type: string
                        enum:
                          - EntityVersionMismatch
                          - DuplicateEntity
        "500":
          description: Unexpected technical error
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/Error"
                  - type: object
                    properties:
                      code:
                        type: string
                        enum:
                          - GeneralErrorOccurred
    delete:
      tags:
        - customer-event
      summary: Unsubscribe from Customer events
      operationId: unsubscribeFromCustomerEvents
      parameters:
        - name: eventSubscriptionId
          in: path
          required: true
          description: The unique id of this subscription to be unsubscribed.
          schema:
            type: string
            example: 40c7fe9f-3bf9-464a-8d3a-937db20f5dae
      responses:
        "200":
          description: Webhook deleted
        "403":
          description: Operation forbidden
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/Error"
                  - type: object
                    properties:
                      code:
                        type: string
                        enum:
                          - InvalidTriggeredBy
        "404":
          description: Subscription not found
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/Error"
                  - type: object
                    properties:
                      code:
                        type: string
                        enum:
                          - SubscriptionNotFound
        "500":
          description: Unexpected technical error
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/Error"
                  - type: object
                    properties:
                      code:
                        type: string
                        enum:
                          - GeneralErrorOccurred

components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-KEY

  schemas:
    NewEventSubscription:
      type: object
      description: Represents a client subscription to a server event feed, whereby the server will call the client's callback for every event item
      properties:
        callbackUrl:
          description: callback url that will be called by server for every subscribed event
          type: string
          format: uri
          example: https://myserver.com/send/callback/here
        apiKey:
          description: Sent back in the x-api-key header of the callback
          type: string
          pattern: ^[A-z0-9=+\/\-:_]{1,128}$
          example: 4EFRLXTFHJKmYKIE7yIsOk7EuLh6Gmh9aBF1FVO4
      required:
        - callbackUrl
        - apiKey

    UpdateEventSubscription:
      type: object
      description: Represents a client subscription to a server event feed, whereby the server will call the client's callback for every event item
      properties:
        callbackUrl:
          description: callback url that will be called by server for every subscribed event
          type: string
          format: uri
          example: https://myserver.com/send/callback/here
        apiKey:
          description: Sent back in the x-api-key header of the callback
          type: string
          pattern: ^[A-z0-9=+\/\-:_]{1,128}$
          example: 4EFRLXTFHJKmYKIE7yIsOk7EuLh6Gmh9aBF1FVO4
      required:
        - callbackUrl
        - apiKey

    EventSubscription:
      type: object
      description: Represents a client subscription to a server event feed, whereby the server will call the client's callback for every event item
      properties:
        id:
          type: string
          format: uuid
          description: Unique id of the subscription
          example: 6d245f63-fdfc-4a6b-a351-bc0b03260dcd
        callbackUrl:
          description: callback url that will be called by server for every subscribed event
          type: string
          format: uri
          example: https://myserver.com/send/callback/here
      required:
        - id
        - callbackUrl

    CustomerEventType:
      type: string
      description: The type of the event, defining also the attributes of which entity are to be found in the data property
      enum:
        - CustomerRegistered

    CustomerEvent:
      type: object
      description: Fired when customer state has changed
      allOf:
        - $ref: "#/components/schemas/EventMetadata"
        - type: object
          properties:
            type:
              $ref: "#/components/schemas/CustomerEventType"
            data:
              type: object
              required:
                - id
              properties:
                id:
                  type: string
                  format: uuid
                  description: The id of the customer
                  example: 40c7fe9f-3bf9-464a-8d3a-937db20f5dae

    EventMetadata:
      description: base set of context attributes that describe event
      type: object
      required:
        - specversion
        - id
        - source
      properties:
        specversion:
          type: string
          description: |
            The version of the CloudEvents specification which the event uses.
            This enables the interpretation of the context.
            Compliant event producers MUST use a value of 1.0 when referring to this version of the specification.
          example: 1.0
        id:
          type: string
          format: uuid
          description: The unique id of the event.
          example: 111abc22-33de-4444-5555-111111111111
        source:
          type: string
          description: Identifies the context in which an event happened
          example: /customer-service
        time:
          type: string
          format: date-time
          description: Timestamp of when the occurrence happened.
          example: 2019-01-31T11:59:59Z
        datacontenttype:
          type: string
          description: Content type of data value
          example: application/json

    ValidationErrorReason:
      type: object
      description: Contains Validation error metadata
      required:
        - errorMessage
      properties:
        fieldName:
          type: string
          description: name of filed that failed validation
          example: customerId
        errorMessage:
          type: string
          description: error message
          example: Value must not be empty

    Error:
      type: object
      description: Contains details about the error
      properties:
        code:
          type: string
          description: The type of error
          enum:
            - Validation
            - EntityVersionMismatch
            - DuplicateEntity
            - InvalidTriggeredBy
            - GeneralErrorOccurred
            - SubscriptionNotFound
        message:
          type: string
          description: A short text describing the error
        moreInfo:
          type: string
          description: A link to the online documentation describing the error in detail
          example: https://developer.example.com/ExampleService/v1.0/errors/validation
        correlationId:
          type: string
          description: Identifies the conversation within which the error got generated
          example: ce8056cd-ae4d-4f2d-87de-7562c92f92cc
        details:
          type: object
          description: Contains additional details of the error
          properties:
            validationErrorReasons:
              type: array
              description: A collection of Validation error details
              items:
                $ref: "#/components/schemas/ValidationErrorReason"
      required:
        - code
        - message

x-webhooks: # change to webhooks once openapi version is changed to 3.1.0
  customerEvent:
    post:
      summary: Customer Event
      description: Customer Event
      operationId: handleCustomerEvent
      tags:
        - customer-event
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CustomerEvent"
      responses:
        "204":
          description: Return a 204 status to indicate that the data was received successfully
