openapi: 3.1.0
info:
  title: Wallet API
  description: Customer's wallet
  version: "v3"
  license:
    name: Purse
    url: https://purse.eu/fr/mentions-legales/

servers:
  - url: https://api.purse-sandbox.com/wallet
    description: Wallet API
paths:
  /v3/merchants/{merchant_id}/customers/{customer_reference}/tokens:
    get:
      tags:
      - Wallet API V3
      summary: Get tokens of a customer
      operationId: getTokens
      parameters:
      - name: merchant_id
        in: path
        required: true
        schema:
          type: string
      - name: customer_reference
        in: path
        required: true
        schema:
          type: string
      - name: status
        in: query
        required: false
        schema:
          type: string
          enum:
          - ACTIVE
          - INACTIVE
          - ARCHIVED
      - name: origin
        in: query
        required: false
        schema:
          type: string
          enum:
          - partner
          - pci_proxy
          - purse
      responses:
        "403":
          description: Forbidden
          content:
            '*/*':
              schema:
                $ref: "#/components/schemas/ApiError"
        "404":
          description: Not Found
          content:
            '*/*':
              schema:
                $ref: "#/components/schemas/ApiError"
        "200":
          description: 'The list of tokens '
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TokensProjectionV3"
      security:
        - purse_oauth2:
            - payment-api
    post:
      tags:
      - Wallet API V3
      summary: Add a token to the customer's wallet
      operationId: addToken
      parameters:
      - name: x-idempotency-key
        in: header
        required: false
        schema:
          type: string
          default: ""
      - name: merchant_id
        in: path
        required: true
        schema:
          type: string
      - name: customer_reference
        in: path
        required: true
        schema:
          type: string
      - name: Authorization
        in: header
        required: false
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TokenRequestV3"
        required: true
      responses:
        "404":
          description: Not Found
          content:
            '*/*':
              schema:
                $ref: "#/components/schemas/ApiError"
        "400":
          description: List of properties rules violations
          content:
            application/json:
              schema:
                type: string
        "201":
          description: The token ID
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TokenProjectionV3"
      security:
        - purse_oauth2:
            - payment-api
    delete:
      tags:
      - Wallet API V3
      summary: Delete all tokens of a customer
      operationId: deleteAllTokens
      parameters:
      - name: merchant_id
        in: path
        required: true
        schema:
          type: string
      - name: customer_reference
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              type: string
      responses:
        "404":
          description: No token for the given owner
        "204":
          description: The tokens are removed
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: array
                  items:
                    type: string
                    format: uuid
      security:
        - purse_oauth2:
            - payment-api

  /v3/merchants/{merchant_id}/customers/{customer_reference}/token/{id}/status:
    patch:
      tags:
      - Wallet API V3
      operationId: updateStatus
      summary: Update the status of a token
      parameters:
      - name: merchant_id
        in: path
        required: true
        schema:
          type: string
      - name: customer_reference
        in: path
        required: true
        schema:
          type: string
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateStatusRequest"
        required: true
      responses:
        "404":
          description: Not Found
          content:
            '*/*':
              schema:
                $ref: "#/components/schemas/ApiError"
        "200":
          description: OK
      security:
      - purse_oauth2:
          - payment-api

  /v3/merchants/{merchant_id}/customers/{customer_reference}/tokens/count:
    get:
      tags:
      - Wallet API V3
      summary: Get token count of a customer
      operationId: countActiveTokens
      parameters:
      - name: merchant_id
        in: path
        required: true
        schema:
          type: string
      - name: customer_reference
        in: path
        required: true
        schema:
          type: string
      - name: status
        in: query
        required: false
        schema:
          type: string
          enum:
          - ACTIVE
          - INACTIVE
          - ARCHIVED
      responses:
        "404":
          description: Not Found
          content:
            '*/*':
              schema:
                $ref: "#/components/schemas/ApiError"
        "400":
          description: Bad Request
          content:
            '*/*':
              schema:
                $ref: "#/components/schemas/ApiError"
        "200":
          description: The count of tokens
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TokenCountProjectionV3"
      security:
        - purse_oauth2:
            - payment-api

  /v3/merchants/{merchant_id}/customers/{customer_reference}/tokens/{id}:
    delete:
      tags:
      - Wallet API V3
      summary: Delete one single token of a customer
      operationId: deleteOneToken
      parameters:
      - name: merchant_id
        in: path
        required: true
        schema:
          type: string
      - name: customer_reference
        in: path
        required: true
        schema:
          type: string
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              type: string
      responses:
        "403":
          description: Forbidden
          content:
            '*/*':
              schema:
                $ref: "#/components/schemas/ApiError"
        "404":
          description: No token for the given customer and token id
        "204":
          description: The token has been deleted
      security:
        - purse_oauth2:
            - payment-api
