Skip to main content

Issue Mortgage Documents to a Personal Wallet

The Story

Imagine Thomas, a software developer who is buying his first apartment in Utrecht for EUR 385,000. To apply for a mortgage, he needs to provide six documents from six different sources: an identity document, a pension overview, a purchase contract, a savings statement, a loan overview, and a student debt statement.

Thomas already has four of these credentials in his personal wallet — his identity document, pension overview, purchase contract, and student debt statement — collected over time from various government and institutional portals. But two are still missing: his savings statement from ING and his loan overview from BKR.

In the old world, Thomas would download PDFs, scan paper statements, and upload files to the bank's portal. But ING and BKR have integrated verifiable credential issuance powered by the Credenco Business Wallet. Thomas visits each portal, a QR code appears, he scans it with his wallet app, and the credential slides in — cryptographically signed, tamper-proof, and instantly verifiable.

The best part? Every institution uses the exact same integration pattern — a single API call. Whether you're a bank, a credit bureau, or any other institution, the process is identical.

This guide shows you how to build that experience.

1
2
3
4
5
6
7
tuliptrustbank.nl/hypotheekTulip Trust BankRequired documents:Identity documentPension overviewPurchase contractStudent debt statementSavings statementLoan overviewProvide documents
My WalletIdentity DocumentPension OverviewPurchase ContractStudent Debt DUO
Thomas has 4 of 6 credentials in his wallet — 2 still missing

How It Works

When issuing a mortgage-related credential to a personal wallet, the flow involves three parties: the issuer's portal (where Thomas interacts), the issuer's backend (which orchestrates the process), and the Credenco Business Wallet (which creates and signs the credential).

The credential holder never needs to install special software beyond a wallet app — the credential lands directly in their wallet via a simple QR code scan.

Key Concepts

ConceptDescription
Personal Wallet AppA mobile app on the user's phone that stores verifiable credentials (e.g., a wallet compliant with the EUDI Wallet standard)
QR CodeThe bridge between the web application and the user's mobile wallet — encodes the credential offer
OpenID4VCIThe open standard protocol used for credential issuance between the wallet app and the Credenco Business Wallet
Correlation IDA business key you provide to track the issuance process and check its status

Sequence Diagram

The diagram below shows the complete interaction between all parties — from the moment Thomas requests a credential to the moment it appears in his wallet. This flow is identical for every credential type.


Step-by-Step Integration

Prerequisites

Before you begin, make sure you have:


Step 1: Start the Credential Issuance

When a user requests a credential from your portal, your backend calls the Start issue Credential API.

Example: Issuing a savings statement credential

Request:

curl -X POST https://your-wallet.credenco.com/api/v2/credential/issue \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"correlation_id": "savings-thomas-2026",
"template_id": "savings_statement",
"claims": {
"bank_name": "ING",
"account_holder": "Thomas van den Berg",
"balance": "47.250",
"balance_date": "2026-03-15"
},
"qr_code": {
"size": 400
}
}'

Tip: The qr_code object is what tells Credenco to generate a QR code for a personal wallet. Without it, the response will contain a deeplink URI instead, suitable for business wallets.

Response:

{
"correlation_id": "savings-thomas-2026",
"request_uri": "openid-credential-offer://?credential_offer_uri=https://your-wallet.credenco.com/openid4vc/credentialOffer?id=a3b7c9d1-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
"status_uri": "https://your-wallet.credenco.com/api/v2/issue/savings-thomas-2026",
"qr_uri": "data:image/png;base64,iVBORw0KGgo..."
}
FieldDescription
correlation_idYour business key to track this issuance
request_uriThe OpenID4VCI credential offer URI (encoded in the QR code)
status_uriEndpoint to poll for status updates
qr_uriBase64-encoded PNG image of the QR code — ready to display

Step 2: Display the QR Code

The qr_uri in the response is a Data URI containing the QR code as a PNG image. Display it directly in your frontend:

<div style="text-align: center; padding: 2rem;">
<h2>Scan this QR code with your wallet app</h2>
<img src="data:image/png;base64,iVBORw0KGgo..." alt="Savings Statement QR Code" />
<p>Open your wallet app and scan the code to receive your savings statement credential.</p>
</div>

Note: The QR code is a one-time use code. Once scanned and the credential is issued, it cannot be reused. Generate a new one for each issuance.


Step 3: The User Scans the QR Code

