|
| 1 | +# Message Formats on the Mobile ID App |
| 2 | + |
| 3 | +Mobile ID App screens can present the Data‑To‑Be‑Displayed (DTBD) in two formats. |
| 4 | + |
| 5 | +Use Classic DTBD for short confirmations and when you must support SIM users. Keep messages concise and always include the "DTBD Prefix" (refer to chapter Error! Reference source not found.). |
| 6 | + |
| 7 | +Use Transaction Approval when readability matters (e.g., PSD2 payments, contract consent, step up login verification). Force the App method with Device LoA4, keep within byte limits, and generate the escaped JSON programmatically. |
| 8 | + |
| 9 | +1. **Classic DTBD** (single text line) uses plain UTF‑8 string that is also signed (DTBS). |
| 10 | + |
| 11 | + Supported by SIM and App methods. |
| 12 | + |
| 13 | + Length limited and no formatting options. |
| 14 | + |
| 15 | +  |
| 16 | + |
| 17 | + |
| 18 | +2. **Transaction Approval** (key/value pairs) is a structured App‑only format that renders a title (type) and one or more key and value rows for improved readability. |
| 19 | + |
| 20 | + Approve/Cancel becomes active only after the user scrolls to the end if content exceeds one screen. |
| 21 | + |
| 22 | + RPs request this by sending a JSON object in the dtbd authorization parameter. |
| 23 | + |
| 24 | +  |
| 25 | + |
| 26 | + |
| 27 | +## Classic DTBD |
| 28 | + |
| 29 | +A single UTF‑8 string shown on the device. The classic DTBD must include the AP‑specific DTBD prefix (e.g., Bank ACME:) and is supported by both SIM and App methods. |
| 30 | + |
| 31 | +Keep the DTBD short. Maximum 239 characters; if any character falls outside the GSM 03.38 set, effective maximum is 119 characters. |
| 32 | + |
| 33 | +Parameter: `dtbd` with a plain string. The OP renders the classic one-line message. |
| 34 | + |
| 35 | +Typical request excerpt: |
| 36 | + |
| 37 | +```bash |
| 38 | + |
| 39 | +...&dtbd=Please%20confirm%20your%20login%20to%20MyBank%20eBanking |
| 40 | + |
| 41 | +``` |
| 42 | + |
| 43 | + |
| 44 | +## Transaction Approval |
| 45 | + |
| 46 | +A structured DTBD that the Mobile ID App renders as a title and rows of key/value pairs. If content overflows, the user must scroll to the bottom; only then are Approve/Cancel enabled. |
| 47 | + |
| 48 | +SIM does not support this format. Always select an App ACR (e.g., `mid_al3_mobileapp`). |
| 49 | + |
| 50 | +How to request it: Send a JSON object via the `dtbd` authorization request parameter; the value must be URL-encoded (percent-encoding). If the decoded value starts with `{` and validates against the schema/limits below and the user has an active App, the OP renders the key/value screen. |
| 51 | + |
| 52 | +```json |
| 53 | +{ |
| 54 | + "type": "<ascii>", |
| 55 | + "dtbd": [ |
| 56 | + { "key": "<ascii>", "value": "<ascii>" } |
| 57 | + /* up to 20 pairs */ |
| 58 | + ] |
| 59 | +} |
| 60 | +``` |
| 61 | + |
| 62 | +Limits (in bytes): |
| 63 | + |
| 64 | +- `type` ≤ 100 |
| 65 | +- ≤ 20 pairs |
| 66 | +- each `key` ≤ 100, each `value` ≤ 2000 |
| 67 | +- sum(keys+values) ≤ 2000 (bytes; non-ASCII uses 2–4 bytes) |
| 68 | +- DTBD Prefix (required): your configured prefix must be in the value of the first pair |
| 69 | + e.g., `{"key":"Company","value":"Acme AG: ..."}` |
| 70 | + |
| 71 | +## Transaction Approval Example |
| 72 | + |
| 73 | +### Pretty JSON |
| 74 | + |
| 75 | +Build this first. |
| 76 | + |
| 77 | +```json |
| 78 | +{ |
| 79 | + "type": "Address Change Confirmation", |
| 80 | + "dtbd": [ |
| 81 | + { "key": "Company", "value": "Acme AG" }, |
| 82 | + { "key": "Full Name", "value": "Philipp Haupt" }, |
| 83 | + { "key": "Old Address", "value": "Bahnhofstrasse 1, 8001 Zürich" }, |
| 84 | + { "key": "New Address", "value": "Sihlquai 55, 8005 Zürich" }, |
| 85 | + { "key": "Effective Date", "value": "01 June 2025" }, |
| 86 | + { "key": "Consent Instruction", "value": "Reply APPROVE to consent or CANCEL" } |
| 87 | + ] |
| 88 | +} |
| 89 | + |
| 90 | +``` |
| 91 | + |
| 92 | +### Single-line |
| 93 | + |
| 94 | +What you URL-encode as `dtbd=` |
| 95 | + |
| 96 | +```json |
| 97 | +{"type":"Address Change Confirmation","dtbd":[{"key":"Company","value":"Acme AG"},{"key":"Full Name","value":"Philipp Haupt"},{"key":"Old Address","value":"Bahnhofstrasse 1, 8001 Zürich"},{"key":"New Address","value":"Sihlquai 55, 8005 Zürich"},{"key":"Effective Date","value":"01 June 2025"},{"key":"Consent Instruction","value":"Reply APPROVE to consent or CANCEL"}]} |
| 98 | + |
| 99 | +``` |
| 100 | +Below is another example that includes the keywords #CLIENT# and #SESSION#, as described in section 2.2. |
| 101 | + |
| 102 | +```bash |
| 103 | +{"type":"LOGIN","dtbd":[{"key":"Company","value":"#CLIENT#"},{"key":"Session","value":"#SESSION#"}]} |
| 104 | + |
| 105 | +``` |
| 106 | + |
| 107 | +### Authorization request (excerpt) |
| 108 | + |
| 109 | +Use PAR to avoid URL length limits and keep parameters confidential. |
| 110 | +Or pass `dtbd` directly on the authorize URL: |
| 111 | + |
| 112 | +```http |
| 113 | +GET /oidc/authorize? |
| 114 | + response_type=code |
| 115 | + &scope=openid |
| 116 | + &client_id=YOUR_CLIENT_ID |
| 117 | + &state=... |
| 118 | + &redirect_uri=https%3A%2F%2Fclient.example%2Fcb |
| 119 | + &acr_values=mid_al3_mobileapp |
| 120 | + &dtbd=%7B%22type%22%3A%22Address%20Change%20Confirmation%22%2C%22dtbd%22%3A%5B%7B%22key%22%3A%22Company%22%2C%22value%22%3A%22Acme%20AG%22%7D%2C...%5D%7D |
| 121 | +``` |
| 122 | + |
| 123 | +Important: Request an App ACR (e.g., `mid_al3_mobileapp`) if you want to ensure the App method is selected. |
| 124 | + |
| 125 | +## What exactly is signed (classic vs. Transaction Approval) |
| 126 | + |
| 127 | +Classic DTBD: the service signs the visible text string. |
| 128 | + |
| 129 | +Transaction Approval: the App signs a normalized JSON object of the form: |
| 130 | + |
| 131 | +```json |
| 132 | +{"format_version":1,"content_string":"[{\"key\":\"Company\",\"value\":\"Test\"}]"} |
| 133 | +``` |
| 134 | + |
| 135 | +i.e., the `dtbd` array only; the `type` label is not part of the signed bytes. |
| 136 | + |
| 137 | +## Best practices |
| 138 | + |
| 139 | +- Build → URL-encode → send: generate the JSON with your library, then URL-encode as `dtbd`. Avoid hand-crafted strings. (Use PAR for large payloads/confidentiality.) |
| 140 | +- Select App method: use `acr_values` (e.g., `mid_al3_mobileapp`) when you want to ensure App UX. |
| 141 | +- Prefix rule: include your DTBD prefix in the value of the first pair. |
| 142 | +- Respect byte limits: limits are in bytes, not characters; UTF-8 non-ASCII uses 2–4 bytes. |
| 143 | +- Number-matching & keywords: `#SESSION#` and `#CLIENT#` keywords are supported in `type`, `key`, or `value` and can be used to implement number matching. |
0 commit comments