asyncapi: '2.6.0'

info:
  title: EventZR Wallet Service - Kafka Event API
  version: '1.0.0'
  description: |
    AsyncAPI specification for wallet-svc Kafka event channels.

    The wallet service publishes events for wallet lifecycle, transactions,
    escrows, payment methods, split payments, and refunds. It consumes events
    from subscriptions-svc, ticketing-svc, booking-svc, and user-svc.

    - Event format: CloudEvents 1.0 specification
    - Partitioning: By tenant_id for multi-tenant isolation
    - Topic naming: eventzr.wallet.<entity>.<action>.v<N>
    - Outbox pattern: Events stored in KafkaOutbox table before publishing
    - DLQ: Failed events moved to KafkaDlq table after max retries
  contact:
    name: EventZR Platform Team
    email: platform@eventzr.com
    url: https://eventzr.com
  license:
    name: Proprietary
    url: https://eventzr.com/legal/license

servers:
  kafka-staging:
    url: boot-gpm4u49z.c2.kafka-serverless.us-east-1.amazonaws.com:9098
    protocol: kafka-secure
    protocolVersion: '3.6.0'
    description: Amazon MSK Serverless (staging)
    security:
      - saslAwsMskIam: []
    bindings:
      kafka:
        schemaRegistryUrl: ''
        schemaRegistryVendor: ''

defaultContentType: application/json

tags:
  - name: wallet-lifecycle
    description: Wallet creation, status changes, balance updates
  - name: transactions
    description: Transaction creation, completion, failure
  - name: refunds
    description: Refund completion and failure
  - name: escrow
    description: Escrow creation, release, refund
  - name: payment-methods
    description: Payment method add, remove, verify
  - name: split-payments
    description: Split payment completion and failure
  - name: consumed
    description: Events consumed from other services

# ── Published Channels ─────────────────────────────────────────────────────────

