openapi: "3.0.2" # it seems swagger editor does not support yet 3.1.0?
info:
  version: 1.1.0
  title: Customer Authentication Service
  description: |
    The Customer Authentication Service is responsible for creating redirect sessions and authenticating customers.
    ## Change Log:
    - 1.1.0 (2023-xx-xx):
      - extend PUT redirect-sessions/{redirectSessionId} with new error codes and limitThresholdExceededReason
      - extend RedirectSession response with kycData
    - 1.0.0 (2023-01-04):
      - initial version

    ## Source
    [Download openapi yaml: latest](customer-authentication-service-v1.x.x-ext.yaml)

    ## Previous Versions
    [Download openapi yaml: v1.0.0](previous-versions/customer-authentication-service-v1.0.0-ext.yaml)
  contact:
    name: Tech Support
    email: techsupport@zastrpay.com
    url: https://zastrpay.com
servers:
  - url: https://host.com/customer-authentication-service/v1
tags:
  - name: redirect-session
    description: Redirect Session
    x-displayName: Redirect Session

security:
  - ApiKeyAuth: []

paths:
  /redirect-sessions/{redirectSessionId}:
    put:
      tags: [redirect-session]
      summary: Create a redirect session for a barcode transaction
      operationId: createRedirectSession
      parameters:
        - name: redirectSessionId
          in: path
          required: true
          description: The id of the redirect session
          schema:
            $ref: "#/components/schemas/RedirectSessionId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: "#/components/schemas/CreateNewTransactionIntentRedirectSession"
                - $ref: "#/components/schemas/CreateExistingTransactionIntentRedirectSession"
                - $ref: "#/components/schemas/CreateNewCustomerRedirectSession"
              discriminator:
                propertyName: type
                mapping:
                  NewTransactionIntent: "#/components/schemas/CreateNewTransactionIntentRedirectSession"
                  ExistingTransactionIntent: "#/components/schemas/CreateExistingTransactionIntentRedirectSession"
                  NewCustomer: "#/components/schemas/CreateNewCustomerRedirectSession"
            examples:
              NewTransactionIntent:
                value:
                  redirectData:
                    successUrl: "https://merchant.com/payment/success?param=someValue"
                    failureUrl: "https://merchant.com/payment/failure?param=someValue"
                    abortUrl: "https://merchant.com/payment/abort?param=someValue"
                    qrCodeSuccessUrl: "https://merchant.com/payment/qrCodeSuccessUrl?param=someValue"
                  locale: "de-DE"
                  type: "NewTransactionIntent"
                  customerId: "234abc22-33de-4444-5555-222222222222"
              ExistingTransactionIntent:
                value:
                  redirectData:
                    successUrl: "https://merchant.com/payment/success?param=someValue"
                    failureUrl: "https://merchant.com/payment/failure?param=someValue"
                    abortUrl: "https://merchant.com/payment/abort?param=someValue"
                    qrCodeSuccessUrl: "https://merchant.com/payment/qrCodeSuccessUrl?param=someValue"
                  locale: "de-DE"
                  type: "ExistingTransactionIntent"
                  customerId: "5d1ea0f0-5601-458c-b9e7-d9a8747149c6"
                  transactionIntentId: "e5cf83f0-6ed8-4472-b0c2-453c10e2a875"
              NewCustomer:
                value:
                  redirectData:
                    successUrl: "https://merchant.com/payment/success?param=someValue"
                    failureUrl: "https://merchant.com/payment/failure?param=someValue"
                    abortUrl: "https://merchant.com/payment/abort?param=someValue"
                    qrCodeSuccessUrl: "https://merchant.com/payment/qrCodeSuccessUrl?param=someValue"
                  locale: "de-DE"
                  type: "NewCustomer"
                  customerData:
                    firstName: "Max"
                    lastName: "Mustermann"
                    dateOfBirth: "1946-10-29"
                    placeOfBirth: "Vienna"
                    nationality: "DE"
                    address:
                      streetAddress: "Hauptstrasse 13/12/1"
                      city: "Vienna"
                      postalCode: "12345"
                      country: "DE"
                    contact:
                      email: "max.mustermann@example.com"
      responses:
        "201":
          description: Expected response to a valid request
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/CreatedNewTransactionIntentRedirectSession"
                  - $ref: "#/components/schemas/CreatedExistingTransactionIntentRedirectSession"
                  - $ref: "#/components/schemas/CreatedNewCustomerRedirectSession"
                discriminator:
                  propertyName: type
                  mapping:
                    NewTransactionIntent: "#/components/schemas/CreatedNewTransactionIntentRedirectSession"
                    ExistingTransactionIntent: "#/components/schemas/CreatedExistingTransactionIntentRedirectSession"
                    NewCustomer: "#/components/schemas/CreatedNewCustomerRedirectSession"
              examples:
                NewTransactionIntent:
                  value:
                    id: "39bfc4da-3fe4-4207-a675-5880d673dc9e"
                    redirectData:
                      successUrl: "https://merchant.com/payment/success?param=someValue"
                      failureUrl: "https://merchant.com/payment/failure?param=someValue"
                      abortUrl: "https://merchant.com/payment/abort?param=someValue"
                      qrCodeSuccessUrl: "https://merchant.com/payment/qrCodeSuccessUrl?param=someValue"
                    locale: "de-DE"
                    type: "NewTransactionIntent"
                    customerId: "234abc22-33de-4444-5555-222222222222"
                    token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJpc3N1ZXIifQ.nbgaqe_ny9RSi3ySOv5BvYYR5Ts34LyW_U8vC48jJfY"
                    redirectUrl: "https://myserver.com/redirect-here"
                ExistingTransactionIntent:
                  value:
                    id: "d7f3265a-12dc-42e4-a4f8-176e7efe61eb"
                    redirectData:
                      successUrl: "https://merchant.com/payment/success?param=someValue"
                      failureUrl: "https://merchant.com/payment/failure?param=someValue"
                      abortUrl: "https://merchant.com/payment/abort?param=someValue"
                      qrCodeSuccessUrl: "https://merchant.com/payment/qrCodeSuccessUrl?param=someValue"
                    locale: "de-DE"
                    type: "ExistingTransactionIntent"
                    customerId: "5d1ea0f0-5601-458c-b9e7-d9a8747149c6"
                    transactionIntentId: "e5cf83f0-6ed8-4472-b0c2-453c10e2a875"
                    token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJpc3N1ZXIifQ.nbgaqe_ny9RSi3ySOv5BvYYR5Ts34LyW_U8vC48jJfY"
                    redirectUrl: "https://myserver.com/redirect-here"
                NewCustomer:
                  value:
                    id: "39bfc4da-3fe4-4207-a675-5880d673dc9e"
                    redirectData:
                      successUrl: "https://merchant.com/payment/success?param=someValue"
                      failureUrl: "https://merchant.com/payment/failure?param=someValue"
                      abortUrl: "https://merchant.com/payment/abort?param=someValue"
                      qrCodeSuccessUrl: "https://merchant.com/payment/qrCodeSuccessUrl?param=someValue"
                    locale: "de-DE"
                    type: "NewCustomer"
                    customerData:
                      firstName: "Max"
                      lastName: "Mustermann"
                      dateOfBirth: "1946-10-29"
                      placeOfBirth: "Vienna"
                      countryOfBirth: "DE"
                      nationality: "DE"
                      address:
                        streetAddress: "Hauptstrasse 13/12/1"
                        city: "Vienna"
                        postalCode: "12345"
                        country: "DE"
                      contact:
                        email: "max.mustermann@example.com"
                    token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJpc3N1ZXIifQ.nbgaqe_ny9RSi3ySOv5BvYYR5Ts34LyW_U8vC48jJfY"
                    redirectUrl: "https://myserver.com/redirect-here"
        "400":
          description: Validation failed
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/Error"
                  - type: object
                    properties:
                      code:
                        type: string
                        enum:
                          - Validation
                          - MergedToCustomer
                          - InvalidTransactionIntent
                      details:
                        type: object
                        description: Contains additional details of the error
                        properties:
                          mergedToCustomerId:
                            type: string
                            format: uuid
                            description: The id of the customer this was merged, to be used to retry to operation
                            example: 40c7fe9f-3bf9-464a-8d3a-937db20f5dae
        "404":
          description: Redirect Session was updated in the meantime, or duplicate
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/Error"
                  - type: object
                    properties:
                      code:
                        type: string
                        enum:
                          - CustomerNotFound
                          - MerchantNotFound
                          - LimitAccountSetNotFound
        "409":
          description: Redirect Session was updated in the meantime, or duplicate
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/Error"
                  - type: object
                    properties:
                      code:
                        type: string
                        enum:
                          - DuplicateEntity

        "422":
          description: Redirect Session could not be processed
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/Error"
                  - type: object
                    properties:
                      code:
                        type: string
                        enum:
                          - CustomerPermissionDenied
                          - LimitThresholdExceeded

        "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:
    CustomerId:
      type: string
      format: uuid
      description: The unique id of the customer. Optional, supplied only in case the merchant is tracking/storing whether a customer is registered at Zastrpay
      example: d80d9e26-ffa0-43f2-8c2b-c96513cc9351

    TriggerSource:
      type: object
      description: |
        The entry point via which the entity was created or its data was updated

        For Admin the following details are mandatory: operatorId
        For System there are no mandatory fields
        For CustomerWebApp the following details are mandatory: customerId
      properties:
        type:
          type: string
          enum:
            - Admin
            - System
            - CustomerWebApp
        operatorId:
          type: string
          description: The operator who performed the operation, in case the type is Admin
          example: E3112
        customerId:
          $ref: "#/components/schemas/CustomerId"
      required:
        - type

    CountryCode:
      type: string
      description: The country code as ISO 3166-1 alpha-2 (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)
      pattern: "^[A-Z]{2}$"
      example: DE

    City:
      type: string
      pattern: '^[\p{L}0-9''\,\ \-\.\\\/\(\)]{2,50}$'
      description: The city name
      maxLength: 50
      example: Vienna

    Address:
      type: object
      description: Contains the address details of a customer
      properties:
        streetAddress:
          type: string
          description: The street including housenumber, housename, etc.
          pattern: '^[\p{L}0-9''\,\ \-\.\\\/\(\)]{2,50}$'
          example: Hauptstrasse 13/12/1
          maxLength: 50
        city:
          $ref: "#/components/schemas/City"
        postalCode:
          type: string
          description: The postal code of the address
          pattern: '^[\p{L}0-9\-\ )]{2,50}$'
          example: "12345"
          maxLength: 50
        country:
          $ref: "#/components/schemas/CountryCode"
      required:
        - streetAddress
        - city
        - postalCode
        - country

    Contact:
      type: object
      properties:
        email:
          type: string
          pattern: '^(?=.{1,100}$)(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$'
          description: The customer's valid email address
          maxLength: 100
          example: max.mustermann@example.com

    PersonName:
      type: string
      pattern: '^[\p{L}''\-\ ]{2,50}$'
      description: The name of the customer

    PlaceOfBirth:
      type: string
      pattern: '^[\p{L}0-9''\,\ \-\.\\\/\(\)]{2,50}$'
      description: The city of birth of the customer
      maxLength: 50
      example: Vienna

    Nationality:
      type: string
      description: The country code of the customer's nationality as ISO 3166-1 alpha-2 (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)
      pattern: "^[A-Z]{2}$"
      example: DE

    CountryOfBirth:
      type: string
      description: The code of the customer's country of birth as ISO 3166-1 alpha-2 (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)
      pattern: "^[A-Z]{2}$"
      example: DE

    CustomerData:
      type: object
      description: The personal, address and contact data of the customer. Optional, supplied when the merchant is tracking customer registrations at Zastrpay and knows that the customer is not yet registered at Zastrpay, and when the customer has allowed the Merchant to share her/his data with Zastrpay
      required:
        - firstName
        - lastName
        - dateOfBirth
        - placeOfBirth
        - nationality
        - address
      properties:
        firstName:
          $ref: "#/components/schemas/PersonName"
        lastName:
          $ref: "#/components/schemas/PersonName"
        maidenName:
          $ref: "#/components/schemas/PersonName"
        middleName:
          $ref: "#/components/schemas/PersonName"
        dateOfBirth:
          type: string
          format: date
          description: The date of birth of the person
          pattern: '^\d{4}-\d{1,2}-\d{1,2}$'
          example: 1946-10-29
        placeOfBirth:
          $ref: "#/components/schemas/PlaceOfBirth"
        countryOfBirth:
          $ref: "#/components/schemas/CountryOfBirth"
        nationality:
          $ref: "#/components/schemas/Nationality"
        address:
          $ref: "#/components/schemas/Address"
        contact:
          $ref: "#/components/schemas/Contact"

    TransactionData:
      type: object
      properties:
        type:
          type: string
          description: The type of the transaction, this corresponds to the type of the transaction intent to be created
          enum:
            - PassthroughDeposit
            - PassthroughWithdrawal
        amount:
          type: number
          minimum: 0
          exclusiveMinimum: true
          maximum: 10000
          description: The amount of the transaction intent.
          example: 100.00
        currency:
          type: string
          enum:
            - EUR
          description: The currency code as ISO 4217 3-digit code (https://en.wikipedia.org/wiki/ISO_4217).
          example: EUR
        externalReference:
          type: string
          description: A reference to a transaction in an external system e.g. bank transfer. Used for MerchantPayment* and DistributorPayment* transaction types only.
          pattern: '^[\d\p{L}]([\d\p{L}\-\. ]{0,48}[\d\p{L}])$'
          minLength: 1
          maxLength: 50
          example: 234abc22-33de-4444-5555-222222222222
      required:
        - type
        - amount
        - currency

    RedirectData:
      type: object
      properties:
        successUrl:
          description: a url that the user will be redirected on successful completion of the overall flow (transaction executed successfully)
          type: string
          format: uri
          example: https://myserver.com/send/callback/here
        failureUrl:
          description: a url that the user will be redirected on failure of the overall flow (transaction failed)
          type: string
          format: uri
          example: https://myserver.com/send/callback/here
        abortUrl:
          description: a url that the user will be redirected on abort of the flow
          type: string
          format: uri
          example: https://myserver.com/send/callback/here
        qrCodeSuccessUrl:
          description: a url that the user will be redirected after successful creation of QR code
          type: string
          format: uri
          example: https://myserver.com/send/callback/here
      required:
        - successUrl
        - failureUrl
        - abortUrl

    MerchantId:
      type: string
      format: uuid
      description: The unique id of the merchant
      example: d80d9e26-ffa0-43f2-8c2b-c96513cc9351

    LastCorrelationId:
      type: string
      format: uuid
      description: Identifies the conversation within which the last change of state occurred. Currently the value of X-Request-Id is used if provided, or an internal UUID is generated if not
      example: 40c7fe9f-3bf9-464a-8d3a-937db20f5dae

    CreatedOn:
      type: string
      description: The creation datetime of the entity, in ISO 8601 format of YYYY-MM-DDThh:mm:ssZ in UTC time
      format: date-time
      example: 2019-01-31T11:59:59Z

    RedirectSessionId:
      type: string
      format: uuid
      description: The unique id of the redirect session
      example: d80d9e26-ffa0-43f2-8c2b-c96513cc9351

    TransactionIntentId:
      type: string
      format: uuid
      description: The unique id of the existing transaction intent
      example: 08a29f86-0dbc-4ceb-a4eb-f202561cb53e

    Locale:
      type: string
      pattern: "^[A-z]{2}(-[A-z]{2})?$"
      description: Used to define the language and region of the customer. RFC 1766 customer's locale. Supported locales are en/en-* and de/de-*. If another or no locale is provided, the default locale is de-DE.
      example: de-DE

    KycData:
      type: object
      description: The customer data required for KYC/KYD. Returned only for certain merchants that were explicitly whitelisted.
      properties:
        firstName:
          $ref: "#/components/schemas/PersonName"
          example: Max
        lastName:
          $ref: "#/components/schemas/PersonName"
          example: Mustermann
      required:
        - firstName
        - lastName

    CreateRedirectSession:
      type: object
      properties:
        redirectData:
          $ref: "#/components/schemas/RedirectData"
        locale:
          $ref: "#/components/schemas/Locale"
      required:
        - redirectData

    CreateNewCustomerRedirectSession:
      allOf:
        - $ref: "#/components/schemas/CreateRedirectSession"
        - type: object
          properties:
            type:
              type: string
              enum:
                - NewCustomer
            customerData:
              $ref: "#/components/schemas/CustomerData"
          required:
            - transactionData
            - type

    PhoneNumber:
      type: string
      pattern: '^(?=(.*\d){2})[0-9\+\/\-\(\)\s]{2,50}$'
      description: A phone number with which the customer has registered at Zastrpay. To be provided when the Merchant wants to have KYD/PreCheck performed but does not have the Zastrpay customerId (e.g. because the customer registered directly with Zastrpay, or via another merchant)
      maxLength: 50
      example: +43650123456789

    CreateNewTransactionIntentRedirectSession:
      allOf:
        - $ref: "#/components/schemas/CreateRedirectSession"
        - type: object
          properties:
            type:
              type: string
              enum:
                - NewTransactionIntent
            customerId:
              $ref: "#/components/schemas/CustomerId"
            transactionData:
              $ref: "#/components/schemas/TransactionData"
            phoneNumber:
              $ref: "#/components/schemas/PhoneNumber"
          required:
            - transactionData
            - type

    CreateExistingTransactionIntentRedirectSession:
      allOf:
        - $ref: "#/components/schemas/CreateRedirectSession"
        - type: object
          properties:
            type:
              type: string
              enum:
                - ExistingTransactionIntent
            customerId:
              $ref: "#/components/schemas/CustomerId"
            transactionIntentId:
              $ref: "#/components/schemas/TransactionIntentId"
          required:
            - customerId
            - transactionIntentId
            - type

    CreatedRedirectSession:
      type: object
      properties:
        id:
          $ref: "#/components/schemas/RedirectSessionId"
        merchantId:
          $ref: "#/components/schemas/MerchantId"
        createdOn:
          $ref: "#/components/schemas/CreatedOn"
        redirectData:
          $ref: "#/components/schemas/RedirectData"
        lastCorrelationId:
          $ref: "#/components/schemas/LastCorrelationId"
        locale:
          $ref: "#/components/schemas/Locale"
        token:
          type: string
          description: a JWT to be used for subsequent authentication of user request
          example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJpc3N1ZXIifQ.nbgaqe_ny9RSi3ySOv5BvYYR5Ts34LyW_U8vC48jJfY
        redirectUrl:
          type: string
          description: a url where to redirect the user to continue with the payment process
          format: uri
          example: https://myserver.com/send/callback/here
      required:
        - id
        - merchantId
        - createdOn
        - lastCorrelationId
        - token
        - locale
        - redirectUrl
        - redirectData

    CreatedNewCustomerRedirectSession:
      allOf:
        - $ref: "#/components/schemas/CreatedRedirectSession"
        - type: object
          properties:
            type:
              type: string
              enum:
                - NewCustomer
            customerData:
              $ref: "#/components/schemas/CustomerData"
          required:
            - type
            - transactionData

    CreatedNewTransactionIntentRedirectSession:
      allOf:
        - $ref: "#/components/schemas/CreatedRedirectSession"
        - type: object
          properties:
            type:
              type: string
              enum:
                - NewTransactionIntent
            customerId:
              $ref: "#/components/schemas/CustomerId"
            transactionData:
              $ref: "#/components/schemas/TransactionData"
            phoneNumber:
              $ref: "#/components/schemas/PhoneNumber"
            kycData:
              $ref: "#/components/schemas/KycData"
          required:
            - type
            - transactionData

    CreatedExistingTransactionIntentRedirectSession:
      allOf:
        - $ref: "#/components/schemas/CreatedRedirectSession"
        - type: object
          properties:
            type:
              type: string
              enum:
                - ExistingTransactionIntent
            customerId:
              $ref: "#/components/schemas/CustomerId"
            transactionIntentId:
              $ref: "#/components/schemas/TransactionIntentId"
          required:
            - type
            - customerId
            - transactionIntentId

    Error:
      type: object
      description: Contains details about the error.
      properties:
        code:
          type: string
          description: The type of error. Used for defining which sub-element will be present in the details property.
        message:
          type: string
          description: A short text describing the error.
          example: The field "customerId" could not be validated.
        moreInfo:
          type: string
          description: A link to the online documentation describing the error in detail.
          example: https://developer.example.com/v1.0/reference#error-handling
        correlationId:
          type: string
          format: uuid
          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:
            customerPermissionDeniedReason:
              $ref: "#/components/schemas/CustomerPermissionDeniedReason"
            validationErrorReasons:
              type: array
              description: A collection of Validation error details
              items:
                $ref: "#/components/schemas/ValidationErrorReason"
            limitThresholdExceededReason:
              $ref: "#/components/schemas/LimitThresholdExceededReason"
      required:
        - code
        - message

    ValidationErrorReason:
      type: object
      description: Contains Validation error metadata
      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
      required:
        - errorMessage

    CustomerPermissionDeniedReason:
      type: string
      description: The reason for CustomerPermissionDenied declineReason
      x-extensible-enum:
        - CustomerRegistrationFailed
        - InitialCustomerVerificationMissing
        - CustomerPendingInternalReview
        - ValidCustomerPOIRequired
        - ValidCustomerPOARequired
        - CustomerAccountClosedByCustomerRequest
        - CustomerAccountClosedDueToFailedKYC
        - DuplicateCustomerAccountClosed
        - ValidCustomerSOFRequired
        - ValidCustomerSOWRequired
        - CustomerAccountClosed
        - CustomerAccountClosedDueToTechnicalIssue
        - CustomerAccountClosedDueToCustomerDeceased
        - CustomerAccountClosedTestAccount
        - CustomerAccountClosedDormant

    LimitThresholdExceededReason:
      type: string
      description: The reason for LimitThresholdExceeded declineReason
      x-extensible-enum:
        - CustomerPendingInternalReview
        - ValidCustomerPOIRequired
        - ValidCustomerPOARequired
        - ValidCustomerSOFRequired
        - ValidCustomerSOWRequired
        - CustomerInformationRevalidationRequired
