> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fynn.eu/llms.txt
> Use this file to discover all available pages before exploring further.

# Extend a payment plan

> Replace every not-yet-paid installment with a new schedule. Already paid installments stay untouched. Send EITHER `installments` OR `split`, exactly like create but without `invoiceId`. The new schedule must sum to the current open amount of the invoice in cents (in split mode the server computes it). A broken plan returns to `active`, and `brokenAt` and `brokenReason` are cleared. Use this instead of creating a new plan when a customer misses an installment or needs more time.



## OpenAPI

````yaml assets/openapi-v2-payment-plans.json post /api/payment-plans/{id}/extend
openapi: 3.1.0
info:
  title: Fynn V2 Payment Plans API
  version: 2026-07
  description: >-
    REST API for Fynn payment plans (Zahlungsplan). Split an open invoice into
    interest-free installments while dunning stays paused, let Fynn collect
    direct-debit installments automatically, and react to the plan lifecycle
    over webhooks. All amounts are integers in the smallest currency unit
    (cents). Authenticate with an Organisation API token.
servers:
  - url: https://coreapi.io
    description: Production
  - url: https://preview.coreapi.io
    description: Sandbox
security:
  - ApiToken: []
tags:
  - name: Payment Plans
    description: Create, read, cancel and extend the installment plan of an open invoice.
paths:
  /api/payment-plans/{id}/extend:
    post:
      tags:
        - Payment Plans
      summary: Extend a payment plan
      description: >-
        Replace every not-yet-paid installment with a new schedule. Already paid
        installments stay untouched. Send EITHER `installments` OR `split`,
        exactly like create but without `invoiceId`. The new schedule must sum
        to the current open amount of the invoice in cents (in split mode the
        server computes it). A broken plan returns to `active`, and `brokenAt`
        and `brokenReason` are cleared. Use this instead of creating a new plan
        when a customer misses an installment or needs more time.
      operationId: extendPaymentPlan
      parameters:
        - $ref: '#/components/parameters/PaymentPlanId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExtendPaymentPlanInput'
      responses:
        '200':
          description: The extended payment plan.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaymentPlan'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
