Transaction Data Profiles

transaction-data-profiles.conf defines the transaction data types the verifier and wallet recognize for binding presentations to specific actions (e.g., payment authorization, account access, SCA payment).

Transaction data types act as namespaces that:

  • Enforce which types the wallet will accept in authorization requests
  • Define the structure and fields for UI/discovery endpoints
  • Are validated by the wallet's TransactionDataTypeRegistry
  • Are used as the DeviceSigned namespace for mso_mdoc transaction-data binding

The transaction-data-profiles feature is enabled by default for Verifier2 and backs the runtime discovery endpoint:

GET /transaction-data-profiles

The same profile format is also used by the walt.id Wallet API (see Wallet2 transaction-data profiles)

mDoc issuance grant: For mso_mdoc credentials, registering a type here is not enough for the holder to device-sign it. The credential's MSO must authorize that type via KeyAuthorizations, which Issuer2 sets from the profile field authorizedTransactionDataTypes. SD-JWT VC presentations bind transaction data in the KB-JWT and do not use that field.

Fields

transactionDataProfiles

Array of Objects — List of recognized transaction data types. Each profile defines:

FieldTypeDescription
typeStringRequired. The transaction data type identifier. Used as the type field in transaction data entries and as the namespace for mdoc DeviceSigned binding. Example: "org.waltid.transaction-data.payment-authorization"
displayNameStringHuman-readable name for this type. Used in UIs and discovery endpoints. Defaults to type if not specified.
fieldsArrayList of expected top-level field names for this type. Used for documentation and UI generation. Nested payloads (e.g. SCA) can declare a single container field such as ["payload"].

Built-in Profiles

The default configuration includes:

transaction-data-profiles.conf
transactionDataProfiles = [
  {
    type = "org.waltid.transaction-data.payment-authorization"
    displayName = "Payment Authorization"
    # Android Credential Manager matcher reads merchant_name and amount for generic payment entries.
    fields = ["merchant_name", "amount", "currency"]
  },
  {
    type = "org.waltid.transaction-data.account-access"
    displayName = "Account Access"
    fields = ["account_identifier", "access_scope"]
  },
  {
    # EUDI TS-12 SCA payment type. Payload nests, so the matcher reads
    # payload.payee.name, payload.currency and payload.amount rather than flat fields.
    type = "urn:eudi:sca:payment:1"
    displayName = "SCA Payment"
    fields = ["payload"]
  },
  {
    # Interop identifier used by some OpenID4VP payment-card verifiers. Prefer a
    # collision-resistant type for new deployments.
    type = "payment_card"
    displayName = "Payment Card"
    fields = ["merchant_name", "amount"]
  }
]
TypeShapeNotes
org.waltid.transaction-data.payment-authorizationFlat fieldswalt.id payment demo type
org.waltid.transaction-data.account-accessFlat fieldsAccount access demo type
urn:eudi:sca:payment:1Nested payloadEUDI TS-12 SCA payment; amount is a JSON number inside payload
payment_cardFlat merchant_name, amountInterop identifier used by some OpenID4VP payment-card verifiers. Prefer a collision-resistant type for new deployments. amount may be a combined string such as "EUR 200.00".

Discovery

The transaction-data-profiles feature is enabled by default and loads transaction-data-profiles.conf. Community Verifier2 exposes that HOCON list at:

GET /transaction-data-profiles

Community Verifier2 does not expose GET /transaction-data-profiles/{type} or create, replace, or delete. Session create uses structure-only validation: it checks transaction_data shape and DCQL binding, and does not apply a type allowlist. The Wallet2 type registry still rejects unknown transaction_data.type values when that feature is enabled.

Runtime overlay mutations are not exposed on Community Verifier2. Durable types live in transaction-data-profiles.conf. Per-service create, replace, delete, and session-create type enforcement live on Enterprise Wallet2 and Verifier2.

Wallet API v1 exposes GET /transaction-data-profiles only.

Adding Custom Types

To add a custom transaction data type, add a new entry to the transactionDataProfiles array in both config files and restart:

  • Verifier: waltid-services/waltid-verifier-api2/config/transaction-data-profiles.conf
  • Wallet: waltid-services/waltid-wallet-api2/config/transaction-data-profiles.conf

For mDoc holders that must device-sign the type, also list it on the Issuer2 profile as authorizedTransactionDataTypes

Example: Adding a subscription authorization type:

transaction-data-profiles.conf
transactionDataProfiles = [
  {
    type = "org.waltid.transaction-data.payment-authorization"
    displayName = "Payment Authorization"
    fields = ["merchant_name", "amount", "currency"]
  },
  {
    type = "org.waltid.transaction-data.account-access"
    displayName = "Account Access"
    fields = ["account_identifier", "access_scope"]
  },
  {
    type = "urn:eudi:sca:payment:1"
    displayName = "SCA Payment"
    fields = ["payload"]
  },
  {
    type = "org.example.subscription-authorization"
    displayName = "Subscription Authorization"
    fields = ["service_name", "billing_cycle", "price"]
  }
]

Important: Transaction data types must be configured on both the verifier and wallet. Mismatched configurations will cause the wallet to reject authorization requests with unknown types.

Usage in Verification Requests

Once configured, use the type in your verification session transaction data.

Flat walt.id payment type:

{
  "flow_type": "cross_device",
  "core_flow": {
    "dcql_query": { "...": "..." }
  },
  "openid": {
    "transactionData": [
      {
        "type": "org.waltid.transaction-data.payment-authorization",
        "credential_ids": ["pid"],
        "require_cryptographic_holder_binding": true,
        "transaction_data_hashes_alg": ["sha-256"],
        "merchant_name": "ACME Corp",
        "amount": "42.00",
        "currency": "EUR"
      }
    ]
  }
}

Nested SCA payment type:

{
  "openid": {
    "transactionData": [
      {
        "type": "urn:eudi:sca:payment:1",
        "credential_ids": ["sca_payment_card"],
        "require_cryptographic_holder_binding": true,
        "transaction_data_hashes_alg": ["sha-256"],
        "payload": {
          "transaction_id": "8D8AC610-566D-4EF0-9C22-186B2A5ED793",
          "payee": {
            "name": "Super Store",
            "id": "merchant-001"
          },
          "currency": "EUR",
          "amount": 11.56
        }
      }
    ]
  }
}

See Transaction Data Authorization for complete usage details.

Last updated on August 24, 2026