---
page_title: Plan Change 
product: Juspay Billing
page_source: https://juspay.io/in/docs/juspay-billing/docs/billing/plan-change
llms_txt: https://juspay.io/in/docs/llms.txt
product_llms_txt: https://juspay.io/in/docs/juspay-billing/llms.txt
---


# Upgrade Plan Changes



Plan Change allows merchants to upgrade or downgrade a customer's subscription plan mid-cycle 

without disrupting the active mandate. The process is a two-step flow: first preview the prorated charge, then execute the plan change by initiating a transaction against that preview.


## How It Works



The plan is **only updated after a successful payment** . If the transaction fails, the customer remains on their existing plan with no change to the billing cycle.

![Image](https://dth95m2xtyv8v.cloudfront.net/tesseract/assets/juspay-billing/Screenshot%202026-04-24%20at%208.40.45%E2%80%AFPM.png)




## Step 1: Preview Prorated Amount



Use this API to calculate the amount to be charged when a customer switches plans mid-cycle. 

The response shows a breakdown of what was used from the current plan, what remains, and the 

net prorated amount.

**Endpoint:** `POST /billing`

**Command:** `preview_prorated_amount`


### Request Parameters




| Parameter | Type | Required | Description |
|---|---|---|---|
| `command` | string | Yes | Must be preview_prorated_amount |
| `billing_execution_info_id` | string | Yes | Unique identifier for the active subscription execution |
| `request_id` | string | Yes | Idempotency key for this preview request |
| `updated_fields.plan_id` | string | Yes | The target plan the customer is switching to |
| `updated_fields.plan_amount` | number | Yes | Amount for the new plan |
| `updated_fields.rule_info.plan_rule_value` | number | No | Billing frequency or rule value for the new plan |



### Response Parameters




| Parameter | Type | Description |
|---|---|---|
| `billing_execution_info_id` | string | Echo of the subscription execution ID |
| `request_id` | string | Echo of the idempotency key |
| `cycle_start` | datetime (UTC) | Start of the current billing cycle |
| `new_cycle_end` | datetime (UTC) | End date of the new cycle after the plan change |
| `previously_paid_amount` | number | Amount already paid in the current cycle |
| `old_used_amount` | number | Value consumed from the existing plan up to today |
| `new_remaining_amount` | number | Credit remaining after accounting for past usage |
| `prorated_amount` | number | Net amount to charge the customer for the plan change |
| `preview_expires_at` | datetime (UTC) | Timestamp after which this preview is no longer valid |


> **Note**
> this timestamp expires, or a fresh preview must be fetched.




## Step 2: Execute Plan Change via Order API



Once the prorated amount is previewed and shown to the customer, initiate a payment using the 

Order API. The `billing_plan_change` payment flow links the transaction to the preview, 

ensuring the plan is updated atomically on payment success.

**Endpoint:** `POST /ecr/orders`


### Request Parameters




| Parameter | Type | Required | Description |
|---|---|---|---|
| `order_id` | string | Yes | Unique identifier for this order |
| `amount` | string | Yes | Prorated amount to charge (from Step 1 response) |
| `currency` | string | Yes | ISO 4217 currency code (e.g., INR) |
| `customer_id` | string | Yes | Juspay customer identifier |
| `gateway_id` | string | Yes | Target payment gateway |
| `return_url` | string | Yes | Redirect URL after payment completion |
| `payment_rules` | string (JSON) | Yes | Encodes the billing_plan_change flow with billing_execution_info_id and request_id from Step 1 |



#### `payment_rules` Structure



The `payment_rules` field drives the plan change execution. Pass the `billing_execution_info_id`

and `request_id` from the Step 1 preview response:


#### json Code Snippet:

```json
{
  "payment_flows": {
    "billing_plan_change": {
      "status": "REQUIRED",
      "info": {
        "billing_execution_info_id": "<from Step 1>",
        "request_id": "<from Step 1>"
      }
    }
  }
}

```


> **Note**
> Step 1 preview call. Mismatched IDs will cause the plan change to be rejected.




## Error Scenarios




| Scenario | Behaviour |
|---|---|
| Preview has expired (`preview_expires_at` passed) | Order creation fails; fetch a fresh preview |
| `request_id` mismatch between preview and order | Plan change rejected |
| Payment fails | Customer remains on existing plan; cycle is unaffected |
| Duplicate `order_id` | Idempotent — returns existing order state |


## Sample Code Snippets:
### Request:

#### Get Prorated Amount Code Snippet:

```get prorated amount
curl --location 'http://api.juspay.in/billing' \
--header 'Authorization: Basic <Auth Key>' \
--header 'Content-Type: application/json' \
--data '{
    "command": "preview_prorated_amount",
    "billing_execution_info_id": "e91247bc23ac4609b20faf3677e506f0",
    "request_id": "test_001",
    "updated_fields": {
        "plan_id": "test02",
    }
}'
```

#### Step 2 :- Order Request Code Snippet:

```step 2 :- order request
curl --location 'http://api.juspay.in/ecr/orders' \
--header 'version: 2018-07-01' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic <Auth Key>' \
--data '{
    "order_id": "1776925371",
    "amount": "1",
    "currency": "INR",
    "customer_id": "cth_rPj21roNSjEbumSy",
    "payment_rules": "{\"payment_flows\":{\"billing_plan_change\":{\"status\":\"REQUIRED\",\"info\":{\"billing_execution_info_id\":\"e91247bc23ac4609b20faf3677e506f0\",\"request_id\":\"test_001\"}}}}",
    "return_url": "https://sandbox.juspay.in"
}'
```

#### Step 2 :- Session API Code Snippet:

```step 2 :- session api
curl --location 'https://api.juspay.in/session' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic <Auth Key>' \
--data '{
    "order_id": "<order_id>",
    "amount": "1.0",
    "customer_id": "<customer_id>",
    "payment_page_client_id": "<payment_page_client_id>",
    "action": "paymentPage",
    "return_url": "<return_url>",
    "description": "Plan upgrade payment",
    "payment_rules": "{\"payment_flows\":{\"billing_plan_change\":{\"status\":\"REQUIRED\",\"info\":{\"billing_execution_info_id\":\"<billing_execution_info_id>\",\"request_id\":\"<request_id>\"}}}}"
}'
```

### Response:

#### Get Prorated Amount Response:
```plaintext
{
    "new_cycle_end": "2026-04-29T00:00:00Z",
    "old_used_amount": 0,
    "request_id": "test_001",
    "billing_execution_info_id": "e91247bc23ac4609b20faf3677e506f0",
    "new_remaining_amount": 12,
    "prorated_amount": 11,
    "preview_expires_at": "2026-04-23T23:58:00Z",
    "previously_paid_amount": 1,
    "cycle_start": "2026-04-23T00:00:00Z"
}
```

#### Order Response:
```plaintext
{
  "status": "CREATED",
  "status_id": 1,
  "id": "ord_e294a26e66ad4336a992ceab81ad704c",
  "order_id": "14183944763",
  "payment_links": {
    "web": "https://api.juspay.in/merchant/pay/ord_e294a26e66ad4336a992ceab81ad704c",
    "mobile": "https://api.juspay.in/merchant/pay/ord_e294a26e66ad4336a992ceab81ad704c?mobile=true",
    "iframe": "https://api.juspay.in/merchant/ipay/ord_e294a26e66ad4336a992ceab81ad704c"
  }
}
```



---

## See Also

- [Order Status](https://juspay.io/in/docs/juspay-billing/docs/billing/order-status)
- [Get Execution Info ](https://juspay.io/in/docs/juspay-billing/docs/billing/get-execution-info)
