openapi: 3.0.3
info:
  title: Purse - Vault API
  description: Vault API
  version: v1
  license:
    name: Purse
    url: https://purse.eu/fr/mentions-legales/
servers:
  - url: https://api.vault.purse-secure.com
tags:
  - name: Forms
    description: Vault API Forms
paths:
  /v1/tenants/{tenant}/forms:
    post:
      tags:
        - Forms
      summary: Submit a payment form
      description: Submit a payment form to the vault API.
      operationId: submitPaymentFormServerToServer
      parameters:
        - name: tenant
          in: path
          required: true
          description: Tenant identifier
          schema:
            type: string
            format: uuid
          example: 123e4567-e89b-12d3-a456-426614174000
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FormApplication'
            examples:
              card-and-cvv:
                value:
                  card:
                    pan: '4242424242424242'
                    expiry_month: 12
                    expiry_year: 2025
                    card_holder_name: John Doe
                    save_token: true
                    selected_network: VISA
                  cvv: '123'
              card-slim:
                value:
                  card:
                    pan: '4242424242424242'
                    expiry_month: 12
                    expiry_year: 2025
              card-full:
                value:
                  card:
                    pan: '4242424242424242'
                    expiry_month: 12
                    expiry_year: 2025
                    card_holder_name: John Doe
                    save_token: true
                    selected_network: VISA
              cvv:
                value:
                  cvv: '123'
        required: true
      responses:
        '201':
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FormRepresentation'
              example:
                form_token: 32oufdHG56-O87sbsaWdRtZ7Q1_ziLAx
                tenant_id: 123e4567-e89b-12d3-a456-426614174000
                created_at: '2025-10-01T20:00:00Z'
                expires_at: '2025-10-01T20:12:00Z'
                card:
                  card_token: T_PEYkrYCFRj-o6DUJhC2yRTaZ8mg5dE
                  tenant_id: 123e4567-e89b-12d3-a456-426614174000
                  created_at: '2025-10-01T20:00:00Z'
                  expires_at: '2027-01-01T00:00:00Z'
                  expiry_month: 12
                  expiry_year: 2026
                  main_brand: VISA
                  co_brand: CARTE_BANCAIRE
                  fingerprint: YoiYDbKwqBzSJeaYim8XSkrpicp7q7oZ
                  bin: '42424242'
                  last_four_digits: '4242'
                  truncated_pan: 424242******4242
                  issuer_name: Credit Agricole S.A.
                  issuer_country: FR
                  billing_currency_default: EUR
                  consumer_type: CONSUMER
                  funding_source: DEBIT
                cvv_token: uEq9stsNhuIJ9UDT0wY0tqy8nDmrNRRI
                card_holder_name: John Doe
                save_token: true
                selected_network: CARTE_BANCAIRE
        '400':
          description: Bad request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
        '403':
          description: 'Forbidden (eg: Unsupported Origin)'
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
        '404':
          description: Tenant was not found
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
      security:
        - purse_oauth2:
            - vault-api
  /v1/tenants/{tenant}/forms/{form_token}:
    get:
      tags:
        - Forms
      summary: Get form by token
      description: Retrieve tokens for pan and cvv.
      operationId: getFormByToken
      parameters:
        - name: tenant
          in: path
          required: true
          description: Tenant identifier
          schema:
            type: string
            format: uuid
            example: 123e4567-e89b-12d3-a456-426614174000
        - name: form_token
          in: path
          required: true
          description: Form token to identify the submitted form
          schema:
            type: string
            pattern: ^[a-zA-Z0-9_-]{32}$
          example: 32oufdHG56-O87sbsaWdRtZ7Q1_ziLAx
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FormRepresentation'
              example:
                form_token: 32oufdHG56-O87sbsaWdRtZ7Q1_ziLAx
                tenant_id: 123e4567-e89b-12d3-a456-426614174000
                created_at: '2025-10-01T20:00:00Z'
                expires_at: '2025-10-01T20:12:00Z'
                card:
                  pan_token: T_PEYkrYCFRj-o6DUJhC2yRTaZ8mg5dE
                  tenant_id: 123e4567-e89b-12d3-a456-426614174000
                  created_at: '2025-10-01T20:00:00Z'
                  expires_at: '2027-01-01T00:00:00Z'
                  expiry_month: 12
                  expiry_year: 2026
                  main_brand: VISA
                  co_brand: CARTE_BANCAIRE
                  fingerprint: YoiYDbKwqBzSJeaYim8XSkrpicp7q7oZ
                  bin: '42424242'
                  last_four_digits: '4242'
                  masked_pan: 424242******4242
                  issuer_name: Credit Agricole S.A.
                  issuer_country: FR
                  billing_currency_default: EUR
                  consumer_type: CONSUMER
                  funding_source: DEBIT
                cvv_token: uEq9stsNhuIJ9UDT0wY0tqy8nDmrNRRI
                card_holder_name: John Doe
                save_token: true
                selected_network: CARTE_BANCAIRE
        '400':
          description: Bad request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
        '401':
          description: Unauthorized
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
        '403':
          description: Forbidden
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
        '404':
          description: Not found
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
      security:
        - purse_oauth2:
            - vault-api
