Skip to main content

Merchant-initiated login

In this flow, a merchant's system or machine triggers a MobilePay or Vipps login.

This supports special cases where there is no browser or app. For example:

  • Log-in directly from merchant systems (e.g. point of sales systems or call-center solutions) based on phone number
  • Log-in directly from machines and vending machines based on phone number

This is available for all Login-enabled clients, but to ensure a consistent user experience, this flow is not allowed on webpages and in apps; thus, log-in can't be done in the user's browser.

The process

In this flow, the merchant's system triggers the authentication/registration using the user's mobile number..

login process

This triggers a push message from the user's Vipps or MobilePay app. By clicking the push message, the user is taken to their Vipps or MobilePay app to confirm the authentication/registration.

note

If the user hasn't enabled push from Vipps or MobilePay, they need to manually open the app and possibly pull the home screen down for a refresh to receive the authentication request.

If the user hasn't already consented to share information with a merchant, such consent will be required.

The merchant controls whether the user should get the confirmation of completion in the Vipps or MobilePay app. For example:

Confirm completion in Vipps or MobilePay app

Alternatively, the merchant may redirect the user to the merchant's web page to finalize the flow (e.g., enable input of more information, accept terms and conditions, log the user in at their web page, show relevant information/offers or to continue to set up an agreement or completing a purchase). For example:

Redirect to browser

For more illustrations, see How it works: Merchant-initiated login.

To get help with this from a partner, go to Find a partner and select the Customer Club in store solution.

Customization

Merchants can customize the login flow to suit their specific needs. Here are the available options:

  • Binding message: As a security measure you can add a simple message or identifier that will help the user verify that they're accepting the correct login by seeing the message on both devices.
  • Redirect to browser: Redirect users to a website once the login is successfully completed.
  • Marketing consents: Use this extra step to collect consents needed for enrolling customers in your loyalty program.
  • Merchant-initiated login texts: Select between different texts that we will display to the user during the flow.

Tailor the flow to fit your use case and create a seamless experience for your customers!

Complete login in the Vipps or MobilePay app

Overview

This flow is based on the Client-Initiated Backchannel Authentication (CIBA) standard. CIBA enables a Client to initiate the authentication of an end-user through out-of-band mechanisms.

  1. The Client shall make an "HTTP POST" request to the Backchannel Authentication Endpoint to ask for end-user authentication.
  2. Login will respond immediately with a unique identifier that identifies that authentication while it tries to authenticate the user in the background.
  3. The Client will receive the ID Token and Access Token by polling the token endpoint to get a response with the tokens.

Call by call

  1. Before all this, the merchant has fetched the OpenID configuration from the well-known endpoint and cached it. See .well-known

  2. The merchant initiates a login by calling the backchannel_authentication_endpoint listed in the OpenID configuration (fetched in the previous step).

    For details see Authentication Request.

    Example request:

    POST https://api.vipps.no/vipps-login-ciba/api/backchannel/authentication
    Authorization: Basic asdkjhasdjhsad=
    Content-Type: application/x-www-form-urlencoded

    scope=name address openid&login_hint=urn:msisdn:{msisdn}&state=13821s837213bng26e2n61gege26&nonce=21hebdhwqdb7261bd1b23

    Example response:

    200 application/json
    {
    "auth_req_id": "VYGaaAMRkI6SyAm_uIywhxsN2K0",
    "expires_in": 600,
    "interval": 5
    }

    The interval returned is the minimum amount of time (in seconds) that the client must wait between polling requests to the token endpoint. Polling in this context means doing repeated HTTP requests with a delay between them.

  3. The merchant starts polling the token endpoint listed in the OpenID configuration (fetched in step 0). Note that the polling interval should not exceed the interval response parameter (in seconds) returned in the previous step.

    Example request:

    POST https://api.vipps.no/access-management-1.0/access/oauth2/token
    Authorization: Basic asdkjhasdjhsad=
    Content-Type: application/x-www-form-urlencoded

    grant_type=urn%3Aopenid%3Aparams%3Agrant-type%3Aciba&auth_req_id=VYGaaAMRkI6SyAm_uIywhxsN2K0

    Example pending response (Other possible error responses can be found in the CIBA standard):

    HTTP/1.1 400 Bad Request
    Content-Type: application/json;charset=UTF-8
    {
    "error": "authorization_pending",
    "error_description": "The authorization request is still pending"
    }

    The merchant should keep polling when it receives authorization_pending in the error response. After the user completes the login in the app, the token endpoint will give a successful response similar to the following example:

    HTTP/1.1 200 OK
    Content-Type: application/json;charset=UTF-8
    {
    "access_token": "ciba.W_IfBcSr-askdjhsakjhd",
    "token_type": "Bearer",
    "expires_in": 300,
    "id_token": "eyaksjdhksajhdjkashdjksadjnn91283hedhn.eyasdkjhaskjdhskajhdkjhasdkjhaskjhdwqiuh"
    }
  4. The merchant must do a GET to the userinfo endpoint with the header: Authorization: Bearer {access_token}, using the access_token retrieved in step 2.

    For details see Userinfo request.

    Example request:

    GET https://api.vipps.no/vipps-userinfo-api/userinfo
    Authorization: Bearer ciba.W_IfBcSr-askdjhsakjhd

    Example response:

    HTTP/1.1 200 OK
    {
    "address": {
    "address_type": "home",
    "country": "NO",
    "formatted": "jghj khhjhhkjh\n0603\nOSLO\nNO",
    "postal_code": "0603",
    "region": "OSLO",
    "street_address": "jghj khhjhhkjh"
    },
    "family_name": "Heyerdahl",
    "given_name": "Tor Fos",
    "name": "Tor Fos Heyerdahl",
    "other_addresses": [],
    "sid": "qwieuhwqiuhdiuwqh",
    "sub": "f350ef33-22e2-47d0-9f47-12345667"
    }

Authentication request

Standard definition: https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#auth_request

The Backchannel Authentication Endpoint is listed as backchannel_authentication_endpoint in the configuration https://api.vipps.no/access-management-1.0/access/.well-known/openid-configuration.

Authentication

The following authentication methods are currently supported:

  • client_secret_basic
  • client_secret_post

The default token endpoint authentication method is client_secret_basic. It's possible to change the authentication method to client_secret_post through portal.vippsmobilepay.com. See: FAQ: How can I use client secret post for authentication.

The parameters are as follows:

ParameterDescription
login_hint (required)The login_hint parameter includes two supported formats: one for mobile phone numbers and another for customer tokens. See login_hint.
scope (required)Supported scopes. See scope.
binding_message (optional)A human-readable identifier. See binding_message.
requested_expiry (optional)The requested expiration time. See requested_expiry.

See sections below for more information.

The login_hint parameter (required)

Supported login hints:

  • Mobile phone numbers can be targeted by passing login hint as an MSISDN.

    Login hint format: login_hint=urn:msisdn:{msisdn}

    Example: ...&login_hint=urn:msisdn:4712345678&....

  • Customer token. This is supplied in the QR checked in webhook

    Login hint format: login_hint=urn:customer-token:{customerToken}

    Example: ...&login_hint=urn:customer-token:ezakjsedhiuqwhiuhd...

The scope parameter (required)

  • We support the scopes listed at Scopes
  • The legacy nnin scope is not supported, use nin instead.

Example: ...&scope=name address birthDate nin&...

The binding_message parameter (optional)

A human-readable identifier or message intended to be displayed on both the consumption device and the authentication device to interlock them together for the transaction by way of a visual cue for the end-user. It should not be used for attempting to conveying other information.

The format possible for this field is limited to capital characters 'A-Z', numbers '0-9' and the character '-'. It must also be between 5 and 8 characters long. Regex: ^[A-Z0-9\\-]{5,8}$.

