> **Description:** Learn how to implement the basic app-to-app login flow where users return directly to your app after authentication.

# Simple Login from a mobile app

In this flow, the user logs in to the merchant's app with  MobilePay or  Vipps. The flow starts with a browser for the initial auth request, and after authentication in the Vipps/MobilePay app, the user is redirected directly back to the merchant app.

Screenshot sequence: App-to-app login flow in five steps -- the merchant's login page with a "Continue with Vipps or MobilePay" button, the Vipps or MobilePay landing page with an "Open app" button, the app loading, a consent screen listing the user's name, phone number, and email with a "Continue" button, and the merchant's home page confirming the user is logged in.

## Overview

The app-to-app flow provides authentication where:

1. The user initiates login from the merchant app
2. A browser opens for the initial auth request
3. The Vipps/MobilePay app opens for authentication
4. The user provides consent within the Vipps/MobilePay app
5. The user is redirected directly back to the merchant app

## The process

App-to-App Flow
```mermaid
flowchart LR
    merchant([Merchant app])
    merchant-- Initiate login -->browser[Browser for initial auth]
    browser-- Open Vipps/MobilePay app -->vmp(["Vipps/MobilePay app"])
    vmp-- User authenticates and consents -->vmp
    vmp-- Direct return to merchant app -->merchant
```

Simple login flow: The merchant app initiates login, opening a browser for initial authentication. The browser opens the Vipps or MobilePay app. The user authenticates and consents within the app. The app then returns the user directly to the merchant app via the redirect_uri.

## Integration

The merchant must specify the app URI where the user will be returned after completing the authentication in the Vipps/MobilePay app.

