diff --git a/src/Stripe.net/Entities/_base/StripeEntity.cs b/src/Stripe.net/Entities/_base/StripeEntity.cs
index c5287e4f4c..6e9916463a 100644
--- a/src/Stripe.net/Entities/_base/StripeEntity.cs
+++ b/src/Stripe.net/Entities/_base/StripeEntity.cs
@@ -4,11 +4,51 @@ namespace Stripe
using System.Reflection;
using System.Runtime.CompilerServices;
using Newtonsoft.Json;
+ using Newtonsoft.Json.Linq;
using Stripe.Infrastructure;
[JsonObject(MemberSerialization.OptIn)]
public abstract class StripeEntity : IStripeEntity
{
+ [JsonIgnore]
+ private JObject rawJObject;
+
+ ///
+ /// Gets the raw JObject exposed by the Newtonsoft.Json library.
+ /// This can be used to access properties that are not directly exposed by Stripe's .NET
+ /// library.
+ ///
+ ///
+ /// You should always prefer using the standard property accessors whenever possible. This
+ /// accessor is not considered fully stable and might change or be removed in future
+ /// versions.
+ ///
+ /// The raw JObject.
+ [JsonIgnore]
+ public JObject RawJObject
+ {
+ get
+ {
+ // Lazily initialize the object the first time the getter is called.
+ if (this.rawJObject == null)
+ {
+ if (this.StripeResponse == null)
+ {
+ return null;
+ }
+
+ this.rawJObject = JObject.Parse(this.StripeResponse.Content);
+ }
+
+ return this.rawJObject;
+ }
+
+ protected set
+ {
+ this.rawJObject = value;
+ }
+ }
+
[JsonIgnore]
public StripeResponse StripeResponse { get; set; }
diff --git a/src/StripeTests/Entities/_base/StripeEntityTest.cs b/src/StripeTests/Entities/_base/StripeEntityTest.cs
index 95b89f9a5b..097c9228a4 100644
--- a/src/StripeTests/Entities/_base/StripeEntityTest.cs
+++ b/src/StripeTests/Entities/_base/StripeEntityTest.cs
@@ -5,8 +5,14 @@ namespace StripeTests
using Stripe.Infrastructure;
using Xunit;
- public class StripeEntityTest
+ public class StripeEntityTest : BaseStripeTest
{
+ public StripeEntityTest(
+ StripeMockFixture stripeMockFixture)
+ : base(stripeMockFixture)
+ {
+ }
+
[Fact]
public void FromJsonAuto()
{
@@ -141,6 +147,29 @@ public void ExpandableAccessors_Id_DoesNotResetExistingExpandedObjectIfIdIsSame(
Assert.Equal(42, o.Nested.Bar);
}
+ [Fact]
+ public void RawJObject()
+ {
+ var service = new SubscriptionService(this.StripeClient);
+ var subscription = service.Get("sub_123");
+
+ Assert.NotNull(subscription);
+
+ // Access `id`, a string element
+ Assert.Equal(subscription.Id, subscription.RawJObject["id"]);
+
+ // Access `created`, a number element
+ Assert.Equal(subscription.Created, subscription.RawJObject["created"]);
+
+ // Access `plan[id]`, a nested string element
+ Assert.Equal(subscription.Plan.Id, subscription.RawJObject["plan"]["id"]);
+
+ // Access `items[data][0][id]`, a deeply nested string element
+ Assert.Equal(
+ subscription.Items.Data[0].Id,
+ subscription.RawJObject["items"]["data"][0]["id"]);
+ }
+
private class TestEntity : StripeEntity
{
[JsonProperty("integer")]