From Thomas's perspective:

  1. Thomas opens his personal wallet app on his phone
  2. He taps "Scan QR code" (or similar)
  3. The wallet app reads the QR code and contacts the Credenco Business Wallet
  4. The wallet and Credenco exchange the credential using the OpenID4VCI protocol
  5. Thomas sees his new credential in his wallet and accepts it

The issuer's portal doesn't need to do anything during this step — the wallet app and Credenco handle everything automatically.


Step 4: Check the Issuance Status

After the QR code is displayed, your backend can poll the Get issue status API to track progress:

curl https://your-wallet.credenco.com/api/v2/credential/issue/savings-thomas-2026 \
-H "x-api-key: YOUR_API_KEY"

Response (after credential is accepted):

{
"status": "issue_completed",
"correlation_id": "savings-thomas-2026",
"last_updated": 1751155200000,
"revocation_uuid": "7f3a2b1c-9d8e-4f5a-6b7c-8d9e0f1a2b3c"
}
StatusMeaning
issue_request_createdThe credential offer has been created, waiting for the wallet to pick it up
credential_offer_retrievedThe wallet app has retrieved the offer
issue_completedThe credential has been successfully issued and accepted
errorSomething went wrong during the issuance process

Tip: Save the revocation_uuid from the completed response. You'll need it if you ever want to revoke the credential in the future.


Optional: Use Callbacks Instead of Polling

Instead of polling the status endpoint, you can provide a callback URL in the issue request. Credenco will notify your backend automatically when the status changes:

{
"correlation_id": "savings-thomas-2026",
"template_id": "pension_overview",
"claims": { ... },
"qr_code": { "size": 400 },
"callback": {
"url": "https://your-backend.com/webhooks/credential-status",
"status": ["issue_completed", "error"]
}
}

Your callback endpoint will receive a POST request with the status update whenever the issuance completes or fails.


Credential Examples

Each institution issues a different credential type. Below are example claims payloads for each of the six mortgage documents.

Identity Document

Issued by the municipality (e.g., Municipality of Utrecht).

{
"template_id": "identity_document",
"claims": {
"full_name": "Thomas van den Berg",
"date_of_birth": "1994-02-18",
"bsn": "123456789",
"document_number": "IDNLD12345",
"valid_until": "2031-02-18"
}
}

Pension Overview

Issued by the pension overview portal (mijnpensioenoverzicht.nl).

{
"template_id": "pension_overview",
"claims": {
"full_name": "Thomas van den Berg",
"pension_provider": "ABP Pensioenfonds",
"annual_accrual": "2.450",
"total_accrued": "42.150",
"retirement_date": "2059-06-15"
}
}

Purchase Contract

Issued by the notary handling the property sale.

{
"template_id": "purchase_contract",
"claims": {
"property_address": "Oudegracht 42, 3511 AR Utrecht",
"purchase_price": "385000",
"buyer_name": "Thomas van den Berg",
"seller_name": "Maria Jansen",
"signing_date": "2026-03-01"
}
}

Savings Statement

Issued by the applicant's bank (e.g., ING).

{
"template_id": "savings_statement",
"claims": {
"bank_name": "ING",
"account_holder": "Thomas van den Berg",
"balance": "47.250",
"balance_date": "2026-03-15"
}
}

Loan Overview

Issued by BKR (Bureau Krediet Registratie).

{
"template_id": "loan_overview",
"claims": {
"full_name": "Thomas van den Berg",
"total_debt": "2.800",
"monthly_obligations": "150",
"number_of_loans": "1",
"registration_date": "2026-03-10"
}
}

Student Debt Statement

Issued by DUO (Dienst Uitvoering Onderwijs).

{
"template_id": "student_debt_statement",
"claims": {
"full_name": "Thomas van den Berg",
"original_debt": "28.000",
"remaining_debt": "18.500",
"monthly_payment": "185",
"expected_end_date": "2034-09-01"
}
}

Complete Flow at a Glance

1
Issuer Backend
Calls the Issue API with the credential details and requests a QR code

2
Show QR Code
Display the returned QR code in the issuer's portal

3
User Scans
Thomas scans the QR code with his personal wallet app

4
Credential Issued
The wallet and Credenco exchange the credential via OpenID4VCI


API Reference

APIMethodEndpointDescription
Start issue CredentialPOST/api/v2/credential/issueStart the credential issuance and get a QR code
Get issue statusGET/api/v2/credential/issue/{correlationId}Check the status of an issuance process
Revoke CredentialPOST/api/v2/credential/revokeRevoke a previously issued credential

What's Next?

Now that you understand how to issue mortgage credentials to a personal wallet, you might want to explore: