Merchant initiated login integration
Merchant initiated login is built to support special cases where login does not start in a browser or app.
Merchant initiated login is based on the Client-Initiated Backchannel Authentication (CIBA) standard.
In this flow, the merchant's system triggers the authentication/registration; thus, log-in cannot be done in the user's browser. To ensure a consistent user experience, Merchant initiated login is not allowed on webpages and in apps.
A sales unit can use the Login API for many flows.
It is recommended to use the same sales unit for all use cases to ensure that you get the same user ID (sub
) on the user across different scenarios.
Login from phone number is initiated using the user's mobile number. 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. If they haven't already consented to share information with a merchant, such consent will be required. 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.
The merchant controls whether the user should get the confirmation of completion in the Vipps or MobilePay app or if they should be taken to the merchant's web page to finalize the flow. For example, the merchant can take the user to their web page to 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. This is illustrated in How Login works from phone number.
Illustration of how the flow will look when the user ends the flow and gets the confirmation of completion in the Vipps or MobilePay app:
Illustration of how the flow will look if the user is taken to the merchant's web page:
The merchant has the option to show a confirmation code (binding_message
) to the user in the app for added security:
Complete login in the Vipps or MobilePay app
Overview
Client-Initiated Backchannel Authentication (CIBA) enables a Client to initiate the authentication of an end-user through out-of-band mechanisms.
- The Client shall make an "HTTP POST" request to the Backchannel Authentication Endpoint to ask for end-user authentication.
- Login will respond immediately with a unique identifier that identifies that authentication while it tries to authenticate the user in the background.
- 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
-
Before all this, the merchant has fetched the OpenID configuration from the well-known endpoint and cached it. See .well-known
-
The merchant initiates a login by calling the
backchannel_authentication_endpoint
listed in the OpenID configuration fetched in step 0.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=21hebdhwqdb7261bd1b23Example response:
200 application/json
{
"auth_req_id": "VYGaaAMRkI6SyAm_uIywhxsN2K0",
"expires_in": 600,
"interval": 5
} -
The merchant starts polling the
token
endpoint listed in the OpenID configuration fetched in step 0. See webhook events for an alternative to polling.Polling in this context means doing repeated HTTP requests with a delay between them.
Information about polling. Note that the polling interval should adhere to the
interval
response parameter (in seconds) returned in step 1.For other details about the request, see Token request.
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_uIywhxsN2K0Example 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, thetoken
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"
} -
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-askdjhsakjhdExample 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 is possible to change the authentication method to client_secret_post
in the merchant portal. More information in the FAQ.
The login_hint
parameter (required)
Supported login hints:
- Norwegian mobile phone numbers can be targeted by passing login hint as an MSISDN.
Example: ...&login_hint=urn:msisdn:4712345678&...
.
The scope
parameter (required)
- We support the scopes listed at Scopes
- The legacy
nnin
scope is not supported, usenin
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 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.
Format
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 standard https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#auth_request
.
Example: ....&binding_message=4MZ-CQ3&...
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
- Long polling as described in the CIBA standard is currently not supported
- Remember not to poll more often than indicated by the
interval
parameter, returned from the authentication request. - See webhook events for an alternative to 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 theRetry-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.
- The Client shall make an "HTTP POST" request to the Backchannel Authentication Endpoint to ask for end-user authentication.
- The user, via their browser, will be redirected to the Client's
redirect_uri
which enables the login to be completed.
Call by call
-
Before all this, the merchant has fetched the OpenID configuration from the well-known endpoint and cached it. See .well-known.
-
The merchant initiates a login by calling the
backchannel_authentication_endpoint
listed in the OpenID configuration fetched in step 0.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/callbackExample response, the
auth_req_id
should be used to connect this login to a token response since the ID token should contain the sameauth_req_id
value.200 application/json
{
"auth_req_id": "VYGaaAMRkI6SyAm_uIywhxsN2K0",
"expires_in": 600,
"interval": 5
} -
The user confirms the login and is then redirected to the
redirect_uri
passed in the initial request 1. The redirect will contain acode
:{redirect_uri}?code={code}
. -
The merchant uses the code-parameter to obtain the login token. Perform a POST request towards the
{token_endpoint}
withcode={code}
,grant_type=urn:vipps:params:grant-type:ciba-redirect
in theapplication/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 theauth_req_id
they have previously received from step 2.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-redirectExample 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
} -
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-askdjhsakjhdasdfggExample 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
The following authentication methods are currently supported:
- client_secret_basic
- client_secret_post
The default token endpoint authentication method is client_secret_basic
. It is possible to change the authentication method to client_secret_post
in the merchant portal. More information in the FAQ.
Required parameters: requested_flow
, login_hint
, scope
, redirect_uri
The login_hint
parameter (required)
Supported login hints:
- Norwegian mobile phone numbers can be targeted by passing login hint as an MSISDN.
Example: ...&login_hint=urn:msisdn:4712345678&...
.
The scope
parameter (required)
- We support the scopes listed at Scopes.
- The legacy
nnin
scope is not supported, usenin
instead. - The
openid
scope is required
Example: ...&scope=openid 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.
Read more about it in the standard https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#auth_request
Note: "the binding_message value SHOULD be relatively short and use a limited set of plain text characters"
Example: ....&binding_message=4MZ-CQ3&...
The redirect_uri
parameter (required)
Redirect URL which the user agent is redirected to after finishing a login. Must be https
in the production environment.
Example: ...&redirect_uri=https://merchant.com/callback&...
Error responses
In addition to the responses defined by the standard these responses might also be returned:
429
status responses: Too many login requests started towards the same user at the same time. Please respect theRetry-After
header returned.- Most of the general error codes
Webhook events
You can receive instant notifications about important events, such as a merchant-initiated login. To set up the basic webhook infrastructure, you need to register your webhook URL, as described in the Webhooks API guide. We'll send the real-time notifications about subscription events to the URL you specify.
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.
Payload
The payload will contain the auth_req_id
that identifies the login.
Example
{
"auth_req_id": "qwieuhwqiuhdiuwqh123"
}
Call by call
- The merchant subscribes to the
login.merchant-initiated.ping.v1
event. - The merchant initiates a login by calling the
backchannel_authentication_endpoint
- The user confirms the login.
- The merchant receives a webhook event with the
auth_req_id
that identifies the login. - The merchant calls the token endpoint to get the tokens.
Redirect to browser flow is not supported
Although this flow also allows for receiving webhook notifications for logins, it has a limitation. The token endpoint can only be called once, which means the flow effectively is not compatible with webhook events.
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.
- 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. - 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.
- The Client will receive the ID Token and Access Token by polling the token endpoint to get a response with the tokens.
- 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 Login from phone number with redirect to browser, by adding scope delegatedConsents to the initial request (1).
Call by call
-
Before all this, the merchant has fetched the OpenID configuration from the well-known endpoint and cached it. See .well-known
-
The merchant initiates a login by calling the
backchannel_authentication_endpoint
listed in the OpenID configuration fetched in step 0 with scopedelegatedConsents
.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=21hebdhwqdb7261bd1b23Example response:
200 application/json
{
"auth_req_id": "VYGaaAMRkI6SyAm_uIywhxsN2K0",
"expires_in": 600,
"interval": 5
} -
The merchant starts polling the
token
endpoint listed in the OpenID configuration fetched in step 0.Polling in this context means doing repeated HTTP requests with a delay between them.
Information about polling. Note that the polling interval should adhere to the
interval
response parameter (in seconds) returned in step 1.For other details about the request, see Token request.
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_uIywhxsN2K0Example 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, thetoken
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"
} -
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-askdjhsakjhdExample 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.
Error responses
Error responses are listed in Error responses login from phone number and Error responses login from phone number with redirect.
Successful responses
See: Successful responses for login from phone number
Token request
See: Token request login from phone number
Polling
See: Polling login from phone number
Check if user exists
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 }