---
title: "Receiving Credentials via OID4VCI"
description: "Learn how to receive verifiable credentials into the Wallet SDK over OID4VCI 1.0."
stack: "Community Stack (open source) — version 1.1.1"
stack_version: "1.1.1"
stack_comparison: https://docs.walt.id/community-vs-enterprise.md
canonical_url: https://docs.walt.id/community-stack/mobile-wallet/receive-credentials
generated: 2026-10-01
---
# Receiving Credentials via OID4VCI

This guide shows you how to receive a verifiable credential into the walt.id Wallet SDK using [OID4VCI 1.0](https://docs.walt.id/concepts/data-exchange-protocols/openid4vci.md). You hand the wallet a **credential offer** — typically an `openid-credential-offer://` URL from [Portal2](https://portal2.demo.walt.id) — and the wallet claims the credential and stores it.

[**OID4VCI**](https://docs.walt.id/concepts/data-exchange-protocols/openid4vci.md): The protocol used to deliver credentials from an issuer to a wallet.

**Note:**

This page uses **isolated session steps** so you can show issuer, credential, and transaction-code metadata before the holder accepts. The same session APIs work for [SD-JWT VC](https://docs.walt.id/concepts/digital-credentials/sd-jwt-vc.md), [W3C VC](https://docs.walt.id/concepts/digital-credentials/verifiable-credentials-w3c.md), and [ISO 18013-5 mDL](https://docs.walt.id/concepts/digital-credentials/mdoc-mdl-iso.md).

## Prerequisites

Before you begin, ensure you have:

- **A wallet with an active signing identity** — Follow [Integrate the SDK](https://docs.walt.id/community-stack/mobile-wallet/integrate-the-sdk.md).
- **A credential offer** — Create one in [portal2.demo.walt.id](https://portal2.demo.walt.id), or follow an Issuer2 issuance guide such as [SD-JWT VC](https://docs.walt.id/community-stack/issuer2/credential-issuance/sd-jwt-vc.md).

**Note:**

Always test receive through [portal2.demo.walt.id](https://portal2.demo.walt.id).

---

## How Issuance Works

Issuance is a **session**. Start it to resolve the offer and show issuer, credential, and transaction-code metadata. Continue it after the holder accepts — and after they enter a transaction code when the issuer requires one.

```mermaid
sequenceDiagram
    participant App
    participant SDK
    participant Issuer
    App->>SDK: startIssuance offer URL
    SDK->>Issuer: Resolve offer and metadata
    SDK-->>App: Session with display metadata
    App->>App: Holder reviews and accepts
    App->>SDK: continue pre-authorized or authorization code
    SDK->>Issuer: Token, proof, credential
    SDK-->>App: Stored credential IDs
```

1. Start the session with the offer URI (or inline JSON for the [Digital Credentials API](https://docs.walt.id/community-stack/mobile-wallet/digital-credentials-api.md) create flow).
2. Show the typed issuer and credential metadata, and collect a transaction code only when the session requires one.
3. Continue the matching grant, or cancel if the holder declines.

## Pre-authorized Code

Use this path when the offer includes a pre-authorized code.

**Option: Kotlin**

```kotlin
val session = wallet.startIssuance(
    MobileWalletIssuanceRequest(offer = MobileWalletCredentialOffer.Uri(offerUrl))
)
val transactionCode = session.offer.transactionCode?.let { requirement ->
    collectTransactionCode(
        inputMode = requirement.inputMode ?: "numeric",
        expectedLength = requirement.length,
        description = requirement.descriptionText,
    )
}
val outcome = wallet.continuePreAuthorizedIssuance(session.id, transactionCode)
val credentialIds = (outcome as? WalletIssuanceOutcome.Stored)?.credentialIds
    ?: error("Issuance did not store credentials: $outcome")
```

**Option: Swift**

```swift
let session = try await wallet.startIssuance(
    IssuanceRequest(
        offer: credentialOfferURL,
        redirectURI: URL(string: "openid://")!
    )
)
let transactionCode: String?
if let requirement = session.offer.transactionCode {
    transactionCode = await collectTransactionCode(
        inputMode: requirement.inputMode,
        expectedLength: requirement.length,
        description: requirement.descriptionText
    )
} else {
    transactionCode = nil
}
let outcome = try await wallet.continuePreAuthorizedIssuance(
    sessionID: session.id,
    transactionCode: transactionCode
)
```

`MobileWalletCredentialOffer.Uri` is for QR and deep-link offers. Use `MobileWalletCredentialOffer.InlineJson` when the offer arrives through the [Digital Credentials API](https://docs.walt.id/community-stack/mobile-wallet/digital-credentials-api.md) create flow.

🎉 You've received a credential into the wallet.

---

## Authorization Code

For an authorization-code offer, start the session, let the holder accept, then open the authorization URL and continue with the callback. `beginAuthorizationIssuance` creates browser state, PKCE, and the callback binding only after that explicit acceptance.

**Option: Kotlin**

```kotlin
val authorization = wallet.beginAuthorizationIssuance(session.id)
openBrowser(authorization.url)
val outcome = wallet.continueAuthorizationIssuance(session.id, callbackUri)
```

**Option: Swift**

```swift
let authorization = try await wallet.beginAuthorizationIssuance(sessionID: session.id)
await openBrowser(authorization.url)
let outcome = try await wallet.continueAuthorizationIssuance(
    sessionID: session.id,
    callbackURI: callbackURI
)
```

If the holder closes the review without accepting, cancel the session instead of continuing:

```kotlin
wallet.cancelIssuance(session.id)
```

## Deferred Issuance

When the issuer defers credential delivery, continuation returns `WalletIssuanceOutcome.Deferred` instead of `Stored`. Poll with `resumeDeferredIssuance(deferredCredentialId)` until the credential is stored.

## Next Steps

- **Present the credential you just received** — [Presenting Credentials via OID4VP](https://docs.walt.id/community-stack/mobile-wallet/present-credentials.md).
- **Issue through the OS picker** — [Digital Credentials API](https://docs.walt.id/community-stack/mobile-wallet/digital-credentials-api.md).
- **See which holder key signed the proof** — [Keys and Storage](https://docs.walt.id/community-stack/mobile-wallet/keys-and-storage.md).
