Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Subscription Schedule #1491

Merged
merged 1 commit into from
Feb 12, 2019

Conversation

remi-stripe
Copy link
Contributor

@remi-stripe remi-stripe commented Jan 28, 2019

Add support for Subscription Schedule APIs

  • Add Subscription Schedule
  • Add Subscription Schedule Revisions
  • Add invoice_settings on the Customer

cc @stripe/api-libraries

@remi-stripe remi-stripe force-pushed the remi-add-subscription-schedules branch from 7ec3fb0 to dd7c76f Compare January 29, 2019 05:46
@remi-stripe remi-stripe force-pushed the remi-add-subscription-schedules branch from dd7c76f to b98952e Compare February 7, 2019 05:38
@remi-stripe
Copy link
Contributor Author

@ob-stripe Okay I think this is ready to review entirely. There is a lot of content here as this is a complex resource with multiple layers of nested hashes and there are "shared" properties where naming (in this PR) is not great.

Can I ask you to review thoroughly to ensure everything is fully correct? Please pay attention to all class names and feel free to ask me to rename everything.

Relatedly, there's a deserialization error because I try to expand phases.coupon but I don't get a coupon backand only getnull` which fails the test and shows either a failure in the fixture/openapi/something else.

/// new billing period.
/// </summary>
[JsonProperty("billing_thresholds")]
public SubscriptionSchedulePhasePlanBillingThresholds BillingThresholds { get; set; }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flagging that this is the same hash as the one on Subscription Item documented here. I did not want to re-use that class name as it's SubscriptionItemBillingThresholds and it's confusing.

@alexander-stripe suggested we unify though and rename both to UsageBasedBillingThreshold for example. Renaming would be a breaking change but since have a major revision shipping tomorrow or Friday maybe it's worth it? This also impacts the Options class(es).

Note that there is also billing_thresholds at the top level of this object and this one matches the one on Subscription and so I shared SubscriptionBillingThresholds because it felt like it made sense.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My default position on this is that we should try to match the OpenAPI spec as much as possible. In this case, the spec uses subscription_item_billing_thresholds here so I think we should do the same. That way, if the structure changes in the future, we'll only have to update one class instead of two.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have clear fud here because openapi is generated based on client-metadata in pay-server. This is a separate discussion though.
Also whatever is in openapi can change without being considered a breaking change by anyone but a few of us.

I am fine using the subscription_item_billing_thresholds if you want, but I think it's for the wrong reasons. We should rename openapi in that case really.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My point was that both resources use the same schema in OpenAPI, which means that in our backend code subscription_item_billing_thresholds is defined once and referenced in both resources. So if it ever changes, it would change for both resources at once and we'd need to reflect that in the bindings.

I agree the name is bad because it specifically mentions subscription_item, and should be changed.

[JsonProperty("current_phase")]
public SubscriptionScheduleCurrentPhase CurrentPhase { get; set; }

// TODO: figure out how we document those
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I bother documenting since this is going away in your next major version?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The properties are not going away, so I'd say yes, we should document them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ob-stripe Sure but the entire "region" is going away though. So my todo/question holds: How should I document this? Can you show me an example with this region on where to put the comments so that your rebase is not too painful?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The region would stay there too, what would change is:

  • public string CustomerId { get; set; } --> public string CustomerId => InternalCustomer.Id;
  • public Customer Customer { get; set; } --> public Customer Customer => InternalCustomer.ExpandedObject;
  • internal object InternalCustomer { ... } --> internal ExpandableField<Customer> InternalCustomer;

Here's an example for documenting the public accessors for the ID and object: https://github.com/stripe/stripe-dotnet/blob/master/src/Stripe.net/Entities/Disputes/Evidence.cs#L16-L28. Not sure it's the best format, but it's something.

using System.Collections.Generic;
using Newtonsoft.Json;

public class SubscriptionScheduleInvoiceSettingsOptions : StripeEntity
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Talking with @alexander-stripe There is a world in which all invoice_settings are merged (instead of being 2 separate hashes). This is not yet scheduled/planned though, just some thoughts. This means that when it happens it'd be a major/breaking change anyway.

Still flagging that I am not happy with all those classes names that are attached to the first object ever seeing them...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I feel the same, but I don't have a great solution to offer. The OpenAPI spec isn't even helpful here.

Maybe the right way to handle this is via inner classes, but we don't have a precedent for this in Stripe.net and I'm really not sure this is how we want to handle these nested parameters.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think last time we tried there was a stylecop rule against nested class.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah right, thanks. I'm not against changing that rule, but we'd have to be sure it's the right move. stripe-java does use inner classes, so it's worth experimenting with them at least.


public class SubscriptionScheduleListOptions : ListOptionsWithCreated
{
// TODO: Figure out how to document those
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do I document those? Do I ignore since you're fixing in the next major revision?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, probably fine to leave them undocumented for now. I'll add docstrings once #1495 lands.

/// Interval at which to renew the subscription schedule for when it ends. Possible values
/// are <code>day</code>, <code>week</code>, <code>month</code>, or <code>year</code>.
/// </summary>
// TODO: Decide if using PlanInterval
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I be using PlanInterval here? It's the same list, but also feels like a different meaning (and maybe we would like this to be renamed to BillingInterval?)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it's annoying, and the OpenAPI spec is no help here either as the enums are not defined as a single schema that is referenced from different parameters, but rather duplicated for each parameter.

I'd leave as is for now, but it's something we should fix upstream.

Copy link
Contributor

@ob-stripe ob-stripe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor comments. LGTM in general, but I haven't reviewed every single resource attribute and request parameter. Someone from Billing should probably take a look too.

[JsonProperty("current_phase")]
public SubscriptionScheduleCurrentPhase CurrentPhase { get; set; }

// TODO: figure out how we document those
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The properties are not going away, so I'd say yes, we should document them.

/// new billing period.
/// </summary>
[JsonProperty("billing_thresholds")]
public SubscriptionSchedulePhasePlanBillingThresholds BillingThresholds { get; set; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My default position on this is that we should try to match the OpenAPI spec as much as possible. In this case, the spec uses subscription_item_billing_thresholds here so I think we should do the same. That way, if the structure changes in the future, we'll only have to update one class instead of two.

using System.Collections.Generic;
using Newtonsoft.Json;

public class SubscriptionScheduleInvoiceSettingsOptions : StripeEntity
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I feel the same, but I don't have a great solution to offer. The OpenAPI spec isn't even helpful here.

Maybe the right way to handle this is via inner classes, but we don't have a precedent for this in Stripe.net and I'm really not sure this is how we want to handle these nested parameters.


public class SubscriptionScheduleListOptions : ListOptionsWithCreated
{
// TODO: Figure out how to document those
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, probably fine to leave them undocumented for now. I'll add docstrings once #1495 lands.

/// Interval at which to renew the subscription schedule for when it ends. Possible values
/// are <code>day</code>, <code>week</code>, <code>month</code>, or <code>year</code>.
/// </summary>
// TODO: Decide if using PlanInterval
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it's annoying, and the OpenAPI spec is no help here either as the enums are not defined as a single schema that is referenced from different parameters, but rather duplicated for each parameter.

I'd leave as is for now, but it's something we should fix upstream.

@remi-stripe remi-stripe force-pushed the remi-add-subscription-schedules branch from b98952e to 33f1c6d Compare February 7, 2019 16:30
@ob-stripe
Copy link
Contributor

Relatedly, there's a deserialization error because I try to expand phases.coupon but I don't get a coupon backand only getnull` which fails the test and shows either a failure in the fixture/openapi/something else.