channels:
  # ── Wallet Lifecycle ───────────────────────────────────────────────────────

  eventzr.wallet.created.v1:
    description: |
      Published when a new wallet is created for a user, team, or system entity.
      Consumed by: analytics-svc, notify-svc, Neptune KG sync
    bindings:
      kafka:
        partitions: 12
        replicas: 3
        topicConfiguration:
          retention.ms: 604800000
          cleanup.policy:
            - delete
    publish:
      operationId: publishWalletCreated
      summary: Wallet created
      tags:
        - name: wallet-lifecycle
      bindings:
        kafka:
          groupId:
            type: string
            enum:
              - wallet-svc-kg-sync
              - analytics-svc-consumer
              - notify-svc-consumer
          clientId:
            type: string
            enum:
              - wallet-svc
          bindingVersion: '0.5.0'
      message:
        $ref: '#/components/messages/WalletCreated'

  eventzr.wallet.balance.updated.v1:
    description: |
      Published when a wallet balance changes (credit, debit, transfer, refund).
      Consumed by: analytics-svc, Neptune KG sync
    bindings:
      kafka:
        partitions: 12
        replicas: 3
        topicConfiguration:
          retention.ms: 604800000
          cleanup.policy:
            - delete
    publish:
      operationId: publishWalletBalanceUpdated
      summary: Wallet balance updated
      tags:
        - name: wallet-lifecycle
      bindings:
        kafka:
          groupId:
            type: string
            enum:
              - wallet-svc-kg-sync
              - analytics-svc-consumer
          clientId:
            type: string
            enum:
              - wallet-svc
          bindingVersion: '0.5.0'
      message:
        $ref: '#/components/messages/WalletBalanceUpdated'

  eventzr.wallet.frozen.v1:
    description: |
      Published when a wallet is frozen due to fraud, compliance, or admin action.
      Consumed by: notify-svc, analytics-svc
    bindings:
      kafka:
        partitions: 12
        replicas: 3
        topicConfiguration:
          retention.ms: 604800000
          cleanup.policy:
            - delete
    publish:
      operationId: publishWalletFrozen
      summary: Wallet frozen
      tags:
        - name: wallet-lifecycle
      bindings:
        kafka:
          groupId:
            type: string
            enum:
              - notify-svc-consumer
              - analytics-svc-consumer
          clientId:
            type: string
            enum:
              - wallet-svc
          bindingVersion: '0.5.0'
      message:
        $ref: '#/components/messages/WalletFrozen'

  eventzr.wallet.closed.v1:
    description: |
      Published when a wallet is permanently closed.
      Consumed by: notify-svc, analytics-svc
    bindings:
      kafka:
        partitions: 12
        replicas: 3
        topicConfiguration:
          retention.ms: 604800000
          cleanup.policy:
            - delete
    publish:
      operationId: publishWalletClosed
      summary: Wallet closed
      tags:
        - name: wallet-lifecycle
      bindings:
        kafka:
          groupId:
            type: string
            enum:
              - notify-svc-consumer
              - analytics-svc-consumer
          clientId:
            type: string
            enum:
              - wallet-svc
          bindingVersion: '0.5.0'
      message:
        $ref: '#/components/messages/WalletClosed'

  # ── Transactions ───────────────────────────────────────────────────────────

  eventzr.wallet.transaction.created.v1:
    description: |
      Published when a new transaction is initiated (pending state).
      Consumed by: analytics-svc, audit-svc
    bindings:
      kafka:
        partitions: 12
        replicas: 3
        topicConfiguration:
          retention.ms: 604800000
          cleanup.policy:
            - delete
    publish:
      operationId: publishTransactionCreated
      summary: Transaction created
      tags:
        - name: transactions
      bindings:
        kafka:
          groupId:
            type: string
            enum:
              - analytics-svc-consumer
              - audit-svc-consumer
          clientId:
            type: string
            enum:
              - wallet-svc
          bindingVersion: '0.5.0'
      message:
        $ref: '#/components/messages/TransactionCreated'

  eventzr.wallet.transaction.completed.v1:
    description: |
      Published when a transaction completes successfully.
      Consumed by: analytics-svc, notify-svc, Neptune KG sync
    bindings:
      kafka:
        partitions: 12
        replicas: 3
        topicConfiguration:
          retention.ms: 604800000
          cleanup.policy:
            - delete
    publish:
      operationId: publishTransactionCompleted
      summary: Transaction completed
      tags:
        - name: transactions
      bindings:
        kafka:
          groupId:
            type: string
            enum:
              - wallet-svc-kg-sync
              - analytics-svc-consumer
              - notify-svc-consumer
          clientId:
            type: string
            enum:
              - wallet-svc
          bindingVersion: '0.5.0'
      message:
        $ref: '#/components/messages/TransactionCompleted'

  eventzr.wallet.transaction.failed.v1:
    description: |
      Published when a transaction fails.
      Consumed by: analytics-svc, notify-svc
    bindings:
      kafka:
        partitions: 12
        replicas: 3
        topicConfiguration:
          retention.ms: 604800000
          cleanup.policy:
            - delete
    publish:
      operationId: publishTransactionFailed
      summary: Transaction failed
      tags:
        - name: transactions
      bindings:
        kafka:
          groupId:
            type: string
            enum:
              - analytics-svc-consumer
              - notify-svc-consumer
          clientId:
            type: string
            enum:
              - wallet-svc
          bindingVersion: '0.5.0'
      message:
        $ref: '#/components/messages/TransactionFailed'

  # ── Refunds ────────────────────────────────────────────────────────────────

  eventzr.wallet.refund.completed.v1:
    description: |
      Published when a refund transaction completes.
      Consumed by: ticketing-svc, booking-svc, notify-svc
    bindings:
      kafka:
        partitions: 12
        replicas: 3
        topicConfiguration:
          retention.ms: 604800000
          cleanup.policy:
            - delete
    publish:
      operationId: publishRefundCompleted
      summary: Refund completed
      tags:
        - name: refunds
      bindings:
        kafka:
          groupId:
            type: string
            enum:
              - ticketing-svc-consumer
              - booking-svc-consumer
              - notify-svc-consumer
          clientId:
            type: string
            enum:
              - wallet-svc
          bindingVersion: '0.5.0'
      message:
        $ref: '#/components/messages/RefundCompleted'

  eventzr.wallet.refund.failed.v1:
    description: |
      Published when a refund transaction fails.
      Consumed by: notify-svc
    bindings:
      kafka:
        partitions: 12
        replicas: 3
        topicConfiguration:
          retention.ms: 604800000
          cleanup.policy:
            - delete
    publish:
      operationId: publishRefundFailed
      summary: Refund failed
      tags:
        - name: refunds
      bindings:
        kafka:
          groupId:
            type: string
            enum:
              - notify-svc-consumer
          clientId:
            type: string
            enum:
              - wallet-svc
          bindingVersion: '0.5.0'
      message:
        $ref: '#/components/messages/RefundFailed'

  # ── Escrow ─────────────────────────────────────────────────────────────────

  eventzr.wallet.escrow.created.v1:
    description: |
      Published when a new escrow is created and funded.
      Consumed by: ticketing-svc, booking-svc, notify-svc
    bindings:
      kafka:
        partitions: 12
        replicas: 3
        topicConfiguration:
          retention.ms: 604800000
          cleanup.policy:
            - delete
    publish:
      operationId: publishEscrowCreated
      summary: Escrow created
      tags:
        - name: escrow
      bindings:
        kafka:
          groupId:
            type: string
            enum:
              - ticketing-svc-consumer
              - booking-svc-consumer
              - notify-svc-consumer
          clientId:
            type: string
            enum:
              - wallet-svc
          bindingVersion: '0.5.0'
      message:
        $ref: '#/components/messages/EscrowCreated'

  eventzr.wallet.escrow.released.v1:
    description: |
      Published when escrow funds are released to the payee.
      Consumed by: ticketing-svc, booking-svc, notify-svc
    bindings:
      kafka:
        partitions: 12
        replicas: 3
        topicConfiguration:
          retention.ms: 604800000
          cleanup.policy:
            - delete
    publish:
      operationId: publishEscrowReleased
      summary: Escrow released
      tags:
        - name: escrow
      bindings:
        kafka:
          groupId:
            type: string
            enum:
              - ticketing-svc-consumer
              - booking-svc-consumer
              - notify-svc-consumer
          clientId:
            type: string
            enum:
              - wallet-svc
          bindingVersion: '0.5.0'
      message:
        $ref: '#/components/messages/EscrowReleased'

  eventzr.wallet.escrow.refunded.v1:
    description: |
      Published when escrow funds are refunded to the payer.
      Consumed by: notify-svc
    bindings:
      kafka:
        partitions: 12
        replicas: 3
        topicConfiguration:
          retention.ms: 604800000
          cleanup.policy:
            - delete
    publish:
      operationId: publishEscrowRefunded
      summary: Escrow refunded
      tags:
        - name: escrow
      bindings:
        kafka:
          groupId:
            type: string
            enum:
              - notify-svc-consumer
          clientId:
            type: string
            enum:
              - wallet-svc
          bindingVersion: '0.5.0'
      message:
        $ref: '#/components/messages/EscrowRefunded'

  # ── Payment Methods ────────────────────────────────────────────────────────

  eventzr.wallet.payment-method.added.v1:
    description: |
      Published when a payment method is added to a wallet.
      Consumed by: analytics-svc
    bindings:
      kafka:
        partitions: 12
        replicas: 3
        topicConfiguration:
          retention.ms: 604800000
          cleanup.policy:
            - delete
    publish:
      operationId: publishPaymentMethodAdded
      summary: Payment method added
      tags:
        - name: payment-methods
      bindings:
        kafka:
          groupId:
            type: string
            enum:
              - analytics-svc-consumer
          clientId:
            type: string
            enum:
              - wallet-svc
          bindingVersion: '0.5.0'
      message:
        $ref: '#/components/messages/PaymentMethodAdded'

  eventzr.wallet.payment-method.removed.v1:
    description: |
      Published when a payment method is removed from a wallet.
      Consumed by: analytics-svc
    bindings:
      kafka:
        partitions: 12
        replicas: 3
        topicConfiguration:
          retention.ms: 604800000
          cleanup.policy:
            - delete
    publish:
      operationId: publishPaymentMethodRemoved
      summary: Payment method removed
      tags:
        - name: payment-methods
      bindings:
        kafka:
          groupId:
            type: string
            enum:
              - analytics-svc-consumer
          clientId:
            type: string
            enum:
              - wallet-svc
          bindingVersion: '0.5.0'
      message:
        $ref: '#/components/messages/PaymentMethodRemoved'

  eventzr.wallet.payment-method.verified.v1:
    description: |
      Published when a payment method passes verification.
      Consumed by: notify-svc
    bindings:
      kafka:
        partitions: 12
        replicas: 3
        topicConfiguration:
          retention.ms: 604800000
          cleanup.policy:
            - delete
    publish:
      operationId: publishPaymentMethodVerified
      summary: Payment method verified
      tags:
        - name: payment-methods
      bindings:
        kafka:
          groupId:
            type: string
            enum:
              - notify-svc-consumer
          clientId:
            type: string
            enum:
              - wallet-svc
          bindingVersion: '0.5.0'
      message:
        $ref: '#/components/messages/PaymentMethodVerified'

  # ── Split Payments ─────────────────────────────────────────────────────────

  eventzr.wallet.split.completed.v1:
    description: |
      Published when all splits in a split payment complete.
      Consumed by: notify-svc, analytics-svc
    bindings:
      kafka:
        partitions: 12
        replicas: 3
        topicConfiguration:
          retention.ms: 604800000
          cleanup.policy:
            - delete
    publish:
      operationId: publishSplitCompleted
      summary: Split payment completed
      tags:
        - name: split-payments
      bindings:
        kafka:
          groupId:
            type: string
            enum:
              - notify-svc-consumer
              - analytics-svc-consumer
          clientId:
            type: string
            enum:
              - wallet-svc
          bindingVersion: '0.5.0'
      message:
        $ref: '#/components/messages/SplitCompleted'

  eventzr.wallet.split.failed.v1:
    description: |
      Published when a split payment fails.
      Consumed by: notify-svc
    bindings:
      kafka:
        partitions: 12
        replicas: 3
        topicConfiguration:
          retention.ms: 604800000
          cleanup.policy:
            - delete
    publish:
      operationId: publishSplitFailed
      summary: Split payment failed
      tags:
        - name: split-payments
      bindings:
        kafka:
          groupId:
            type: string
            enum:
              - notify-svc-consumer
          clientId:
            type: string
            enum:
              - wallet-svc
          bindingVersion: '0.5.0'
      message:
        $ref: '#/components/messages/SplitFailed'

  # ── Consumed Channels ──────────────────────────────────────────────────────

  eventzr.subscription.charge.posted.v1:
    description: |
      Consumed from subscriptions-svc. Processes subscription charges by
      debiting the user wallet and adding AI credits.
    subscribe:
      operationId: consumeSubscriptionChargePosted
      summary: Handle subscription charge from subscriptions-svc
      tags:
        - name: consumed
      bindings:
        kafka:
          groupId:
            type: string
            enum:
              - wallet-svc-consumer
          bindingVersion: '0.5.0'
      message:
        $ref: '#/components/messages/ExternalSubscriptionChargePosted'

  eventzr.ticketing.purchase.completed.v1:
    description: |
      Consumed from ticketing-svc. Processes ticket purchase by debiting
      the buyer wallet and crediting the organizer wallet.
    subscribe:
      operationId: consumeTicketingPurchaseCompleted
      summary: Handle ticket purchase from ticketing-svc
      tags:
        - name: consumed
      bindings:
        kafka:
          groupId:
            type: string
            enum:
              - wallet-svc-consumer
          bindingVersion: '0.5.0'
      message:
        $ref: '#/components/messages/ExternalTicketingPurchaseCompleted'

  eventzr.booking.deposit.received.v1:
    description: |
      Consumed from booking-svc. Creates escrow for booking deposit.
    subscribe:
      operationId: consumeBookingDepositReceived
      summary: Handle booking deposit from booking-svc
      tags:
        - name: consumed
      bindings:
        kafka:
          groupId:
            type: string
            enum:
              - wallet-svc-consumer
          bindingVersion: '0.5.0'
      message:
        $ref: '#/components/messages/ExternalBookingDepositReceived'

  eventzr.user.kyc.verified.v1:
    description: |
      Consumed from user-svc. Updates wallet limits and enables features
      based on KYC verification level.
    subscribe:
      operationId: consumeUserKycVerified
      summary: Handle KYC verification from user-svc
      tags:
        - name: consumed
      bindings:
        kafka:
          groupId:
            type: string
            enum:
              - wallet-svc-consumer
          bindingVersion: '0.5.0'
      message:
        $ref: '#/components/messages/ExternalUserKycVerified'