Read more about it in the Client-Initiated Backchannel Authentication Request.

Example: ....&binding_message=4MZ-CQ3&...

Optional confirmation code (binding_message)

The requested_expiry parameter (optional)

A positive integer representing the requested expiration time, in seconds, for the authentication. This will set the maximum time the authentication request is valid. The default value typically corresponds to ~10-15 minutes. Minimum is 60 seconds. Maximum is 900 seconds.

Responses

Successful responses

Standard definition: OpenID Connect Client-Initiated Backchannel Authentication Flow: Successful Authentication Request Acknowledgement

Responses according to the standard. Note, we do return an interval parameter which indicates the minimum amount of time in seconds that the Client MUST wait between polling requests to the token endpoint.

Token request

Standard definition: OpenID Connect Client-Initiated Backchannel Authentication Flow: Token Request Using CIBA Grant Type

The responses from this endpoint is according to the standard.

  • Note the required grant_type: urn:openid:params:grant-type:ciba.
  • The access token can be used towards the standard OIDC userinfo endpoint.

Polling

Error responses

In addition to the responses defined by the standard these responses might be returned:

  • 429 status responses: Too many login requests started towards the same user at the same time. Please respect the Retry-After header returned.
  • error_code=old_app: The user's Vipps or MobilePay app is outdated and does not support this login flow.
  • error_code=invalid_user: No account exists, the user's account is not active, or the user is in some way not eligible to use this login flow currently e.g. U15 users.

Redirect to browser

Overview

This CIBA-related flow enables a Client to initiate the authentication of an end-user through out-of-band mechanisms and additionally facilitates the end user to be taken to the client's web page to finalize the flow.

  1. The Client shall make an "HTTP POST" request to the Backchannel Authentication Endpoint to ask for end-user authentication.
  2. The user, via their browser, will be redirected to the Client's redirect_uri which enables the login to be completed.

Redirect-to-browser flow

