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 /v1/topups endpoints #1110

Merged
merged 5 commits into from
May 21, 2018
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions src/Stripe.Tests.XUnit/topups/_fixture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace Stripe.Tests.Xunit
{
public class topups_fixture
{
public StripeTopupCreateOptions TopupCreateOptions { get; }
public StripeTopupUpdateOptions TopupUpdateOptions { get; }
public StripeTopupListOptions TopupListOptions { get; }

public StripeTopup Topup { get; }
public StripeTopup TopupUpdated { get; }
public StripeTopup TopupRetrieved { get; }
public StripeList<StripeTopup> TopupList { get; }

public topups_fixture()
{
StripeSource source = new StripeSourceService(Cache.ApiKey).Create(new StripeSourceCreateOptions
{
Type = StripeSourceType.AchCreditTransfer,
Currency = "usd",
Owner = new StripeSourceOwner
{
Email = "amount_4242@example.com"
}
});

// Sleep for 5 seconds to ensure the Source is chargeable
// 1 or 2 seconds are unfortunately not enough.
System.Threading.Thread.Sleep(5000);
Copy link
Contributor

Choose a reason for hiding this comment

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

This is awful, but I can't see another way for now 😢

Copy link
Contributor

Choose a reason for hiding this comment

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

Fuuu :/ Yeah, I don't know of one either.


TopupCreateOptions = new StripeTopupCreateOptions
{
Amount = 1000,
Currency = "usd",
Description = "Test Topup",
SourceTokenOrExistingSourceId = source.Id,
StatementDescriptor = "Descriptor",
};

TopupUpdateOptions = new StripeTopupUpdateOptions
{
Metadata = new Dictionary<string, string>()
{
{ "some-key", "some-value" }
}
};

var service = new StripeTopupService(Cache.ApiKey);
Topup = service.Create(TopupCreateOptions);
TopupUpdated = service.Update(Topup.Id, TopupUpdateOptions);
TopupRetrieved = service.Get(Topup.Id);

TopupListOptions = new StripeTopupListOptions
{
Created = new StripeDateFilter { EqualTo = Topup.Created },
};

TopupList = service.List(TopupListOptions);
}
}
}
41 changes: 41 additions & 0 deletions src/Stripe.Tests.XUnit/topups/creating_and_updating_topups.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using FluentAssertions;
using Xunit;

namespace Stripe.Tests.Xunit
{
public class creating_and_updating_topups : IClassFixture<topups_fixture>
{
private readonly topups_fixture fixture;

public creating_and_updating_topups(topups_fixture topupsFixture)
{
fixture = topupsFixture;
}

[Fact]
public void created_has_right_details()
{
fixture.Topup.Should().NotBeNull();
fixture.Topup.Id.Should().StartWith("tu_");
fixture.Topup.Amount.Should().Be(fixture.TopupCreateOptions.Amount);
fixture.Topup.Currency.Should().Be(fixture.TopupCreateOptions.Currency);
fixture.Topup.Description.Should().Be(fixture.TopupCreateOptions.Description);
fixture.Topup.StatementDescriptor.Should().Be(fixture.TopupCreateOptions.StatementDescriptor);
}

[Fact]
public void get_is_not_null()
{
fixture.TopupRetrieved.Should().NotBeNull();
fixture.TopupRetrieved.Id.Should().Be(fixture.Topup.Id);
fixture.TopupRetrieved.Amount.Should().Be(fixture.Topup.Amount);
fixture.TopupRetrieved.Currency.Should().Be(fixture.Topup.Currency);
}

[Fact]
public void updated_has_the_right_metadata()
{
fixture.TopupUpdated.Metadata.Keys.Should().BeEquivalentTo(fixture.TopupUpdateOptions.Metadata.Keys);
}
}
}
66 changes: 66 additions & 0 deletions src/Stripe.Tests.XUnit/topups/when_listing_topups.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using FluentAssertions;
using Stripe.Tests.Xunit;
using System.Collections.Generic;
using System;
using System.Linq;
using Xunit;

namespace Stripe.Tests.XUnit
{
public class when_listing_topups : IClassFixture<topups_fixture>
{
private readonly topups_fixture fixture;
private StripeList<StripeTopup> result;

public when_listing_topups(topups_fixture topupsFixture)
{
fixture = topupsFixture;
result = fixture.TopupList;
}

[Fact]
public void list_is_iterable()
{
var count = 0;
IEnumerable<StripeTopup> enumerable = result as IEnumerable<StripeTopup>;
foreach (var obj in enumerable)
{
count += 1;
}
Assert.Equal(result.ToList().Count > 0, true);
Assert.Equal(result.ToList().Count, count);

}

[Fact]
public void list_contents_equal()
{

var datahash = new HashSet<String>();
foreach (var obj in result.Data)
{
datahash.Add(obj.Id);
}

var enumhash = new HashSet<String>();
IEnumerable<StripeTopup> enumerable = result as IEnumerable<StripeTopup>;
foreach (var obj in enumerable)
{
enumhash.Add(obj.Id);
}

Assert.Equal(datahash, enumhash);

}

[Fact]
public void list_contains_extra_attributes()
{
Assert.NotNull(result.Object);
Assert.Equal(result.Object, "list");
Assert.NotNull(result.Data);
Assert.NotNull(result.Url);
}

}
}
94 changes: 94 additions & 0 deletions src/Stripe.net/Entities/StripeTopup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Stripe.Infrastructure;