components:
  schemas:
    ApiError:
      type: object
      properties:
        timestamp:
          type: string
          format: ISO 8601
          description: The moment at which the error happened.
          example: 2030-08-25T10:42:59
        errorCode:
          type: string
          description: The error code to interpret.
          enum:
          - INTERNAL_SERVER_ERROR
          - BAD_REQUEST
          - TOKEN_NOT_FOUND
          - MERCHANT_NOT_FOUND
          - TOKEN_BALANCE_NOT_FOUND
          - SESSION_NOT_FOUND
          - STORE_CREDIT_NOT_FOUND
          - USER_NOT_FOUND
          - ALREADY_EXISTS
          - ALREADY_FAVORITE
          - NAME_ALREADY_USED
          - OPERATION_NOT_PERMITTED
          - INSUFFICIENT_BALANCE
          - MERCHANT_MESSING_CONFIGURATION
          - FORBIDDEN
          - STORE_CREDIT_INVALID_CURRENCY
          - IBAN_NOT_FOUND
          - INVALID_IBAN
        message:
          type: string
          description: The message explaining the cause of the error.
        error:
          type: string
    TokenDescriptionV3:
      type: object
      description: Description of the token
      properties:
        brand_name:
          type: string
          minLength: 1
        display_token:
          type: string
          minLength: 1
        holder_name:
          type: string
      required:
      - brand_name
      - display_token
    TokenProjectionV3:
      type: object
      description: Representation of a token in the wallet system
      properties:
        id:
          type: string
          format: uuid
        fingerprint:
          type: string
        pin_code:
          type: string
        expiration_date:
          type: string
          format: date-time
        customer_reference:
          type: string
        merchant_id:
          type: string
        status:
          type: string
          enum:
          - ACTIVE
          - INACTIVE
          - ARCHIVED
        description:
          $ref: "#/components/schemas/TokenDescriptionV3"
        scope:
          $ref: "#/components/schemas/TokenScopeV3"
        created_at:
          type: string
          format: date-time
        value:
          type: string
        updated_at:
          type: string
          format: date-time
        favorite:
          type: boolean
        label:
          type: string
        source:
          type: string
          enum:
          - MERCHANT
          - SHARED_WALLET
        savable_to_shared_wallet:
          type: boolean
    TokenScopeV3:
      type: object
      description: Scope of the token
      properties:
        partner:
          type: string
        method:
          type: string
        origin:
          type: string
          enum:
          - partner
          - pci_proxy
          - purse
    TokenDescription:
      type: object
      properties:
        brand_name:
          type: string
          minLength: 1
        display_token:
          type: string
          minLength: 1
        holder_name:
          type: string
      required:
      - brand_name
      - display_token
    TokenRequestV3:
      type: object
      properties:
        token:
          type: string
          minLength: 1
        fingerprint:
          type: string
        pin_code:
          type: string
        expiration_date:
          type: string
          format: date-time
        description:
          $ref: "#/components/schemas/TokenDescription"
        scope:
          $ref: "#/components/schemas/TokenScopeV3"
        reason:
          type: string
        label:
          type: string
          pattern: "^[a-zA-Z0-9 ]{0,25}$"
      required:
      - description
      - expiration_date
      - scope
      - token
    UpdateStatusRequest:
      type: object
      properties:
        status:
          type: string
          enum:
          - ACTIVE
          - INACTIVE
          - ARCHIVED
        reason:
          type: string
      required:
      - status
    TokensProjectionV3:
      type: object
      description: List of tokens
      properties:
        tokens:
          type: array
          items:
            $ref: "#/components/schemas/TokenProjectionV3"
        shared_wallet_user:
          type: boolean
        total_elements:
          type: integer
          format: int64
    TokenCountProjectionV3:
      type: object
      description: Count of tokens
      properties:
        count:
          type: integer
          format: int32
  securitySchemes:
    purse_oauth2:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: https://api.purse-live.com/oauth2/token
          scopes:
            payment-api: use payment-api
    api_key:
      type: apiKey
      name: api_key
      in: header
