For some reason PromotionTools.removePromotion() is getting called by some of the API's.
ATG provided source code for PromotionTools.java which you can copy into your module workspace and debug.
Add a break point in removePromotion() method to see the stack thread who is calling it. Or modify this method to print the stack trace to find the calling method.
This will lead you to find out why the promotion is revoked.
I couldn't find the reason why my coupon is being removed.
I tried to use another component, /atg/commerce/promotion/CouponFormHandler. When I put the couponCode in the form, it applies the discount but not the coupon code.
It gives the discount in the order, but the couponCode is not persisted, so it seems like just a promotion (without my coupon) is being applied.
Any suggestion? I really don't know why it is happening and why my couponCode is not being persisted.