> **Description:** All notable changes to the Recurring API will be documented here.

# Changelog

**NOTE**

Changes for Payment Service Providers (PSPs) are in the [Recurring PSP API changelog](https://developer.vippsmobilepay.com/docs/APIs/psp-recurring-api/CHANGELOG.md).

## July 2026

* Stopping active agreements when a user deletes their Vipps MobilePay profile.
  * Previously, if a user deleted their profile, any new charges on existing active agreements would fail with reason `non_technical_error`, while the agreements themselves would remain active.
  * Going forward, all active agreements will be stopped automatically when a user deletes their profile.
  * The corresponding `recurring.agreement-stopped.v1` webhooks will have the `Actor` field set to `ADMIN`.
  * **Please note**: We are also identifying and stopping agreements belonging to previously deleted user profiles. As a result, some merchants may experience a temporary burst of `agreement-stopped` webhooks in the near future.

## June 2026

* Improved error responses for the [Capture charge](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml), [Cancel charge](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml), and [Refund charge](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) endpoints when a charge is in an invalid status. The `detail` field now includes the current charge status, so the cause is obvious from the response alone.
  * Example: trying to capture a `CANCELLED` charge now returns `detail: "CANCELLED charge can't be captured. Must be 'RESERVED', 'PARTIALLY_CAPTURED', 'PARTIALLY_REFUNDED' or 'REFUNDED'."`.

## April 2026

* Deprecated the `explanation` field in the `campaign` object returned by the [Get agreement](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) endpoint.
  * Due to recent improvements in how [campaigns are displayed](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/how-it-works/payment-agreement/recurring-api-campaigns-howitworks.md#how-it-looks-in-the-app) in the app, the field is no longer relevant.
  * The field will from now on just return an empty string.
  * The 1st of September the field will be removed completely from the `campaign` object.

## February 2026

* Added `Illegal agreement create` to list of problem types. See [Recurring API problem types](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-problems.md#illegal-agreement-create).

## January 2026

* Fixed a bug for period campaigns where the end date displayed to the user in the app was incorrect. See: [Agreement period campaigns](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-guide.md#period-campaign)

## December 2025

* Added new field `transactionId` to charge webhook payloads. This can be used to distinguish between multiple equivalent payment operations--like captures--performed on the same charge. See: [Charge webhook event payloads](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-guide.md#charge-webhook-event-payloads)
  * `transactionId` is a nullable string field containing a unique identifier for a specific payment operation that happened on a charge.
    * Example: if a capture was initiated on a charge and has finished processing, the `transactionId` field might be included in the payload of the emitted `recurring.charge-captured.v1` webhook event and will contain a unique identifier for that specific capture operation.
  * The following payment operations and equivalent charge webhook events might contain the `transactionId` field:
    * RESERVE: `recurring.charge-reserved.v1`
    * CAPTURE: `recurring.charge-captured.v1`
    * REFUND: `recurring.charge-refunded.v1`
    * CANCEL: `recurring.charge-canceled.v1`
  * Please note that this is considered a backwards compatible change according to our [API lifecycle policy](https://developer.vippsmobilepay.com/docs/knowledge-base/api-lifecycle.md#adding-an-optional-field-to-a-request).
* Starting 9th of December, we enforce the age requirement by rejecting any attempt to sign a new payment agreement for users below 18 years of age. See [Under-18 users](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/how-it-works/payment-agreement/recurring-api-under-18-users-howitworks.md).

## October 2025

* Changed the default lead time for recurring charge creation from 2 days to 1 day. This update provides greater flexibility and enables merchants and partners to request payments until midnight before the due date. See: [Recurring charges](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/how-it-works/charges/recurring-charges-howitworks.md) and [Recurring API guide - Due date](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-guide.md#due-date).
* Added support for specifying that certain payment sources should be blocked when drafting new agreements (DK, FI, SE). See: [Draft agreement](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml)
  * Specifying which payment sources should be blocked is done through the new `paymentMethod` object property. E.g. if you want to block commercial cards, you would add the following to the draft agreement request body:

  ```json
    paymentMethod: {
      blockedSources: ["COMMERCIAL_CARDS"]
    }
  ```

  * Only **commercial cards** are supported for now, meaning that this is the only payment source that can be blocked for any given agreement. This is also limited to Danish, Finnish, and Swedish cards; Norwegian commercial cards are not currently supported. This might change in the future.
  * This functionality is only supported for *new* agreements--it's not possible to update existing agreements to add or remove blocked payment sources.
* Fixed a bug where `failureReason` could be present in the `ChargeResponseV3` in  [Charges endpoints](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml) for certain charge states that shouldn't have failure reasons.
  * Example: if a charge was in `DUE` and had a failure reason before it got canceled, the `failureReason` would still be present in the `ChargeResponseV3` along with state `CANCELLED`.
  * Now, only charges in states `PENDING`, `DUE`, `PROCESSING` and `FAILED` can have a failure reason.

## September 2025

* Updated the rate limit for the charge creation endpoint. Instead of having separate limits for `RECURRING` (500/minute) and `UNSCHEDULED` (300/minute), there is now a single limit of 500 requests per minute. See: [Rate limits](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-guide.md#rate-limiting)
* Added `Not Acceptable` to list of problem types. See [Recurring API problem types](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-problems.md#not-acceptable).

## August 2025

* Enabled refunds of recurring transactions on the [business portal](https://portal.vippsmobilepay.com) for merchants in Denmark and Finland.
  * Previously, if you performed a manual refund on the business portal, the API could return outdated charge details until you repeated the same refund operation via the API.
  * From 19 August 2025, the API returns updated information immediately, including any refund operations performed in the business portal, and a webhook event is sent.

## July 2025

* Removed deprecated `countryCode` field from create agreement request schema. See: [Create agreement](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml)
  * Existing integrations that include `countryCode` as part of the request body when creating new agreements, will continue to work as usual. The field will simply be ignored when parsing the request.
* Updated sections of the documentation following the launch of new designs for payment agreement sign up flow in Android version > 8.23.0 and iOS version > 8.25.0.

## June 2025

* Adjusted auto-fail logic for recurring `SINGLE_ATTEMPT` charges.
  See [Processing mode](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-guide.md#processing-mode).
  * `SINGLE_ATTEMPT` charges that are not able to be successfully processed, will now be auto-failed
    after initial processing time on due date + 2 hours--instead of end of day on due date + 2 hours.
  * E.g. if the charge is picked up for processing as part of a charge batch that runs 2025-06-12T00:03:00Z,
    it will be auto-failed sometime after 2025-06-12T00:05:00Z, depending on processing time in the batch.
* Updated request body validation for Create Charge endpoints
  * Increased character limit on the `orderId` field from 50 to 64.

## May 2025

* Adjusted serialization logic for agreement webhook payloads, so null values are now omitted. See: [Agreement webhook event payloads](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-guide.md#agreement-webhook-event-payloads)
  * This change mainly affects the `actor` field, which used to be included with a default value of `null` for all agreement webhook event payloads except the `recurring.agreement-stopped.v1` event (which has a non-null value that indicates who stopped the agreement).
  * Only `recurring.agreement-stopped.v1` webhook event payloads will now contain the `actor` field.
* Standardized format of ISO 8601 UTC timestamp included in the `occurred` field for all webhook event payloads. See: [Agreement webhook event payloads](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-guide.md#agreement-webhook-event-payloads) and [Charge webhook event payloads](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-guide.md#charge-webhook-event-payloads)
  * The format of ISO dates can vary, having optional seconds and fractional seconds. We have standardized the format of the timestamp in this field to always include seconds and fractional seconds with 7 decimal precision, e.g. `2025-05-02T10:36:43.4880000Z`.

## April 2025

* Updated failure codes and explanations for charge webhook payloads. See: [Charge webhook event payloads](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-guide.md#charge-webhook-event-payloads)
* Added new charge webhook event type: `recurring.charge-refunded.v1`. See:
  [Webhooks](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-guide.md#webhooks-integration)

## February 2025

* Removed references to V2 API

## January 2025

* Webhook improvements:

  We have introduced  `failureReason` to charge webhook payloads. This field will match the `failureReason` supplied in the API response for failing charges.
We also added a deprecation notice to the `failureText` field, which has been replaced by `failureReason`

* Flexible Pricing representation for agreements:
  Flexible pricing agreements are supported for Norway.

* We have introduced an optional parameter `processingMode` for charges, that could be set to modify the retry behavior of a charge.
  Both new and existing charges will contain this parameter when fetched/listed.
  See [Processing mode](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-guide.md#processing-mode).

## December 2024

* Webhook improvements:
We have stopped sending `failureCode`, `failureText` and `chargeExternalId` from charge webhook payloads if they were null.

## November 2024

* Webhook improvements:
  We have expanded Agreement and Charge webhooks with the `msn` (Merchant Serial Number) property.
  See [Recurring API event types](https://developer.vippsmobilepay.com/docs/APIs/webhooks-api/events.md#recurring-api-event-types).

* Stopping agreements in the Vipps app (released on 2024-11-04):
  Please read [stopping an agreement in the Vipps MobilePay app](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-guide.md#stopping-an-agreement-in-the-vipps-mobilepay-app) and [see what it looks like in the app](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/how-it-works/payment-agreement/README.md).

* Landing page: More robust handling of retries. See [General changelog](https://developer.vippsmobilepay.com/docs/changelog.md#landing-page-more-robust-handling-of-retries) for details.

## September 2024

* List agreements v3 endpoint now supports pagination using the `pageNumber` and `pageSize` query parameters.
  See [List Agreements endpoint](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml)
  We recommend that you use the `pageNumber` and `pageSize` query to paginate the response. If not used, it could result in increased response times when the number of agreements is more. The chances of causing instabilities to other endpoints cannot be ruled out either.
  Also, the API endpoint allows merchants to fetch all agreements. If no query status is supplied, it will default to only retrieving the active agreements. There is no way to list all agreements with all statuses, due to performance.

## July 2024

* `phoneNumber` is validated only if `skipLandingPage` is set to `true`
   If `phoneNumber` is invalid and `skipLandingPage` is set to `false`, the Recurring API ignores the value and the user will have to enter their phone number on the landing page.
   If `phoneNumber` is invalid and `skipLandingPage` is set to `true`, the Recurring API will return the following error:

   ```json
   {
    "type": "https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-problems/#validation-error",
    "title": "Bad Request",
    "status": 400,
    "detail": "Invalid phone number",
    "instance": "/vipps-recurring-merchant-api/v3/agreements",
    "contextId": "8d728430-e5f1-4d76-a045-6a57231618b4"
   }
   ```

* `merchantRedirectUrl` max length was increased to 2048.
   See:
   [DraftAgreementV3 definition:](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml)

* Updated Payment Batches Schedule for Danish and Finnish market. The new timings are to avoid the batches running
  during the scheduled maintenance windows of Vipps MobilePay's vendors/partner banks.
  See:
  [Payment Batches Schedule:](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-guide.md#payment-batches-schedule).

## May 2024

* Added Danish and Finnish for in-app texts and push notification texts.
  See:
  [Notifications and error messages](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-guide.md#notifications-to-users-for-failed-charges).
* Added new limit of 2000 charges per request for the Recurring endpoint
  [`POST:/recurring/v3/agreements/charges`][create-multiple-charges-endpoint].
  See:
  [Create multiple charges](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-guide.md#create-multiple-charges).
* Added documentation about the cancellation of charges when an agreement is stopped by the user.
  See:
  [Stop an agreement](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-guide.md#stop-an-agreement).

## April 2024

* Fixed issue that caused some webhooks/callbacks to be sent before amounts were updated,
  which caused incorrect information in webhooks/callbacks. There is no plan for resending
  these webhooks/callbacks as of now, please reach out if this has caused any issues.

## March 2024

* If `externalId` is specified on the charge, it will be visible to the user on the charge order details screen.

## February 2024

* Added new webhook event type `recurring.charge-creation-failed.v1`.
  See:
  [Webhooks](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-guide.md#webhooks-integration).

* Added documentation for charge batch creation endpoint.
  See:
  [Create multiple charges](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-guide.md#create-multiple-charges).

* Unscheduled charge release. Please note that for MobilePay re-integrating merchants, this is
  the equivalent of the one-off `auto-reserve` feature.
  See:
  [Unscheduled charge](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-guide.md#unscheduled-charge).

* Flexible interval
  * Make interval a non required field anymore in the
    [`POST:/recurring/v3/agreements`][draft-agreement-endpoint]
    request body. If not specified, the agreement will have a `FLEXIBLE` interval type.
  * Make it possible to update the type of agreement interval. Update of
    [`PATCH:/recurring/v3/agreements/{agreementId}`][update-agreement-patch-endpoint]
    endpoint.

## January 2024

* Added webhook integration documentation. See:
  [Webhooks](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-guide.md#webhooks-integration)
  and the
  [Webhooks API](https://developer.vippsmobilepay.com/docs/APIs/webhooks-api/README.md).

## December 2023

* Fixed: `extraDetails` is now returned in the error response body format according to the RFC.
  See:
  [Errors](https://developer.vippsmobilepay.com/docs/knowledge-base/errors.md).

## November 2023

* Landing page update. Due to complexity of which price applies to an agreement, whether
  it's the agreement price, initial charge price, or promotional price, the
  [landing page](https://developer.vippsmobilepay.com/docs/knowledge-base/landing-page.md)
  will show agreement names instead of prices.

* Charge `externalId`:
  * If specified, the `externalId` will be used as order ID, meaning it will show up on
    settlement reports in place of the `orderId` field.
  * If both `orderId` and `externalId` are specified, the `externalId` will be used as
    order ID, while orderId will just be used to identify the charge in the Recurring API.

## October 2023

* Fixes in the Recurring OpenAPI spec file:
  * The optional field `externalId` can be set on an initial charge in the request body of the
    [`POST:/recurring/v3/agreements`][draft-agreement-endpoint]
    request.
  * `createdAfter` query parameter on the
    [`GET:/recurring/v3/agreements`][list-agreements-endpoint]
     is of type `int64`.
  * `failureReason` field returned in the `ChargeResponseV3` can be null.
  * `chargeId` field in the `DraftAgreementResponseV3` can be null.
  * `campaign` field in the `AgreementResponseV3` can be null.
  * `PricingResponse` can either be of type `VariableAmountPricingResponse` or `LegacyPricingResponse`.

* New optional field `interval` in the
  [`PATCH:/recurring/v3/agreements/{agreementId}`][update-agreement-patch-endpoint]
  endpoint, which allows updating the interval of an active agreement.

## August 2023

* Removed charge-amount-too-high-for-interval validation used in charge creation endpoint
  [`POST:/recurring/v3/agreements/{agreementId}/charges`][create-charge-endpoint].
  The `suggestedMaxAmount` field for a variable amount agreement should be set to what
  the maximum amount could be for each charge.

## June 2023

* A new field is returned by the
 [`GET:/recurring/v3/agreements/{agreementId}`][fetch-agreement-endpoint]
  endpoint:
  * `vippsConfirmationUrl`: previously redirected the user to the
    [landing page](https://developer.vippsmobilepay.com/docs/knowledge-base/landing-page.md)
    in a desktop flow (with `https://`), or to the Vipps or MobilePay app in a mobile flow
    (with `vipps://`), where the user can then approve the agreement.

## May 2023

* New fields returned by the
  [`GET:/recurring/v3/agreements/{agreementId}`][fetch-agreement-endpoint]
  endpoint:
  * `merchantAgreementUrl`: URL where Vipps can send the customer to view/manage their subscription.
  * `merchantRedirectUrl`: URL where customer should be redirected after the agreement has been
    approved/rejected in the Vipps mobile application.
  * `created`: Date when agreement was created in ISO 8601 format.

* New fields returned by the
 [`GET:/recurring/v3/agreements/{agreementId}/charges/{chargeId}`](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml)
 endpoint:
  * `retryDays`: The service will attempt to charge the customer for the number of days specified in `retryDays` after the `due` date.
  * `externalAgreementId`: Can be used by the merchant to map the `agreementId` to an ID in a subscription system or similar.

## April 2023

* New **optional** field `externalId` for agreements introduced. This field can be used to store an
  external ID for the agreement. Can be set in the request body of the
  [`POST:/recurring/v3/agreements`][draft-agreement-endpoint]
  request. `externalId` will be returned by the
  [`GET:/recurring/v3/agreements/{agreementId}`][fetch-agreement-endpoint]
  endpoint. It is also possible to update it using the
  [`PATCH:/recurring/v3/agreements/{agreementId}`][update-agreement-patch-endpoint]
  endpoint.

* New **optional** field `countryCode` for agreements introduced. Can be set in the request body
 of the
 [`POST:/recurring/v3/agreements`][draft-agreement-endpoint]
 request. `countryCode` will also be returned by the
 [`GET:/recurring/v3/agreements/{agreementId}`][fetch-agreement-endpoint]
 endpoint.

* New field `uuid` (UUID representation of agreement ID) returned by the
  [`GET:/recurring/v3/agreements/{agreementId}`][fetch-agreement-endpoint]
  response.

* New **optional** field `externalId` for charges introduced. This field can be used to store
  an external ID for the charge. Can be set in the
  [`POST:/recurring/v3/agreements/{agreementId}/charges`][draft-agreement-endpoint]
  request.

## March 2023

* The new endpoint
 [`GET:/recurring/v3/charges/{chargeId}`](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml)
 makes it possible to retrieve a charge specified by `chargeId`, without knowing the `agreementId`
 (unlike
 [`GET:/recurring/v3/agreements/{agreementId}/charges/{chargeId}`](https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml)).
  The resulting charge now contains the `agreementId`. Its purpose is to simplify investigations when
  the merchant lost track of which charge belongs to which agreement.

## December 2022

* Version 3 is available and includes new and improved functionality for campaigns, the ability
  to reserve and capture charges, and several technical improvements. The
  migration guide and
  [quick start](https://developer.vippsmobilepay.com/docs/APIs/recurring-api/recurring-api-quick-start.md)
  provide more details for upgrading to v3.  Version 2 will be phased out and will no longer
  be available from 2023-11-01.

[fetch-agreement-endpoint]: https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml
[list-agreements-endpoint]: https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml
[get-charge-by-id]: https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml
[draft-agreement-endpoint]: https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml
[create-charge-endpoint]: https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml
[update-agreement-patch-endpoint]: https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml
[create-multiple-charges-endpoint]: https://developer.vippsmobilepay.com/redocusaurus/recurring-swagger-id.yaml

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