This flow is enabled by adding the `requested_flow=app_to_app_v2` parameter to the [Authorize](https://developer.vippsmobilepay.com/docs/APIs/login-api/api-guide/browser-flow-integration.md#oauth-20-authorize) request.

**PKCE Required**

This OIDC flow requires **PKCE (Proof Key for Code Exchange)** for enhanced security. PKCE is an OAuth 2.0 security extension that prevents authorization code interception attacks.

- **PKCE Standard**: [RFC 7636](https://tools.ietf.org/html/rfc7636)

**INFO**

For app URIs, we recommend using universal links (Apple)/asset links (Android) instead of custom URL schemes for better security.

The `redirect_uri` should be a URI that makes the device switch back to the merchant's app after the Vipps/MobilePay app portion of the flow is complete (example: `https://example.com/app/callback`).

This URI must be added to the sales unit on the [business portal](https://portal.vippsmobilepay.com). For help, see [Portal: How to set up login on your sales unit](https://developer.vippsmobilepay.com/docs/knowledge-base/portal.md#how-to-set-up-login-for-your-sales-unit).

**Important**

URIs specified on the [business portal](https://portal.vippsmobilepay.com) must be *exactly* the same as used in the API calls. Be extra careful with trailing `/` and URL-encoded entities.

## Sequence diagram

A typical flow/implementation might look like this:

App-to-App Flow Sequence

```mermaid
sequenceDiagram
    autonumber
    participant vmBackend as Vipps MobilePay Backend
    participant merchantBackend as Merchant backend
    participant merchantApp as Merchant app
    participant merchantAppControlledBrowser as Merchant app controlled browser
    participant vmApp as Vipps/MobilePay app

    merchantApp ->> merchantBackend : Initiate login
    merchantBackend ->> merchantApp: Authorize request with app_to_app_v2
    merchantApp ->> merchantAppControlledBrowser : Open authorize request URL
    merchantAppControlledBrowser -->> vmApp : User opens Vipps/MobilePay app in login client
    vmApp -->> vmApp: User authenticates and consents
    vmApp -->> merchantApp : Open redirect_uri with tokens
    merchantApp ->> merchantBackend : Exchange tokens for userinfo
    merchantBackend ->> vmBackend : Get userinfo using tokens
    vmBackend -->> merchantBackend : Userinfo
    merchantBackend ->> merchantApp : Userinfo
```

  Merchant app initiates login with the merchant backend.
  Merchant backend returns an Authorize request with app_to_app_v2 to the merchant app.
  Merchant app opens the Authorize request URL in the merchant app controlled browser.
  Browser opens the Vipps or MobilePay app in the login client.
  User authenticates and consents within the Vipps or MobilePay app.
  Vipps or MobilePay app opens the redirect_uri with tokens directly in the merchant app.
  Merchant app sends the tokens to the merchant backend to exchange for userinfo.
  Merchant backend requests userinfo from Vipps MobilePay Backend using the tokens.
  Vipps MobilePay Backend returns the userinfo to the merchant backend.
  Merchant backend returns the userinfo to the merchant app.

The dotted lines in this diagram are handled by us (or the user), while the filled lines need to be implemented by the merchant.

1. The merchant's backend generates an [OpenID authentication flow authorization URI](https://developer.vippsmobilepay.com/docs/APIs/login-api/api-guide/browser-flow-integration.md#oauth-20-authorize) with `requested_flow=app_to_app_v2`.
2. The URI is communicated to the merchant's app in the API response.
3. The merchant's app uses the URI to initiate Login in an external browser that is opened within the app.
4. Login will open the Vipps/MobilePay app for authentication.
5. The user authenticates and provides consent within the Vipps/MobilePay app.
6. Vipps/MobilePay app opens the deep link `redirect_uri` with authentication tokens.
7. Merchant app receives the tokens and exchanges them for user information.
8. Merchant backend fetches the user information using the received tokens.
9. Login provides user information.
10. Merchant backend delivers user information to merchant app.

## Example authorize request URL

```http
.../oauth2/auth?requested_flow=app_to_app_v2&scope=<scopes>&response_type=code&redirect_uri=https://example.com/app-callback&code_challenge_method=S256&state=<state>&nonce=<nonce>&client_id=<clientid>&code_challenge=<challenge>
```

## Example callback from app

Example success callback from app (step 6):

```http
https://example.com/app-callback?state=218gz18yveu1ybajwh2g1h3g&code=<code>&scope=openid
```

Example error callback from app (step 6):

```http
https://example.com/app-callback?state=218gz18yveu1ybajwh2g1h3g&error=unknown_error
```

## Implementation considerations

### Security

- Use universal links (Apple)/asset links (Android) for better security
- Validate the `state` parameter to prevent CSRF attacks

### User experience

- Provide clear messaging about the authentication process
- Handle error cases gracefully

### Platform-specific considerations

- iOS: Use `ASWebAuthenticationSession` or `SFSafariViewController` for the initial browser interaction
- Android: Use Chrome Custom Tabs for the initial browser interaction
- Ensure proper deep link handling in your app for the callback

## When to use this flow

This simple flow is recommended when you want:

- **Easy implementation** with automatic return to your app
- **Direct handling** of authentication results
- **Minimal configuration** requirements
- **Good user experience** with seamless app switching

## Alternative flows

If this flow doesn't meet your needs, consider these alternatives:

- **[Advanced Login from a mobile app](https://developer.vippsmobilepay.com/docs/APIs/login-api/api-guide/mobile-app-flows/advanced-login.md)** - More complex but supports third-party redirect URIs
- **[Login from a website](https://developer.vippsmobilepay.com/docs/APIs/login-api/api-guide/browser-flow-integration.md)** - Simple implementation, no automatic return

## Migration from legacy flow

If you're currently using the [advanced app-to-app flow](https://developer.vippsmobilepay.com/docs/APIs/login-api/api-guide/mobile-app-flows/advanced-login.md), you can migrate to this flow by:

1. Updating your authorize request to use `requested_flow=app_to_app_v2`
2. Ensuring your implementation uses PKCE (Proof Key for Code Exchange)
3. Simplifying your callback handling by cleaning up any `app_callback_uri` handling which is no longer used.

> **Full site overview:** For every page in this documentation, read [https://developer.vippsmobilepay.com/llms.txt](https://developer.vippsmobilepay.com/llms.txt).
