openapi: 3.1.0
info:
  version: '1.0'
  title: d1-ecom_dcs-inbound-api
servers:
  - url: 'https://api.d1.thalescloud.io/ecom-dcs'
    description: Production server
  - url: 'https://api.d1-stg.thalescloud.io/ecom-dcs'
    description: Staging server
paths:
  /oauth2/token:
    post:
      tags:
        - Oauth2
      summary: Get Access Token
      description: This request is used by the Merchant Gateway backend to get an access token.
      operationId: getAccessToken
      parameters:
        - $ref: '#/components/parameters/x-correlation-id-header'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/auth2Request'
            examples:
              Example 1:
                value:
                  grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer'
                  assertion: hhhhhhh.pppppppp.ssssssssss
      responses:
        '200':
          description: Default allowed response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/auth2Response'
        '400':
          description: |-
            Bad Request - Not Retryable

            |Error Code|Description|
            |-------|-------|            
            | INVALID_FIELD |  Contains the field in error (first found) |
            | MISSING_FIELD  |  Contains the missing field (first found) |            

            -----------------
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error'
      servers:
        - url: 'https://api.d1.thalescloud.io/authz/v1'
          description: Production server
        - url: 'https://api.d1-stg.thalescloud.io/authz/v1'
          description: Staging server
  '/merchant-gateways/{merchantGatewayId}/merchants':
    post:
      tags:
        - Merchant Onboarding
      summary: Create a Merchant
      description: Create a merchant.
      operationId: createMerchant
      parameters:
        - $ref: '#/components/parameters/x-correlation-id-header'
        - $ref: '#/components/parameters/merchant-gateway-id-path'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/createMerchantRequest'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/createMerchantResponse'
        '400':
          description: |-
            Bad Request - Not Retryable

            |Error Code|Description|
            |-------|-------|            
            | FIELD_INVALID_FORMAT |  JSON not well formatted or one field is not expected format as defined in this documentation (first found) |

            -----------------
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error'
        '401':
          $ref: '#/components/responses/401'
        '403':
          description: |-
            Forbidden - Not Retryable
             |Error Code|Description|
             |-------|-------|            
             | AUTHORIZER_FORBIDDEN  | User is not authorized to access this resource |

             -----------------
        '500':
          description: |-
            Server Error - Not Retryable

            |Error Code|Description|
            |-------|-------|            
            | INTERNAL_ERROR |  Internal D1 error |
            | TSP_ERROR  |  An error occurred with TSP |

            -----------------
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error'
        '503':
          $ref: '#/components/responses/503'
      security:
        - bearerAuth: []
      servers:
        - url: 'https://api.d1.thalescloud.io/ecom-dcs'
          description: Production server
        - url: 'https://api.d1-stg.thalescloud.io/ecom-dcs'
          description: Staging server
  '/merchant-gateways/{merchantGatewayId}/merchants/{merchantId}/tokens':
    post:
      tags:
        - Token Management
      summary: Create a Token
      description: Create a token from specified card details.
      operationId: createToken
      parameters:
        - $ref: '#/components/parameters/x-correlation-id-header'
        - $ref: '#/components/parameters/merchant-gateway-id-path'
        - $ref: '#/components/parameters/merchant-id-path'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/createTokenRequest'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/createTokenResponse'
        '400':
          description: |-
            Bad Request - Not Retryable
            |Error Code|Description|
            |-------|-------|            
            | FIELD_INVALID_FORMAT |  JSON not well formatted or one field is not expected format as defined in this documentation (first found) |
            | CRYPTO_ERROR  |  Unable to decrypt payload |

            -----------------
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error'
        '401':
          $ref: '#/components/responses/401'
        '403':
          description: |-
            Forbidden - Not Retryable

            |Error Code|Description|
            |-------|-------|  
            | AUTHORIZER_FORBIDDEN  | User is not authorized to access this resource |         
            |PAN_NOT_ELIGIBLE|The PAN is not eligible for tokenization. For a cobadge card having an auxiliary PAN, this error is returned if the auxiliary PAN has never been registered by the card issuer into D1.|            
            |ISSUER_DECLINED|The Issuer declined the tokenization.|

            -----------------
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error'
        '404':
          description: |-
            Bad Request - Not Retryable

            |Error Code|Description|
            |-------|-------|
            |UNKNOWN_ISSUER|Not able to identify the card issuer. The PAN used in the request does not match any card registered in D1 by an issuer.|
            |UNKNOWN_MERCHANT|Not able to identify the merchant.|

            -----------------
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error'
        '500':
          description: |-
            Bad Request - Not Retryable

            |Error Code|Description|
            |-------|-------|
            | INTERNAL_ERROR |  Internal D1 error |
            | TSP_ERROR  |  An error occurred with TSP |
            | ISSUER_ERROR  |  An error occurred with Issuer |

            -----------------
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error'
        '503':
          $ref: '#/components/responses/503'
      security:
        - bearerAuth: []
      servers:
        - url: 'https://api.d1.thalescloud.io/ecom-dcs'
          description: Production server
        - url: 'https://api.d1-stg.thalescloud.io/ecom-dcs'
          description: Staging server
  '/merchant-gateways/{merchantGatewayId}/merchants/{merchantId}/tokens/{tokenId}':
    delete:
      tags:
        - Token Management
      summary: Delete a token
      description: Delete a token.
      operationId: deleteToken
      parameters:
        - $ref: '#/components/parameters/x-correlation-id-header'
        - $ref: '#/components/parameters/merchant-gateway-id-path'
        - $ref: '#/components/parameters/merchant-id-path'
        - $ref: '#/components/parameters/token-id-path'
      responses:
        '204':
          $ref: '#/components/responses/204'
        '400':
          description: |-
            Bad Request - Not Retryable
            |Error Code|Description|
            |-------|-------|            
            | FIELD_INVALID_FORMAT |  JSON not well formatted or one field is not expected format as defined in this documentation (first found) |

            -----------------
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error'
        '401':
          $ref: '#/components/responses/401'
        '403':
          description: |-
            Forbidden - Not Retryable
             |Error Code|Description|
             |-------|-------|            
             | AUTHORIZER_FORBIDDEN  | User is not authorized to access this resource |

             -----------------
        '404':
          description: |-
            Bad Request - Not Retryable

            |Error Code|Description|
            |-------|-------|
            |UNKNOWN_TOKEN|Not able to identify the token.|
            |UNKNOWN_MERCHANT|Not able to identify the merchant.|

            -----------------
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error'
        '500':
          description: |-
            Bad Request - Not Retryable

            |Error Code|Description|
            |-------|-------|
            | INTERNAL_ERROR |  Internal D1 error |
            | TSP_ERROR  |  An error occurred with TSP |

            -----------------
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error'
        '503':
          $ref: '#/components/responses/503'
      security:
        - bearerAuth: []
      servers:
        - url: 'https://api.d1.thalescloud.io/ecom-dcs'
          description: Production server
        - url: 'https://api.d1-stg.thalescloud.io/ecom-dcs'
          description: Staging server
  '/merchant-gateways/{merchantGatewayId}/merchants/{merchantId}/tokens/{tokenId}/metadata':
    get:
      tags:
        - Token Management
      summary: Get the token metadata
      description: Get token metadata.
      operationId: getTokenMetadata
      parameters:
        - $ref: '#/components/parameters/x-correlation-id-header'
        - $ref: '#/components/parameters/merchant-gateway-id-path'
        - $ref: '#/components/parameters/merchant-id-path'
        - $ref: '#/components/parameters/token-id-path'
      responses:
        '200':
          description: Get Token Metadata response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/getTokenMetadataResponse'
        '400':
          description: |-
            Bad Request - Not Retryable
            |Error Code|Description|
            |-------|-------|            
            | FIELD_INVALID_FORMAT |  JSON not well formatted or one field is not expected format as defined in this documentation (first found) |

            -----------------
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error'
        '401':
          $ref: '#/components/responses/401'
        '403':
          description: |-
            Forbidden - Not Retryable
             |Error Code|Description|
             |-------|-------|            
             | AUTHORIZER_FORBIDDEN  | User is not authorized to access this resource |

             -----------------
        '404':
          description: |-
            Bad Request - Not Retryable

            |Error Code|Description|
            |-------|-------|
            |UNKNOWN_TOKEN|Not able to identify the token.|
            |UNKNOWN_MERCHANT|Not able to identify the merchant.|

            -----------------
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error'
        '500':
          description: |-
            Bad Request - Not Retryable

            |Error Code|Description|
            |-------|-------|
            | INTERNAL_ERROR |  Internal D1 error |

            -----------------
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error'
        '503':
          $ref: '#/components/responses/503'
      security:
        - bearerAuth: []
      servers:
        - url: 'https://api.d1.thalescloud.io/ecom-dcs'
          description: Production server
        - url: 'https://api.d1-stg.thalescloud.io/ecom-dcs'
          description: Staging server
  '/merchant-gateways/{merchantGatewayId}/merchants/{merchantId}/tokens/{tokenId}/transactions':
    post:
      tags:
        - Transaction Management
      summary: Create Transaction
      description: Provide all required data to the Merchant/PSP to build a transaction authorisation request.
      operationId: createTransaction
      parameters:
        - $ref: '#/components/parameters/x-correlation-id-header'
        - $ref: '#/components/parameters/merchant-gateway-id-path'
        - $ref: '#/components/parameters/merchant-id-path'
        - $ref: '#/components/parameters/token-id-path'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/createTransactionRequest'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/createTransactionResponse'
        '400':
          description: |-
            Bad Request - Not Retryable
            |Error Code|Description|
            |-------|-------|            
            | FIELD_INVALID_FORMAT |  JSON not well formatted or one field is not expected format as defined in this documentation (first found) |

            -----------------
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error'
        '401':
          $ref: '#/components/responses/401'
        '403':
          description: |-
            Forbidden - Not Retryable
             |Error Code|Description|
             |-------|-------|            
             | AUTHORIZER_FORBIDDEN  | User is not authorized to access this resource |
             | OPERATION_NOT_ALLOWED | Invalid token state |

             -----------------
        '404':
          description: |-
            Bad Request - Not Retryable

            |Error Code|Description|
            |-------|-------|
            |UNKNOWN_TOKEN|Not able to identify the token.|

            -----------------
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error'
        '500':
          description: |-
            Bad Request - Not Retryable

            |Error Code|Description|
            |-------|-------|
            | INTERNAL_ERROR |  Internal D1 error |
            | TSP_ERROR  |  An error occurred with TSP |

            -----------------
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error'
        '503':
          $ref: '#/components/responses/503'
      security:
        - bearerAuth: []
      servers:
        - url: 'https://api.d1.thalescloud.io/ecom-dcs'
          description: Production server
        - url: 'https://api.d1-stg.thalescloud.io/ecom-dcs'
          description: Staging server
