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..860653b8 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()
{