Call by call

  1. Before all this, the merchant has fetched the OpenID configuration from the well-known endpoint and cached it. See .well-known.

  2. The merchant initiates a login by calling the backchannel_authentication_endpoint listed in the OpenID configuration (fetched in the previous step).

    For details see Authentication Request With Redirect.

    Example request (the real payload will likely look different because of encoding):

    POST https://api.vipps.no/vipps-login-ciba/api/backchannel/authentication
    Authorization: Basic asdkjhasdjhsad=
    Content-Type: application/x-www-form-urlencoded

    requested_flow=login_to_webpage&scope=openid name address&login_hint=urn:msisdn:{msisdn}&redirect_uri=https://merchantwebpage.com/callback

    Example response, the auth_req_id should be used to connect this login to a token response since the ID token should contain the same auth_req_id value.

    200 application/json
    {
    "auth_req_id": "VYGaaAMRkI6SyAm_uIywhxsN2K0",
    "expires_in": 600,
    "interval": 5
    }

    The interval returned is the minimum amount of time (in seconds) that the client must wait between polling requests to the token endpoint.

  3. The user confirms the login and is then redirected to the redirect_uri passed in the initial request 1. The redirect will contain a code: {redirect_uri}?code={code}.

  4. The merchant uses the code-parameter to obtain the login token. Perform a POST request towards the {token_endpoint} with code={code}, grant_type=urn:vipps:params:grant-type:ciba-redirect in the application/x-www-form-urlencoded-body. This returns an ID token and an access token that can be used to fetch userinfo. The ID token is a JWS that must be validated, see ID Token. The merchant must validate that it contains the auth_req_id they have previously received from step 1.

    Example request (the real payload will likely look different because of encoding):

    POST https://api.vipps.no/access-management-1.0/access/oauth2/token
    Authorization: Basic sadlksadkjasjdaksd
    Content-Type: application/x-www-form-urlencoded

    code=some-valid-code&grant_type=urn:vipps:params:grant-type:ciba-redirect

    Example response:

    {
    "access_token": "hel39XaKjGH5tkCvIENGPNbsSHz1DLKluOat4qP-A4.WyV61hCK1E2snVs1aOvjOWZOXOayZad0K-Qfo3lLzus",
    "id_token": "eyJraWQiOiJwdWJsaWM6ZWUzNmQzZjUtMzkzNC00MDI5LTkyNmYtNzdmYTY1YmYwYjRiIiwiYWxnIjoiRVMyNTYifQ.eyJhdWQiOiJlZGRkYjMyZi01MDI4LTQzOTctYjBhYi1lOGVjZjIxOGZkYzIiLCJzdWIiOiI1MTY4ZWUwNi04NzFlLTQ2ZTYtOTQxZS0wMTAzYjk1NzA0OGUiLCJhdXRoUmVxSWQiOiI3QnpBWS1TYlZRSjM4Vi1VMEM3WjZrMjNfQ1kiLCJpc3MiOiJodHRwczpcL1wvZWNlNDZlYzQtNmY5Yy00ODliLThmZTUtMTQ2YTg5ZTExNjM1LnRlY2gtMDIubmV0XC9hY2Nlc3MtbWFuYWdlbWVudC0xLjBcL2FjY2Vzc1wvIiwiZXhwIjoxNjQzMTc5ODM3LCJpYXQiOjE2NDMxNzkyMzd9.iFvmdtRQVliAe91dBu_CZDfBD5I7WCbDTiDQxu4sOTApXFPb5EsSuEBEVfK_-14E7xjcfQLSMa6ZO06YvhRHAA",
    "expires_in": 3599,
    "scope": "openid",
    "token_type": "bearer"
    }

    Decoded ID token JWS example:

    Header

    {
    "kid": "public:ee36d3f5-3934-4029-926f-77fa65bf0b4b",
    "alg": "ES256"
    }

    Payload

    {
    "aud": "edddb32f-5028-4397-b0ab-e8ecf218fdc2",
    "sub": "5168ee06-871e-46e6-941e-0103b957048e",
    "auth_req_id": "7BzAY-SbVQJ38V-U0C7Z6k23_CY",
    "iss": "https://ece46ec4-6f9c-489b-8fe5-146a89e11635.tech-02.net/access-management-1.0/access/",
    "exp": 1643179837,
    "iat": 1643179237
    }
  5. The merchant must do a GET to the userinfo endpoint with the header: Authorization: Bearer {access_token}, using the access_token retrieved in step 3.

    For details see Userinfo request.

    Example request:

    GET https://api.vipps.no/vipps-userinfo-api/userinfo
    Authorization: Bearer W_IfBcSr-askdjhsakjhdasdfgg

    Example response:

    HTTP/1.1 200 OK
    {
    "address": {
    "address_type": "home",
    "country": "NO",
    "formatted": "jghj khhjhhkjh\n0603\nOSLO\nNO",
    "postal_code": "0603",
    "region": "OSLO",
    "street_address": "jghj khhjhhkjh"
    },
    "family_name": "Heyerdahl",
    "given_name": "Tor Fos",
    "name": "Tor Fos Heyerdahl",
    "other_addresses": [],
    "sid": "qwieuhwqiuhdiuwqh",
    "sub": "f350ef33-22e2-47d0-9f47-12345667"
    }

Authentication request with redirect

The Backchannel Authentication Endpoint is listed as backchannel_authentication_endpoint in the configuration https://api.vipps.no/access-management-1.0/access/.well-known/openid-configuration.

Authentication

Same as authentication request without redirect with the addition of redirect_uri, which is the redirect URL that the user agent is redirected to after finishing a login. It must be https in the production environment. Example: ...&redirect_uri=https://merchant.com/callback&...

Error responses

Same as authentication request without redirect