tags:
  - name: Merchant Onboarding
  - name: Token Management
  - name: Token Migration
  - name: Transaction Management
  - name: Oauth2
components:
  parameters:
    merchant-gateway-id-path:
      name: merchantGatewayId
      in: path
      description: The merchant gateway identifier
      required: true
      schema:
        $ref: '#/components/schemas/merchantGatewayId'
    merchant-id-path:
      name: merchantId
      in: path
      description: The merchant identifier
      required: true
      schema:
        $ref: '#/components/schemas/merchantId'
    token-id-path:
      name: tokenId
      in: path
      description: The token identifier
      required: true
      schema:
        $ref: '#/components/schemas/tokenId'
    x-correlation-id-header:
      name: x-correlation-id
      in: header
      description: |-
        Random identifier which can be used to correlate the different API calls done as part of a single use-case. This identifier will be the one primarily used for troubleshooting.

        **Warning:** This identifier should not be derived from sensitive personal data, as its value will be logged in clear.

        There is no strong guarantee of the uniqueness of this identifier, so please refrain from using it for other purpose than logging and troubleshooting.
      required: true
      schema:
        type: string
        pattern: '^[A-Za-z0-9_-]{1,64}$'
  securitySchemes:
    bearerAuth:
      type: http
      description: |-
        A JWT generated by the [Get Access Token API](reference/d1-ecom_dcs-inbound-api.yaml/paths/~1oauth2~1token/post).<br/>
        The server checks the validity of the provided token to control access to this protected resource.
      scheme: bearer
      bearerFormat: JWT
  responses:
    '204':
      description: No Content
    '401':
      description: Unauthorized - Not Retryable
    '503':
      description: Service Unavailable - Retryable
  schemas:
    auth2Request:
      type: object
      additionalProperties: false
      properties:
        grant_type:
          $ref: '#/components/schemas/grant_type'
        assertion:
          $ref: '#/components/schemas/assertion'
      required:
        - grant_type
        - assertion
    grant_type:
      const: 'urn:ietf:params:oauth:grant-type:jwt-bearer'
      description: 'Describes the <b>flow</b>.<br/>In our case we have defined the JWT bearer flow, so you will have to set urn:ietf:params:oauth:grant-type:jwt-bearer'
    assertion:
      type: string
      description: 'The assertion is the entire JWT value.<br/>Please refer to [OAuth2 Access Token](/docs/d1-ecom-dcs/f228b234b4203-backend-oauth-2-access-token) for more details on how to generate this JWT.<br/>The JWT must contain the following fields: <ul><li><b>iss:</b> Issuer of the JWT. It shall be the merchant gateway identifier and it will be used to lookup the onboarded public key.</li><li><b>exp:</b> The validity must be the expiration time of the assertion within 15 minutes, expressed as the number of seconds from 1970-01-01T0:0:0Z measured in UTC.</li></ul>Supported alg: ES256.'
      examples:
        - ey...HRT8LOON8z
    auth2Response:
      type: object
      additionalProperties: false
      properties:
        access_token:
          $ref: '#/components/schemas/access_token'
        expires_in:
          $ref: '#/components/schemas/expires_in'
        token_type:
          $ref: '#/components/schemas/token_type'
        scope:
          $ref: '#/components/schemas/scope'
          example: 'd1-s2s:api:merchant-gtw'
    access_token:
      type: string
      description: The access_token that will be used to call the APIs.
      examples:
        - ey...HRT6LOON7w
    expires_in:
      type: number
      description: Remaining time in seconds for the access_token to expire.
      examples:
        - 900
    token_type:
      type: string
      description: Type of the access_token that will be used to call the APIs.
      examples:
        - Bearer
    scope:
      type: string
      description: Scope of the access_token.
    error:
      type: object
      additionalProperties: false
      properties:
        errorCode:
          type: string
          description: The type of error
          examples:
            - FIELD_INVALID_FORMAT
        error:
          type: string
          description: |-
            Provide additional information about the error if possible.<br/>
            Used for logging and troubleshooting purpose. It can change at any time so MUST NOT be parsed, and is not supposed to be human readable so CANNOT be displayed to end users.
    createMerchantRequest:
      type: object
      additionalProperties: false
      properties:
        merchantName:
          $ref: '#/components/schemas/merchantName'
      required:
        - merchantName
    merchantName:
      type: string
      description: An unique merchant name that is end user friendly.
      pattern: '^[A-Za-z0-9-_. ]+$'
      minLength: 1
      maxLength: 64
      examples:
        - My Merchant
    createMerchantResponse:
      type: object
      additionalProperties: false
      properties:
        merchantId:
          $ref: '#/components/schemas/merchantId'
        creationDateTime:
          $ref: '#/components/schemas/creationDateTime'
      required:
        - merchantId
        - creationDateTime
    merchantId:
      type: string
      description: Merchant Identifier (aka Token Requestor ID) generated by the scheme TSP for that merchant.
      pattern: '^[A-Za-z0-9_-]{11}$'
      minLength: 11
      maxLength: 11
      examples:
        - '10610027312'
    creationDateTime:
      type: string
      description: 'Creation date time as defined by RFC 3339, section 5.6'
      format: date-time
    createTokenRequest:
      type: object
      additionalProperties: false
      properties:
        encryptedData:
          $ref: '#/components/schemas/encryptedCardAndUserData'
      required:
        - encryptedData
    encryptedCardAndUserData:
      type: string
      description: |-
        The user and card information encrypted in a JWE structure (see data encryption section).

        Once decrypted, the JWE plaintext contains the following JSON object:

        |JSON field parameter name|description|MOC|Length|
        |-------|-------|-------|-------|
        |fpan|The funding pan to tokenize.|M|From 10 to 19|
        |exp|The expiry date in format MMYY.|M|4|        
        |name|The card holder name in the format FIRSTNAME LASTNAME or as written on the card.|O|Up to 128 char|
        |cvv|The security code.</br>It can help the issuer in the decision of approving the payment.|O|3 or 4|

        **Example**: ```{"fpan":"5123456789012345", "exp":"0822", "name":"JOHN DOE", "cvv":"123"}```
      examples:
        - ey...4FT8LOON8z
    createTokenResponse:
      type: object
      additionalProperties: false
      properties:
        tokenId:
          $ref: '#/components/schemas/tokenId'
        cardLastDigits:
          $ref: '#/components/schemas/cardLastDigits'
        cardExpiryDate:
          $ref: '#/components/schemas/cardExpiryDate'
        tokenState:
          $ref: '#/components/schemas/tokenState'
        encryptedTokenData:
          $ref: '#/components/schemas/encryptedTokenData'
        creationDateTime:
          $ref: '#/components/schemas/creationDateTime'
      required:
        - tokenId
        - cardLastDigits
        - cardExpiryDate
        - tokenState
        - encryptedTokenData
        - creationDateTime
    tokenId:
      type: string
      description: Token unique identifier
      pattern: '^[A-Za-z0-9_-]{1,48}$'
      minLength: 1
      maxLength: 48
      examples:
        - 01fb32ff-5ed0-497f-8835-6af0916f29c0
    cardLastDigits:
      type: string
      description: |
        The card last digits

        If the card is a cobagde card with a primary and an auxiliary PAN, then the primary PAN is used to generate the last digits
      pattern: '^[0-9]{4}$'
      examples:
        - '0037'
    cardExpiryDate:
      type: string
      description: Card expiry date in MMYY format
      pattern: '^(0[1-9]|1[0-2])\d{2}$'
      examples:
        - '0928'
    tokenState:
      type: string
      enum:
        - ACTIVE
        - SUSPENDED
        - DELETED
      description: Token state
    encryptedTokenData:
      type: string
      description: |-
        The token data encrypted in a JWE structure (see data encryption section).

        Once decrypted, the JWE plaintext contains the following JSON object:

        |JSON field parameter name|description|MOC|Length|
        |-------|-------|-------|-------|
        |dpan|The token pan value.|M|From 10 to 19|
        |exp|The token expiry date in format MMYY.|M|4|        

        **Example**: ```{"dpan":"5123456789012345", "exp":"0822"}```
      examples:
        - ey...8GT8LOON8z
    getTokenMetadataResponse:
      type: object
      description: Notice that the card last digits and the card expiry are always returned except if the card has been deleted by the issuer.
      additionalProperties: false
      properties:
        cardLastDigits:
          $ref: '#/components/schemas/cardLastDigits'
        cardExpiryDate:
          $ref: '#/components/schemas/cardExpiryDate'
        tokenState:
          $ref: '#/components/schemas/tokenState'
        creationDateTime:
          $ref: '#/components/schemas/creationDateTime'
        lastUpdateDateTime:
          type: string
          description: 'Last update date time as defined by RFC 3339, section 5.6'
          format: date-time
      required:
        - tokenState
        - creationDateTime
    createTransactionRequest:
      type: object
      additionalProperties: false
      properties:
        transactionId:
          type: string
          description: The unique transaction identifier
          pattern: '^[A-Za-z0-9]{1,12}$'
          examples:
            - Rrn123456789
        transactionDateTime:
          type: string
          description: UTC Transaction date in 'YYYYMMDDhhmmss' format.
          pattern: '^[0-9]{14}$'
          examples:
            - '20260225140530'
        amount:
          type: string
          description: 'Amount in the smallest unit of currency, right justified with leading zeros'
          pattern: '^[0-9]{12}$'
          examples:
            - '000000002100'
        currencyCode:
          type: string
          description: Currency code as per ISO 4217
          pattern: '^[0-9]{3}$'
          examples:
            - '978'
      required:
        - transactionId
        - transactionDateTime
        - amount
        - currencyCode
    createTransactionResponse:
      type: object
      additionalProperties: false
      properties:
        encryptedData:
          type: string
          description: |-
            The payment credentials data encrypted in a JWE structure (see security section in the documentation).

            Once decrypted, the JWE plaintext contains the following JSON object:

            |JSON field parameter name|description|MOC|Length|
            |-------|-------|-------|-------|
            |dpan|The token PAN value|M|Up to 19|
            |exp|The token expiry date in the format MMYY|M|4|
            |cryptogram|The payment cryptogram to use with the token for a payment|M|Up to 256|

            **Example**: ```{"dpan:"9580981500100002", "exp":"1222", "cryptogram": "45f8grzty7f4f5gs5s2c"}```       
      required:
        - encryptedData
    merchantGatewayId:
      type: string
      description: Merchant Gateway Identifier.
      pattern: '^[A-Za-z0-9_-]{10}$'
      minLength: 10
      maxLength: 10
      examples:
        - MGW_000001
