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

Serializing a parent object with a Chargebee Subscription fails #71

Open
dcreeronbemo opened this issue Jul 30, 2024 · 9 comments
Open

Comments

@dcreeronbemo
Copy link

dcreeronbemo commented Jul 30, 2024

Description of the Bug

We have a class that has a property for ChargeBee.Models.Subscription. When we try and serialize this parent class we get an exception with the following details:

Error getting value from 'SubscriptionId' on 'ChargeBee.Models.Subscription+SubscriptionContractTerm'.
The property subscription_id is not present!

If I look in the debug visualizer and drill down to the ChargeBeeSubscription.ContractTerm.SubscriptionId I see a circular red-X for the property, and the value is:

"'(new System.Collections.Generic.ICollectionDebugView<Bemo.Services.ShoppingCart.Models.BemoCartLineItem>(value.LineItems).Items[0]).BemoSub.ChargeBeeSubscription.ContractTerm.SubscriptionId' threw an exception of type 'System.ArgumentException'"

If I clone the latest chargebee-dotnet repository, include the project in my solution, and then comment out the SubscriptionContractTerm.SubscriptionId property in Subscription.cs (lines 6540-6542) then the serialization works as expected. ETA: I can also change that property so the call the GetValue() sets the "required" parameter to false.

Steps to reproduce

  1. Create a parent class with a ChargeBee.Models.Subscription
  2. Populate the parent class, including the CB Subscription property
  3. Try and Serialize the parent class with Newtonsoft
  4. Error/exception as noted in description

Expected Behavior

Serialization should not throw this exception.

Code Snippets (if applicable)

No response

Operating System

Windows 10/11

Language version

.Net 8.0

Library version

v3.20.0

Additional context

No response

@cb-alish
Copy link
Collaborator

Hi @dcreeronbemo, subscription_id is a required field and it looks like this is missing while populating ContractTerm object inside Subscription property. Can you please help with more details on how you're populating the Chargebee Subscription property in your parent class? Are you directly using the API response from Chargebee or are you constructing this yourself?

@dcreeronbemo
Copy link
Author

dcreeronbemo commented Jul 31, 2024

Hello @cb-alish. Thanks for the quick response.

I see from the code that the CB SubscriptionContractTerm.SubscriptionId is supposed to be required.

Our code is calling:

EntityResult chargebeeResult =
Subscription.CreateForCustomer("CUSTOMERIDHERE)
.PlanId("PLANIDHERE")
.PlanQuantity(1)
.InvoiceImmediately(true)
.StartDate(SubscriptionStartDate(true))
.ContractTermActionAtTermEnd(Subscription.SubscriptionContractTerm.ActionAtTermEndEnum.Renew)
.BillingCycles(12)
.ContractTermBillingCycleOnRenewal(12)
.Request()

With the 3.20.0 NUGET package (or the project directly in our code) with the default "required == true" then the ContractTerm.SubscriptionId isn't populated and throws the error. This causes the serialization further downstream to fail.

If I set required == false, then the ContractTerm.SubscriptionId value is set to null, and the serialization works.

It seems to me that the data being returned from the API call isn't populating the ContractTerm.SubscriptionId for some reason.

For what it's worth, the rest of the ContractTerm looks like it's populated correctly (see attached screenshot).

image

@dcreeronbemo
Copy link
Author

dcreeronbemo commented Jul 31, 2024

Additional info @cb-alish. A co-worker performed an API get subscription call directly and got the following JSON. Notice how the "contract_term" doesn't contain a "subscription_id" property. It does have an "id" property, which matches the parent subscription id.

To me the "id" of the contract_term seems like it should be a unique id for the contract_term, and not the id of the parent subscription. Thus, the need/thought for having a SubscriptionId ("subscription_id") property.

I'm guessing someone set Id instead of SubscriptionId, thus overwriting the ContractTerm unique Id, and not setting the Contract Term subscription Id.

"subscription": {
"id" : "AzqC89UK7EV8y1DIh",
"currency_code" : "USD",
"plan_id" : "6C1E56E1-E195-4D6A-8252-CE9C7A1E10EC",
"plan_quantity" : "11",
"plan_unit_price" : "3900",
"billing_period" : "1",
"billing_period_unit" : "month",
"remaining_billing_cycles" : "11",
"customer_id" : "1dde681a-6a9b-4d0a-b00c-0e2366355d6e",
"plan_amount" : "42900",
"plan_free_quantity" : "0",
"status" : "active",
"current_term_start" : "31-Jul-2024 00:00:00",
"current_term_end" : "30-Aug-2024 23:59:59",
"next_billing_at" : "31-Aug-2024 00:00:00",
"created_at" : "31-Jul-2024 14:36:54",
"started_at" : "31-Jul-2024 00:00:00",
"activated_at" : "31-Jul-2024 00:00:00",
"contract_term_billing_cycle_on_renewal" : "12",
"resource_version" : "1722436616424",
"updated_at" : "31-Jul-2024 14:36:56",
"has_scheduled_advance_invoices" : "false",
"has_scheduled_changes" : "false",
"channel" : "web",
"due_invoices_count" : "0",
"mrr" : "0",
"deleted" : "false",
"contract_term" : {
"id" : "AzqC89UK7EV951DIi",
"status" : "active",
"contract_start" : "31-Jul-2024 00:00:00",
"contract_end" : "30-Jul-2025 23:59:59",
"billing_cycle" : "12",
"action_at_term_end" : "renew",
"total_contract_value" : "514800",
"total_contract_value_before_tax" : "514800",
"cancellation_cutoff_period" : "31",
"created_at" : "31-Jul-2024 14:36:56",
"remaining_billing_cycles" : "11",
}

}

@dcreeronbemo
Copy link
Author

@cb-alish Hello. Any updates or suggestions? We're having a similar issue with SubscriptionAddress as well.

Thanks.

@cb-alish
Copy link
Collaborator

Hi @dcreeronbemo, we're working on the fix and will update you here once it's ready. Could you also provide more details on SubscriptionAddress so we can address it fully? Thanks for your patience!

@dcreeronbemo
Copy link
Author

Thanks for the response @cb-alish. The issue is the same as the earlier issue, just a different object. In this case Subscription.

We try to get the Subscriptions for a specific user by:

            var subscriptionList = (await Subscription.List()
                .CustomerId().Is(customerId)
                .Status().IsNot(Subscription.StatusEnum.Cancelled)
                .RequestAsync()).List.Select(x => x.Subscription).ToList();

We save this list into a parent object and then try to serial the parent object. The serialization throws an exception:

"Exception caught: ArgumentException
Message: The property subscription_id is not present!
StackTrace: at ChargeBee.Internal.Resource.ThrowIfKeyMissed(String key)
at SubscriptionIdGetter(Object)"

image

The problem appears to be that it's trying to serialize the Subscription.ShippingAddress and throwing this error.

at ChargeBee.Internal.Resource.ThrowIfKeyMissed(String key)
at System.Text.Json.Serialization.Metadata.JsonPropertyInfo1.GetMemberAndWriteJson(Object obj, WriteStack& state, Utf8JsonWriter writer) at System.Text.Json.Serialization.Converters.ObjectDefaultConverter1.OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, WriteStack& state)
at System.Text.Json.Serialization.JsonConverter1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state) at System.Text.Json.Serialization.Metadata.JsonPropertyInfo1.GetMemberAndWriteJson(Object obj, WriteStack& state, Utf8JsonWriter writer)
at System.Text.Json.Serialization.Converters.ObjectDefaultConverter1.OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, WriteStack& state) at System.Text.Json.Serialization.JsonConverter1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
at System.Text.Json.Serialization.JsonConverter1.WriteCore(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state) at System.Text.Json.Serialization.Metadata.JsonTypeInfo1.Serialize(Utf8JsonWriter writer, T& rootValue, Object rootValueBoxed)
at System.Text.Json.JsonSerializer.WriteString[TValue](TValue& value, JsonTypeInfo`1 jsonTypeInfo)
at System.Text.Json.JsonSerializer.Serialize[TValue](TValue value, JsonSerializerOptions options)
at Prismo.Services.Chargebee.Services.ChargeBeeService.d__6.MoveNext() in C:\Users\DanielCreeron\source\repos\PCvsCB_BemoReconciliationReport\Prismo.Services.Chargebee\Services\ChargebeeService.cs:line 151

Th

@cb-alish
Copy link
Collaborator

Hi @dcreeronbemo,

The issue with SubscriptionContractTerm has been resolved. Please give it a try and let us know if it still doesn't work for you.

We're working on the SubscriptionAddress issue and will update you once it's fixed. Apologies for the inconvenience, and thank you for your patience.

@dcreeronbemo
Copy link
Author

Thanks @cb-alish. I updated the project to go back to the Chargebee dotnet 3.24.0 NUGET package, and initial testing is working as expected. Was there a change to the NUGET package source (I didn't see anything related, but may have missed it) or was it a backend issue?

@cb-alish
Copy link
Collaborator

Hi @dcreeronbemo, it was a backend issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants