# Create Change Request

The merchant business system initiates an upgrade (UPGRADE) or downgrade (DOWNGRADE) of a user's subscription plan via the Create Change Request API. The change uses a two-phase confirmation model: this API only creates a change reservation and generates a cashier confirmation link. The actual change is executed only after the user confirms on the cashier page.

# API Description

API

Request API: /api/subscription/change/create

Request Method: POST

Request Type: application/json or application/x-www-form-urlencoded

# Request Parameters

Field Name Variable Name Required Type Example Value Description
Merchant No mchNo Yes String(30) M1621873433953 Merchant Number
App ID appId Yes String(24) 60cc09bce4b0f1c0b83761c9 App ID
Subscription ID subscriptionId Yes String(32) SUB_20210618164232 Subscription ID to be changed
Target Plan ID newPlanId No String(32) PLAN_002 Target subscription plan ID for upgrade/downgrade; mutually exclusive with newPlanCode
Target Plan Code newPlanCode No String(64) PRO_MONTH Target subscription plan code for upgrade/downgrade; mutually exclusive with newPlanId
Change Type changeType Yes String(20) UPGRADE Change type: UPGRADE / DOWNGRADE
Effective Type effectiveType No String(20) IMMEDIATE Effective type: IMMEDIATE / NEXT_PERIOD.
Optional for downgrade (defaults to NEXT_PERIOD); required for upgrade

| Change Return URL | returnUrl | No | String(256) | https://merchant.com/changeReturn | Change-level return URL for cashier cancel/supplement redirect.
Notification URL reuses the subscription-level notifyUrl | | Request Time | reqTime | Yes | long | 1622016572190 | Request timestamp (13 digits) | | API Version | version | Yes | String(3) | 1.0 | API version, fixed: 1.0 | | Sign | sign | Yes | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | Signature value, see signature algorithm | | Sign Type | signType | Yes | String(32) | MD5 | Signature type, currently only supports MD5 |

# Request Example Data

{
  "mchNo": "M1623984572",
  "appId": "60cc09bce4b0f1c0b83761c9",
  "subscriptionId": "SUB_20210618164232",
  "newPlanId": "PLAN_002",
  "changeType": "UPGRADE",
  "effectiveType": "IMMEDIATE",
  "returnUrl": "https://merchant.com/changeReturn",
  "reqTime": "1622016572190",
  "version": "1.0",
  "signType": "MD5",
  "sign": "84F606FA25A6EC4783BECC08D4FDC681"
}

Target Plan Parameter

Provide either newPlanId or newPlanCode. The example uses newPlanId; merchants may instead pass newPlanCode (e.g. "newPlanCode": "PRO_MONTH") to identify the target plan — the system resolves it to the corresponding planId using the subscription's mchNo/appId/currency.

# Response Parameters

Field Name Variable Name Required Type Example Value Description
Return State code Yes int 0 0-Success, others-Error, see error codes
Return Msg msg No String(128) Signature failed Specific error reason
Sign Info sign No String(32) CCD9083A6DAD9A2DA9F668C3D4517A84 Signature for data
Return Data data No Object {} Returned change data

# Data Format (SubscriptionChangeRS)

Field Name Variable Name Type Example Value Description
Change ID changeId String CHG_20210618164201 Unique change record ID, used for subsequent confirm/query/reconciliation
Diff Amount diffAmount Long 1500 Difference in cents, computed from new vs original plan proration; positive means supplement required at confirmation for immediate upgrade
Currency currency String USD Subscription currency, pair with diffAmount for amount display
Cashier Confirm URL confirmUrl String https://cashier.enjoypayment.com/change/CHG_xxx/TOKEN Cashier link guiding user to confirm the change, expires after 1 hour
Change State changeState Integer 0 0-Pending, 1-Effective, 2-Canceled, 3-Failed
Replaced Change ID replacedChangeId String CHG_20210618160001 Returned when an unconfirmed old change is auto-replaced on creation, for reconciliation

# Response Example Data

{
  "code": 0,
  "msg": "SUCCESS",
  "data": {
    "changeId": "CHG_20210618164201",
    "diffAmount": 1500,
    "currency": "USD",
    "confirmUrl": "https://cashier.enjoypayment.com/change/CHG_20210618164201/a1b2c3d4-e5f6",
    "changeState": 0
  },
  "sign": "F4DA202C516D1F33A12F1E547C5004FD"
}

# Business Rules

Note

  • Subscription State: Only Active or Overdue subscriptions can initiate a change.
  • Target Plan: Must be in PUBLISHED state, and belong to the same app (appId), merchant (mchNo), and currency as the current subscription. Changing to the same current plan is not allowed.
  • Upgrade (UPGRADE):
    • effectiveType is required.
    • Immediate (IMMEDIATE): Prohibited when less than 24 hours remain in the current period; diff amount must be greater than 0; the subscription must have a bound payment method (paymentMethodToken). A supplement pay order is created on confirmation and charged; the plan switches after successful payment.
    • Next Period (NEXT_PERIOD): Writes the pending plan on confirmation and switches at the next renewal deduction.
    • The target plan amount must be higher than the current (dual validation on first phase and landing tier).
  • Downgrade (DOWNGRADE): Only supports next period (NEXT_PERIOD); passing IMMEDIATE is rejected. The target plan amount must be lower than the current.
  • Cross-subscription plan occupation: The system checks whether the target plan is already occupied by another subscription of the same user (active subscription, unconfirmed change, confirmed next-period change); changes are rejected if occupied.
  • Concurrent replacement: If an unconfirmed pending change exists, the new change auto-cancels and replaces the old one (returns replacedChangeId; the old change receives a SUBSCRIPTION_CHANGE_CANCELED notification). If a confirmed immediate change is in-flight (funds in transit), creation is rejected.

# Change Flow

1. Merchant calls [Create Change Request] → obtains changeId + confirmUrl
2. Guide user to open confirmUrl (cashier confirm page)
   ├─ User confirms → [Confirm Change] executes the actual change
   └─ User cancels → [Cashier Cancel Change] cancels the reservation
3. Change result is asynchronously notified via [Subscription Notification]

Tip

The confirmation link is valid for 1 hour. After expiration, a new change request must be initiated. Unconfirmed changes are automatically cleaned up by the system after expiration.

Last Updated: 8/25/2026, 11:42:47 PM