# ── Components ─────────────────────────────────────────────────────────────────

components:
  securitySchemes:
    saslAwsMskIam:
      type: scramSha512
      description: AWS MSK IAM authentication via SASL OAUTHBEARER

  messageTraits:
    CloudEventEnvelope:
      headers:
        type: object
        required:
          - ce_specversion
          - ce_type
          - ce_source
          - ce_id
          - ce_time
          - ce_tenantid
        properties:
          ce_specversion:
            type: string
            const: '1.0'
          ce_type:
            type: string
            description: 'CloudEvents type (e.g., com.eventzr.wallet.created)'
          ce_source:
            type: string
            const: 'https://eventzr.com/wallet-svc'
          ce_id:
            type: string
            format: uuid
          ce_time:
            type: string
            format: date-time
          ce_subject:
            type: string
            description: 'e.g., wallet/<walletId>'
          ce_datacontenttype:
            type: string
            const: application/json
          ce_tenantid:
            type: string
            format: uuid
            description: Tenant ID (also Kafka partition key)
          ce_actor:
            type: string
            description: User or system ID that triggered the event
      bindings:
        kafka:
          key:
            type: string
            format: uuid
            description: Kafka message key is always tenant_id
          bindingVersion: '0.5.0'

  schemas:
    CloudEventBase:
      type: object
      required: [specversion, type, source, subject, id, time, datacontenttype, tenantid, data]
      properties:
        specversion:
          type: string
          const: '1.0'
        type:
          type: string
          description: 'Reverse-DNS: com.eventzr.wallet.<entity>.<action>'
        source:
          type: string
          const: 'https://eventzr.com/wallet-svc'
        subject:
          type: string
          description: 'e.g., wallet/<walletId>, transaction/<txId>'
        id:
          type: string
          format: uuid
        time:
          type: string
          format: date-time
        datacontenttype:
          type: string
          const: application/json
        tenantid:
          type: string
          format: uuid
        actor:
          type: string
        data:
          type: object

    WalletData:
      type: object
      required: [walletId, tenantId, ownerId, walletType, balance, currency, status]
      properties:
        walletId:
          type: string
          format: uuid
        tenantId:
          type: string
          format: uuid
        ownerId:
          type: string
          format: uuid
        walletType:
          type: string
          enum: [user, team, office, escrow, system, revenue]
        balance:
          type: string
          description: Decimal string
        frozenBalance:
          type: string
        availableBalance:
          type: string
        currency:
          type: string
          description: ISO 4217
          example: USD
        status:
          type: string
          enum: [active, suspended, frozen, closed]

    TransactionData:
      type: object
      required: [transactionId, tenantId, transactionType, status, amount, currency]
      properties:
        transactionId:
          type: string
          format: uuid
        tenantId:
          type: string
          format: uuid
        fromWalletId:
          type: string
          format: uuid
          nullable: true
        toWalletId:
          type: string
          format: uuid
          nullable: true
        transactionType:
          type: string
          enum:
            [
              credit,
              debit,
              transfer,
              refund,
              fee,
              adjustment,
              escrow_hold,
              escrow_release,
              escrow_refund,
              split,
              payout,
            ]
        status:
          type: string
          enum: [pending, processing, completed, failed, cancelled, reversed]
        amount:
          type: string
        currency:
          type: string
        fee:
          type: string
        netAmount:
          type: string
        category:
          type: string
          enum:
            [
              ai_credit_purchase,
              marketplace_purchase,
              subscription_payment,
              ticket_purchase,
              payout,
              refund,
              transfer,
              fee,
              deposit,
              withdrawal,
              escrow,
              split_payment,
              reward,
              other,
            ]
        referenceId:
          type: string
          nullable: true
        referenceType:
          type: string
          nullable: true
        completedAt:
          type: string
          format: date-time
          nullable: true
        metadata:
          type: object
          nullable: true

    EscrowData:
      type: object
      required:
        [escrowId, tenantId, payerWalletId, payeeWalletId, escrowType, status, amount, currency]
      properties:
        escrowId:
          type: string
          format: uuid
        tenantId:
          type: string
          format: uuid
        payerWalletId:
          type: string
          format: uuid
        payeeWalletId:
          type: string
          format: uuid
        escrowType:
          type: string
          enum: [marketplace, service, subscription, ticket, custom]
        status:
          type: string
          enum: [pending, funded, released, refunded, disputed, cancelled, expired]
        amount:
          type: string
        currency:
          type: string
        fee:
          type: string
        referenceId:
          type: string
          nullable: true
        referenceType:
          type: string
          nullable: true
        expiresAt:
          type: string
          format: date-time
        releasedAt:
          type: string
          format: date-time
          nullable: true
        refundedAt:
          type: string
          format: date-time
          nullable: true

    PaymentMethodData:
      type: object
      required: [paymentMethodId, tenantId, walletId, paymentMethodType, provider, status]
      properties:
        paymentMethodId:
          type: string
          format: uuid
        tenantId:
          type: string
          format: uuid
        walletId:
          type: string
          format: uuid
        paymentMethodType:
          type: string
        provider:
          type: string
        status:
          type: string
        isDefault:
          type: boolean

    SplitPaymentData:
      type: object
      required: [splitPaymentId, tenantId, sourceTransactionId, totalAmount, currencyCode, status]
      properties:
        splitPaymentId:
          type: string
          format: uuid
        tenantId:
          type: string
          format: uuid
        sourceTransactionId:
          type: string
          format: uuid
        totalAmount:
          type: string
        currencyCode:
          type: string
        recipients:
          type: array
          items:
            type: object
        completedCount:
          type: number
        failedCount:
          type: number
        status:
          type: string
          enum: [pending, processing, completed, failed, partially_completed, cancelled]
        completedAt:
          type: string
          format: date-time

    SubscriptionChargeData:
      type: object
      required: [tenantId, userId, subscriptionId, amount, credits, tier]
      properties:
        tenantId:
          type: string
          format: uuid
        userId:
          type: string
          format: uuid
        subscriptionId:
          type: string
          format: uuid
        amount:
          type: number
        credits:
          type: number
        tier:
          type: string
        billingPeriod:
          type: string

    TicketingPurchaseData:
      type: object
      required: [tenantId, userId, ticketId, eventId, quantity, totalAmount, currency]
      properties:
        tenantId:
          type: string
          format: uuid
        userId:
          type: string
          format: uuid
        ticketId:
          type: string
          format: uuid
        eventId:
          type: string
          format: uuid
        quantity:
          type: number
        totalAmount:
          type: number
        currency:
          type: string
        paymentMethodId:
          type: string
          format: uuid

    BookingDepositData:
      type: object
      required: [tenantId, userId, bookingId, venueId, depositAmount, totalAmount, currency]
      properties:
        tenantId:
          type: string
          format: uuid
        userId:
          type: string
          format: uuid
        bookingId:
          type: string
          format: uuid
        venueId:
          type: string
          format: uuid
        depositAmount:
          type: number
        totalAmount:
          type: number
        currency:
          type: string
        eventDate:
          type: string
          format: date-time

    UserKycData:
      type: object
      required: [tenantId, userId, kycStatus, verificationType]
      properties:
        tenantId:
          type: string
          format: uuid
        userId:
          type: string
          format: uuid
        kycStatus:
          type: string
          enum: [verified, rejected, pending]
        verificationType:
          type: string
          enum: [basic, standard, premium, enterprise]
        verifiedAt:
          type: string
          format: date-time
        rejectionReason:
          type: string

  messages:
    # ── Published Messages ─────────────────────────────────────────────────

    WalletCreated:
      name: WalletCreated
      title: Wallet Created
      summary: A new wallet was created
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/CloudEventEnvelope'
      payload:
        allOf:
          - $ref: '#/components/schemas/CloudEventBase'
          - type: object
            properties:
              type:
                const: com.eventzr.wallet.created
              data:
                $ref: '#/components/schemas/WalletData'

    WalletBalanceUpdated:
      name: WalletBalanceUpdated
      title: Wallet Balance Updated
      summary: Wallet balance changed
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/CloudEventEnvelope'
      payload:
        allOf:
          - $ref: '#/components/schemas/CloudEventBase'
          - type: object
            properties:
              type:
                const: com.eventzr.wallet.balance.updated
              data:
                $ref: '#/components/schemas/WalletData'

    WalletFrozen:
      name: WalletFrozen
      title: Wallet Frozen
      summary: Wallet was frozen
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/CloudEventEnvelope'
      payload:
        allOf:
          - $ref: '#/components/schemas/CloudEventBase'
          - type: object
            properties:
              type:
                const: com.eventzr.wallet.frozen
              data:
                $ref: '#/components/schemas/WalletData'

    WalletClosed:
      name: WalletClosed
      title: Wallet Closed
      summary: Wallet was permanently closed
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/CloudEventEnvelope'
      payload:
        allOf:
          - $ref: '#/components/schemas/CloudEventBase'
          - type: object
            properties:
              type:
                const: com.eventzr.wallet.closed
              data:
                $ref: '#/components/schemas/WalletData'

    TransactionCreated:
      name: TransactionCreated
      title: Transaction Created
      summary: A new transaction was initiated
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/CloudEventEnvelope'
      payload:
        allOf:
          - $ref: '#/components/schemas/CloudEventBase'
          - type: object
            properties:
              type:
                const: com.eventzr.wallet.transaction.created
              data:
                $ref: '#/components/schemas/TransactionData'

    TransactionCompleted:
      name: TransactionCompleted
      title: Transaction Completed
      summary: Transaction completed successfully
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/CloudEventEnvelope'
      payload:
        allOf:
          - $ref: '#/components/schemas/CloudEventBase'
          - type: object
            properties:
              type:
                const: com.eventzr.wallet.transaction.completed
              data:
                $ref: '#/components/schemas/TransactionData'

    TransactionFailed:
      name: TransactionFailed
      title: Transaction Failed
      summary: Transaction failed
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/CloudEventEnvelope'
      payload:
        allOf:
          - $ref: '#/components/schemas/CloudEventBase'
          - type: object
            properties:
              type:
                const: com.eventzr.wallet.transaction.failed
              data:
                $ref: '#/components/schemas/TransactionData'

    RefundCompleted:
      name: RefundCompleted
      title: Refund Completed
      summary: Refund completed successfully
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/CloudEventEnvelope'
      payload:
        allOf:
          - $ref: '#/components/schemas/CloudEventBase'
          - type: object
            properties:
              type:
                const: com.eventzr.wallet.refund.completed
              data:
                $ref: '#/components/schemas/TransactionData'

    RefundFailed:
      name: RefundFailed
      title: Refund Failed
      summary: Refund transaction failed
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/CloudEventEnvelope'
      payload:
        allOf:
          - $ref: '#/components/schemas/CloudEventBase'
          - type: object
            properties:
              type:
                const: com.eventzr.wallet.refund.failed
              data:
                $ref: '#/components/schemas/TransactionData'

    EscrowCreated:
      name: EscrowCreated
      title: Escrow Created
      summary: A new escrow was created and funded
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/CloudEventEnvelope'
      payload:
        allOf:
          - $ref: '#/components/schemas/CloudEventBase'
          - type: object
            properties:
              type:
                const: com.eventzr.wallet.escrow.created
              data:
                $ref: '#/components/schemas/EscrowData'

    EscrowReleased:
      name: EscrowReleased
      title: Escrow Released
      summary: Escrow funds released to payee
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/CloudEventEnvelope'
      payload:
        allOf:
          - $ref: '#/components/schemas/CloudEventBase'
          - type: object
            properties:
              type:
                const: com.eventzr.wallet.escrow.released
              data:
                $ref: '#/components/schemas/EscrowData'

    EscrowRefunded:
      name: EscrowRefunded
      title: Escrow Refunded
      summary: Escrow funds refunded to payer
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/CloudEventEnvelope'
      payload:
        allOf:
          - $ref: '#/components/schemas/CloudEventBase'
          - type: object
            properties:
              type:
                const: com.eventzr.wallet.escrow.refunded
              data:
                $ref: '#/components/schemas/EscrowData'

    PaymentMethodAdded:
      name: PaymentMethodAdded
      title: Payment Method Added
      summary: Payment method added to wallet
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/CloudEventEnvelope'
      payload:
        allOf:
          - $ref: '#/components/schemas/CloudEventBase'
          - type: object
            properties:
              type:
                const: com.eventzr.wallet.payment-method.added
              data:
                $ref: '#/components/schemas/PaymentMethodData'

    PaymentMethodRemoved:
      name: PaymentMethodRemoved
      title: Payment Method Removed
      summary: Payment method removed from wallet
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/CloudEventEnvelope'
      payload:
        allOf:
          - $ref: '#/components/schemas/CloudEventBase'
          - type: object
            properties:
              type:
                const: com.eventzr.wallet.payment-method.removed
              data:
                $ref: '#/components/schemas/PaymentMethodData'

    PaymentMethodVerified:
      name: PaymentMethodVerified
      title: Payment Method Verified
      summary: Payment method passed verification
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/CloudEventEnvelope'
      payload:
        allOf:
          - $ref: '#/components/schemas/CloudEventBase'
          - type: object
            properties:
              type:
                const: com.eventzr.wallet.payment-method.verified
              data:
                $ref: '#/components/schemas/PaymentMethodData'

    SplitCompleted:
      name: SplitCompleted
      title: Split Payment Completed
      summary: All splits in payment completed
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/CloudEventEnvelope'
      payload:
        allOf:
          - $ref: '#/components/schemas/CloudEventBase'
          - type: object
            properties:
              type:
                const: com.eventzr.wallet.split.completed
              data:
                $ref: '#/components/schemas/SplitPaymentData'

    SplitFailed:
      name: SplitFailed
      title: Split Payment Failed
      summary: Split payment failed
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/CloudEventEnvelope'
      payload:
        allOf:
          - $ref: '#/components/schemas/CloudEventBase'
          - type: object
            properties:
              type:
                const: com.eventzr.wallet.split.failed
              data:
                $ref: '#/components/schemas/SplitPaymentData'

    # ── Consumed Messages ──────────────────────────────────────────────────

    ExternalSubscriptionChargePosted:
      name: ExternalSubscriptionChargePosted
      title: Subscription Charge Posted (from subscriptions-svc)
      summary: Subscription charge event from subscriptions-svc
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/CloudEventEnvelope'
      payload:
        allOf:
          - $ref: '#/components/schemas/CloudEventBase'
          - type: object
            properties:
              type:
                const: com.eventzr.subscription.charge.posted
              source:
                const: 'https://eventzr.com/subscriptions-svc'
              data:
                $ref: '#/components/schemas/SubscriptionChargeData'

    ExternalTicketingPurchaseCompleted:
      name: ExternalTicketingPurchaseCompleted
      title: Ticketing Purchase Completed (from ticketing-svc)
      summary: Ticket purchase event from ticketing-svc
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/CloudEventEnvelope'
      payload:
        allOf:
          - $ref: '#/components/schemas/CloudEventBase'
          - type: object
            properties:
              type:
                const: com.eventzr.ticketing.purchase.completed
              source:
                const: 'https://eventzr.com/ticketing-svc'
              data:
                $ref: '#/components/schemas/TicketingPurchaseData'

    ExternalBookingDepositReceived:
      name: ExternalBookingDepositReceived
      title: Booking Deposit Received (from booking-svc)
      summary: Booking deposit event from booking-svc
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/CloudEventEnvelope'
      payload:
        allOf:
          - $ref: '#/components/schemas/CloudEventBase'
          - type: object
            properties:
              type:
                const: com.eventzr.booking.deposit.received
              source:
                const: 'https://eventzr.com/booking-svc'
              data:
                $ref: '#/components/schemas/BookingDepositData'

    ExternalUserKycVerified:
      name: ExternalUserKycVerified
      title: User KYC Verified (from user-svc)
      summary: KYC verification event from user-svc
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/CloudEventEnvelope'
      payload:
        allOf:
          - $ref: '#/components/schemas/CloudEventBase'
          - type: object
            properties:
              type:
                const: com.eventzr.user.kyc.verified
              source:
                const: 'https://eventzr.com/user-svc'
              data:
                $ref: '#/components/schemas/UserKycData'
