ISV (Independent Software Vendor): A Microsoft program that helps customers adopt Microsoft Cloud solutions and drive user adoption.
Hello Aniruddha Joshi,
Greetings! Thanks for raising this question in the Q&A forum.
The behavior you are seeing is expected up to a point, and then it runs into a genuine platform side limitation rather than something wrong in your webhook handler.
- Intended behavior of "Upgrade to Paid"
This button is meant to end the free trial early and start billing immediately for the same plan, it is not meant to move the customer to a different plan or a different SKU. A trial and its paid continuation share the same plan ID, the only thing that changes is the isFreeTrial flag and the billing start date. This is why Marketplace sends a CHANGE_PLAN webhook with the same plan ID on both sides, from the platform's point of view ending a trial early is technically modeled as a plan operation even though the plan itself does not change. This answers your first question, your assumption was correct, it should immediately end the trial and convert to paid for the same azure-plan.
- Why your webhook handling is not the problem
Since the source and target plan IDs are identical, there is nothing for your fulfillment service to actually change on its own side, the correct response is to accept the operation and call the Update Status of Operation API with a success status without attempting any internal plan migration logic, since none is needed. You already did this and your backend returned success correctly.
- Where the actual failure is happening
The error message you are seeing, Line item ... is already in for SkuId ... and cannot be converted to it, is generated by Microsoft's own commerce backend when it tries to finalize the early trial to paid conversion at the billing layer, not by anything your webhook returned. This is the same validation rule documented for the Change Plan API where the target plan being identical to the current plan is treated as a bad request, except here it is Microsoft's own internal call hitting that same validation rather than a call you made. This points to the early trial conversion flow for the "Upgrade to paid" button not being fully wired through for this specific combination, and since you are testing this on a Preview offer, this kind of edge case in early trial termination is more likely to surface before an offer goes live.
- What to do next
Since this failure originates in Microsoft's backend and is not something a publisher side webhook fix can resolve, you will need to escalate this through Partner Center support so the Marketplace engineering team can look directly at the failed operation.
Partner Center > Support > New support request
Category: Marketplace offers
Subcategory: SaaS technical issues
Include the subscription ID, the publisher ID and offer ID, the plan ID azure-plan, the approximate timestamp of the failed upgrade attempt, and the exact error text shown in the portal, this lets the engineer pull the operation record on their side and confirm whether this is a known issue with early trial termination on Preview SaaS offers.
- Workaround while this is being investigated
Until this is resolved, avoid relying on customers clicking "Upgrade to paid" mid trial for this offer, since the conversion will keep failing at the platform layer regardless of how your webhook responds. The automatic conversion that happens naturally at the end of the trial period should still work normally, since that is a different internal flow than the explicit early upgrade action.
If this answer helps you kindly accept the answer which will help others who have similar questions.
Best Regards,
Jerald Felix