---
title: Change Price - Action
description: Changes the price and/or product of a subscription.
---

Required for :badge{label="Change Price Offer"} to work.

To implement the `Change Price` action, you need to implement an endpoint and define `features`

## Prerequisites
::grid{cols="2"}
    ::card-baseline{title="Subscriptions - Controller" to="/integrations/controllers/subscriptions"}
      You must implement a `Subscriptions` controller first.
      ::flex{class="mt-4"}
        :badge{label="Required" color="green"}
      ::
    ::
    ::card-baseline{title="Prices - Controller" to="/integrations/controllers/prices"}
      You must implement a `Prices` controller first.
      ::flex{class="mt-4"}
        :badge{label="Required" color="green"}
      ::
    ::
    ::card-baseline{title="Cancel - Action" to="/integrations/actions/cancel"}
      Price change is a part of the Cancel Flow. You must implement the `Cancel` action first.
      ::flex{class="mt-4"}
        :badge{label="Required" color="green"}
      ::
    ::
::

## SDK
If you are using the SDK, you can implement the `Change Price` action by following the code example below. You don't need to get into the details of the API endpoints, the SDK will take care of that for you.

::code-group
```typescript [Typescript]
import { Integrator } from '@churnkey/sdk'
import { Subscriptions } from '../controllers/Subscriptions'
import { Prices } from '../controllers/Prices'

export const ChangePrice = Integrator.ChangePrice.config({
    Subscriptions: Subscriptions,
    Prices: Prices,
    features: {
        enabled: true,
        schedules: {
            [Integrator.ChangePrice.Schedule.Immediate]: true,
            [Integrator.ChangePrice.Schedule.EndOfPeriod]: true
        },
        prorate: true
    },
    async handle(ctx, options) {
        const subscription = await this.subscriptions.retrieve({
            customerId: options.customerId,
            id: options.subscriptionId
        })

        const price = await this.prices.retrieve({
            id: options.price
        })

        await ctx.db.changePrice({ subscription, price, at: options.scheduledAt, prorate: options.prorate })
    }
})
```
::

## Endpoints

### Handle :badge{label="Required" color="green"}

`POST /churnkey/actions/subscription/apply-coupon`

This endpoint changes a price of subscription. You should find the subscription by `customerId` and `subscriptionId` and set a new price to it.

Options for this action provided in the request body.

::collapsible{name="request body"}
  :field-schema{schema="/types/actions/change-price/request.type.json"}
::

::collapsible{name="response"}
    ::tabs
        ::div{label="200"}
        Must return empty response.
        ::
        ::div{label="Error"}
        See [Error Responses](/integrations/general#error-responses).
        ::
    ::
::

::collapsible{name="code example"}
  ::code-group
  ```typescript [Typescript Express]
    app.post('/churnkey/actions/subscription/change-price', async (req, res) => {
        const subscription = await db.findSubscription(req.body.customerId, req.body.subscriptionId)
        const price = await db.findPrice(req.body.id)

        await db.changePrice({subscription, price, at: req.body.scheduledAt, prorate: req.body.prorate})
        res.send()
    })
  ```
  ::
::

## Features :badge{label="required" color="green"}

Features define which behavior is supported for the `Change Price` action. Depending on the features you enabled, requests body will have different options.

::collapsible{name="schema"}
  :field-schema{schema="/types/actions/change-price/features.type.json"}
::
::collapsible{name="code example"}
  ::code-group
  ```typescript [Typescript]
  export interface Features {
    enabled: boolean
    schedules: {
        immediate: boolean,
        'end-of-period': boolean
    },
    prorate: boolean
  }

  export const features: Features = {
    enabled: true,
    schedules: {
        immediate: true,
        'end-of-period': true
    },
    prorate: true
  }
  ```
::