ARTICLE AD BOX
Use case: we have a subscription based system in our platform.
Plus tier monthly ( 199/- ) yearly ( 1199/- ) Pro tier monthly ( 499/- ) yearly ( 2999/- )Subscriptions are being handled in Razorpay with backend in Golang.
Scenario:
User wants to change the subscription mid cycle, say Plus Yearly subscription 1199/- to Pro Monthly subscription 499/-
Scenario 1 (Change at 6th month end) Credits of 600/- is still left to be used Net payment is 499 - 600 < -100 This will be adjusted in billing user pays 0 and pro monthly is unlocked. Next subsequent billings are 499/- only
Scenario 2 (Change at 11th month end) Credits of 100/- is left net payment is 499 - 100 = 399 user pays 399 and pro monthly is unlocked. Next subsequent billings are 499/- only
Query : How does the razorpay dialog box in frontend show 0 or 399 ( custom values ) for the first payment? And will razorpay charge 499 from next months are we sure about it? How does updation works basically thats what i want to ask in golang.
I tried an addon Feature but that didn't seem to work
if creditsLeft > 0 { err = s.CreateSubscriptionAddon(subscriptionID, creditsLeft) if err != nil { s.Logger.Error().Err(err).Str("subscription_id", subscriptionID).Float64("credits", creditsLeft).Msg("Failed to create addon for proration credit - proceeding anyway") } } func (s *PaymentService) CreateSubscriptionAddon(subscriptionID string, creditAmount float64) error { url := fmt.Sprintf("https://api.razorpay.com/v1/subscriptions/%s/addons", subscriptionID) amountInPaise := int(creditAmount * -100) addonData := map[string]interface{}{ "item": map[string]interface{}{ "name": "Proration Credit", "amount": amountInPaise, "currency": "INR", "description": fmt.Sprintf("Unused credit from previous subscription (₹%.2f)", creditAmount), }, "quantity": 1, } jsonData, err := json.Marshal(addonData) if err != nil { return fmt.Errorf("failed to marshal addon data: %w", err) } req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData)) if err != nil { return fmt.Errorf("failed to create request: %w", err) } req.SetBasicAuth(s.Config.RAZORPAY_KEY_ID, s.Config.RAZORPAY_SECRET) req.Header.Set("Content-Type", "application/json") client := &http.Client{Timeout: 10 * time.Second} resp, err := client.Do(req) if err != nil { return fmt.Errorf("failed to make request to Razorpay: %w", err) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { return fmt.Errorf("failed to read response: %w", err) } if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated { s.Logger.Error(). Int("status_code", resp.StatusCode). Str("response", string(body)). Msg("Razorpay addon creation failed") return fmt.Errorf("razorpay API error (status %d): %s", resp.StatusCode, string(body)) } var addonResponse map[string]interface{} if err := json.Unmarshal(body, &addonResponse); err != nil { return fmt.Errorf("failed to parse addon response: %w", err) } s.Logger.Info(). Str("addon_id", addonResponse["id"].(string)). Float64("credit_amount", creditAmount). Str("subscription_id", subscriptionID). Msg("Successfully created addon for subscription") return nil }I get these logs :
2025-11-19T22:41:13+05:30 | INFO | create_order.razorpay.go:265 Calculated proration credits current_date=2025-11-19T22:41:13+05:30 days_elapsed=2.3787112890856483 file = create_order.razorpay.go line=265 start_date=2025-11-17T08:05:53Z subscription_amount=199 total_days=31.43341435185185 unused_credits=183.94075313520128 used_credits=15.059246864798718 2025-11-19T22:41:14+05:30 | INFO | create_order.razorpay.go:303 Created Razorpay subscription file = create_order.razorpay.go line=303 subscription_id=sub_Rhg05WWkWI9Ona 2025-11-19T22:41:14+05:30 | INFO | create_order.razorpay.go:313 Applying proration credit via addon credits=183.94075313520128 file = create_order.razorpay.go line=313 subscription_id=sub_Rhg05WWkWI9Ona 2025-11-19T22:41:15+05:30 | INFO | create_order.razorpay.go:494 Successfully created addon for subscription addon_id=ao_Rhg06tuDnnsdNR credit_amount=183.94075313520128 file = create_order.razorpay.go line=494 subscription_id=sub_Rhg05WWkWI9OnaBut still I get this in the frontend ( this can be because they're using sub id which I send back )

![Razorpay]
Wasn't I supposed to get a lesser amount.
Response that is sent back in Create Razorpay Order API:
{ "resp_code": "1", "message": "Razorpay subscription created successfully with Universal Autopay", "response": { "subscription_id": "sub_Rhg05WWkWI9Ona", "amount_to_pay": "315.06", "autopay_enabled": false, "approval_url": "https://rzp.io/rzp/gJBZZXd" } }What should I do ? Also, is there any other part of the code that I should share