Webhook events

To avoid frequent polling of the token endpoint, register a webhook to be notified via a login.merchant-initiated.ping.v1 event when a login is completed.

The payload will contain:

NameTypeDescription
auth_req_idStringThe auth_req_id that identifies the login.

Example:

{
"auth_req_id": "qwieuhwqiuhdiuwqh123"
}

We support up to 25 webhook registrations per sales unit (MSN) for each event type.

Call by call

  1. The merchant subscribes to the login.merchant-initiated.ping.v1 event.
  2. The merchant initiates a login by calling the backchannel_authentication_endpoint.
  3. The user confirms the login.
  4. The merchant receives a webhook event with the auth_req_id that identifies the login.
  5. The merchant calls the token endpoint to get the tokens.
Redirect to browser flow is not supported

Although the Redirect to browser flow also allows for receiving webhook notifications for logins, it has a key limitation:

  • The token endpoint can be called only once per authentication. Doing the token exchange based on the webhook will prevent doing the token exchange based on the browser redirect which might not be intended.

Merchant-initiated login marketing consents

If you are just starting out, review the Marketing consents section.

Overview

For Client-Initiated Backchannel Authentication (CIBA), it's possible to initiate the authentication of an end-user through out-of-band mechanisms and collect consents on behalf of the merchant.

  1. The Client shall make an "HTTP POST" request to the Backchannel Authentication Endpoint with scope delegatedConsents to ask for end-user authentication and on behalf of the merchant consents.
  2. Login will respond immediately with a unique identifier that identifies that authentication while it tries to authenticate the user in the background, along with collecting consents.
  3. The Client will receive the ID Token and Access Token by polling the token endpoint to get a response with the tokens.
  4. Token can be used by the Client to retrieve information about the user through the userinfo endpoint, this response will also contain the consents that are approved/declined by the user.

Requesting on behalf consents for merchant is also available for redirect to browser, by adding scope delegatedConsents to the initial request (1).