components:
  securitySchemes:
    purse_oauth2:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: https://api.purse-live.com/oauth2/token
          scopes:
            vault-api: use vault-api
    api_key:
      type: apiKey
      name: api_key
      in: header
  schemas:
    BrandEnum:
      type: string
      description: Enum for card brands.
      enum:
        - VISA
        - MASTERCARD
        - AMERICAN_EXPRESS
        - CARTE_BANCAIRE
        - MAESTRO
        - ONEY
    PaymentCardFormCardApplication:
      type: object
      description: Payment card form submitted by the user.
      required:
        - pan
        - expiry_month
        - expiry_year
      properties:
        pan:
          description: Primary Account Number (PAN) of the payment card
          type: string
          pattern: ^[0-9]{15,16}$
        expiry_month:
          description: Expiry month of the payment card
          type: integer
          minimum: 1
          maximum: 12
        expiry_year:
          description: Expiry year of the payment card
          type: integer
          minimum: 2025
          maximum: 2999
        card_holder_name:
          description: Name of the card holder
          type: string
          pattern: ^[a-zA-Z'. -]{2,255}$
        save_token:
          description: Flag to indicate if the card should be saved for future use
          type: boolean
          default: false
        selected_network:
          description: Selected network for the payment card
          $ref: '#/components/schemas/BrandEnum'
    PaymentCardFormCvvApplication:
      description: Card Verification Value (CVV) of the payment card
      type: string
      pattern: ^[0-9]{3,4}$
    MinimalCardRepresentation:
      type: object
      description: Minimal represenation of a payment card.
      required:
        - bin
        - last_four_digits
      properties:
        bin:
          description: Bank Identification Number (BIN) of the payment card
          type: string
          pattern: ^[0-9]{8}$
        last_four_digits:
          description: Last four digits of the payment card
          type: string
          pattern: ^[0-9]{4}$
    CardRepresentation:
      type: object
      description: Full representation of a payment card.
      allOf:
        - $ref: '#/components/schemas/MinimalCardRepresentation'
        - type: object
          required:
            - tenant_id
            - pan_token
            - expiry_month
            - expiry_year
          properties:
            pan_token:
              description: Token representing the Primary Account Number (PAN) of the payment card
              type: string
              pattern: ^[a-zA-Z0-9_-]{32}$
            tenant_id:
              description: Tenant identifier
              type: string
              format: uuid
            created_at:
              description: Timestamp when the card was created
              type: string
              format: date-time
            expires_at:
              description: Timestamp when the card expires in our Vault
              type: string
              format: date-time
            expiry_month:
              description: Expiry month of the payment card
              type: integer
              minimum: 1
              maximum: 12
            expiry_year:
              description: Expiry year of the payment card
              type: integer
              minimum: 2025
              maximum: 2999
            main_brand:
              description: Main brand of the payment card
              $ref: '#/components/schemas/BrandEnum'
            co_brand:
              description: Co-brand of the payment card, if applicable
              $ref: '#/components/schemas/BrandEnum'
            masked_pan:
              description: Masked Primary Account Number (PAN) of the payment card
              type: string
              example: 424242******5969
            fingerprint:
              description: Unique fingerprint of the payment card
              type: string
            issuer_name:
              description: Name of the card issuer
              type: string
              example: Credit Agricole S.A.
            issuer_country:
              description: Country of the card issuer (ISO 3166-1 alpha-2)
              type: string
              example: FR
            billing_currency_default:
              description: Default billing currency (ISO 4217)
              type: string
            consumer_type:
              description: Consumer type (e.g., consumer, corporate)
              type: string
              enum:
                - CONSUMER
                - CORPORATE
            funding_source:
              description: Funding source of the card (e.g., credit, debit, prepaid)
              type: string
              enum:
                - CREDIT
                - DEBIT
                - PREPAID
    FormRepresentation:
      type: object
      description: Representation of a payment card form.
      required:
        - form_token
        - tenant_id
        - created_at
        - expires_at
        - save_token
      properties:
        form_token:
          description: Token to identify the submitted form
          type: string
          pattern: ^[a-zA-Z0-9_-]{32}$
        tenant_id:
          description: Tenant identifier
          type: string
          format: uuid
        created_at:
          description: Timestamp when the form was created
          type: string
          format: date-time
        expires_at:
          description: Timestamp when the form expires
          type: string
          format: date-time
        card:
          description: Payment card details
          $ref: '#/components/schemas/CardRepresentation'
        cvv_token:
          description: Token representing the Card Verification Value (CVV) of the payment card
          type: string
          pattern: ^[a-zA-Z0-9_-]{32}$
        card_holder_name:
          description: Name of the card holder
          type: string
          maximum: 26
        save_token:
          description: Flag to indicate if the card should be saved for future use
          type: boolean
          default: false
        selected_network:
          description: Selected network for the payment card
          $ref: '#/components/schemas/BrandEnum'
    FormApplication:
      description: Payment card form submitted by the user.
      type: object
      properties:
        card:
          description: Payment card details
          $ref: '#/components/schemas/PaymentCardFormCardApplication'
        cvv:
          description: Card Verification Value (CVV) of the payment card
          $ref: '#/components/schemas/PaymentCardFormCvvApplication'
      example:
        card:
          pan: '4242424242424242'
          expiry_month: 12
          expiry_year: 2025
          card_holder_name: John Doe
          save_token: true
          selected_network: VISA
        cvv: '123'
    ProblemDetail:
      title: An RFC 7807 problem object
      type: object
      properties:
        type:
          type: string
          format: uri-reference
          description: A URI reference that identifies the problem type.
        title:
          type: string
          description: A short, human-readable summary of the problem type.
        status:
          type: integer
          description: |
            The HTTP status code generated by the origin server for this occurrence
            of the problem.
          minimum: 100
          maximum: 599
        detail:
          type: string
          description: A human-readable explanation specific to this occurrence of the problem.
        instance:
          type: string
          format: uri-reference
          description: |
            A URI reference that identifies the  specific occurrence of the problem.
            It may or may not yield  further information if dereferenced.
        error:
          description: Single error detail
        errors:
          type: array
          description: Error details
          items:
            type: object
            properties:
              detail:
                type: string
                description: Error detail
              pointer:
                type: string
                description: JSON Pointer for the field
