Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ on:
branches:
- master
- beta
- private-preview
- sdk-release/**
- feature/**

Expand Down
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@ This release changes the pinned API version to `2025-08-27.preview`.
* Add support for `PixDisplayQrCode` on `SetupIntent.NextAction`
* Add support for `ReaderSecurity` on `Terminal.ConfigurationCreateOptions`, `Terminal.ConfigurationUpdateOptions`, and `Terminal.Configuration`

## 48.5.0 - 2025-08-27
* [#3164](https://github.com/stripe/stripe-dotnet/pull/3164) Add section on private preview SDKs in readme
* [#3159](https://github.com/stripe/stripe-dotnet/pull/3159) Update generated code. This release changes the pinned API version to `2025-08-27.basil`.
* Add support for `BalanceReport`, `PayoutDetails`, and `PayoutReconciliationReport` on `AccountSession.Components` and `AccountSessionComponentsOptions`
* Add support for `Name` on `BillingPortal.ConfigurationCreateOptions`, `BillingPortal.ConfigurationUpdateOptions`, and `BillingPortal.Configuration`
* Add support for `Installments` on `Charge.PaymentMethodDetails.Alma`
* Add support for `TransactionId` on `Charge.PaymentMethodDetails.Alma`, `Charge.PaymentMethodDetails.AmazonPay`, `Charge.PaymentMethodDetails.Billie`, `Charge.PaymentMethodDetails.KakaoPay`, `Charge.PaymentMethodDetails.KrCard`, `Charge.PaymentMethodDetails.NaverPay`, `Charge.PaymentMethodDetails.Payco`, `Charge.PaymentMethodDetails.RevolutPay`, `Charge.PaymentMethodDetails.SamsungPay`, and `Charge.PaymentMethodDetails.Satispay`
* Add support for `Location` and `Reader` on `Charge.PaymentMethodDetails.Paynow`
* Add support for `AmountIncludesIof` on `Checkout.Session.PaymentMethodOptions.Pix`, `CheckoutSessionPaymentMethodOptionsPixOptions`, `PaymentIntent.PaymentMethodOptions.Pix`, and `PaymentIntentPaymentMethodOptionsPixOptions`
* Add support for `Metadata` and `Period` on `InvoiceScheduleDetailsPhaseAddInvoiceItemOptions`, `SubscriptionAddInvoiceItemOptions`, `SubscriptionSchedule.Phase.AddInvoiceItem`, and `SubscriptionSchedulePhaseAddInvoiceItemOptions`
* Add support for `ExpMonth` and `ExpYear` on `Issuing.CardCreateOptions`
* Add support for `ExcludedPaymentMethodTypes` on `PaymentIntentCreateOptions` and `PaymentIntent`
* Add support for `PayoutMethod` on `PayoutCreateOptions` and `Payout`
* Add support for `Mxn` on `Terminal.Configuration.Tipping` and `TerminalConfigurationTippingOptions`
* Add support for `Card` on `Terminal.TestHelpersReaderPresentPaymentMethodOptions`

## 48.5.0-beta.2 - 2025-08-08
* [#3160](https://github.com/stripe/stripe-dotnet/pull/3160) Bring back invoice payments APIs that were missing in the public preview SDKs
* Add support for new resource `InvoicePayment`
Expand Down
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ how to use the library.

### Using StripeClient

In version 46 of the Stripe .NET SDK, we have enhanced the `StripeClient` class to be the entry point to access all services that had to be previously independently instantiated with global configuration. This improves discoverability during IDE auto-completion and creates a more intuitive developer experience for you.
In version 46 of the Stripe .NET SDK, we have enhanced the `StripeClient` class to be the entry point to access all services that had to be previously independently instantiated with global configuration. This improves discoverability during IDE auto-completion and creates a more intuitive developer experience for you.

Each client instantiation can have its own configuration so you can access Stripe API with different API keys or different configuration (like number of retries) on a per client basis and without changing a global configuration.

Expand Down Expand Up @@ -335,7 +335,7 @@ The [RawJObject property](#properties) is ignored on serialization in both Json.
Stripe has features in the [public preview phase](https://docs.stripe.com/release-phases) that can be accessed via versions of this package that have the `-beta.X` suffix like `45.1.0-beta.2`.
We would love for you to try these as we incrementally release new features and improve them based on your feedback.

To install, choose the version that includes support for the preview feature you are interested in by reviewing the [releases page](https://github.com/stripe/stripe-dotnet/releases/) and then use it in the version parameter with `dotnet add package` command:
To install, pick the latest version with the `beta` suffix by reviewing the [releases page](https://github.com/stripe/stripe-dotnet/releases/) and then use it in the version parameter with `dotnet add package` command:

```
dotnet add package Stripe.net --version <replace-with-the-version-of-your-choice>
Expand All @@ -349,6 +349,9 @@ Some preview features require a name and version to be set in the `Stripe-Versio
```csharp
StripeConfiguration.AddBetaVersion("feature_beta", "v3");
```
### Private Preview SDKs

Stripe has features in the [private preview phase](https://docs.stripe.com/release-phases) that can be accessed via versions of this package that have the `-alpha.X` suffix like `45.2.0-alpha.2`. These are invite-only features. Once invited, you can install the private preview SDKs by following the same instructions as for the [public preview SDKs](https://github.com/stripe/stripe-dotnet?tab=readme-ov-file#public-preview-sdks) above and replacing the term `beta` with `alpha`.

### Custom requests

Expand Down
2 changes: 1 addition & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ ci-test: (_test "--no-build" "" "Release")
# ⭐ format all files
format *args:
# This sets TargetFramework because of a race condition in dotnet format when it tries to format to multiple targets at a time, which could lead to code with compiler errors after it completes
TargetFramework=net5.0 dotnet format src/Stripe.net/Stripe.net.csproj --severity warn {{args}}
TargetFramework=net5.0 dotnet format src/Stripe.net.sln --severity warn {{args}}

# verify, but don't modify, the project's formatting
format-check: (format "--verify-no-changes")
Expand Down
2 changes: 1 addition & 1 deletion src/Examples/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public Program()
/// are set before running the example.
///
/// </summary>
/// <param name="args">command line args</param>
/// <param name="args">command line args.</param>
/// <returns></returns>
public static async Task Main(string[] args)
{
Expand Down
12 changes: 6 additions & 6 deletions src/Examples/V2/ThinEventWebhookHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@
[ApiController]
public class ThinEventWebhookHandler : ControllerBase
{
private readonly StripeClient _client;
private readonly string _webhookSecret;
private readonly StripeClient client;
private readonly string webhookSecret;

public ThinEventWebhookHandler()

Check warning on line 28 in src/Examples/V2/ThinEventWebhookHandler.cs

View workflow job for this annotation

GitHub Actions / Build and test

Non-nullable field 'webhookSecret' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 28 in src/Examples/V2/ThinEventWebhookHandler.cs

View workflow job for this annotation

GitHub Actions / Build and test

Non-nullable field 'webhookSecret' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
{
var apiKey = Environment.GetEnvironmentVariable("STRIPE_API_KEY");
_client = new StripeClient(apiKey);
client = new StripeClient(apiKey);

_webhookSecret = Environment.GetEnvironmentVariable("WEBHOOK_SECRET");
webhookSecret = Environment.GetEnvironmentVariable("WEBHOOK_SECRET");

Check warning on line 33 in src/Examples/V2/ThinEventWebhookHandler.cs

View workflow job for this annotation

GitHub Actions / Build and test

Possible null reference assignment.

Check warning on line 33 in src/Examples/V2/ThinEventWebhookHandler.cs

View workflow job for this annotation

GitHub Actions / Build and test

Possible null reference assignment.
}

[HttpPost]
Expand All @@ -39,10 +39,10 @@
var json = await new StreamReader(HttpContext.Request.Body).ReadToEndAsync();
try
{
var thinEvent = _client.ParseThinEvent(json, Request.Headers["Stripe-Signature"], _webhookSecret);
var thinEvent = client.ParseThinEvent(json, Request.Headers["Stripe-Signature"], webhookSecret);

// Fetch the event data to understand the failure
var baseEvent = await _client.V2.Core.Events.GetAsync(thinEvent.Id);
var baseEvent = await client.V2.Core.Events.GetAsync(thinEvent.Id);
if (baseEvent is V1BillingMeterErrorReportTriggeredEvent fullEvent)
{
var meter = await fullEvent.FetchRelatedObjectAsync();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// File generated from our OpenAPI spec
namespace Stripe
{
using System.Collections.Generic;
using Newtonsoft.Json;
#if NET6_0_OR_GREATER
using STJS = System.Text.Json.Serialization;
Expand Down Expand Up @@ -107,7 +108,7 @@ public class PaymentIntentNextAction : StripeEntity<PaymentIntentNextAction>
#if NET6_0_OR_GREATER
[STJS.JsonPropertyName("use_stripe_sdk")]
#endif
public PaymentIntentNextActionUseStripeSdk UseStripeSdk { get; set; }
public Dictionary<string, object> UseStripeSdk { get; set; }

[JsonProperty("verify_with_microdeposits")]
#if NET6_0_OR_GREATER
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// File generated from our OpenAPI spec
namespace Stripe
{
using System.Collections.Generic;
using Newtonsoft.Json;
#if NET6_0_OR_GREATER
using STJS = System.Text.Json.Serialization;
Expand Down Expand Up @@ -47,7 +48,7 @@ public class SetupIntentNextAction : StripeEntity<SetupIntentNextAction>
#if NET6_0_OR_GREATER
[STJS.JsonPropertyName("use_stripe_sdk")]
#endif
public SetupIntentNextActionUseStripeSdk UseStripeSdk { get; set; }
public Dictionary<string, object> UseStripeSdk { get; set; }

[JsonProperty("verify_with_microdeposits")]
#if NET6_0_OR_GREATER
Expand Down

This file was deleted.

30 changes: 30 additions & 0 deletions src/Stripe.net/Entities/V2/DeletedObject/DeletedObject.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// File generated from our OpenAPI spec
namespace Stripe.V2
{
using Newtonsoft.Json;
#if NET6_0_OR_GREATER
using STJS = System.Text.Json.Serialization;
#endif

public class DeletedObject : StripeEntity<DeletedObject>, IHasId, IHasObject
{
/// <summary>
/// The ID of the object that's being deleted.
/// </summary>
[JsonProperty("id")]
#if NET6_0_OR_GREATER
[STJS.JsonPropertyName("id")]
#endif
public string Id { get; set; }

/// <summary>
/// String representing the type of the object that has been deleted. Objects of the same
/// type share the same value of the object field.
/// </summary>
[JsonProperty("object")]
#if NET6_0_OR_GREATER
[STJS.JsonPropertyName("object")]
#endif
public string Object { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ private static List<KeyValuePair<string, object>> FlattenParamsValue(object valu
flatParams = SingleParam(keyPrefix, s);
break;

case MultipartFileContent f:
flatParams = SingleParam(keyPrefix, f);
break;

case Stream s:
flatParams = SingleParam(keyPrefix, s);
break;
Expand Down
4 changes: 4 additions & 0 deletions src/Stripe.net/Infrastructure/FormEncoding/FormEncoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ private static List<KeyValuePair<string, object>> FlattenParamsValue(object valu
flatParams = SingleParam(keyPrefix, s);
break;

case MultipartFileContent f:
flatParams = SingleParam(keyPrefix, f);
break;

case Stream s:
flatParams = SingleParam(keyPrefix, s);
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,26 +41,29 @@ public MultipartFormDataContent(
private static StringContent CreateStringContent(string value)
=> new StringContent(value, System.Text.Encoding.UTF8);

private static StreamContent CreateStreamContent(Stream value, string name)
private static StreamContent CreateStreamContent(MultipartFileContent value, string name)
{
var fileName = "blob";
var extension = string.Empty;
var fileName = value.Name ?? "blob";
var extension = Path.GetExtension(fileName);
var stream = value.Data;

FileStream fileStream = value as FileStream;
FileStream fileStream = stream as FileStream;
if ((fileStream != null) && (!string.IsNullOrEmpty(fileStream.Name)))
{
fileName = fileStream.Name;
extension = Path.GetExtension(fileName);
}

var content = new StreamContent(value);
var type = value.Type ?? MimeTypes.GetMimeType(extension);

var content = new StreamContent(stream);
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = name,
FileName = fileName,
FileNameStar = fileName,
};
content.Headers.ContentType = new MediaTypeHeaderValue(MimeTypes.GetMimeType(extension));
content.Headers.ContentType = new MediaTypeHeaderValue(type);
return content;
}

Expand All @@ -79,8 +82,16 @@ private void ProcessParameters(IEnumerable<KeyValuePair<string, object>> nameVal
this.Add(CreateStringContent(s), QuoteString(kvp.Key));
break;

case MultipartFileContent f:
this.Add(CreateStreamContent(f, QuoteString(kvp.Key)));
break;

case Stream s:
this.Add(CreateStreamContent(s, QuoteString(kvp.Key)));
var fileData = new MultipartFileContent
{
Data = s,
};
this.Add(CreateStreamContent(fileData, QuoteString(kvp.Key)));
break;

default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public override Task<T> RequestAsync<T>(
if (baseAddress != BaseAddress.Api)
{
requestOptions ??= new RequestOptions();
requestOptions.BaseUrl = this.GetBaseUrl(baseAddress);
requestOptions.InternalBaseUrl = this.GetBaseUrl(baseAddress);
}

return this.client.RequestAsync<T>(method, path, options, requestOptions, cancellationToken);
Expand Down
2 changes: 1 addition & 1 deletion src/Stripe.net/Infrastructure/Public/LiveApiRequestor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ private StripeRequest MakeStripeRequest(
}

var uri = StripeRequest.BuildUri(
requestOptions?.BaseUrl ?? this.GetBaseUrl(baseAddress),
requestOptions?.InternalBaseUrl ?? this.GetBaseUrl(baseAddress),
method,
path,
options,
Expand Down
3 changes: 1 addition & 2 deletions src/Stripe.net/Services/Files/FileCreateOptions.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// File generated from our OpenAPI spec
namespace Stripe
{
using System.IO;
using Newtonsoft.Json;
#if NET6_0_OR_GREATER
using STJS = System.Text.Json.Serialization;
Expand All @@ -17,7 +16,7 @@ public class FileCreateOptions : BaseOptions
#if NET6_0_OR_GREATER
[STJS.JsonPropertyName("file")]
#endif
public Stream File { get; set; }
public MultipartFileContent File { get; set; }

/// <summary>
/// Optional parameters that automatically create a <a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,17 @@ public virtual V2.EventDestination Create(EventDestinationCreateOptions options,
/// <summary>
/// Delete an event destination.
/// </summary>
public virtual V2.EventDestination Delete(string id, EventDestinationDeleteOptions options = null, RequestOptions requestOptions = null)
public virtual V2.DeletedObject Delete(string id, EventDestinationDeleteOptions options = null, RequestOptions requestOptions = null)
{
return this.Request<V2.EventDestination>(BaseAddress.Api, HttpMethod.Delete, $"/v2/core/event_destinations/{WebUtility.UrlEncode(id)}", options, requestOptions);
return this.Request<V2.DeletedObject>(BaseAddress.Api, HttpMethod.Delete, $"/v2/core/event_destinations/{WebUtility.UrlEncode(id)}", options, requestOptions);
}

/// <summary>
/// Delete an event destination.
/// </summary>
public virtual Task<V2.EventDestination> DeleteAsync(string id, EventDestinationDeleteOptions options = null, RequestOptions requestOptions = null, CancellationToken cancellationToken = default)
public virtual Task<V2.DeletedObject> DeleteAsync(string id, EventDestinationDeleteOptions options = null, RequestOptions requestOptions = null, CancellationToken cancellationToken = default)
{
return this.RequestAsync<V2.EventDestination>(BaseAddress.Api, HttpMethod.Delete, $"/v2/core/event_destinations/{WebUtility.UrlEncode(id)}", options, requestOptions, cancellationToken);
return this.RequestAsync<V2.DeletedObject>(BaseAddress.Api, HttpMethod.Delete, $"/v2/core/event_destinations/{WebUtility.UrlEncode(id)}", options, requestOptions, cancellationToken);
}

/// <summary>
Expand Down
4 changes: 0 additions & 4 deletions src/Stripe.net/Services/V2/CoreService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ public class CoreService : Service
{
private V2.Core.AccountService accounts;
private V2.Core.AccountLinkService accountLinks;
private V2.Core.EventService events;
private V2.Core.EventDestinationService eventDestinations;
private V2.Core.VaultService vault;

Expand All @@ -29,9 +28,6 @@ internal CoreService(IStripeClient client)
public virtual V2.Core.AccountLinkService AccountLinks => this.accountLinks ??= new V2.Core.AccountLinkService(
this.Requestor);

public virtual V2.Core.EventService Events => this.events ??= new V2.Core.EventService(
this.Requestor);

public virtual V2.Core.EventDestinationService EventDestinations => this.eventDestinations ??= new V2.Core.EventDestinationService(
this.Requestor);

Expand Down
31 changes: 31 additions & 0 deletions src/Stripe.net/Services/_common/MultipartFileContent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
namespace Stripe
{
using System.IO;

/// <summary>
/// Represents Data and optional Name and Type that will be encoded as multipart form
/// data. Used in e.g. FileService.Create.
///
/// </summary>
public class MultipartFileContent
{
/// <summary>
/// The file data to send. If this is a FileStream, the SDK will infer
/// the name and type from the file name and extension. If this is not
/// a FileStream set Name and Type to configure the file upload.
/// </summary>
public Stream Data { get; set; }

/// <summary>
/// The optional name to send with this file data. Uses the file name if omitted
/// and Data is a FileStream.
/// </summary>
public string Name { get; set; }

/// <summary>
/// The optional mime type to use when sending file data. Uses the type that
/// matches the file extension from Name (or the file name from Data) if omitted.
/// </summary>
public string Type { get; set; }
}
}
7 changes: 7 additions & 0 deletions src/Stripe.net/Services/_common/RawRequestOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ namespace Stripe

public class RawRequestOptions : RequestOptions
{
/// <summary>Gets or sets the base URL for the raw request.</summary>
/// <remarks>
/// Use this to send API calls to e.g. files.stripe.com or
/// a proxy address.
/// </remarks>
public string BaseUrl { get => this.InternalBaseUrl; set => this.InternalBaseUrl = value; }

/// <summary>Gets or sets additional headers for the request.</summary>
public Dictionary<string, string> AdditionalHeaders { get; set; } = new Dictionary<string, string>();

Expand Down
Loading
Loading