Yes, phases.coupon is null in the fixtures file for both the schedule and schedule revision objects. Mind commenting out that assertion in the test for now?

@remi-stripe remi-stripe force-pushed the remi-add-subscription-schedules branch 2 times, most recently from 21795c8 to 7caa820 Compare February 7, 2019 18:02
@remi-stripe
Copy link
Contributor Author

@alexander-stripe Assigning to you for the final review to ensure all the resources are described properly and that I did not miss anything.

The main "meta" question left is whether we want to "share" BillingThresholds classes between the one on a subscription item and the one on the phases[][plans][]. If you don't feel strongly we will go with what the PR did (separate classes) for now.

@alexander-stripe
Copy link
Contributor

I glanced over this, it looks like it has the right shape to me. Thanks for this :-) I don't feel strongly to share the classes, although I can't see them diverge in the future so it may be worth unifying. Other than that

LGTM

@remi-stripe remi-stripe force-pushed the remi-add-subscription-schedules branch from 7caa820 to 48b1b7a Compare February 9, 2019 19:02
@remi-stripe
Copy link
Contributor Author

After spending a while on the stripe-java version (manual and autogenerated) I decided that I agreed and that Phase and PhaseItem were better names and that I should re-use the SubscriptionItemBillingThresholds* classes so I did just that.

* Add Subscription Schedule
* Add Subscription Schedule Revisions
* Add `invoice_settings` on the Customer
@remi-stripe remi-stripe force-pushed the remi-add-subscription-schedules branch from 48b1b7a to 58fa431 Compare February 12, 2019 06:17
@remi-stripe remi-stripe changed the title [WIP] Add support for Subscription Schedule Add support for Subscription Schedule Feb 12, 2019
@remi-stripe
Copy link
Contributor Author

@ob-stripe now that stripe-mock has been released, we should be able to merge. The feature is stable (but gated for a bit)

Copy link
Contributor

@ob-stripe ob-stripe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@ob-stripe ob-stripe assigned remi-stripe and unassigned ob-stripe Feb 12, 2019
@remi-stripe remi-stripe merged commit 3da6eea into master Feb 12, 2019
@remi-stripe remi-stripe deleted the remi-add-subscription-schedules branch February 12, 2019 17:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants