Skip to main content

PSP API guide

Settlements for Payment Service Provider (PSP) integrations are handled by the PSP, but you can use the PSP API to initiate PSP payments.

API version: 3.0

How it works

Vipps på Nett (eCommerce) via PSP offers functionality for payments where the user simply enters their Norwegian mobile number to complete a payment in the Vipps app.

In the Vipps app, the user selects a payment card (a payment source). Vipps then gives the PSP a token for that card so the PSP can process the payment.

The PSP processes the payment, provides feedback to merchant, and sends Vipps an update of the payment transaction success or failure. The user is shown the correct status for the payment in Vipps.

All PSPs must be able to process network tokens. See the EMVco documentation for more information.

Important: Cards that were added to Vipps after January 1, 2021 are only enrolled with Vipps' new PSP. That means Vipps is only able to provide a token for those cards, not the card details. If you are not able to process tokens, you should respond with HTTP 403 Forbidden, as that gives the best (least bad) customer experience in Vipps.

There are some differences between Vipps payments done through a PSP and payments done through direct integration. See: What functionality is included in the eCom API, but not the PSP API?.

PSP payment sequence

The following diagram illustrates the PSP payment sequence.

Important: Some users may close Vipps immediately after seeing the payment confirmation, therefore not being "redirected" back to the merchant. Because of this, it is important for the merchant and the PSP to not base their transaction logic on the user reaching the pspRedirectUrl.

For example: Check for "reserved" status with the PSP's API (not Vipps' API), then do "capture" when the goods have been shipped/delivered.

API overview

Vipps HTTP headers

We recommend using the standard Vipps HTTP headers for all requests.

See Vipps HTTP headers in the Common topics, for details.

Authentication

All Vipps API calls are authenticated with an access token and an API subscription key. See Get an access token, for details.

Initiate payment

When a user chooses Vipps as the payment method, a payment request is initiated by the PSP to the Vipps API. Vipps creates the payment and returns a link that does the following:

  • For users on a mobile device, the Vipps app is opened.
  • For other users, the Vipps landing page is opened in a browser. The user can then enter their phone number and continue in the Vipps app on their phone.

The user then confirms the payment in Vipps.

See landing page in the Common topics area, for more details.

Skip landing page

Only available for whitelisted sales units.

Please note: This feature has to be enabled by Vipps for eligible sales units. The sales units must be whitelisted by Vipps. Skipping the landing page is typically used at physical points of sale where there is no display available.

See Skip landing page for more details.

Payment confirmation

After the payment initiation, Vipps sends a push notification or redirects the user to the Vipps app. The user logs in, selects payment source, and confirms the payment.

makePaymentUrl

Once the Vipps user has confirmed the payment in the Vipps app, Vipps shares the network token with the PSP by POST-ing to the makePaymentUrl: POST:makePaymentUrl.

Vipps requires a HTTP 200 OK response and a response body with "paymentInfo.status": "OK" for the POST request to the makePaymentUrl. Vipps then sets the payment's status to RESERVED.

If Vipps does not receive the expected response, the payment's status will be FAILED.

The process of using POST to the makePaymentUrl is synchronous, and while Vipps is waiting for a response from the PSP, the user will see a "spinner" in the Vipps app.

After Vipps´ successful POST to the makePaymentUrl, the PSP uses the card token to process the payment through the acquirer. This is the PSP's responsibility. Vipps is not involved in the actual payment, Vipps only provides the PSP with the card token. Vipps does not have any information about the actual payment at this point.

The PSP then sends Vipps an update on the status of the payment: POST:/v3/psppayments/updatestatus

It is important that the PSP sends this update, so the user can see the correct status of the payment in Vipps. Without a status update from the PSP, the user will see an incorrect status. Payment updates are processed in batches. See: Batch processing of status updates.

The Vipps user receives confirmation of the payment in Vipps, and Vipps redirects the end user to the redirectUrl provided during payment initiation.

Please note:

  • The normal timeouts apply to the PSP API. If the user does not act on the payment request within 10 minutes, Vipps will make a POST request towards the makePaymentUrl with a status of timeout.
  • The makePaymentUrl has a timeout of 15 seconds. If no response is received within this period, Vipps will mark the transaction as FAILED. This is a known issue with the current API. Future improvements to address this issue are planned.
  • Some users may close Vipps immediately after seeing the payment confirmation, therefore not being "redirected" back to the merchant. Because of this, it is important for the merchant and the PSP to not base their transaction logic on the user reaching the pspRedirectUrl.

isApp

See isApp in Common topics.

EMVCo Token processing

In order to give the best possible payment experience, the Vipps PSP API uses EMVCO token based processing.

The solution requires the PSP to have support for EMVCO token processing.

The makePaymentUrl call to the PSP sends the network token and cryptogram in the following format. This is referred to as the makePayment request.

Authorization: makePaymentToken
{
"pspTransactionId": "7686f7788898767977",
"merchantSerialNumber": "123456",
"paymentState": "ACCEPTED/TIMEOUT/USER_CANCEL",
"paymentInstrument": "TOKEN",
"binNumber": "492556",
"networkToken": {
"number": "12345678901234",
"expiryMonth": "12",
"cryptogram": "aFgdgjdkfgjdFDF=",
"tokenType": "VISA",
"expiryYear": "2025",
"eci": "07"
}
}

Where:

  • paymentInstrument is as an indicator that can be used to differentiate the two alternatives.
  • networkToken is the Network token of the card, up to 16-19 digits. A full replacement of the PAN.

Scheme specific details

Visa

Visa tokens must be processed with the acquirer submitting the TAVV cryptogram in field 126.8. The cryptogram received with the Network Token will contain the information for Delegated Authentication (DA) and the SCA factors used.

The Visa Token Service will during detokenization populate a flag for DA in field 34 to issuers and the Vipps TRID in field 123 Usage 2 Tag 03. In this way, Issuers recognize Vipps originated transactions and will not soft-decline for DS step-up unless the issuing bank has opted out of the Visa D-SCA program. The expected ECI value for VISA requests is ECI-07.

Mastercard

A MasterCard transaction should be processed as an eCom token in accordance with the acquirers instructions from Mastercard. Mastercard adds the Token Requestor ID (TRID) to the authorization message. It will always be available in DE48, SE33, SF6.

Vipps is working on providing delegated authentication with MasterCard. As the time of writing, you should expect soft declines on all MasterCard transactions. Vipps initially returns ECI-06 for Mastercard, this should be handled as "no 3DS, no challenge requested" in accordance with your acquirer.

Token Requestor Ids

For Visa/Mastercard, the Token Requestor ID (TRID) is an eleven-digit number. It is added by the scheme in the processing of the payments.

3DSecure and Network tokens

In order to start a 3DS session, simply use the Network Token Number instead of the regular PAN. The scheme Directory Server maps the Network Token to the underlying PAN before it requests the challenge session from the Issuing Bank's ACS. CVC is not required in order to perform the 3DS session with a network token.

Once the 3DS CAVV cryptogram is acquired from the 3DS session, both the CAVV and the token cryptogram must be submitted in the authorization request in the fields specified by the acquirer. This is necessary to perform a valid authorization.

Magic Numbers for EMVCo Tokens

Any request to the Vipps PSP API will return a Visa Token. However, this can be changed by setting the amount in the init request. No matter what is selected in the app, the token returned by the MakePayment request will be:

Amount ValueToken NumberExpiryCryptogram
22.00522660311548803105/25AlhlvxmN2ZKuAAESNFZ4GoABFA==
31.00Emulates Card not eligible
32.00411111111111111103/30uxToh3Ep6gsR8AAkvZALN19Iz34=
42.00489537001319350003/30AlhlvxmN2ZKuAAESNFZ4GoABFA==
43.00522660311548803103/30AlhlvxmN2ZKuAAESNFZ4GoABFA==
44.00489537001279268212/22AgAAAAAAAIR8CQrXSohbQAAAAAA=
51.00426827008730287109/24AgAAAAAAAIR8CQrXSohbQAAAAAA=
52.00541333008901044212/25AgAAAAAAAIR8CQrXSohbQAAAAAA=
All other amounts489537001319350005/25AlhlvxmN2ZKuAAESNFZ4GoABFA==

Status Updates

To provide a consistent end user experience, it is important that Vipps is notified by changes to the payment status when it is captured, cancelled, or refunded: POST:/v3/psppayments/updatestatus

Vipps also provides an endpoint allowing you to check the payment status: GET:/v3/psppayments/{pspTransactionId}/details

Please note: For single payments you do not need to send an update for the reservation, since that is handled by the synchronous response to the Makepayment call. But for recurring payments you must send it.

For customers upgrading from the PSP API v1: It is ok to call POST:/v3/psppayments/updatestatus with the v3 API on payments done with the v1 API.

Batch processing of status updates

Requests to POST:/v3/psppayments/updatestatus receive a HTTP 200 OK response if the JSON payload was valid. The actual processing of the data is done as a batch.

The reason for this is that some PSPs send Vipps all their status updates once a day. Based on this, we created a service that can handle thousands of transaction updates in one operation.

To avoid all of these updates being written to our database at once, with the resulting performance hit, we chose to defer these into a nightly batch job.

Because of this, the updated status is only visible in Vipps the next day.

Please note: The batch update is not run in the test environment, as there are some technical details preventing it from being run in the same way as in the production environment. The status of PSP payments will therefore always be in the initiated state in the test environment.

Cancelling pending transactions

A user might return to the PSP's checkout without logging in to the Vipps App, or they might abort the transaction in the Vipps App. Vipps's recommendation is that the PSP then cancels the transaction in their backend and returns an error code.

| 85 | Response received too late |

See: Error codes.

A typical flow would be:

  1. The user selects Vipps as payment method.
  2. The user returns without completing in the app (no makePaymentUrl request has been received by the PSP).
  3. The PSP cancels the payment on their end and restarts the checkout.
  4. The user might end up going back to the Vipps app. If that happens and a makePaymentUrl request is sent, the PSP responds with error code 85.

Example request

Authorization: makePaymentToken
{
"pspTransactionId": "7686f7788898767977",
"merchantSerialNumber": "123456",
"paymentState": "ACCEPTED/TIMEOUT/USER_CANCEL",
"paymentInstrument": "TOKEN",
"binNumber": "492556",
"networkToken": {
"number": "12345678901234",
"expiryMonth": "12",
"cryptogram": "aFgdgjdkfgjdFDF=",
"tokenType": "VISA",
"expiryYear": "2025",
"eci": "07"
}
}

Example response

{
"errorMessage": {
"errorId": 82,
"errorText": "Refused by Issuer"
},
"paymentInfo": {
"pspTransactionId": "7686f7788898767977",
"status": "FAIL"
}
}

Idempotency

Many API requests to Vipps APIs can be retried without any side effects by providing Request-Id(or Idempotency-key) in the header of the request.

See the Idempotency header for more details.

PSP API implementation checklist

See: Vipps PSP API Checklist.

Errors

The PSP should return the following errorIds and errorTexts, when applicable:

errorIderrorTextDescription (should not be included in response)
71Invalid requestThe request received from Vipps failed validation.
72Different textsFor errors that are not in this list. Please include text describing the error.
81No such issuerThe PSP were unable to identify the card issuer.
82Refused by IssuerGeneric response for cards that were refused by issuer, without the PSP knowing why.
83Suspected fraudSuspected fraud.
84Exceeds withdrawal amount limitThe amount exceeds an amount limit. Could be per transaction limit, or for a period.
85Response received too lateA third party didn't respond in time for the makePayment or Cancelling pending transactions.
86Expired cardExpired card.
87Invalid card number (no such number)The card provided is invalid.
88Merchant does not allow credit cardsIf the PSP supports disallowing credit cards.
89Insufficient fundsInsufficient funds.
91Internal errorUnhandled or unknown exception.
93Status from Vipps:CANCELResponse to Vipps sending CANCEL. Caused by customer cancelling the payment from the Vipps App, or in the Vipps landing page.
93Status from Vipps:TIMEOUTResponse to Vipps sending TIMEOUT. Caused by customer not acting on the payment. This will happen within 5-10 minutes of the customer not acting. Vipps immediately processes and sends the TIMEOUT notification to the PSP
93Status from Vipps:NOResponse to Vipps sending NO. Something failed during payment approval. Often caused by failure to retrieve and send networkToken.
94Unhandled soft declineResponse to a Soft Decline from the bank that could not be processed or forwarded to the Vipps App.

PSD2 Compliance and Secure Customer Authentication (SCA)

3DSecure Fallback

In case of a soft decline (when the issuer requires 3DS), the PSP must host a 3DSecure session and must provide the URL to Vipps.

The format of the MakePaymentRequest response provided by the PSP in case of a soft decline:

{
"errorMessage": {
"errorId": 1036,
"errorText": "Soft Decline"
},
"paymentInfo": {
"pspTransactionId": "7686f7788898767977",
"status": "SOFT_DECLINE",
"url3dSecure": "https://psp.com/3ds/123123"
}
}

The Vipps App will then open the URL in a web view, letting the user complete the 3DSecure flow. The PSP must host and retrieve any necessary data from the session. Once the session is completed, the PSP must finish with a redirect according to the Operations.url object sent in the initial makePayment request, whereupon the app will close the iframe. Vipps will then resend the makePayment request.

For example, if a 3DSecure session succeeds, you should redirect to the Operations.url with the operation 3dssuccess.

operations\":[{\"url\":\"https://example.com/?transactionId=xxxxx&responsecode=OK\",\"operation\":\"3dssuccess\"}"

Note that the responseCode query parameter is critical.

When Vipps sends the status in the response to the second makePayment request, it should never be SOFT_DECLINE, only FAIL or OK. Once the status is returned, it will be displayed to the user as normal in the app.

Authorization: makePaymentToken
{
"pspTransactionId": "7686f7788898767977",
"merchantSerialNumber": "123456",
"confirmed": "YES/TIMEOUT/CANCEL",
"paymentInstrument": "TOKEN",
"binNumber": "492556",
"networkToken": {
"number": "12345678901234",
"expiryMonth": "12",
"cryptogram": "aFgdgjdkfgjdFDF=",
"tokenType": "VISA",
"expiryYear": "2025",
"eci": "07"
}
}

Recurring payments

Please note: We are currently not onboarding new PSP partners to Pass-through Recurring Payments due to challenges with user experience under PSD2. We will update this section when there is new information.

The PSP API supports recurring payments, allowing the PSP to perform recurring payments through Vipps, while retaining full transactional control. This has been built as an extension to the existing PSP v3 API, and no existing integrations will be affected, other than the possibility to initialize and preform recurring payments.

Scope

As of now, there is one possible way to perform a recurring payment: psp_subscription. This is referred to as the scope of the recurring agreement. Only one scope can be used at a time, and it's not possible to change the scope of an agreement.

Subscription-based payments are created as a consent to an agreement that allows the PSP to withdraw money on unknown intervals. This implies that the user won't have to accept the payment on each occasion, only the first one when consenting to the agreement. An example of this could be a subscription to a music streaming service.

Initialize a recurring payment

Initializing a recurring payment works in the same way as a non-recurring payment, but with the inclusion of a scope and agreementURL in the init call.

At that time, the scope can be set to psp_subscription. The agreementURL should be a link to where the user can click to manage the agreement.

To start the initialization, create a standard /init call with the addition of the required fields. If you want to initialize a recurring psp_subscription, the init request body could look like this.

{
"pspRedirectUrl": "https://example.com/yourRedirectUrl",
"amount": 1337,
"makePaymentToken": "tokenGoesHerenco3rt8y34obcwierunnw3oirtycbvwo",
"makePaymentUrl": "https://example.com/yourCallbackEndpointUrl",
"currency": "NOK",
"merchantOrderId": "123123123",
"pspTransactionId": "{{psptransactionid}}",
"paymentText": "Order id: 213213",
"scope": "psp_subscription",
"agreementURL": "https://example.com/linkToTheAgreement"
}

In the same way as a normal, non-recurring PSP v3 payment, the PSP will receive a POST:makePaymentURL callback. In the body of this callback, you will now also find a userToken.

For merchantOrderId: See Recommendations for reference and orderId.

The user token

The user token is a token generated when the user has given a consent. This token is provided to the PSP in the makePayment callback when initializing or preforming a recurring payment.

A userToken contains the scope of the consent, in the claim named scope. The token also includes various useful information:

{
"sub" // agreement_id
"aud" // audience (usually something like "https://vipps.no")
"iat" // issue_day_time
"scope"
}

Make the next recurring payment

After initialization, the next payment can be made by passing your userToken to the POST:/v3/psppayments/payments endpoint as a header with the name User-Token.

HEADER: "
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5c<snip>
Ocp-Apim-Subscription-Key: c1b1a8846ec56d09db39bd3b5403bf9
PSP-ID: C948DFD1546347568874C4DDC93A2E3C
Merchant-Serial-Number: 123456
User-Token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9
"
{
"pspTransactionId": "7686f7788898767977",
"merchantOrderId": "8874C4DDC93A2E3C",
"amount": 39900,
"currency": "NOK",
"paymentText": "Description of payment"
}

Response with network token:

{
"pspTransactionId": "7686f7788898767977",
"merchantOrderId": "8874C4DDC93A2E3C",
"paymentInstrument": "TOKEN",
"networkToken": {
"number": "12345678901234",
"expiryMonth": "12",
"cryptogram": "aFgdgjdkfgjdFDF=",
"tokenType": "MASTERCARD",
"expiryYear": "2025",
"eci": "07"
}
}

Once the card data is received from POST:/v3/psppayments/payments and the payment has been processed, the PSP must call POST:/v3/psppayments/updatestatus to notify Vipps of the status. In this context, updateStatus accepts a RESERVED status. If the status for the previous payment has not been received, the agreement will be locked from processing future payments until the update is received. If a recurring payment fails, you should call POST:/v3/psppayments/updatestatus with operationStatus: FAILED set in the body.

URL Validation

All URLs in Vipps eCommerce API are validated with the Apache Commons UrlValidator.

If isApp is true, any pspRedirectUrl is not validated with Apache Commons UrlValidator, as the app-switch URL may be something like vipps://, which is not a valid URL.

The endpoints required by Vipps must be publicly available.

URLs that start with https://localhost will be rejected. If you want to use localhost as fallback, please use http://127.0.0.1. It is not possible to use https://localhost or http://127.0.0.1 for the callback, as the Vipps backend would then call itself.

Here is a simple Java class suitable for testing URLs, using the dummy URL https://example.com/vipps/fallback-result-page/acme-shop-123-order123abc:

import org.apache.commons.validator.routines.UrlValidator;

public class UrlValidate {
public static void main(String[] args) {
UrlValidator urlValidator = new UrlValidator();

if (urlValidator.isValid("https://example.com/vipps/fallback-result-page/acme-shop-123-order123abc")) {
System.out.println("URL is valid");
} else {
System.out.println("URL is invalid");
}
}
}

HTTP responses

This API returns the following HTTP statuses in the responses:

HTTP statusDescription
200 OKRequest successful
400 Bad RequestInvalid request, see the error for details
401 UnauthorizedInvalid credentials
403 ForbiddenAuthentication ok, but credentials lacks authorization
404 Not FoundThe resource was not found
500 Server ErrorAn internal Vipps problem

Error codes

Error codeError messageDescription
21Merchant not available or active
42Invalid payment model type
44PSP Transaction ID already exists
51Invalid request
51Invalid pspRedirectUrl
99OrderId already exists
amountamount.less.than.one
currencytransaction.currency.invalid
makePaymentUrlInvalid makePaymentUrl
121Agreement not foundThe agreement does not exist
122Agreement not activeThe agreement has been deactivated via the Delete agreement endpoint
123Connected payment source not active for AgreementThe connected card is no longer active or valid
124No Network token available for this AgreementThe connected card does not have an active network token available

Recommendations regarding handling redirects

Since Vipps is a mobile entity, the amount of control Vipps has over the redirect back to the merchant after the purchase is completed is limited. A merchant must not assume that Vipps will redirect to the exact same session and for example rely entirely on cookies in order to handle the redirect event. For example the redirect could happen to another browser.

Examples of some, but not all, factors outside Vipps' control.

  • Configurations set by the OS itself, for example the default browser.
  • User configurations of browsers.
  • Users closing app immediately upon purchase.

Therefore, Vipps recommends having a stateless approach in the site that is supposed to be the end session. An example would be a polling-based result handling from a value in the redirect URL.

For demonstration purposes, an example that should be handled is:

  1. User starts is in web session in a Chrome Browser.
  2. A Vipps purchase is started, a redirect URL is defined by the Merchant.
  3. The user completes the purchase.
  4. The Vipps app redirects the user.
  5. The OS defaults to a Safari Browser for the redirect.
  6. The merchant handles the redirect without the customer noticing any discrepancies from the browser switch.

Differences from previous versions

Differences from PSP API v2 to v3

The PSP API v3 adds functionality for network tokens and allows PSPs to use the API to obtain tokens from Vipps, not the actual card details.

Additionally, $.makePaymentRequest.confirmed has been renamed to $.makePaymentRequest.paymentState

Values for this enum have changed accordingly:

Old ValueNew Value
YesACCEPTED
TIMEOUTTIMEOUT
CANCELUSER_CANCEL
NOUSER_CANCEL

Differences from PSP API v1 to v2

  • Added support for redirection of user after payment completion in the Vipps app
  • Added support for providing the makePaymentUrl in the initiate payment call
  • Improved authorization of the makePaymentUrl call by adding the Authorization header value
  • Improved and more consistent parameter names in the API

Proposals

Recurring 3DS Update Card

The following is a proposal for triggering 3DS when a user changes the card attached to a PSP recurring agreement in the Vipps app.

A new optional updateCardUrl property would be added to the initiate call. This callback will be triggered when the user changes card with the following request;

HTTP headers:

PSP-ID: C948DFD1546347568874C4DDC93A2E3C
Merchant-Serial-Number: 123456
User-Token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9

Request body:

{
"agreementId": "7686f7788898767977",
"paymentInstrument": "TOKEN",
"binNumber": "492556",
"networkToken": {
"number": "12345678901234",
"expiryMonth": "12",
"cryptogram": "aFgdgjdkfgjdFDF=",
"tokenType": "VISA",
"expiryYear": "2025",
"eci": "07"
}
}

To which the PSP should respond with a require3DS boolean flag which, if true, will cause a 3DS session to be hosted in the Vipps app.

{
"require3DS": true,
"url3dSecure": "https://psp.com/3ds/123123"
}

The Vipps app will then host a 3DS session from the PSP. Once this session is completed, the PSP should redirect to https://www.vipps.no/mobileintercept.

Once the user completes the 3DS session, the updateCardUrl will be called again. The PSP should then only approve or deny the request.