> **Description:** A chronological record of all significant changes, updates, and improvements made to the Recurring PSP API, including new features, bug fixes, and deprecation notices.

> **AI agent:** Read [https://developer.vippsmobilepay.com/docs/knowledge-base/ai-tools.md](https://developer.vippsmobilepay.com/docs/knowledge-base/ai-tools.md) first. It covers keeping API keys and secrets out of generated code.

> **Full site overview:** For an overview of the entire site, read [https://developer.vippsmobilepay.com/llms.txt](https://developer.vippsmobilepay.com/llms.txt).

# Recurring PSP API changelog

**NOTE**

This page covers Recurring API changes that are specific to PSP integrations. There may be additional changes that apply to all Recurring API integrations -- see the [Recurring API changelog](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/CHANGELOG.md).

## October 2026

* Added a `citReference` object to the card info returned by [Create PSP charges](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) and [Get payment info](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml). It contains references to the customer-initiated transaction (CIT) of the agreement's card, so you can link a merchant-initiated transaction (MIT) to it.
  * `networkTransactionReference`: The `networkTransactionReference` you returned in the [card callback](https://developer.vippsmobilepay.com/docs/APIs/psp-recurring-api/recurring-psp-api-guide.md#card-callback) response when the card was added to the agreement, at agreement sign-up or payment source update.
* The `tokenType` field in `networkToken` is now always present in the card info returned by [Create PSP charges](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) and [Get payment info](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml).
* The v4 charge endpoints now consistently return `403 Forbidden` with the [`invalid-sale-unit`](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-problems.md#invalid-sale-unit) problem type when called by a merchant that is not a PSP.
  * [Get payment info](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) and [Report charge result](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) previously returned `404 Not Found` or `409 Conflict` in this case.
  * [Create PSP charges](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) already returned `403 Forbidden`, but now includes a problem body.
* The `cardPassthrough` object on agreements has been renamed to `psp`, and its `cardCallbackUrl` field has been renamed to `callbackUrl`, matching the `psp` object in the [ePayment PSP API](https://developer.vippsmobilepay.com/docs/APIs/psp-epayment-api/epayment-psp-api-guide.md). The other fields inside the object are unchanged.
  * Send `psp` instead of `cardPassthrough`, with `callbackUrl` instead of `cardCallbackUrl`, when [drafting an agreement](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) and when [updating an agreement](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml).
  * [Fetch agreement](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) and [List agreements](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) return the object as `psp`, with `callbackUrl`.
  * The old names are not accepted. Agreement sign-up with `cardPassthrough` or `psp.cardCallbackUrl` is rejected, and updates using the old names do not change the PSP data.

## September 2026

* The `cardInfo.cardType` field in the [card callback](https://developer.vippsmobilepay.com/docs/APIs/psp-recurring-api/recurring-psp-api-guide.md#card-callback) now uses underscores instead of hyphens, matching the values of `allowedCardTypes` on the agreement and the [ePayment PSP API](https://developer.vippsmobilepay.com/docs/APIs/psp-epayment-api/epayment-psp-api-guide.md). For example, `VISA-DEBIT` is now sent as `VISA_DEBIT`.
  * Possible values are `VISA_DEBIT`, `VISA_CREDIT`, `ELEC_DEBIT`, `MC_DEBIT`, `MC_CREDIT` and `DANKORT`.
* The `Psp-Id` header is now required on every Recurring API request made with PSP credentials, matching the [ePayment PSP API](https://developer.vippsmobilepay.com/docs/APIs/psp-epayment-api/epayment-psp-api-guide.md). Send your PSP ID, the same value for all your merchants.
  * A request without the header is rejected with `401 Unauthorized`.
  * A request where `Psp-Id` does not match the PSP the `Merchant-Serial-Number` belongs to is rejected with `403 Forbidden` and the [`invalid-sale-unit`](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-problems.md#invalid-sale-unit) problem type -- usually a sign of credentials from the wrong environment.
* The `description` field is now optional on each charge item in [Create PSP charges](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml). When it is omitted, the charge description falls back to the `productName` of the agreement.
* The `description` field is now optional on the `initialCharge` in PSP [agreement sign-up](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml), matching the behavior above. When it is omitted, the initial charge description falls back to the `productName` of the agreement.
* The `chargeId` field on each charge item in [Create PSP charges](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) now also accepts underscores (`_`). Allowed characters are `a-z`, `A-Z`, `0-9`, dash (`-`) and underscore (`_`), up to 64 characters (`^[a-zA-Z0-9-_]{1,64}$`).
* The `pspReference` field in `cardPassthrough` on [agreement sign-up](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) and [Update agreement](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) must now match `^[a-zA-Z0-9-_]{1,64}$`.
  * Requests with other characters are rejected with `400 Bad Request`.
  * Existing agreements are not affected.
* Added an optional `externalId` field to each charge item in [Create PSP charges](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml), matching `externalId` on the v3 charge endpoints. Use it to map a charge to an ID in your own system.
  * It must match `^[a-zA-Z0-9-_]{1,64}$`, the same format as `chargeId`. Other values are rejected in `failedCharges` with `external_id_invalid_format`.
  * It is not required to be unique and is not used for idempotency: charges are still identified by `agreementId` + `chargeId`.

## August 2026

* The Recurring PSP API is now enabled in the production environment.
  * Contact your PSP Partner Manager to have your PSP enabled in production once your integration has been validated.

## July 2026

* The v4 charge endpoint for reporting a payment outcome has been renamed from `POST:/recurring/v4/agreements/{agreementId}/charges/{chargeId}/finalize` to [`POST:/recurring/v4/agreements/{agreementId}/charges/{chargeId}/result`](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml). The behavior is unchanged apart from the `error` object below.
  * The `error.retry` field is now **required** when reporting a `FAILED` result -- send `true` if the payment may be retried, `false` otherwise.
  * The `error.message` field is now **optional**.
* `DIRECT_CAPTURE` is now supported for the `initialCharge` on PSP [agreement sign-up](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml). The initial charge is captured for its full amount automatically once the sign-up CIT succeeds, going straight to `CHARGED`.
  * Only full capture is supported. If you need partial captures, use `RESERVE_CAPTURE` and the [Capture charge](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) endpoint.

## June 2026

* The PSP-only [Create PSP charges](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) endpoint has the following changes:
  * Returns retryable item-level failures in a separate `retryableCharges` array.
    * This applies to transient errors where the outcome is uncertain, such as `processing_timeout` and `technical_error`.
    * These charges can be retried with the same `agreementId` + `chargeId` pair.
  * Requires a `type` field on each charge, distinguishing unscheduled from scheduled charges:
    * `UNSCHEDULED`: `due` must be omitted, and `cardInfo` is returned directly in the response.
    * `RECURRING`: `due` is required (at least one day in advance), and `cardInfo` is *not* returned. Fetch it from [Get payment info](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) on the `due` date (see the entry below).
    * The maximum number of charges per batch has been reduced from 100 to 50.
  * Caps the `due` date of a `RECURRING` charge at **31 days** from creation. A `due` date further out is rejected in `failedCharges` with `due_date_too_far`.
  * Accepts an optional `retryDays` field on `RECURRING` charges.
    * For PSP charges, `retryDays` sets how many days after the `due` date the charge stays payable -- i.e. how long payment info stays available from [Get payment info](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) so you can retry the payment -- before the charge is automatically failed (0-14 days).
    * If omitted on a `RECURRING` charge it defaults to `14`. For `UNSCHEDULED` charges, `retryDays` must be omitted or `0`.
    * Two new item-level error codes can be returned in `failedCharges`: `retry_days_invalid` and `retry_days_not_allowed`.
    * Added support for `DIRECT_CAPTURE` charges on the [Create PSP charges](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) endpoint. Previously only `RESERVE_CAPTURE` was accepted.
  * A `DIRECT_CAPTURE` charge is captured for its full amount automatically once you [finalize](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) it with `status: SUCCESS` -- it goes straight to `CHARGED` with no separate capture call.
  * Only full capture is supported for `DIRECT_CAPTURE`. If you need partial captures, create the charge as `RESERVE_CAPTURE` and use the [Capture charge](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) endpoint.
* Added a new PSP-only v4 endpoint, [Get payment info](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml), for fetching payment info for `DUE` charges. This is needed for scheduled [`RECURRING` charges](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-guide.md#recurring-charge) created above, where payment info is *not* returned in the initial [Create PSP charges](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) response.
  * Fetching payment info on demand avoids storing card data and ensures you always get
  the most up-to-date payment info for the agreement and charge.
  * For unscheduled charges, payment info is still returned directly in the [Create PSP
  charges](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml)
  response.
  * Like the other v4 endpoints, this is PSP-only for now and enabled in the Merchant
  Test (MT) environment.
* The PSP-only [Finalize charge](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) endpoint now requires [Get payment info](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) to have been called first for a `RECURRING` charge.
  * This ensures you perform the payment with the latest payment info rather than stale data.
  * Unscheduled charges are unaffected -- you already receive their card info in the [Create PSP charges](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) response.
* The PSP-only v4 charge endpoints now have rate limits, consistent with the rest of the Recurring API. See: [Rate limits](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-guide.md#rate-limiting).
  * [Create PSP charges](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml): 50 requests per minute per merchant.
  * [Finalize charge](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) and [Get payment info](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml): 5 requests per minute per `agreementId` + `chargeId`.

## May 2026

* Added initial support for Payment Service Providers (PSPs).
  * **This is only enabled in the Merchant Test (MT) environment for now; PROD will be enabled when the first PSPs have a validated and tested integration ready.**
  * PSPs are a new merchant type, separate from existing direct merchants. PSPs process payments on behalf of their onboarded merchants, whereas Vipps MobilePay processes payments for direct merchants (i.e., all current integrators).
  * This change affects all payment flows in Recurring--three customer-initiated (CIT) and one merchant-initiated (MIT):
    * Agreement sign-up with initial charge (CIT)
    * Agreement sign-up without initial charge (CIT)
    * Payment source updates (CIT)
    * Charges on existing agreements (MIT)
  * PSP merchants must include the new `cardPassthrough` object when [creating an agreement](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml). See [Agreement sign-up](https://developer.vippsmobilepay.com/docs/APIs/psp-recurring-api/recurring-psp-api-guide.md#agreement-sign-up) for more information.
    * This is a *PSP-only field*--direct merchants will get a 400 error response if this is included in the request body.
  * All affected v3 endpoints and their changes are listed below:
    * [Draft agreement](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml): Added support for PSP-only *cardPassthrough* field
    * [Fetch agreement](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) and [List agreements](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml): Added PSP-only *cardPassthrough* field to the response
    * [Update agreement](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml): Added support for partial updates of the PSP-only *cardPassthrough* field
  * Two new v4 endpoints have been added for PSP merchants:
    * [Create PSP charges](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml): Batch create PSP charges. Each successful charge returns the card data (network token, optionally the encrypted PAN) needed to process a MIT payment.
    * [Finalize PSP charge](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml): Report the outcome of a MIT payment, so it can be applied to the corresponding charge and shown to the user in the app.
    * The v4 endpoints are PSP-only for now; they may be extended to direct merchants in the future.
  * As part of this change, three new currencies have been added: `GBP`, `USD`, and `SEK`.
    * PSP merchants can use all supported currencies: `NOK`, `DKK`, `EUR`, `GBP`, `USD`, and `SEK`.
    * Direct merchants must continue to use `NOK`, `DKK`, or `EUR`; attempting to use the new currencies will result in a 400 error response.