Call by call

  1. Before all this, the merchant has fetched the OpenID configuration from the well-known endpoint and cached it. See .well-known

  2. The merchant initiates a login by calling the backchannel_authentication_endpoint listed in the OpenID configuration (fetched in the previous step). Use scope delegatedConsents.

    For details see Authentication Request.

    Example request:

    POST https://api.vipps.no/vipps-login-ciba/api/backchannel/authentication
    Authorization: Basic asdkjhasdjhsad=
    Content-Type: application/x-www-form-urlencoded

    scope=name delegatedConsents openid&login_hint=urn:msisdn:{msisdn}&state=13821s837213bng26e2n61gege26&nonce=21hebdhwqdb7261bd1b23

    Example response:

    200 application/json
    {
    "auth_req_id": "VYGaaAMRkI6SyAm_uIywhxsN2K0",
    "expires_in": 600,
    "interval": 5
    }

    The interval returned is the minimum amount of time (in seconds) that the client must wait between polling requests to the token endpoint.

  3. The merchant starts polling the token endpoint listed in the OpenID configuration (fetched in step 0). Note that the polling interval should not exceed the interval response parameter (in seconds) returned in the previous step.

    Polling in this context means doing repeated HTTP requests with a delay between them.

    Example request:

    POST https://api.vipps.no/access-management-1.0/access/oauth2/token
    Authorization: Basic asdkjhasdjhsad=
    Content-Type: application/x-www-form-urlencoded

    grant_type=urn%3Aopenid%3Aparams%3Agrant-type%3Aciba&auth_req_id=VYGaaAMRkI6SyAm_uIywhxsN2K0

    Example pending response (Other possible error responses can be found in the CIBA standard):

    HTTP/1.1 400 Bad Request
    Content-Type: application/json;charset=UTF-8
    {
    "error": "authorization_pending",
    "error_description": "The authorization request is still pending"
    }

    The merchant should keep polling when it receives authorization_pending in the error response. After the user completes the login in the app, the token endpoint will give a successful response similar to the following example:

    HTTP/1.1 200 OK
    Content-Type: application/json;charset=UTF-8
    {
    "access_token": "ciba.W_IfBcSr-askdjhsakjhd",
    "token_type": "Bearer",
    "expires_in": 300,
    "id_token": "eyaksjdhksajhdjkashdjksadjnn91283hedhn.eyasdkjhaskjdhskajhdkjhasdkjhaskjhdwqiuh"
    }
  4. The merchant must do a GET to the userinfo endpoint with the header: Authorization: Bearer {access_token}, using the access_token retrieved in step 2.

    For details see Userinfo request.

    Example request:

    GET https://api.vipps.no/vipps-userinfo-api/userinfo
    Authorization: Bearer ciba.W_IfBcSr-askdjhsakjhd

    Example response:

    HTTP/1.1 200 OK
    {
    "family_name": "Heyerdahl",
    "given_name": "Tor Fos",
    "name": "Tor Fos Heyerdahl",
    "other_addresses": [],
    "sid": "qwieuhwqiuhdiuwqh",
    "sub": "f350ef33-22e2-47d0-9f47-12345667"
    "delegatedConsents" : {
    "language" : "EN",
    "heading" : "Give consent",
    "text" : "oidc-testclient wants to send you relevant offers through their digital channels.",
    " termsDescription" : "By confirming, you accept oidc-testclient's terms of membership. They are responsible for processing the consents. You can withdraw them at any time on their website.",
    "confirmConsentButtonText" : "Confirm",
    "links" : {
    "termsLinkText" : "Read the terms of use.",
    "termsLinkUrl" : "http://vippsmobilepay.com/legal/terms-and-conditions",
    "privacyStatementLinkText" : "Read the privacy policy.",
    "privacyStatementLinkUrl" : "https://vippsmobilepay.com/privacy-notice"
    },
    "timeOfConsent" : "2022-11-23T11:40:13Z",
    "consents" : [ {
    "id" : "email",
    "accepted" : true,
    "required" : true,
    "textDisplayedToUser" : "Receive offers via email"
    }, {
    "id" : "sms",
    "accepted" : true,
    "required" : false,
    "textDisplayedToUser" : "Receive offers via SMS"
    }, {
    "id" : "digital",
    "accepted" : true,
    "required" : false,
    "textDisplayedToUser" : "I would like to receive digital marketing"
    }, {
    "id" : "personal",
    "accepted" : true,
    "required" : false,
    "textDisplayedToUser" : "Get customized offers"
    } ]
    }
    }

Authentication request

Required parameters are listed in Authentication request login from phone number and Authentication request login from phone number with redirect.

SectionDescription
Error responsesSee: Error responses login from phone number and Error responses login from phone number with redirect.
Successful responsesSee: Successful responses for login from phone number
Token requestSee: Token request login from phone number
PollingSee: Polling login from phone number

Merchant-initiated login texts

A merchant can select between different texts that we will display to the user during the flow. The text type can be changed on portal.vippsmobilepay.com, under the Login settings for your sales unit.

The following are examples on how the different text types will look in the app:

  • Join customer club

    Join customer club texts

  • Confirm information

    Confirm information texts

  • Share information

    Share information texts

Check if user exists

A merchant can select check if a user exists in Vipps MobilePay before initiating an authentication. This is done with the POST:/vipps-login-ciba/api/v1/user-exists endpoint.

Provide the login-hint in the body. For example: login_hint=urn:msisdn:4712345678.

Example request:

POST https://api.vipps.no/vipps-login-ciba/api/v1/user-exists
Authorization: Basic asdkjhasdjhsad=
Content-Type: application/x-www-form-urlencoded

login_hint=urn:msisdn:{msisdn}

Example response:

{ "exists": true }

Help us improve our documentation

Did you find what you were looking for?