components:
  parameters:
    PaymentPlanId:
      name: id
      in: path
      required: true
      schema:
        type: string
        format: uuid
        example: 10000000-0000-0000-00e0-000000000001
      description: The payment plan UUID.
  schemas:
    ExtendPaymentPlanInput:
      type: object
      description: >-
        Like the create body without invoiceId. Send EITHER installments OR
        split.
      properties:
        installments:
          type: array
          description: >-
            Manual mode. Replaces every not-yet-paid installment. Must sum to
            the current open amount in cents.
          items:
            $ref: '#/components/schemas/InstallmentInput'
        split:
          $ref: '#/components/schemas/SplitInput'
    PaymentPlan:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 10000000-0000-0000-00e0-000000000001
        invoiceId:
          type: string
          format: uuid
          example: 10000000-0000-0000-0003-000000000001
        status:
          $ref: '#/components/schemas/PlanStatus'
        totalAmount:
          type: integer
          description: >-
            Sum of all installments in cents. Equals the open amount at
            creation.
          example: 1190
        currencyCode:
          type: string
          example: EUR
        paymentMethodId:
          type: string
          format: uuid
          nullable: true
          example: 10000000-0000-0000-004f-000000000001
        createdAt:
          type: string
          format: date-time
          example: '2026-07-05T16:20:00+00:00'
        completedAt:
          type: string
          format: date-time
          nullable: true
          description: Timestamp the plan completed (all installments paid), or null.
          example: null
        brokenAt:
          type: string
          format: date-time
          nullable: true
          description: Timestamp the plan broke, or null.
          example: null
        canceledAt:
          type: string
          format: date-time
          nullable: true
          description: Timestamp the plan was canceled, or null.
          example: null
        brokenReason:
          type: string
          nullable: true
          description: Reason the plan broke, or null while active.
          example: null
        installments:
          type: array
          items:
            $ref: '#/components/schemas/Installment'
      required:
        - id
        - invoiceId
        - status
        - totalAmount
        - currencyCode
        - paymentMethodId
        - createdAt
        - completedAt
        - brokenAt
        - canceledAt
        - brokenReason
        - installments
    InstallmentInput:
      type: object
      description: One installment in manual mode.
      properties:
        dueAt:
          type: string
          format: date
          description: >-
            Due date of the installment (Y-m-d). Must lie in the future and be
            strictly after the previous installment.
          example: '2026-08-05'
        amount:
          type: integer
          description: >-
            Installment amount in the smallest currency unit (cents). Must be
            positive.
          example: 595
      required:
        - dueAt
        - amount
    SplitInput:
      type: object
      description: Even split of the open amount into a number of installments.
      properties:
        count:
          type: integer
          minimum: 2
          maximum: 36
          description: Number of installments to create.
          example: 3
        interval:
          type: string
          description: >-
            Distance between due dates as {n}{D|W|M|Y}, for example 1M for one
            month. Defaults to 1M.
          pattern: ^[0-9]+[DWMY]$
          default: 1M
          example: 1M
        firstDueAt:
          type: string
          format: date
          description: Due date of the first installment (Y-m-d). Must lie in the future.
          example: '2026-08-05'
      required:
        - count
        - firstDueAt
    PlanStatus:
      type: string
      description: Lifecycle status of a payment plan.
      enum:
        - active
        - completed
        - broken
        - canceled
    Installment:
      type: object
      properties:
        id:
          type: string
          format: uuid
        position:
          type: integer
          description: 1-based position within the plan.
          example: 1
        dueAt:
          type: string
          format: date
          description: Due date (Y-m-d).
          example: '2026-08-05'
        amount:
          type: integer
          description: Installment amount in cents.
          example: 595
        status:
          $ref: '#/components/schemas/InstallmentStatus'
        paidAt:
          type: string
          format: date-time
          nullable: true
          description: Timestamp the installment was fully covered (ISO 8601), or null.
          example: null
      required:
        - id
        - position
        - dueAt
        - amount
        - status
        - paidAt
    ProblemError:
      type: object
      description: >-
        Problem detail error body (application/problem+json). Additional members
        may be present depending on the error.
      properties:
        status:
          type: integer
          example: 422
        type:
          type: string
          description: Stable machine readable error key.
          example: PAYMENT_PLAN__SUM_MISMATCH
        title:
          type: string
          example: An error occurred
        detail:
          type: string
          example: The installments must sum to the open amount of the invoice.
      required:
        - status
        - type
        - title
        - detail
    ValidationError:
      type: object
      description: >-
        Validation error body (application/problem+json) returned when input
        fails field level validation.
      properties:
        status:
          type: integer
          example: 422
        type:
          type: string
          example: https://tools.ietf.org/html/rfc2616#section-10
        title:
          type: string
          example: Validation Failed
        violations:
          type: array
          items:
            type: object
            properties:
              propertyPath:
                type: string
                example: installments[0].amount
              message:
                type: string
                example: This value should be positive.
              code:
                type: string
                nullable: true
      required:
        - status
        - type
        - title
        - violations
    InstallmentStatus:
      type: string
      description: Status of a single installment.
      enum:
        - open
        - collecting
        - paid
        - failed
  responses:
    Unauthorized:
      description: Authentication is missing or the token is invalid.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemError'
    Forbidden:
      description: The token is valid but lacks the required permission.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemError'
    NotFound:
      description: The requested resource does not exist for this Organisation.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemError'
    UnprocessableEntity:
      description: The request failed validation or a business rule was violated.
      content:
        application/problem+json:
          schema:
            oneOf:
              - $ref: '#/components/schemas/ValidationError'
              - $ref: '#/components/schemas/ProblemError'
  securitySchemes:
    ApiToken:
      type: http
      scheme: bearer
      description: >-
        Organisation API token. Send it as Authorization: Bearer api_... The
        token is scoped to a single Organisation. Reading a plan needs the
        invoice read permission, creating, canceling and extending need the
        invoice write permission.

````