diff --git a/Library/ProrationSettings.cs b/Library/ProrationSettings.cs new file mode 100644 index 00000000..1fa964db --- /dev/null +++ b/Library/ProrationSettings.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; + +namespace Recurly +{ + public class ProrationSettings + { + public enum Options + { + ProratedAmount, + FullAmount, + None + } + + /// + /// Proration behavior to be applied to charges for the subscription change. + /// Can be set to FullAmount, ProratedAmount, or None. + /// When not set, default proration settings will be applied. + /// + public Options? Charge { get; set; } + + /// + /// Proration behavior to be applied to credits for the subscription change. + /// Can be set to FullAmount, ProratedAmount, or None. + /// When not set, default proration settings will be applied. + /// + public Options? Credit { get; set; } + } +} diff --git a/Library/SubscriptionChange.cs b/Library/SubscriptionChange.cs index c6c19a93..af04aaf3 100644 --- a/Library/SubscriptionChange.cs +++ b/Library/SubscriptionChange.cs @@ -24,6 +24,12 @@ public enum ChangeTimeframe : short public string PlanCode { get; set; } + /// + /// Proration settings to be applied to the subscription change. + /// If not set, the default proration behavior will apply. + /// + public ProrationSettings ProrationSettings { get; set; } + /// /// List of custom fields /// @@ -127,6 +133,20 @@ internal void WriteChangeSubscriptionXml(XmlTextWriter xmlWriter) xmlWriter.WriteStringIfValid("plan_code", PlanCode); + if (ProrationSettings != null) + { + xmlWriter.WriteStartElement("proration_settings"); + + if (ProrationSettings.Charge != null) + xmlWriter.WriteElementString("charge", ProrationSettings.Charge.Value.ToString().EnumNameToTransportCase()); + + if (ProrationSettings.Credit != null) + xmlWriter.WriteElementString("credit", ProrationSettings.Credit.Value.ToString().EnumNameToTransportCase()); + + xmlWriter.WriteEndElement(); + } + + if (AddOns != null) xmlWriter.WriteIfCollectionHasAny("subscription_add_ons", AddOns); diff --git a/Test/SubscriptionTest.cs b/Test/SubscriptionTest.cs index 4b3b902e..d8a61255 100644 --- a/Test/SubscriptionTest.cs +++ b/Test/SubscriptionTest.cs @@ -305,6 +305,54 @@ public void UpdateSubscription() Assert.Equal(newSubscription.NetTermsType, NetTermsType.NET); } + [RecurlyFact(TestEnvironment.Type.Integration)] + public void UpdateSubscriptionWithProrationSettings() + { + var plan = new Plan(GetMockPlanCode(), GetMockPlanName()) + { + Description = "Update Subscription Plan 1" + }; + plan.UnitAmountInCents.Add("USD", 1500); + plan.Create(); + PlansToDeactivateOnDispose.Add(plan); + + var plan2 = new Plan(GetMockPlanCode(), GetMockPlanName()) + { + Description = "Update Subscription Plan 2" + }; + plan2.UnitAmountInCents.Add("USD", 750); + plan2.Create(); + PlansToDeactivateOnDispose.Add(plan2); + + var account = CreateNewAccountWithBillingInfo(); + + var sub = new Subscription(account, plan, "USD"); + sub.Create(); + + var subChange = new SubscriptionChange() + { + PlanCode = plan2.PlanCode, + ProrationSettings = new ProrationSettings() + { + Charge = ProrationSettings.Options.None, + Credit = ProrationSettings.Options.FullAmount + } + }; + + Assert.Equal(subChange.ProrationSettings.Charge, ProrationSettings.Options.None); + Assert.Equal(subChange.ProrationSettings.Credit, ProrationSettings.Options.FullAmount); + + Subscription.ChangeSubscription(sub.Uuid, subChange); + + var newSubscription = Subscriptions.Get(sub.Uuid); + var invoices = account.GetInvoices(); + var chargeInvoice = invoices.FirstOrDefault(invoice => invoice.Type == "charge"); + var creditInvoice = invoices.FirstOrDefault(invoice => invoice.Type == "credit"); + + Assert.Equal(0, chargeInvoice.SubtotalInCents); + Assert.Equal(-1500, creditInvoice.SubtotalInCents); + } + [RecurlyFact(TestEnvironment.Type.Integration)] public void CancelSubscription() {