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_mdoctransaction-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:
| Field | Type | Description |
|---|---|---|
type | String | Required. 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" |
displayName | String | Human-readable name for this type. Used in UIs and discovery endpoints. Defaults to type if not specified. |
fields | Array | List 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:
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"]
}
]
| Type | Shape | Notes |
|---|---|---|
org.waltid.transaction-data.payment-authorization | Flat fields | walt.id payment demo type |
org.waltid.transaction-data.account-access | Flat fields | Account access demo type |
urn:eudi:sca:payment:1 | Nested payload | EUDI TS-12 SCA payment; amount is a JSON number inside payload |
payment_card | Flat merchant_name, amount | Interop 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:
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.
