How can we create a subs using appSubscriptionCreate such that the cancellation is deferred upto end of billing cycle but the upgrade is immediate i.e. the old subs is cancelled immediately and prorated upgrade plan starts. Given, that this subs behavior is handled by replacementBehavior but that can have only one behavior.
And the docs mentions that this behavior of appSubscriptionCancel is also handled by `replacementBehavior`
appSubscriptionCancel
mutation
Cancels an active app subscription, stopping future billing cycles. The cancellation behavior depends on the replacementBehavior setting
The replacement behavior when creating an app subscription for a merchant with an already existing app subscription.
Hide enum values
APPLY_IMMEDIATELY
Cancels the merchant’s current app subscription immediately and replaces it with the newly created app subscription.
APPLY_ON_NEXT_BILLING_CYCLE
Defers canceling the merchant’s current app subscription and applying the newly created app subscription until the start of the next billing cycle. This value is ignored if the new app subscription is using a different currency than the current app subscription, in which case the new app subscription is applied immediately.
STANDARD
Cancels the merchant’s current app subscription immediately and replaces it with the newly created app subscription, with the exception of the following scenarios where replacing the current app subscription will be deferred until the start of the next billing cycle.
The current app subscription is annual and the newly created app subscription is annual, using the same currency, but is of a lesser value.
The current app subscription is annual and the newly created app subscription is monthly and using the same currency.
The current app subscription and the newly created app subscription are identical except for the discount value.
Cancellation and upgrades are actually handled by two separate mutations, so you shouldn’t need a single replacementBehavior value to cover both cases.
For upgrades (replacing the current sub with a higher plan), you’d use appSubscriptionCreate with replacementBehavior: APPLY_IMMEDIATELY. This should cancel the old sub right away and start the new one, with proration applied.
For cancellations (merchant just wants to cancel, no new plan), you’d use the appSubscriptionCancel mutation instead. When you call this without prorate: true, the subscription is cancelled but the merchant has already paid through the current billing period - so access continues until currentPeriodEnd. The sub just won’t auto-renew for the next cycle.
So the flow would look something like:
Merchant upgrades → call appSubscriptionCreate with the new plan and replacementBehavior: APPLY_IMMEDIATELY
Merchant cancels → call appSubscriptionCancel (with prorate: false which is the default)
The replacementBehavior enum on appSubscriptionCreate is usually only useful when you’re creating a new subscription to replace an existing one - it shouldn’t come into play for standalone cancellations.
Sharing the docs for reference in case it’s help too:
For upgrades (replacing the current sub with a higher plan), you’d use appSubscriptionCreate with replacementBehavior: APPLY_IMMEDIATELY. This should cancel the old sub right away and start the new one, with proration applied.
how does proration work in detail for shopify subs?
When a merchant upgrades to a higher-priced plan mid-cycle via appSubscriptionCreate with replacementBehavior: APPLY_IMMEDIATELY, we calculate the prorated charge based on what the merchant has already paid, the cost difference between the plans, and the time left in the current billing cycle.