namespace Stripe
{
public class StripeTopup : StripeEntityWithId
{
[JsonProperty("object")]
public string Object { get; set; }

/// <summary>
/// A positive integer in the smallest currency unit (e.g., 100 cents to top up $1.00 or 100 to topup ¥100, a 0-decimal currency) representing how much to top up. The minimum amount is $0.50 US or equivalent in Top-up currency.
/// </summary>
[JsonProperty("amount")]
public int Amount { get; set; }

#region Expandable Balance Transaction
/// <summary>
/// ID of the balance transaction that describes the impact of this Top-up on your account balance (not including refunds or disputes).
/// </summary>
public string BalanceTransactionId { get; set; }

[JsonIgnore]
public StripeBalanceTransaction BalanceTransaction { get; set; }

[JsonProperty("balance_transaction")]
internal object InternalBalanceTransaction
{
set
{
StringOrObject<StripeBalanceTransaction>.Map(value, s => BalanceTransactionId = s, o => BalanceTransaction = o);
}
}
#endregion

[JsonProperty("created")]
[JsonConverter(typeof(StripeDateTimeConverter))]
public DateTime Created { get; set; }

[JsonProperty("expected_availability_date")]
[JsonConverter(typeof(StripeDateTimeConverter))]
public DateTime? ExpectedAvailabilityDate { 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.

Weirdly this value is null in Test so I had to make it optional with the ?. I feel like we should consider making all properties always optional to be resilient to changes on Stripe's end.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think what you have here is correct given that it's also marked optional in the backend too.

I'm not too sure that we should go around applying this too liberally because the ? does require a little extra code to use for the user (making it a little less sound ergonomically).

On that note though. I was cross-referencing this with the API resource and noticed these fields are also optional:

  • BalanceTransactionId
  • Description
  • FailureCode
  • FailureMessage
  • StatementDescriptor

Should we add ? for them as well? These are all strings so I think the answer is "no" when comparing to other optional properties throughout the library, but it seems a little strange that nullable is only used for certain types.

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 think for strings it's fine. But it'd be great to figure out a better way than throwing the ? when a test breaks because it means we never fully test the edge-cases


/// <summary>
/// Three-letter ISO currency code representing the currency in which the Top-up was made.
/// </summary>
[JsonProperty("currency")]
public string Currency { get; set; }

[JsonProperty("description")]
public string Description { get; set; }

/// <summary>
/// Error code explaining reason for topup failure if available (see the errors section for a list of codes).
/// </summary>
[JsonProperty("failure_code")]
public string FailureCode { get; set; }

/// <summary>
/// Message to user further explaining reason for topup failure if available.
/// </summary>
[JsonProperty("failure_message")]
public string FailureMessage { get; set; }

[JsonProperty("livemode")]
public bool LiveMode { get; set; }

/// <summary>
/// A set of key/value pairs that you can attach to a topup object. It can be useful for storing additional information about the topup in a structured format.
/// </summary>
[JsonProperty("metadata")]
public Dictionary<string, string> Metadata { get; set; }

/// <summary>
/// For most Stripe users, the source of every Top-up is a bank account. This hash is then the source object describing that bank account.
/// </summary>
[JsonProperty("source")]
public Source Source { get; set; }

/// <summary>
/// Extra information about a topup. This will appear on your customer’s credit card statement.
/// </summary>
[JsonProperty("statement_descriptor")]
public string StatementDescriptor { get; set; }

/// <summary>
/// The status of the payment is either succeeded, pending, or failed
/// </summary>
[JsonProperty("status")]
public string Status { get; set; }
}
}
2 changes: 2 additions & 0 deletions src/Stripe.net/Infrastructure/Urls.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,7 @@ internal static class Urls
private static string BaseUploadsUrl => "https://uploads.stripe.com/v1";

public static string FileUploads => BaseUploadsUrl + "/files";

public static string Topups => BaseUrl + "/topups";
}
}
42 changes: 42 additions & 0 deletions src/Stripe.net/Services/Topups/StripeTopupCreateOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;

namespace Stripe
{
public class StripeTopupCreateOptions : StripeBaseOptions
{
/// <summary>
/// A positive integer in the smallest currency unit (e.g., 100 cents to top up $1.00 or 100 to top up ¥100, a 0-decimal currency) representing how much to top up your Stripe balance.
/// </summary>
[JsonProperty("amount")]
public int? Amount { get; set; }

/// <summary>
/// 3-letter ISO code for currency.
/// </summary>
[JsonProperty("currency")]
public string Currency { get; set; }

/// <summary>
/// An arbitrary string which you can attach to a Top-up object. It is displayed when in the web interface alongside the Top-up.
/// </summary>
[JsonProperty("description")]
public string Description { get; set; }

/// <summary>
/// A set of key/value pairs that you can attach to a Top-up object. It can be useful for storing additional information in a structured format.
/// </summary>
[JsonProperty("metadata")]
public Dictionary<string, string> Metadata { get; set; }

[JsonProperty("source")]
public string SourceTokenOrExistingSourceId { get; set; }

/// <summary>
/// An arbitrary string to be displayed on your bank statement. This may be up to 22 characters. The statement description may not include <>"' characters, and will appear on your bank statement in capital letters. Non-ASCII characters are automatically stripped. While most banks display this information consistently, some may display it incorrectly or not at all.
/// </summary>
[JsonProperty("statement_descriptor")]
public string StatementDescriptor { get; set; }
}
}
10 changes: 10 additions & 0 deletions src/Stripe.net/Services/Topups/StripeTopupListOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Newtonsoft.Json;

namespace Stripe
{
public class StripeTopupListOptions : StripeListOptions
{
[JsonProperty("created")]
public StripeDateFilter Created { get; set; }
}
}
Loading