From c5238f51c286044e78094473d083c7a494f70bf8 Mon Sep 17 00:00:00 2001 From: solid-maksymtielnyi Date: Thu, 4 Sep 2025 00:59:52 +0300 Subject: [PATCH 01/22] Add Sigma query run and scheduled query run resources --- lib/messages.dart | 5 + lib/messages.g.dart | 270 +++++++++++++++++- lib/src/messages/file.dart | 41 +++ lib/src/messages/file_link.dart | 39 +++ .../requests/create_sigma_query_run.dart | 17 ++ lib/src/messages/sigma_query_run.dart | 48 ++++ .../messages/sigma_scheduled_query_run.dart | 68 +++++ lib/src/resources/sigma_query_run.dart | 28 ++ .../resources/sigma_scheduled_query_run.dart | 24 ++ lib/stripe.dart | 10 +- 10 files changed, 537 insertions(+), 13 deletions(-) create mode 100644 lib/src/messages/file.dart create mode 100644 lib/src/messages/file_link.dart create mode 100644 lib/src/messages/requests/create_sigma_query_run.dart create mode 100644 lib/src/messages/sigma_query_run.dart create mode 100644 lib/src/messages/sigma_scheduled_query_run.dart create mode 100644 lib/src/resources/sigma_query_run.dart create mode 100644 lib/src/resources/sigma_scheduled_query_run.dart diff --git a/lib/messages.dart b/lib/messages.dart index bdb6bcf..e74bf33 100644 --- a/lib/messages.dart +++ b/lib/messages.dart @@ -18,6 +18,8 @@ part 'src/messages/customer_balance_transaction.dart'; part 'src/messages/data_list.dart'; part 'src/messages/discount.dart'; part 'src/messages/event.dart'; +part 'src/messages/file.dart'; +part 'src/messages/file_link.dart'; part 'src/messages/invoice.dart'; part 'src/messages/invoice_line_item.dart'; part 'src/messages/pause_collection.dart'; @@ -39,6 +41,7 @@ part 'src/messages/requests/create_portal_session.dart'; part 'src/messages/requests/create_price.dart'; part 'src/messages/requests/create_product.dart'; part 'src/messages/requests/create_refund.dart'; +part 'src/messages/requests/create_sigma_query_run.dart'; part 'src/messages/requests/create_subscription.dart'; part 'src/messages/requests/create_subscription_schedule.dart'; part 'src/messages/requests/created.dart'; @@ -58,6 +61,8 @@ part 'src/messages/requests/update_subscription.dart'; part 'src/messages/requests/update_subscription_item.dart'; part 'src/messages/requests/update_subscription_schedule.dart'; part 'src/messages/shipping_specification.dart'; +part 'src/messages/sigma_query_run.dart'; +part 'src/messages/sigma_scheduled_query_run.dart'; part 'src/messages/source.dart'; part 'src/messages/stripe_api_error.dart'; part 'src/messages/subscription.dart'; diff --git a/lib/messages.g.dart b/lib/messages.g.dart index b15573b..90e0e93 100644 --- a/lib/messages.g.dart +++ b/lib/messages.g.dart @@ -831,6 +831,117 @@ Map _$CouponEventToJson(CouponEvent instance) => 'livemode': instance.livemode, }; +File _$FileFromJson(Map json) => File( + object: $enumDecode(_$_FileObjectEnumMap, json['object']), + id: json['id'] as String, + purpose: json['purpose'] as String, + created: + const TimestampConverter().fromJson((json['created'] as num).toInt()), + size: (json['size'] as num).toInt(), + type: json['type'] as String?, + expiresAt: _$JsonConverterFromJson( + json['expires_at'], const TimestampConverter().fromJson), + filename: json['filename'] as String?, + links: json['links'] == null + ? null + : DataList.fromJson(json['links'] as Map, + (value) => FileLink.fromJson(value as Map)), + title: json['title'] as String?, + url: json['url'] as String?, + ); + +Map _$FileToJson(File instance) { + final val = { + 'object': _$_FileObjectEnumMap[instance.object]!, + 'id': instance.id, + 'purpose': instance.purpose, + }; + + void writeNotNull(String key, dynamic value) { + if (value != null) { + val[key] = value; + } + } + + writeNotNull('type', instance.type); + val['created'] = const TimestampConverter().toJson(instance.created); + writeNotNull( + 'expires_at', + _$JsonConverterToJson( + instance.expiresAt, const TimestampConverter().toJson)); + writeNotNull('filename', instance.filename); + writeNotNull('title', instance.title); + writeNotNull( + 'links', + instance.links?.toJson( + (value) => value.toJson(), + )); + val['size'] = instance.size; + writeNotNull('url', instance.url); + return val; +} + +const _$_FileObjectEnumMap = { + _FileObject.file: 'file', +}; + +Value? _$JsonConverterFromJson( + Object? json, + Value? Function(Json json) fromJson, +) => + json == null ? null : fromJson(json as Json); + +Json? _$JsonConverterToJson( + Value? value, + Json? Function(Value value) toJson, +) => + value == null ? null : toJson(value); + +FileLink _$FileLinkFromJson(Map json) => FileLink( + object: $enumDecode(_$_FileLinkObjectEnumMap, json['object']), + id: json['id'] as String, + file: json['file'] as String, + created: + const TimestampConverter().fromJson((json['created'] as num).toInt()), + expired: json['expired'] as bool, + livemode: json['livemode'] as bool, + expiresAt: _$JsonConverterFromJson( + json['expires_at'], const TimestampConverter().fromJson), + metadata: (json['metadata'] as Map?)?.map( + (k, e) => MapEntry(k, e as String), + ), + url: json['url'] as String?, + ); + +Map _$FileLinkToJson(FileLink instance) { + final val = { + 'object': _$_FileLinkObjectEnumMap[instance.object]!, + 'id': instance.id, + }; + + void writeNotNull(String key, dynamic value) { + if (value != null) { + val[key] = value; + } + } + + writeNotNull( + 'expires_at', + _$JsonConverterToJson( + instance.expiresAt, const TimestampConverter().toJson)); + val['file'] = instance.file; + writeNotNull('metadata', instance.metadata); + writeNotNull('url', instance.url); + val['created'] = const TimestampConverter().toJson(instance.created); + val['expired'] = instance.expired; + val['livemode'] = instance.livemode; + return val; +} + +const _$_FileLinkObjectEnumMap = { + _FileLinkObject.fileLink: 'file_link', +}; + Invoice _$InvoiceFromJson(Map json) => Invoice( id: json['id'] as String, amountDue: (json['amount_due'] as num).toInt(), @@ -1005,18 +1116,6 @@ const _$PauseCollectionBehaviorEnumMap = { PauseCollectionBehavior.void_: 'void', }; -Value? _$JsonConverterFromJson( - Object? json, - Value? Function(Json json) fromJson, -) => - json == null ? null : fromJson(json as Json); - -Json? _$JsonConverterToJson( - Value? value, - Json? Function(Value value) toJson, -) => - value == null ? null : toJson(value); - PaymentIntent _$PaymentIntentFromJson(Map json) => PaymentIntent( object: $enumDecode(_$_PaymentIntentObjectEnumMap, json['object']), @@ -2208,6 +2307,28 @@ Map _$CreateRefundRequestToJson(CreateRefundRequest instance) { return val; } +CreateSigmaQueryRunRequest _$CreateSigmaQueryRunRequestFromJson( + Map json) => + CreateSigmaQueryRunRequest( + fromSavedQuery: json['from_saved_query'] as String?, + sql: json['sql'] as String?, + ); + +Map _$CreateSigmaQueryRunRequestToJson( + CreateSigmaQueryRunRequest instance) { + final val = {}; + + void writeNotNull(String key, dynamic value) { + if (value != null) { + val[key] = value; + } + } + + writeNotNull('from_saved_query', instance.fromSavedQuery); + writeNotNull('sql', instance.sql); + return val; +} + CreateSubscriptionRequest _$CreateSubscriptionRequestFromJson( Map json) => CreateSubscriptionRequest( @@ -2916,6 +3037,131 @@ Map _$ShippingSpecificationToJson( return val; } +SigmaQueryRun _$SigmaQueryRunFromJson(Map json) => + SigmaQueryRun( + object: $enumDecode(_$_SigmaQueryRunObjectEnumMap, json['object']), + id: json['id'] as String, + created: + const TimestampConverter().fromJson((json['created'] as num).toInt()), + livemode: json['livemode'] as bool, + sql: json['sql'] as String, + status: $enumDecode(_$SigmaQueryRunStatusEnumMap, json['status']), + finalizedAt: _$JsonConverterFromJson( + json['finalized_at'], const TimestampConverter().fromJson), + ); + +Map _$SigmaQueryRunToJson(SigmaQueryRun instance) { + final val = { + 'object': _$_SigmaQueryRunObjectEnumMap[instance.object]!, + 'id': instance.id, + 'created': const TimestampConverter().toJson(instance.created), + }; + + void writeNotNull(String key, dynamic value) { + if (value != null) { + val[key] = value; + } + } + + writeNotNull( + 'finalized_at', + _$JsonConverterToJson( + instance.finalizedAt, const TimestampConverter().toJson)); + val['livemode'] = instance.livemode; + val['sql'] = instance.sql; + val['status'] = _$SigmaQueryRunStatusEnumMap[instance.status]!; + return val; +} + +const _$_SigmaQueryRunObjectEnumMap = { + _SigmaQueryRunObject.sigmaSigmaQueryRun: 'sigma.sigma_query_run', +}; + +const _$SigmaQueryRunStatusEnumMap = { + SigmaQueryRunStatus.succeeded: 'succeeded', + SigmaQueryRunStatus.pending: 'pending', + SigmaQueryRunStatus.running: 'running', + SigmaQueryRunStatus.failed: 'failed', +}; + +SigmaScheduledQueryRun _$SigmaScheduledQueryRunFromJson( + Map json) => + SigmaScheduledQueryRun( + object: + $enumDecode(_$_SigmaScheduledQueryRunObjectEnumMap, json['object']), + sql: json['sql'] as String, + status: + $enumDecode(_$SigmaScheduledQueryRunStatusEnumMap, json['status']), + created: + const TimestampConverter().fromJson((json['created'] as num).toInt()), + livemode: json['livemode'] as bool, + dataLoadTime: _$JsonConverterFromJson( + json['data_load_time'], const TimestampConverter().fromJson), + file: json['file'] == null + ? null + : File.fromJson(json['file'] as Map), + name: json['name'] as String?, + error: json['error'] == null + ? null + : SigmaScheduledQueryRunError.fromJson( + json['error'] as Map), + resultAvailableUntil: _$JsonConverterFromJson( + json['result_available_until'], const TimestampConverter().fromJson), + ); + +Map _$SigmaScheduledQueryRunToJson( + SigmaScheduledQueryRun instance) { + final val = { + 'object': _$_SigmaScheduledQueryRunObjectEnumMap[instance.object]!, + }; + + void writeNotNull(String key, dynamic value) { + if (value != null) { + val[key] = value; + } + } + + writeNotNull( + 'data_load_time', + _$JsonConverterToJson( + instance.dataLoadTime, const TimestampConverter().toJson)); + writeNotNull('file', instance.file?.toJson()); + val['sql'] = instance.sql; + val['status'] = _$SigmaScheduledQueryRunStatusEnumMap[instance.status]!; + writeNotNull('name', instance.name); + val['created'] = const TimestampConverter().toJson(instance.created); + writeNotNull('error', instance.error?.toJson()); + val['livemode'] = instance.livemode; + writeNotNull( + 'result_available_until', + _$JsonConverterToJson( + instance.resultAvailableUntil, const TimestampConverter().toJson)); + return val; +} + +const _$_SigmaScheduledQueryRunObjectEnumMap = { + _SigmaScheduledQueryRunObject.scheduledQueryRun: 'scheduledQueryRun', +}; + +const _$SigmaScheduledQueryRunStatusEnumMap = { + SigmaScheduledQueryRunStatus.completed: 'completed', + SigmaScheduledQueryRunStatus.canceled: 'canceled', + SigmaScheduledQueryRunStatus.failed: 'failed', + SigmaScheduledQueryRunStatus.timedOut: 'timed_out', +}; + +SigmaScheduledQueryRunError _$SigmaScheduledQueryRunErrorFromJson( + Map json) => + SigmaScheduledQueryRunError( + message: json['message'] as String, + ); + +Map _$SigmaScheduledQueryRunErrorToJson( + SigmaScheduledQueryRunError instance) => + { + 'message': instance.message, + }; + Source _$SourceFromJson(Map json) => Source( id: json['id'] as String, object: json['object'] as String, diff --git a/lib/src/messages/file.dart b/lib/src/messages/file.dart new file mode 100644 index 0000000..fe3058d --- /dev/null +++ b/lib/src/messages/file.dart @@ -0,0 +1,41 @@ +part of '../../messages.dart'; + +enum _FileObject { + file, +} + +@JsonSerializable() +class File extends Message { + final _FileObject object; + final String id; + final String purpose; + final String? type; + @TimestampConverter() + final DateTime created; + @TimestampConverter() + final DateTime? expiresAt; + final String? filename; + final String? title; + final DataList? links; + final int size; + final String? url; + + const File({ + required this.object, + required this.id, + required this.purpose, + required this.created, + required this.size, + this.type, + this.expiresAt, + this.filename, + this.links, + this.title, + this.url, + }); + + factory File.fromJson(Map json) => _$FileFromJson(json); + + @override + Map toJson() => _$FileToJson(this); +} diff --git a/lib/src/messages/file_link.dart b/lib/src/messages/file_link.dart new file mode 100644 index 0000000..b94b4aa --- /dev/null +++ b/lib/src/messages/file_link.dart @@ -0,0 +1,39 @@ +part of '../../messages.dart'; + +enum _FileLinkObject { + @JsonValue('file_link') + fileLink, +} + +@JsonSerializable() +class FileLink extends Message { + final _FileLinkObject object; + final String id; + @TimestampConverter() + final DateTime? expiresAt; + final String file; + final Map? metadata; + final String? url; + @TimestampConverter() + final DateTime created; + final bool expired; + final bool livemode; + + const FileLink({ + required this.object, + required this.id, + required this.file, + required this.created, + required this.expired, + required this.livemode, + this.expiresAt, + this.metadata, + this.url, + }); + + factory FileLink.fromJson(Map json) => + _$FileLinkFromJson(json); + + @override + Map toJson() => _$FileLinkToJson(this); +} diff --git a/lib/src/messages/requests/create_sigma_query_run.dart b/lib/src/messages/requests/create_sigma_query_run.dart new file mode 100644 index 0000000..fbd690d --- /dev/null +++ b/lib/src/messages/requests/create_sigma_query_run.dart @@ -0,0 +1,17 @@ +part of '../../../messages.dart'; + +@JsonSerializable() +class CreateSigmaQueryRunRequest { + final String? fromSavedQuery; + final String? sql; + + const CreateSigmaQueryRunRequest({ + this.fromSavedQuery, + this.sql, + }); + + factory CreateSigmaQueryRunRequest.fromJson(Map json) => + _$CreateSigmaQueryRunRequestFromJson(json); + + Map toJson() => _$CreateSigmaQueryRunRequestToJson(this); +} diff --git a/lib/src/messages/sigma_query_run.dart b/lib/src/messages/sigma_query_run.dart new file mode 100644 index 0000000..8dde4cc --- /dev/null +++ b/lib/src/messages/sigma_query_run.dart @@ -0,0 +1,48 @@ +part of '../../messages.dart'; + +enum _SigmaQueryRunObject { + @JsonValue('sigma.sigma_query_run') + sigmaSigmaQueryRun +} + +enum SigmaQueryRunStatus { + succeeded, + pending, + running, + failed, +} + +@JsonSerializable() +class SigmaQueryRun extends Message { + final _SigmaQueryRunObject object; + + final String id; + + @TimestampConverter() + final DateTime created; + + @TimestampConverter() + final DateTime? finalizedAt; + + final bool livemode; + + final String sql; + + final SigmaQueryRunStatus status; + + const SigmaQueryRun({ + required this.object, + required this.id, + required this.created, + required this.livemode, + required this.sql, + required this.status, + this.finalizedAt, + }); + + factory SigmaQueryRun.fromJson(Map json) => + _$SigmaQueryRunFromJson(json); + + @override + Map toJson() => _$SigmaQueryRunToJson(this); +} diff --git a/lib/src/messages/sigma_scheduled_query_run.dart b/lib/src/messages/sigma_scheduled_query_run.dart new file mode 100644 index 0000000..9c4948e --- /dev/null +++ b/lib/src/messages/sigma_scheduled_query_run.dart @@ -0,0 +1,68 @@ +part of '../../messages.dart'; + +enum _SigmaScheduledQueryRunObject { + scheduledQueryRun, +} + +enum SigmaScheduledQueryRunStatus { + completed, + canceled, + failed, + @JsonValue('timed_out') + timedOut, +} + +@JsonSerializable() +class SigmaScheduledQueryRun extends Message { + final _SigmaScheduledQueryRunObject object; + + @TimestampConverter() + final DateTime? dataLoadTime; + final File? file; + final String sql; + final SigmaScheduledQueryRunStatus status; + final String? name; + + @TimestampConverter() + final DateTime created; + + final SigmaScheduledQueryRunError? error; + final bool livemode; + + @TimestampConverter() + final DateTime? resultAvailableUntil; + + const SigmaScheduledQueryRun({ + required this.object, + required this.sql, + required this.status, + required this.created, + required this.livemode, + this.dataLoadTime, + this.file, + this.name, + this.error, + this.resultAvailableUntil, + }); + + factory SigmaScheduledQueryRun.fromJson(Map json) => + _$SigmaScheduledQueryRunFromJson(json); + + @override + Map toJson() => _$SigmaScheduledQueryRunToJson(this); +} + +@JsonSerializable() +class SigmaScheduledQueryRunError extends Message { + final String message; + + const SigmaScheduledQueryRunError({ + required this.message, + }); + + factory SigmaScheduledQueryRunError.fromJson(Map json) => + _$SigmaScheduledQueryRunErrorFromJson(json); + + @override + Map toJson() => _$SigmaScheduledQueryRunErrorToJson(this); +} diff --git a/lib/src/resources/sigma_query_run.dart b/lib/src/resources/sigma_query_run.dart new file mode 100644 index 0000000..8d98175 --- /dev/null +++ b/lib/src/resources/sigma_query_run.dart @@ -0,0 +1,28 @@ +import 'package:stripe/messages.dart'; +import 'package:stripe/src/client.dart'; +import 'package:stripe/src/resources/_resource.dart'; + +class SigmaQueryRunResource extends Resource { + static const _resourceName = 'sigma/query_runs'; + + SigmaQueryRunResource(Client client) : super(client); + + Future create( + CreateSigmaQueryRunRequest request, { + String? idempotencyKey, + }) async { + final map = await post( + _resourceName, + data: request.toJson(), + idempotencyKey: idempotencyKey, + ); + + return SigmaQueryRun.fromJson(map); + } + + Future retrieve(String sigmaQueryRunId) async { + final map = await get('$_resourceName/$sigmaQueryRunId'); + + return SigmaQueryRun.fromJson(map); + } +} diff --git a/lib/src/resources/sigma_scheduled_query_run.dart b/lib/src/resources/sigma_scheduled_query_run.dart new file mode 100644 index 0000000..a6fd64f --- /dev/null +++ b/lib/src/resources/sigma_scheduled_query_run.dart @@ -0,0 +1,24 @@ +import 'package:stripe/messages.dart'; +import 'package:stripe/src/client.dart'; +import 'package:stripe/src/resources/_resource.dart'; + +class SigmaScheduledQueryRunResource extends Resource { + static const _resourceName = 'sigma/scheduled_query_runs'; + + SigmaScheduledQueryRunResource(Client client) : super(client); + + Future retrieve(String sigmaQueryRunId) async { + final map = await get('$_resourceName/$sigmaQueryRunId'); + + return SigmaScheduledQueryRun.fromJson(map); + } + + Future> list() async { + final map = await get(_resourceName); + + return DataList.fromJson( + map, + (value) => SigmaScheduledQueryRun.fromJson(value as Map), + ); + } +} diff --git a/lib/stripe.dart b/lib/stripe.dart index e1dd6a9..bd1273f 100644 --- a/lib/stripe.dart +++ b/lib/stripe.dart @@ -14,6 +14,8 @@ import 'src/resources/price.dart'; import 'src/resources/product.dart'; import 'src/resources/promotion_code.dart'; import 'src/resources/refund.dart'; +import 'src/resources/sigma_query_run.dart'; +import 'src/resources/sigma_scheduled_query_run.dart'; import 'src/resources/subscription.dart'; import 'src/resources/subscription_item.dart'; import 'src/resources/subscription_schedule.dart'; @@ -85,6 +87,10 @@ class Stripe { final CustomerBalanceTransactionResource customerBalanceTransaction; + final SigmaQueryRunResource sigmaQueryRun; + + final SigmaScheduledQueryRunResource sigmaScheduledQueryRun; + factory Stripe(String apiKey) { final client = DioClient(apiKey: apiKey); return Stripe.withClient(client); @@ -106,5 +112,7 @@ class Stripe { promotionCode = PromotionCodeResource(client), coupon = CouponResource(client), invoice = InvoiceResource(client), - customerBalanceTransaction = CustomerBalanceTransactionResource(client); + customerBalanceTransaction = CustomerBalanceTransactionResource(client), + sigmaQueryRun = SigmaQueryRunResource(client), + sigmaScheduledQueryRun = SigmaScheduledQueryRunResource(client); } From 307c8188f451c34ad917594b3381b786bb460e7d Mon Sep 17 00:00:00 2001 From: solid-maksymtielnyi Date: Thu, 4 Sep 2025 01:24:30 +0300 Subject: [PATCH 02/22] Fix: scheduled_query_run JSON value --- lib/messages.g.dart | 2 +- lib/src/messages/sigma_scheduled_query_run.dart | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/messages.g.dart b/lib/messages.g.dart index 90e0e93..4bd6133 100644 --- a/lib/messages.g.dart +++ b/lib/messages.g.dart @@ -3140,7 +3140,7 @@ Map _$SigmaScheduledQueryRunToJson( } const _$_SigmaScheduledQueryRunObjectEnumMap = { - _SigmaScheduledQueryRunObject.scheduledQueryRun: 'scheduledQueryRun', + _SigmaScheduledQueryRunObject.scheduledQueryRun: 'scheduled_query_run', }; const _$SigmaScheduledQueryRunStatusEnumMap = { diff --git a/lib/src/messages/sigma_scheduled_query_run.dart b/lib/src/messages/sigma_scheduled_query_run.dart index 9c4948e..2d78e4b 100644 --- a/lib/src/messages/sigma_scheduled_query_run.dart +++ b/lib/src/messages/sigma_scheduled_query_run.dart @@ -1,6 +1,7 @@ part of '../../messages.dart'; enum _SigmaScheduledQueryRunObject { + @JsonValue('scheduled_query_run') scheduledQueryRun, } From c9721429503e0c21608895a6cbf7170fb8fa2bcb Mon Sep 17 00:00:00 2001 From: solid-maksymtielnyi Date: Thu, 4 Sep 2025 02:12:47 +0300 Subject: [PATCH 03/22] Add file resource --- lib/src/client.dart | 56 ++++++++++++++++++++++++-------- lib/src/resources/_resource.dart | 7 ++++ lib/src/resources/file.dart | 18 ++++++++++ lib/stripe.dart | 6 +++- 4 files changed, 73 insertions(+), 14 deletions(-) create mode 100644 lib/src/resources/file.dart diff --git a/lib/src/client.dart b/lib/src/client.dart index 85c3a37..0c70389 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:convert'; +import 'dart:typed_data'; import 'package:dio/dio.dart'; import 'package:meta/meta.dart'; @@ -32,8 +33,15 @@ abstract class Client { Map? queryParameters, }); + /// Makes a GET request to the Stripe API + Future getBytes( + final String path, { + String? idempotencyKey, + Map? queryParameters, + }); + @protected - Map processResponse({ + T processResponse({ required int? statusCode, required Object? data, }) { @@ -65,14 +73,13 @@ abstract class Client { ); } } - if (data == null || data is! Map) { - throw InvalidRequestException( - 'The JSON returned was unparsable ($data).', - statusCode: statusCode, - ); - } - return data; + if (data is T) return data; + + throw InvalidRequestException( + 'The JSON returned was unparsable ($data).', + statusCode: statusCode, + ); } } @@ -183,13 +190,36 @@ class DioClient extends Client { return _processDioResponse(response); } - Options? _createRequestOptions({String? idempotencyKey}) => - idempotencyKey == null + @override + Future getBytes( + String path, { + String? idempotencyKey, + Map? queryParameters, + }) async { + final response = await dio.get( + path, + queryParameters: queryParameters, + options: _createRequestOptions(idempotencyKey: idempotencyKey), + ); + return _processDioResponse(response); + } + + Options? _createRequestOptions({ + String? idempotencyKey, + ResponseType? responseType, + }) => + idempotencyKey == null && + (responseType == null || responseType == ResponseType.json) ? null - : Options(headers: {'Idempotency-Key': idempotencyKey}); + : Options( + headers: { + 'Idempotency-Key': idempotencyKey, + }, + responseType: responseType, + ); - Map _processDioResponse( - Response> response, + T _processDioResponse( + Response response, ) { return processResponse( statusCode: response.statusCode, diff --git a/lib/src/resources/_resource.dart b/lib/src/resources/_resource.dart index 333798d..c6939db 100644 --- a/lib/src/resources/_resource.dart +++ b/lib/src/resources/_resource.dart @@ -1,3 +1,5 @@ +import 'dart:typed_data'; + import 'package:meta/meta.dart'; import '../../messages.dart'; @@ -20,6 +22,11 @@ abstract class Resource { {Map? queryParameters}) => _client.get(makeUrl(path), queryParameters: queryParameters); + @protected + Future getBytes(final String path, + {Map? queryParameters}) => + _client.getBytes(makeUrl(path), queryParameters: queryParameters); + @protected Future> post( final String path, { diff --git a/lib/src/resources/file.dart b/lib/src/resources/file.dart new file mode 100644 index 0000000..1a1eb60 --- /dev/null +++ b/lib/src/resources/file.dart @@ -0,0 +1,18 @@ +import 'dart:typed_data'; + +import 'package:stripe/src/client.dart'; + +import '../../messages.dart'; +import '_resource.dart'; + +class FileResource extends Resource { + static const _resourceName = 'files'; + + FileResource(Client client) : super(client); + + Future downloadContentBytes(String fileId) async { + final bytes = await getBytes('$_resourceName/$fileId'); + + return bytes; + } +} diff --git a/lib/stripe.dart b/lib/stripe.dart index bd1273f..9d78cb0 100644 --- a/lib/stripe.dart +++ b/lib/stripe.dart @@ -7,6 +7,7 @@ import 'src/resources/checkout_session.dart'; import 'src/resources/coupon.dart'; import 'src/resources/customer.dart'; import 'src/resources/customer_balance_transaction.dart'; +import 'src/resources/file.dart'; import 'src/resources/invoice.dart'; import 'src/resources/payment_intent.dart'; import 'src/resources/portal_session.dart'; @@ -91,6 +92,8 @@ class Stripe { final SigmaScheduledQueryRunResource sigmaScheduledQueryRun; + final FileResource fileResource; + factory Stripe(String apiKey) { final client = DioClient(apiKey: apiKey); return Stripe.withClient(client); @@ -114,5 +117,6 @@ class Stripe { invoice = InvoiceResource(client), customerBalanceTransaction = CustomerBalanceTransactionResource(client), sigmaQueryRun = SigmaQueryRunResource(client), - sigmaScheduledQueryRun = SigmaScheduledQueryRunResource(client); + sigmaScheduledQueryRun = SigmaScheduledQueryRunResource(client), + fileResource = FileResource(client); } From f06395075145cfbab3abcb1b1f4805186e7aae5b Mon Sep 17 00:00:00 2001 From: solid-maksymtielnyi Date: Thu, 4 Sep 2025 02:20:57 +0300 Subject: [PATCH 04/22] Add id field to SigmaScheduledQueryRun --- lib/messages.g.dart | 2 ++ lib/src/messages/sigma_scheduled_query_run.dart | 2 ++ 2 files changed, 4 insertions(+) diff --git a/lib/messages.g.dart b/lib/messages.g.dart index 4bd6133..505018e 100644 --- a/lib/messages.g.dart +++ b/lib/messages.g.dart @@ -3087,6 +3087,7 @@ const _$SigmaQueryRunStatusEnumMap = { SigmaScheduledQueryRun _$SigmaScheduledQueryRunFromJson( Map json) => SigmaScheduledQueryRun( + id: json['id'] as String, object: $enumDecode(_$_SigmaScheduledQueryRunObjectEnumMap, json['object']), sql: json['sql'] as String, @@ -3113,6 +3114,7 @@ Map _$SigmaScheduledQueryRunToJson( SigmaScheduledQueryRun instance) { final val = { 'object': _$_SigmaScheduledQueryRunObjectEnumMap[instance.object]!, + 'id': instance.id, }; void writeNotNull(String key, dynamic value) { diff --git a/lib/src/messages/sigma_scheduled_query_run.dart b/lib/src/messages/sigma_scheduled_query_run.dart index 2d78e4b..0b44bd7 100644 --- a/lib/src/messages/sigma_scheduled_query_run.dart +++ b/lib/src/messages/sigma_scheduled_query_run.dart @@ -17,6 +17,7 @@ enum SigmaScheduledQueryRunStatus { class SigmaScheduledQueryRun extends Message { final _SigmaScheduledQueryRunObject object; + final String id; @TimestampConverter() final DateTime? dataLoadTime; final File? file; @@ -34,6 +35,7 @@ class SigmaScheduledQueryRun extends Message { final DateTime? resultAvailableUntil; const SigmaScheduledQueryRun({ + required this.id, required this.object, required this.sql, required this.status, From ba124b667ba4033c2c094ca3abdeb88c2faac118 Mon Sep 17 00:00:00 2001 From: solid-maksymtielnyi Date: Thu, 4 Sep 2025 02:21:54 +0300 Subject: [PATCH 05/22] Fix the response parsing error message --- lib/src/client.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/client.dart b/lib/src/client.dart index 0c70389..b50997a 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -77,7 +77,7 @@ abstract class Client { if (data is T) return data; throw InvalidRequestException( - 'The JSON returned was unparsable ($data).', + 'The returned data was unparsable ($data).', statusCode: statusCode, ); } From acb2c564c23c7fd885260b828dcf18e8756ceb32 Mon Sep 17 00:00:00 2001 From: solid-maksymtielnyi Date: Thu, 4 Sep 2025 02:23:24 +0300 Subject: [PATCH 06/22] Rename fileResource field to file --- lib/stripe.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/stripe.dart b/lib/stripe.dart index 9d78cb0..7afaf70 100644 --- a/lib/stripe.dart +++ b/lib/stripe.dart @@ -92,7 +92,7 @@ class Stripe { final SigmaScheduledQueryRunResource sigmaScheduledQueryRun; - final FileResource fileResource; + final FileResource file; factory Stripe(String apiKey) { final client = DioClient(apiKey: apiKey); @@ -118,5 +118,5 @@ class Stripe { customerBalanceTransaction = CustomerBalanceTransactionResource(client), sigmaQueryRun = SigmaQueryRunResource(client), sigmaScheduledQueryRun = SigmaScheduledQueryRunResource(client), - fileResource = FileResource(client); + file = FileResource(client); } From 851ba53e556f8635ab918729d8ddf6a9ac6e9b79 Mon Sep 17 00:00:00 2001 From: solid-maksymtielnyi Date: Thu, 4 Sep 2025 02:27:04 +0300 Subject: [PATCH 07/22] Fix getBytes responseType --- lib/src/client.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/src/client.dart b/lib/src/client.dart index b50997a..22231c1 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -199,7 +199,10 @@ class DioClient extends Client { final response = await dio.get( path, queryParameters: queryParameters, - options: _createRequestOptions(idempotencyKey: idempotencyKey), + options: _createRequestOptions( + idempotencyKey: idempotencyKey, + responseType: ResponseType.bytes, + ), ); return _processDioResponse(response); } From 84d424066af85867bbe5893bde67a9e4dd55979e Mon Sep 17 00:00:00 2001 From: solid-maksymtielnyi Date: Thu, 4 Sep 2025 02:51:49 +0300 Subject: [PATCH 08/22] Parse body on error --- lib/src/client.dart | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/lib/src/client.dart b/lib/src/client.dart index 22231c1..8b177ec 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -46,15 +46,26 @@ abstract class Client { required Object? data, }) { if (statusCode != 200) { - if (data == null || - data is! Map || - data['error'] == null) { + final Map? bodyJson; + + if (data is Map) { + bodyJson = data; + } else if (data is String) { + bodyJson = jsonDecode(data); + } else if (data is List) { + final body = utf8.decode(data); + bodyJson = jsonDecode(body); + } else { + bodyJson = null; + } + + if (bodyJson == null || bodyJson['error'] == null) { throw InvalidRequestException( 'The status code returned was $statusCode but no error was provided.', statusCode: statusCode, ); } - final errorJson = data['error'] as Map; + final errorJson = bodyJson['error'] as Map; final error = StripeApiError.fromJson(errorJson); switch (error.type) { From ca08c8fcfa97648bb59976fbc72fe00fd1bc3a0a Mon Sep 17 00:00:00 2001 From: solid-maksymtielnyi Date: Thu, 4 Sep 2025 02:58:53 +0300 Subject: [PATCH 09/22] Disable automatic Dio response status validation --- lib/src/client.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/client.dart b/lib/src/client.dart index 8b177ec..12d135c 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -230,6 +230,7 @@ class DioClient extends Client { 'Idempotency-Key': idempotencyKey, }, responseType: responseType, + validateStatus: (_) => true, ); T _processDioResponse( From ca1358eb778797fe60259716cd2ac7e08cfdaeb3 Mon Sep 17 00:00:00 2001 From: solid-maksymtielnyi Date: Thu, 4 Sep 2025 03:06:04 +0300 Subject: [PATCH 10/22] Add doc comments for getBytes methods --- lib/src/client.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/src/client.dart b/lib/src/client.dart index 12d135c..a09fbb1 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -33,7 +33,7 @@ abstract class Client { Map? queryParameters, }); - /// Makes a GET request to the Stripe API + /// Makes a GET request to the Stripe API, returns body bytes Future getBytes( final String path, { String? idempotencyKey, @@ -202,6 +202,8 @@ class DioClient extends Client { } @override + + /// Makes a get request to the Stripe API, returns body bytes. Future getBytes( String path, { String? idempotencyKey, From cf4eaa179a91b2de8ca8f25a021900ee14010567 Mon Sep 17 00:00:00 2001 From: solid-maksymtielnyi Date: Thu, 4 Sep 2025 03:12:26 +0300 Subject: [PATCH 11/22] Add downloadContentPlain method to FileResource --- lib/src/client.dart | 24 ++++++++++++++++++++++++ lib/src/resources/_resource.dart | 5 +++++ lib/src/resources/file.dart | 6 ++++++ 3 files changed, 35 insertions(+) diff --git a/lib/src/client.dart b/lib/src/client.dart index a09fbb1..99f43af 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -33,6 +33,13 @@ abstract class Client { Map? queryParameters, }); + /// Makes a GET request to the Stripe API, returns plain body + Future getPlain( + final String path, { + String? idempotencyKey, + Map? queryParameters, + }); + /// Makes a GET request to the Stripe API, returns body bytes Future getBytes( final String path, { @@ -201,9 +208,26 @@ class DioClient extends Client { return _processDioResponse(response); } + /// Makes a GET request to the Stripe API, returns plain body @override + Future getPlain( + String path, { + String? idempotencyKey, + Map? queryParameters, + }) async { + final response = await dio.get( + path, + queryParameters: queryParameters, + options: _createRequestOptions( + idempotencyKey: idempotencyKey, + responseType: ResponseType.plain, + ), + ); + return _processDioResponse(response); + } /// Makes a get request to the Stripe API, returns body bytes. + @override Future getBytes( String path, { String? idempotencyKey, diff --git a/lib/src/resources/_resource.dart b/lib/src/resources/_resource.dart index c6939db..3162ebb 100644 --- a/lib/src/resources/_resource.dart +++ b/lib/src/resources/_resource.dart @@ -22,6 +22,11 @@ abstract class Resource { {Map? queryParameters}) => _client.get(makeUrl(path), queryParameters: queryParameters); + @protected + Future getPlain(final String path, + {Map? queryParameters}) => + _client.getPlain(makeUrl(path), queryParameters: queryParameters); + @protected Future getBytes(final String path, {Map? queryParameters}) => diff --git a/lib/src/resources/file.dart b/lib/src/resources/file.dart index 1a1eb60..9b08368 100644 --- a/lib/src/resources/file.dart +++ b/lib/src/resources/file.dart @@ -10,6 +10,12 @@ class FileResource extends Resource { FileResource(Client client) : super(client); + Future downloadContentPlain(String fileId) async { + final content = await getPlain('$_resourceName/$fileId'); + + return content; + } + Future downloadContentBytes(String fileId) async { final bytes = await getBytes('$_resourceName/$fileId'); From 8b3db0727ffa0694c3f718bf2168ede14800d525 Mon Sep 17 00:00:00 2001 From: solid-maksymtielnyi Date: Thu, 4 Sep 2025 03:21:25 +0300 Subject: [PATCH 12/22] Fix file contents endpoints paths --- lib/src/resources/file.dart | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/src/resources/file.dart b/lib/src/resources/file.dart index 9b08368..237042b 100644 --- a/lib/src/resources/file.dart +++ b/lib/src/resources/file.dart @@ -11,13 +11,21 @@ class FileResource extends Resource { FileResource(Client client) : super(client); Future downloadContentPlain(String fileId) async { - final content = await getPlain('$_resourceName/$fileId'); + final content = await getPlain(_buildContentsPath(fileId)); return content; } + String _buildContentsPath(String fileId) { + return [ + _resourceName, + fileId, + 'contents', + ].join('/'); + } + Future downloadContentBytes(String fileId) async { - final bytes = await getBytes('$_resourceName/$fileId'); + final bytes = await getBytes(_buildContentsPath(fileId)); return bytes; } From 96c48afff7fde5b2f0bb6c70dfa249be1971522c Mon Sep 17 00:00:00 2001 From: solid-maksymtielnyi Date: Thu, 4 Sep 2025 04:54:54 +0300 Subject: [PATCH 13/22] Fix file contents endpoints base url, refactor resource and client --- lib/src/client.dart | 41 +++++++--------- lib/src/resources/_api_config.dart | 17 +++++++ lib/src/resources/_resource.dart | 45 +++-------------- lib/src/resources/balance_transaction.dart | 8 +++- lib/src/resources/charge.dart | 7 ++- lib/src/resources/checkout_session.dart | 13 +++-- lib/src/resources/coupon.dart | 8 +++- lib/src/resources/customer.dart | 32 ++++++++----- .../customer_balance_transaction.dart | 20 ++++---- lib/src/resources/file.dart | 17 +++++-- lib/src/resources/invoice.dart | 13 +++-- lib/src/resources/payment_intent.dart | 29 +++++++---- lib/src/resources/portal_session.dart | 10 ++-- lib/src/resources/price.dart | 21 +++++--- lib/src/resources/product.dart | 21 +++++--- lib/src/resources/promotion_code.dart | 9 +++- lib/src/resources/refund.dart | 8 +++- lib/src/resources/sigma_query_run.dart | 12 +++-- .../resources/sigma_scheduled_query_run.dart | 12 +++-- lib/src/resources/source.dart | 11 ++++- lib/src/resources/subscription.dart | 37 ++++++++------ lib/src/resources/subscription_item.dart | 20 +++++--- lib/src/resources/subscription_schedule.dart | 21 ++++---- lib/stripe.dart | 48 ++++++++++--------- test/resources/balance_transaction_test.dart | 12 ++++- test/resources/checkout_session_test.dart | 9 +++- test/resources/customer_test.dart | 9 +++- test/resources/payment_intent_test.dart | 9 +++- test/resources/subscription_test.dart | 9 +++- 29 files changed, 329 insertions(+), 199 deletions(-) create mode 100644 lib/src/resources/_api_config.dart diff --git a/lib/src/client.dart b/lib/src/client.dart index 99f43af..24e0f70 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -7,42 +7,39 @@ import 'package:meta/meta.dart'; import 'package:stripe/messages.dart'; import 'package:stripe/src/exceptions.dart'; -const _defaultUrl = 'https://api.stripe.com/v1/'; -const _defaultVersion = '2020-08-27'; - /// The http client that will make requests to the stripe API. abstract class Client { /// Makes a POST request to the Stripe API Future> post( - final String path, { + final Uri url, { final Map? data, final String? idempotencyKey, }); /// Makes a DELETE request to the Stripe API Future> delete( - final String path, { + final Uri url, { final Map? data, final String? idempotencyKey, }); /// Makes a GET request to the Stripe API Future> get( - final String path, { + final Uri url, { String? idempotencyKey, Map? queryParameters, }); /// Makes a GET request to the Stripe API, returns plain body Future getPlain( - final String path, { + final Uri url, { String? idempotencyKey, Map? queryParameters, }); /// Makes a GET request to the Stripe API, returns body bytes Future getBytes( - final String path, { + final Uri url, { String? idempotencyKey, Map? queryParameters, }); @@ -111,12 +108,10 @@ class DioClient extends Client { /// Creates a [Dio] client that will make requests to [baseUrl]. factory DioClient({ required String apiKey, - String baseUrl = _defaultUrl, - String version = _defaultVersion, + required String version, }) => DioClient.withDio( Dio(), - baseUrl: baseUrl, version: version, apiKey: apiKey, ); @@ -125,12 +120,10 @@ class DioClient extends Client { DioClient.withDio( this.dio, { required this.apiKey, - String baseUrl = _defaultUrl, - this.version = _defaultVersion, + required this.version, }) { dio.transformer = FormDataTransformer(); dio.options - ..baseUrl = baseUrl ..responseType = ResponseType.json ..contentType = 'application/x-www-form-urlencoded' ..headers = { @@ -148,12 +141,12 @@ class DioClient extends Client { /// Makes a post request to the Stripe API @override Future> post( - final String path, { + final Uri url, { final Map? data, final String? idempotencyKey, }) async { try { - final response = await dio.post>(path, + final response = await dio.post>(url.toString(), data: data, options: _createRequestOptions(idempotencyKey: idempotencyKey)); return _processDioResponse(response); @@ -172,12 +165,12 @@ class DioClient extends Client { /// Makes a DELETE request to the Stripe API @override Future> delete( - final String path, { + final Uri url, { final Map? data, final String? idempotencyKey, }) async { try { - final response = await dio.delete>(path, + final response = await dio.delete>(url.toString(), data: data, options: _createRequestOptions(idempotencyKey: idempotencyKey)); return _processDioResponse(response); @@ -196,12 +189,12 @@ class DioClient extends Client { /// Makes a get request to the Stripe API @override Future> get( - final String path, { + final Uri url, { String? idempotencyKey, Map? queryParameters, }) async { final response = await dio.get>( - path, + url.toString(), queryParameters: queryParameters, options: _createRequestOptions(idempotencyKey: idempotencyKey), ); @@ -211,12 +204,12 @@ class DioClient extends Client { /// Makes a GET request to the Stripe API, returns plain body @override Future getPlain( - String path, { + final Uri url, { String? idempotencyKey, Map? queryParameters, }) async { final response = await dio.get( - path, + url.toString(), queryParameters: queryParameters, options: _createRequestOptions( idempotencyKey: idempotencyKey, @@ -229,12 +222,12 @@ class DioClient extends Client { /// Makes a get request to the Stripe API, returns body bytes. @override Future getBytes( - String path, { + final Uri url, { String? idempotencyKey, Map? queryParameters, }) async { final response = await dio.get( - path, + url.toString(), queryParameters: queryParameters, options: _createRequestOptions( idempotencyKey: idempotencyKey, diff --git a/lib/src/resources/_api_config.dart b/lib/src/resources/_api_config.dart new file mode 100644 index 0000000..5afb882 --- /dev/null +++ b/lib/src/resources/_api_config.dart @@ -0,0 +1,17 @@ +class ApiConfig { + static const defaultVersion = '2020-08-27'; + static const defaultApiUrl = 'https://api.stripe.com/v1/'; + static const defaultFilesUrl = 'https://files.stripe.com/v1/'; + + final String apiKey; + final String version; + final String baseApiUrl; + final String baseFilesUrl; + + const ApiConfig({ + required this.apiKey, + this.version = defaultVersion, + this.baseApiUrl = defaultApiUrl, + this.baseFilesUrl = defaultFilesUrl, + }); +} diff --git a/lib/src/resources/_resource.dart b/lib/src/resources/_resource.dart index 3162ebb..3beea2c 100644 --- a/lib/src/resources/_resource.dart +++ b/lib/src/resources/_resource.dart @@ -1,51 +1,20 @@ -import 'dart:typed_data'; - import 'package:meta/meta.dart'; +import 'package:stripe/src/resources/_api_config.dart'; import '../../messages.dart'; import '../client.dart'; abstract class Resource { @protected - final Client _client; + final Client client; + @protected + final ApiConfig config; - Resource(this._client); + Resource(this.client, this.config); @protected @visibleForOverriding - String makeUrl(String path) { - return path; + Uri makeUrl(String path) { + return Uri.parse(config.baseApiUrl).resolve(path); } - - @protected - Future> get(final String path, - {Map? queryParameters}) => - _client.get(makeUrl(path), queryParameters: queryParameters); - - @protected - Future getPlain(final String path, - {Map? queryParameters}) => - _client.getPlain(makeUrl(path), queryParameters: queryParameters); - - @protected - Future getBytes(final String path, - {Map? queryParameters}) => - _client.getBytes(makeUrl(path), queryParameters: queryParameters); - - @protected - Future> post( - final String path, { - final Map? data, - String? idempotencyKey, - }) => - _client.post( - makeUrl(path), - data: data, - idempotencyKey: idempotencyKey, - ); - - @protected - Future> delete(final String path, - {final Map? data}) => - _client.delete(makeUrl(path), data: data); } diff --git a/lib/src/resources/balance_transaction.dart b/lib/src/resources/balance_transaction.dart index 1c7edae..18def5e 100644 --- a/lib/src/resources/balance_transaction.dart +++ b/lib/src/resources/balance_transaction.dart @@ -1,15 +1,19 @@ import 'dart:async'; import 'package:stripe/messages.dart'; +import 'package:stripe/src/resources/_api_config.dart'; import '../client.dart'; import '_resource.dart'; class BalanceTransactionResource extends Resource { - BalanceTransactionResource(Client client) : super(client); + BalanceTransactionResource(Client client, ApiConfig config) + : super(client, config); Future retrieve(String balanceTransactionId) async { - final map = await get('balance_transactions/$balanceTransactionId'); + final map = await client.get( + makeUrl('balance_transactions/$balanceTransactionId'), + ); return BalanceTransaction.fromJson(map); } } diff --git a/lib/src/resources/charge.dart b/lib/src/resources/charge.dart index c71a781..da37ea6 100644 --- a/lib/src/resources/charge.dart +++ b/lib/src/resources/charge.dart @@ -1,15 +1,18 @@ import 'dart:async'; import 'package:stripe/messages.dart'; +import 'package:stripe/src/resources/_api_config.dart'; import '../client.dart'; import '_resource.dart'; class ChargeResource extends Resource { - ChargeResource(Client client) : super(client); + ChargeResource(Client client, ApiConfig config) : super(client, config); Future retrieve(String chargeId) async { - final map = await get('charges/$chargeId'); + final map = await client.get( + makeUrl('charges/$chargeId'), + ); return Charge.fromJson(map); } } diff --git a/lib/src/resources/checkout_session.dart b/lib/src/resources/checkout_session.dart index 5abef18..07af89e 100644 --- a/lib/src/resources/checkout_session.dart +++ b/lib/src/resources/checkout_session.dart @@ -1,21 +1,28 @@ import 'dart:async'; import 'package:stripe/messages.dart'; +import 'package:stripe/src/resources/_api_config.dart'; import '../client.dart'; import '_resource.dart'; class CheckoutSessionResource extends Resource { - CheckoutSessionResource(Client client) : super(client); + CheckoutSessionResource(Client client, ApiConfig config) + : super(client, config); /// Creates a Stripe Checkout Session. Future create(CreateCheckoutSessionRequest request) async { - final response = await post('checkout/sessions', data: request.toJson()); + final response = await client.post( + makeUrl('checkout/sessions'), + data: request.toJson(), + ); return CheckoutSession.fromJson(response); } Future retrieve(String id) async { - final response = await get('checkout/sessions/$id'); + final response = await client.get( + makeUrl('checkout/sessions/$id'), + ); return CheckoutSession.fromJson(response); } } diff --git a/lib/src/resources/coupon.dart b/lib/src/resources/coupon.dart index e633cd2..52bf1dc 100644 --- a/lib/src/resources/coupon.dart +++ b/lib/src/resources/coupon.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:stripe/messages.dart'; +import 'package:stripe/src/resources/_api_config.dart'; import '../client.dart'; import '_resource.dart'; @@ -8,12 +9,15 @@ import '_resource.dart'; class CouponResource extends Resource { static const _resourceName = 'coupons'; - CouponResource(Client client) : super(client); + CouponResource(Client client, ApiConfig config) : super(client, config); Future> list([ ListCouponsRequest? request, ]) async { - final map = await get(_resourceName, queryParameters: request?.toJson()); + final map = await client.get( + makeUrl(_resourceName), + queryParameters: request?.toJson(), + ); return DataList.fromJson( map, (value) => Coupon.fromJson(value as Map), diff --git a/lib/src/resources/customer.dart b/lib/src/resources/customer.dart index a157fe6..a67d44b 100644 --- a/lib/src/resources/customer.dart +++ b/lib/src/resources/customer.dart @@ -1,31 +1,35 @@ import 'dart:async'; import 'package:stripe/messages.dart'; +import 'package:stripe/src/resources/_api_config.dart'; import 'package:stripe/src/resources/source.dart'; import '../client.dart'; import '_resource.dart'; class CustomerResource extends Resource { - final Client _client; - - CustomerResource(Client client) - : _client = client, - super(client); + CustomerResource(Client client, ApiConfig config) : super(client, config); Future create(CreateCustomerRequest request) async { - final response = await post('customers', data: request.toJson()); + final response = await client.post( + makeUrl('customers'), + data: request.toJson(), + ); return Customer.fromJson(response); } Future retrieve(String customerId) async { - final map = await get('customers/$customerId'); + final map = await client.get( + makeUrl('customers/$customerId'), + ); return Customer.fromJson(map); } Future update(UpdateCustomerRequest request) async { - final response = - await post('customers/${request.id}', data: request.toJson()); + final response = await client.post( + makeUrl('customers/${request.id}'), + data: request.toJson(), + ); return Customer.fromJson(response); } @@ -33,8 +37,8 @@ class CustomerResource extends Resource { /// https://docs.stripe.com/search#query-fields-for-customers required String queryString, }) async { - final Map map = await get( - 'customers/search', + final Map map = await client.get( + makeUrl('customers/search'), queryParameters: {'query': queryString}, ); @@ -51,6 +55,10 @@ We recommend that you adopt the PaymentMethods API. This newer API provides access to our latest features and payment method types. ''') SourceResource sources(String customerId) { - return SourceResource(_client, customerId); + return SourceResource( + client, + config, + customerId, + ); } } diff --git a/lib/src/resources/customer_balance_transaction.dart b/lib/src/resources/customer_balance_transaction.dart index 0b4a088..0daed72 100644 --- a/lib/src/resources/customer_balance_transaction.dart +++ b/lib/src/resources/customer_balance_transaction.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:stripe/messages.dart'; +import 'package:stripe/src/resources/_api_config.dart'; import '../client.dart'; import '_resource.dart'; @@ -8,7 +9,8 @@ import '_resource.dart'; /// https://docs.stripe.com/api/customer_balance_transactions class CustomerBalanceTransactionResource extends Resource { - CustomerBalanceTransactionResource(Client client) : super(client); + CustomerBalanceTransactionResource(Client client, ApiConfig config) + : super(client, config); /// Creates an immutable transaction that updates the customer’s credit /// balance. @@ -17,8 +19,8 @@ class CustomerBalanceTransactionResource CreateCustomerBalanceTransactionRequest request, { String? idempotencyKey, }) async { - final map = await post( - _buildPath(customerId), + final map = await client.post( + makeUrl(_buildPath(customerId)), data: request.toJson(), idempotencyKey: idempotencyKey, ); @@ -42,8 +44,8 @@ class CustomerBalanceTransactionResource String customerBalanceTransactionId, UpdateCustomerBalanceTransactionRequest request, ) async { - final map = await post( - _buildPath(customerId, customerBalanceTransactionId), + final map = await client.post( + makeUrl(_buildPath(customerId, customerBalanceTransactionId)), data: request.toJson(), ); @@ -54,8 +56,8 @@ class CustomerBalanceTransactionResource /// customer’s balances. Future retrieve( String customerId, String customerBalanceTransactionId) async { - final map = await get( - _buildPath(customerId, customerBalanceTransactionId), + final map = await client.get( + makeUrl(_buildPath(customerId, customerBalanceTransactionId)), ); return CustomerBalanceTransaction.fromJson(map); @@ -66,8 +68,8 @@ class CustomerBalanceTransactionResource String customerId, [ ListCouponsRequest? request, ]) async { - final map = await get( - _buildPath(customerId), + final map = await client.get( + makeUrl(_buildPath(customerId)), queryParameters: request?.toJson(), ); diff --git a/lib/src/resources/file.dart b/lib/src/resources/file.dart index 237042b..5e546a6 100644 --- a/lib/src/resources/file.dart +++ b/lib/src/resources/file.dart @@ -1,6 +1,7 @@ import 'dart:typed_data'; import 'package:stripe/src/client.dart'; +import 'package:stripe/src/resources/_api_config.dart'; import '../../messages.dart'; import '_resource.dart'; @@ -8,10 +9,14 @@ import '_resource.dart'; class FileResource extends Resource { static const _resourceName = 'files'; - FileResource(Client client) : super(client); + FileResource(Client client, ApiConfig config) : super(client, config); Future downloadContentPlain(String fileId) async { - final content = await getPlain(_buildContentsPath(fileId)); + final content = await client.getPlain( + _makeFilesUrl( + _buildContentsPath(fileId), + ), + ); return content; } @@ -25,8 +30,14 @@ class FileResource extends Resource { } Future downloadContentBytes(String fileId) async { - final bytes = await getBytes(_buildContentsPath(fileId)); + final bytes = await client.getBytes( + _makeFilesUrl(_buildContentsPath(fileId)), + ); return bytes; } + + Uri _makeFilesUrl(String path) { + return Uri.parse(config.baseFilesUrl).resolve(path); + } } diff --git a/lib/src/resources/invoice.dart b/lib/src/resources/invoice.dart index aa5206d..81e0a6e 100644 --- a/lib/src/resources/invoice.dart +++ b/lib/src/resources/invoice.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:stripe/messages.dart'; import 'package:stripe/src/expanded.dart'; +import 'package:stripe/src/resources/_api_config.dart'; import 'package:stripe/src/utils/expandable_field.dart'; import 'package:stripe/src/utils/expandable_fields/discounts_expandable_field.dart'; import 'package:stripe/src/utils/expandable_fields/payment_intent_expandable_field.dart'; @@ -12,11 +13,13 @@ import '_resource.dart'; class InvoiceResource extends Resource { static const _resourceName = 'invoices'; - InvoiceResource(Client client) : super(client); + InvoiceResource(Client client, ApiConfig config) : super(client, config); Future createPreview(CreatePreviewInvoiceRequest request) async { - final response = - await post('$_resourceName/create_preview', data: request.toJson()); + final response = await client.post( + makeUrl('$_resourceName/create_preview'), + data: request.toJson(), + ); return Invoice.fromJson(response); } @@ -26,8 +29,8 @@ class InvoiceResource extends Resource { required Set expand, }) async { final expandableFields = _expandableFields(expand); - final response = await post( - '$_resourceName/create_preview', + final response = await client.post( + makeUrl('$_resourceName/create_preview'), data: { ...request.toJson(), 'expand': expandableFields.map((e) => e.field).toList(), diff --git a/lib/src/resources/payment_intent.dart b/lib/src/resources/payment_intent.dart index 8209b97..1dcc11a 100644 --- a/lib/src/resources/payment_intent.dart +++ b/lib/src/resources/payment_intent.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:logging/logging.dart'; import 'package:stripe/messages.dart'; +import 'package:stripe/src/resources/_api_config.dart'; import '../client.dart'; import '_resource.dart'; @@ -11,22 +12,30 @@ final log = Logger('Stripe PaymentIntentResource'); class PaymentIntentResource extends Resource { static const _resourceName = 'payment_intents'; - PaymentIntentResource(Client client) : super(client); + PaymentIntentResource(Client client, ApiConfig config) + : super(client, config); Future create(CreatePaymentIntentRequest request) async { - final response = await post('payment_intents', data: request.toJson()); + final response = await client.post( + makeUrl('payment_intents'), + data: request.toJson(), + ); return PaymentIntent.fromJson(response); } Future retrieve(String paymentIntentId) async { - final map = await get('payment_intents/$paymentIntentId'); + final map = await client.get( + makeUrl('payment_intents/$paymentIntentId'), + ); return PaymentIntent.fromJson(map); } /// Returns true if successful. Future cancel(String paymentIntentId) async { try { - await post('payment_intents/$paymentIntentId/cancel'); + await client.post( + makeUrl('payment_intents/$paymentIntentId/cancel'), + ); } catch (e) { log.warning(e); return false; @@ -38,8 +47,8 @@ class PaymentIntentResource extends Resource { /// https://docs.stripe.com/search#query-fields-for-payment-intents required String queryString, }) async { - final Map map = await get( - 'payment_intents/search', + final Map map = await client.get( + makeUrl('payment_intents/search'), queryParameters: {'query': queryString}, ); @@ -57,8 +66,8 @@ class PaymentIntentResource extends Resource { String id, { required UpdatePaymentIntentRequest request, }) async { - final response = await post( - '$_resourceName/$id', + final response = await client.post( + makeUrl('$_resourceName/$id'), data: request.toJson(), ); @@ -70,8 +79,8 @@ class PaymentIntentResource extends Resource { String id, { required ConfirmPaymentIntentRequest request, }) async { - final response = await post( - '$_resourceName/$id/confirm', + final response = await client.post( + makeUrl('$_resourceName/$id/confirm'), data: request.toJson(), ); diff --git a/lib/src/resources/portal_session.dart b/lib/src/resources/portal_session.dart index 660ddb5..26ecc47 100644 --- a/lib/src/resources/portal_session.dart +++ b/lib/src/resources/portal_session.dart @@ -1,17 +1,21 @@ import 'dart:async'; import 'package:stripe/messages.dart'; +import 'package:stripe/src/resources/_api_config.dart'; import '../client.dart'; import '_resource.dart'; class PortalSessionResource extends Resource { - PortalSessionResource(Client client) : super(client); + PortalSessionResource(Client client, ApiConfig config) + : super(client, config); /// Creates a Stripe Checkout Session. Future create(CreatePortalSessionRequest request) async { - final response = - await post('billing_portal/sessions', data: request.toJson()); + final response = await client.post( + makeUrl('billing_portal/sessions'), + data: request.toJson(), + ); return PortalSession.fromJson(response); } } diff --git a/lib/src/resources/price.dart b/lib/src/resources/price.dart index a03842d..14f6d88 100644 --- a/lib/src/resources/price.dart +++ b/lib/src/resources/price.dart @@ -1,26 +1,35 @@ import 'dart:async'; import 'package:stripe/messages.dart'; +import 'package:stripe/src/resources/_api_config.dart'; import '../client.dart'; import '_resource.dart'; class PriceResource extends Resource { - PriceResource(Client client) : super(client); + PriceResource(Client client, ApiConfig config) : super(client, config); Future retrieve(String id) async { - final map = await get('prices/$id'); + final map = await client.get( + makeUrl('prices/$id'), + ); return Price.fromJson(map); } Future> list([ListPricesRequest? request]) async { - final map = await get('prices', queryParameters: request?.toJson()); + final map = await client.get( + makeUrl('prices'), + queryParameters: request?.toJson(), + ); return DataList.fromJson( map, (value) => Price.fromJson(value as Map)); } Future create(CreatePriceRequest request) async { - final map = await post('prices', data: request.toJson()); + final map = await client.post( + makeUrl('prices'), + data: request.toJson(), + ); return Price.fromJson(map); } @@ -28,8 +37,8 @@ class PriceResource extends Resource { /// https://docs.stripe.com/search#query-fields-for-prices required String queryString, }) async { - final Map map = await get( - 'prices/search', + final Map map = await client.get( + makeUrl('prices/search'), queryParameters: {'query': queryString}, ); diff --git a/lib/src/resources/product.dart b/lib/src/resources/product.dart index 4f13cbd..cc23c8d 100644 --- a/lib/src/resources/product.dart +++ b/lib/src/resources/product.dart @@ -1,26 +1,35 @@ import 'dart:async'; import 'package:stripe/messages.dart'; +import 'package:stripe/src/resources/_api_config.dart'; import '../client.dart'; import '_resource.dart'; class ProductResource extends Resource { - ProductResource(Client client) : super(client); + ProductResource(Client client, ApiConfig config) : super(client, config); Future retrieve(String id) async { - final map = await get('products/$id'); + final map = await client.get( + makeUrl('products/$id'), + ); return Product.fromJson(map); } Future> list([ListProductsRequest? request]) async { - final map = await get('products', queryParameters: request?.toJson()); + final map = await client.get( + makeUrl('products'), + queryParameters: request?.toJson(), + ); return DataList.fromJson( map, (value) => Product.fromJson(value as Map)); } Future create(CreateProductRequest request) async { - final map = await post('products', data: request.toJson()); + final map = await client.post( + makeUrl('products'), + data: request.toJson(), + ); return Product.fromJson(map); } @@ -28,8 +37,8 @@ class ProductResource extends Resource { /// https://docs.stripe.com/search#query-fields-for-products required String queryString, }) async { - final Map map = await get( - 'products/search', + final Map map = await client.get( + makeUrl('products/search'), queryParameters: {'query': queryString}, ); diff --git a/lib/src/resources/promotion_code.dart b/lib/src/resources/promotion_code.dart index 578fab3..c96fd37 100644 --- a/lib/src/resources/promotion_code.dart +++ b/lib/src/resources/promotion_code.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:stripe/messages.dart'; +import 'package:stripe/src/resources/_api_config.dart'; import '../client.dart'; import '_resource.dart'; @@ -8,12 +9,16 @@ import '_resource.dart'; class PromotionCodeResource extends Resource { static const _resourceName = 'promotion_codes'; - PromotionCodeResource(Client client) : super(client); + PromotionCodeResource(Client client, ApiConfig config) + : super(client, config); Future> list([ ListPromotionCodesRequest? request, ]) async { - final map = await get(_resourceName, queryParameters: request?.toJson()); + final map = await client.get( + makeUrl(_resourceName), + queryParameters: request?.toJson(), + ); return DataList.fromJson( map, (value) => PromotionCode.fromJson(value as Map), diff --git a/lib/src/resources/refund.dart b/lib/src/resources/refund.dart index b2f333e..056dd90 100644 --- a/lib/src/resources/refund.dart +++ b/lib/src/resources/refund.dart @@ -1,15 +1,19 @@ import 'dart:async'; import 'package:stripe/messages.dart'; +import 'package:stripe/src/resources/_api_config.dart'; import '../client.dart'; import '_resource.dart'; class RefundResource extends Resource { - RefundResource(Client client) : super(client); + RefundResource(Client client, ApiConfig config) : super(client, config); Future create(CreateRefundRequest request) async { - final map = await post('refunds', data: request.toJson()); + final map = await client.post( + makeUrl('refunds'), + data: request.toJson(), + ); return Refund.fromJson(map); } } diff --git a/lib/src/resources/sigma_query_run.dart b/lib/src/resources/sigma_query_run.dart index 8d98175..cffc410 100644 --- a/lib/src/resources/sigma_query_run.dart +++ b/lib/src/resources/sigma_query_run.dart @@ -1,18 +1,20 @@ import 'package:stripe/messages.dart'; import 'package:stripe/src/client.dart'; +import 'package:stripe/src/resources/_api_config.dart'; import 'package:stripe/src/resources/_resource.dart'; class SigmaQueryRunResource extends Resource { static const _resourceName = 'sigma/query_runs'; - SigmaQueryRunResource(Client client) : super(client); + SigmaQueryRunResource(Client client, ApiConfig config) + : super(client, config); Future create( CreateSigmaQueryRunRequest request, { String? idempotencyKey, }) async { - final map = await post( - _resourceName, + final map = await client.post( + makeUrl(_resourceName), data: request.toJson(), idempotencyKey: idempotencyKey, ); @@ -21,7 +23,9 @@ class SigmaQueryRunResource extends Resource { } Future retrieve(String sigmaQueryRunId) async { - final map = await get('$_resourceName/$sigmaQueryRunId'); + final map = await client.get( + makeUrl('$_resourceName/$sigmaQueryRunId'), + ); return SigmaQueryRun.fromJson(map); } diff --git a/lib/src/resources/sigma_scheduled_query_run.dart b/lib/src/resources/sigma_scheduled_query_run.dart index a6fd64f..7e6ad72 100644 --- a/lib/src/resources/sigma_scheduled_query_run.dart +++ b/lib/src/resources/sigma_scheduled_query_run.dart @@ -1,20 +1,26 @@ import 'package:stripe/messages.dart'; import 'package:stripe/src/client.dart'; +import 'package:stripe/src/resources/_api_config.dart'; import 'package:stripe/src/resources/_resource.dart'; class SigmaScheduledQueryRunResource extends Resource { static const _resourceName = 'sigma/scheduled_query_runs'; - SigmaScheduledQueryRunResource(Client client) : super(client); + SigmaScheduledQueryRunResource(Client client, ApiConfig config) + : super(client, config); Future retrieve(String sigmaQueryRunId) async { - final map = await get('$_resourceName/$sigmaQueryRunId'); + final map = await client.get( + makeUrl('$_resourceName/$sigmaQueryRunId'), + ); return SigmaScheduledQueryRun.fromJson(map); } Future> list() async { - final map = await get(_resourceName); + final map = await client.get( + makeUrl(_resourceName), + ); return DataList.fromJson( map, diff --git a/lib/src/resources/source.dart b/lib/src/resources/source.dart index 9a2062b..3fd4d66 100644 --- a/lib/src/resources/source.dart +++ b/lib/src/resources/source.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:stripe/messages.dart'; +import 'package:stripe/src/resources/_api_config.dart'; import '../client.dart'; import '_resource.dart'; @@ -18,10 +19,16 @@ class SourceResource extends Resource { String get _resourcePath => 'customers/$customerId/sources'; - SourceResource(Client client, this.customerId) : super(client); + SourceResource( + Client client, + ApiConfig config, + this.customerId, + ) : super(client, config); Future> list() async { - final map = await get(_resourcePath); + final map = await client.get( + makeUrl(_resourcePath), + ); return DataList.fromJson( map, (value) => Source.fromJson(value as Map)); } diff --git a/lib/src/resources/subscription.dart b/lib/src/resources/subscription.dart index ee4f123..b2b21dd 100644 --- a/lib/src/resources/subscription.dart +++ b/lib/src/resources/subscription.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:stripe/messages.dart'; import 'package:stripe/src/expanded.dart'; +import 'package:stripe/src/resources/_api_config.dart'; import '../client.dart'; import '_resource.dart'; @@ -9,11 +10,14 @@ import '_resource.dart'; class SubscriptionResource extends Resource { static const _resourceName = 'subscriptions'; - SubscriptionResource(Client client) : super(client); + SubscriptionResource(Client client, ApiConfig config) : super(client, config); /// https://docs.stripe.com/api/subscriptions/create Future create(CreateSubscriptionRequest request) async { - final response = await post(_resourceName, data: request.toJson()); + final response = await client.post( + makeUrl(_resourceName), + data: request.toJson(), + ); return SubscriptionExpanded.fromJson(response, { SubscriptionExpandableField.discounts, @@ -22,7 +26,9 @@ class SubscriptionResource extends Resource { } Future retrieve(String id) async { - final response = await get('$_resourceName/$id'); + final response = await client.get( + makeUrl('$_resourceName/$id'), + ); return Subscription.fromJson(response); } @@ -30,8 +36,8 @@ class SubscriptionResource extends Resource { String id, { required Set expand, }) async { - final response = await get( - '$_resourceName/$id', + final response = await client.get( + makeUrl('$_resourceName/$id'), queryParameters: { 'expand': _expandParamComponents(expand), }, @@ -59,7 +65,10 @@ class SubscriptionResource extends Resource { Future> list( [ListSubscriptionsRequest? request]) async { - final map = await get(_resourceName, queryParameters: request?.toJson()); + final map = await client.get( + makeUrl(_resourceName), + queryParameters: request?.toJson(), + ); return DataList.fromJson( map, (value) => Subscription.fromJson(value as Map)); } @@ -68,8 +77,8 @@ class SubscriptionResource extends Resource { required Set expand, ListSubscriptionsRequest? request, }) async { - final response = await get( - _resourceName, + final response = await client.get( + makeUrl(_resourceName), queryParameters: { ...?request?.toJson(), 'expand': _expandParamComponents(expand).map((e) => 'data.$e').toList(), @@ -89,8 +98,8 @@ class SubscriptionResource extends Resource { /// https://docs.stripe.com/search#query-fields-for-subscriptions required String queryString, }) async { - final Map map = await get( - '$_resourceName/search', + final Map map = await client.get( + makeUrl('$_resourceName/search'), queryParameters: {'query': queryString}, ); @@ -108,8 +117,8 @@ class SubscriptionResource extends Resource { String id, { required SubscriptionUpdate update, }) async { - final response = await post( - '$_resourceName/$id', + final response = await client.post( + makeUrl('$_resourceName/$id'), data: update.toJson(), ); @@ -122,8 +131,8 @@ class SubscriptionResource extends Resource { bool? invoiceNow, bool? prorate, }) async { - final response = await delete( - '$_resourceName/$id', + final response = await client.delete( + makeUrl('$_resourceName/$id'), data: { if (invoiceNow != null) 'invoice_now': invoiceNow, if (prorate != null) 'prorate': prorate, diff --git a/lib/src/resources/subscription_item.dart b/lib/src/resources/subscription_item.dart index e260e1c..eba616b 100644 --- a/lib/src/resources/subscription_item.dart +++ b/lib/src/resources/subscription_item.dart @@ -1,23 +1,27 @@ import 'dart:async'; import 'package:stripe/messages.dart'; +import 'package:stripe/src/resources/_api_config.dart'; import '../client.dart'; import '_resource.dart'; class SubscriptionItemResource extends Resource { - SubscriptionItemResource(Client client) : super(client); + SubscriptionItemResource(Client client, ApiConfig config) + : super(client, config); Future retrieve(String id) async { - final response = await get('subscription_items/$id'); + final response = await client.get( + makeUrl('subscription_items/$id'), + ); return SubscriptionItem.fromJson(response); } Future> list([ ListSubscriptionItemsRequest? request, ]) async { - final map = await get( - 'subscription_items', + final map = await client.get( + makeUrl('subscription_items'), queryParameters: request?.toJson(), ); return DataList.fromJson( @@ -30,8 +34,8 @@ class SubscriptionItemResource extends Resource { String id, { required SubscriptionItemUpdate update, }) async { - final response = await post( - 'subscription_items/$id', + final response = await client.post( + makeUrl('subscription_items/$id'), data: update.toJson(), ); @@ -42,7 +46,9 @@ class SubscriptionItemResource extends Resource { String id, { bool? clearUsage, }) async { - final response = await delete('subscription_items/$id'); + final response = await client.delete( + makeUrl('subscription_items/$id'), + ); return SubscriptionItem.fromJson(response); } diff --git a/lib/src/resources/subscription_schedule.dart b/lib/src/resources/subscription_schedule.dart index 456aaed..6ced2e7 100644 --- a/lib/src/resources/subscription_schedule.dart +++ b/lib/src/resources/subscription_schedule.dart @@ -1,13 +1,18 @@ +import 'package:stripe/src/resources/_api_config.dart'; + import '../../messages.dart'; import '../client.dart'; import '_resource.dart'; class SubscriptionScheduleResource extends Resource { - SubscriptionScheduleResource(Client client) : super(client); + SubscriptionScheduleResource(Client client, ApiConfig config) + : super(client, config); /// https://stripe.com/docs/api/subscription_schedules/retrieve Future retrieve(String id) async { - final response = await get('subscription_schedules/$id'); + final response = await client.get( + makeUrl('subscription_schedules/$id'), + ); return SubscriptionSchedule.fromJson(response); } @@ -16,8 +21,8 @@ class SubscriptionScheduleResource extends Resource { Future> list([ ListSubscriptionSchedulesRequest? request, ]) async { - final map = await get( - 'subscription_schedules', + final map = await client.get( + makeUrl('subscription_schedules'), queryParameters: request?.toJson(), ); @@ -31,8 +36,8 @@ class SubscriptionScheduleResource extends Resource { Future create( CreateSubscriptionScheduleRequest request, ) async { - final response = await post( - 'subscription_schedules', + final response = await client.post( + makeUrl('subscription_schedules'), data: request.toJson(), ); @@ -44,8 +49,8 @@ class SubscriptionScheduleResource extends Resource { String id, UpdateSubscriptionScheduleRequest request, ) async { - final response = await post( - 'subscription_schedules/$id', + final response = await client.post( + makeUrl('subscription_schedules/$id'), data: request.toJson(), ); diff --git a/lib/stripe.dart b/lib/stripe.dart index 7afaf70..3201649 100644 --- a/lib/stripe.dart +++ b/lib/stripe.dart @@ -1,5 +1,7 @@ library stripe; +import 'package:stripe/src/resources/_api_config.dart'; + import 'src/client.dart'; import 'src/resources/balance_transaction.dart'; import 'src/resources/charge.dart'; @@ -95,28 +97,30 @@ class Stripe { final FileResource file; factory Stripe(String apiKey) { - final client = DioClient(apiKey: apiKey); - return Stripe.withClient(client); + final config = ApiConfig(apiKey: apiKey); + final client = DioClient(apiKey: config.apiKey, version: config.version); + return Stripe.withClient(client, config); } - Stripe.withClient(this.client) - : checkoutSession = CheckoutSessionResource(client), - portalSession = PortalSessionResource(client), - customer = CustomerResource(client), - refund = RefundResource(client), - paymentIntent = PaymentIntentResource(client), - price = PriceResource(client), - product = ProductResource(client), - subscription = SubscriptionResource(client), - subscriptionItem = SubscriptionItemResource(client), - subscriptionSchedule = SubscriptionScheduleResource(client), - charge = ChargeResource(client), - balanceTransaction = BalanceTransactionResource(client), - promotionCode = PromotionCodeResource(client), - coupon = CouponResource(client), - invoice = InvoiceResource(client), - customerBalanceTransaction = CustomerBalanceTransactionResource(client), - sigmaQueryRun = SigmaQueryRunResource(client), - sigmaScheduledQueryRun = SigmaScheduledQueryRunResource(client), - file = FileResource(client); + Stripe.withClient(this.client, ApiConfig config) + : checkoutSession = CheckoutSessionResource(client, config), + portalSession = PortalSessionResource(client, config), + customer = CustomerResource(client, config), + refund = RefundResource(client, config), + paymentIntent = PaymentIntentResource(client, config), + price = PriceResource(client, config), + product = ProductResource(client, config), + subscription = SubscriptionResource(client, config), + subscriptionItem = SubscriptionItemResource(client, config), + subscriptionSchedule = SubscriptionScheduleResource(client, config), + charge = ChargeResource(client, config), + balanceTransaction = BalanceTransactionResource(client, config), + promotionCode = PromotionCodeResource(client, config), + coupon = CouponResource(client, config), + invoice = InvoiceResource(client, config), + customerBalanceTransaction = + CustomerBalanceTransactionResource(client, config), + sigmaQueryRun = SigmaQueryRunResource(client, config), + sigmaScheduledQueryRun = SigmaScheduledQueryRunResource(client, config), + file = FileResource(client, config); } diff --git a/test/resources/balance_transaction_test.dart b/test/resources/balance_transaction_test.dart index d229e44..7b337ae 100644 --- a/test/resources/balance_transaction_test.dart +++ b/test/resources/balance_transaction_test.dart @@ -4,17 +4,25 @@ import 'dart:io'; import 'package:dio/dio.dart'; import 'package:stripe/messages.dart' show FeeDetails; import 'package:stripe/src/client.dart'; +import 'package:stripe/src/resources/_api_config.dart'; import 'package:stripe/src/resources/balance_transaction.dart'; import 'package:test/test.dart'; void main() { late DioClient client; late BalanceTransactionResource balanceTransactionResource; + final config = ApiConfig( + apiKey: 'sk_foobar', + baseApiUrl: 'http://void/', + ); setUp(() { // We set the baseUrl to something unreachable, because we define // interceptors in the tests. - client = DioClient(apiKey: 'sk_foobar', baseUrl: 'http://void/'); - balanceTransactionResource = BalanceTransactionResource(client); + client = DioClient( + apiKey: config.apiKey, + version: config.version, + ); + balanceTransactionResource = BalanceTransactionResource(client, config); }); group('BalanceTransactionResource', () { test('properly decodes all values', () async { diff --git a/test/resources/checkout_session_test.dart b/test/resources/checkout_session_test.dart index b168295..23ed093 100644 --- a/test/resources/checkout_session_test.dart +++ b/test/resources/checkout_session_test.dart @@ -4,17 +4,22 @@ import 'dart:io'; import 'package:dio/dio.dart'; import 'package:stripe/messages.dart'; import 'package:stripe/src/client.dart'; +import 'package:stripe/src/resources/_api_config.dart'; import 'package:stripe/src/resources/checkout_session.dart'; import 'package:test/test.dart'; void main() { late DioClient client; late CheckoutSessionResource checkoutSessionResource; + final config = ApiConfig( + apiKey: 'sk_foobar', + baseApiUrl: 'http://void/', + ); setUp(() { // We set the baseUrl to something unreachable, because we define // interceptors in the tests. - client = DioClient(apiKey: 'sk_foobar', baseUrl: 'http://void/'); - checkoutSessionResource = CheckoutSessionResource(client); + client = DioClient(apiKey: config.apiKey, version: config.version); + checkoutSessionResource = CheckoutSessionResource(client, config); }); group('CheckoutSessionResource', () { test('properly decodes all values', () async { diff --git a/test/resources/customer_test.dart b/test/resources/customer_test.dart index 57231bc..21a4480 100644 --- a/test/resources/customer_test.dart +++ b/test/resources/customer_test.dart @@ -4,17 +4,22 @@ import 'dart:io'; import 'package:dio/dio.dart'; import 'package:stripe/messages.dart'; import 'package:stripe/src/client.dart'; +import 'package:stripe/src/resources/_api_config.dart'; import 'package:stripe/src/resources/customer.dart'; import 'package:test/test.dart'; void main() { late DioClient client; late CustomerResource customerResource; + final config = ApiConfig( + apiKey: 'sk_foobar', + baseApiUrl: 'http://void/', + ); setUp(() { // We set the baseUrl to something unreachable, because we define // interceptors in the tests. - client = DioClient(apiKey: 'sk_foobar', baseUrl: 'http://void/'); - customerResource = CustomerResource(client); + client = DioClient(apiKey: config.apiKey, version: config.version); + customerResource = CustomerResource(client, config); }); group('CustomerResource', () { test('properly decodes all values', () async { diff --git a/test/resources/payment_intent_test.dart b/test/resources/payment_intent_test.dart index 3439353..356e220 100644 --- a/test/resources/payment_intent_test.dart +++ b/test/resources/payment_intent_test.dart @@ -10,17 +10,22 @@ import 'package:stripe/messages.dart' SetupFutureUsage, ShippingSpecification; import 'package:stripe/src/client.dart'; +import 'package:stripe/src/resources/_api_config.dart'; import 'package:stripe/src/resources/payment_intent.dart'; import 'package:test/test.dart'; void main() { late DioClient client; late PaymentIntentResource paymentIntentResource; + final config = ApiConfig( + apiKey: 'sk_foobar', + baseApiUrl: 'http://void/', + ); setUp(() { // We set the baseUrl to something unreachable, because we define // interceptors in the tests. - client = DioClient(apiKey: 'sk_foobar', baseUrl: 'http://void/'); - paymentIntentResource = PaymentIntentResource(client); + client = DioClient(apiKey: config.apiKey, version: config.version); + paymentIntentResource = PaymentIntentResource(client, config); }); group('PaymentIntentResource', () { test('properly decodes all values', () async { diff --git a/test/resources/subscription_test.dart b/test/resources/subscription_test.dart index df181a1..63ac799 100644 --- a/test/resources/subscription_test.dart +++ b/test/resources/subscription_test.dart @@ -4,17 +4,22 @@ import 'dart:io'; import 'package:dio/dio.dart'; import 'package:stripe/messages.dart'; import 'package:stripe/src/client.dart'; +import 'package:stripe/src/resources/_api_config.dart'; import 'package:stripe/src/resources/subscription.dart'; import 'package:test/test.dart'; void main() { late DioClient client; late SubscriptionResource subscriptionResource; + final config = ApiConfig( + apiKey: 'sk_foobar', + baseApiUrl: 'http://void/', + ); setUp(() { // We set the baseUrl to something unreachable, because we define // interceptors in the tests. - client = DioClient(apiKey: 'sk_foobar', baseUrl: 'http://void/'); - subscriptionResource = SubscriptionResource(client); + client = DioClient(apiKey: config.apiKey, version: config.version); + subscriptionResource = SubscriptionResource(client, config); }); group('SubscriptionResource', () { test('properly decodes all values', () async { From 271eaba8c212f3d01456d9ef59ecc0299078006b Mon Sep 17 00:00:00 2001 From: solid-maksymtielnyi Date: Thu, 4 Sep 2025 05:01:14 +0300 Subject: [PATCH 14/22] Change url param type from Uri to String --- lib/src/client.dart | 30 +++++++++++++++--------------- lib/src/resources/_resource.dart | 4 ++-- lib/src/resources/file.dart | 4 ++-- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/lib/src/client.dart b/lib/src/client.dart index 24e0f70..13e451a 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -11,35 +11,35 @@ import 'package:stripe/src/exceptions.dart'; abstract class Client { /// Makes a POST request to the Stripe API Future> post( - final Uri url, { + final String url, { final Map? data, final String? idempotencyKey, }); /// Makes a DELETE request to the Stripe API Future> delete( - final Uri url, { + final String url, { final Map? data, final String? idempotencyKey, }); /// Makes a GET request to the Stripe API Future> get( - final Uri url, { + final String url, { String? idempotencyKey, Map? queryParameters, }); /// Makes a GET request to the Stripe API, returns plain body Future getPlain( - final Uri url, { + final String url, { String? idempotencyKey, Map? queryParameters, }); /// Makes a GET request to the Stripe API, returns body bytes Future getBytes( - final Uri url, { + final String url, { String? idempotencyKey, Map? queryParameters, }); @@ -141,12 +141,12 @@ class DioClient extends Client { /// Makes a post request to the Stripe API @override Future> post( - final Uri url, { + final String url, { final Map? data, final String? idempotencyKey, }) async { try { - final response = await dio.post>(url.toString(), + final response = await dio.post>(url, data: data, options: _createRequestOptions(idempotencyKey: idempotencyKey)); return _processDioResponse(response); @@ -165,12 +165,12 @@ class DioClient extends Client { /// Makes a DELETE request to the Stripe API @override Future> delete( - final Uri url, { + final String url, { final Map? data, final String? idempotencyKey, }) async { try { - final response = await dio.delete>(url.toString(), + final response = await dio.delete>(url, data: data, options: _createRequestOptions(idempotencyKey: idempotencyKey)); return _processDioResponse(response); @@ -189,12 +189,12 @@ class DioClient extends Client { /// Makes a get request to the Stripe API @override Future> get( - final Uri url, { + final String url, { String? idempotencyKey, Map? queryParameters, }) async { final response = await dio.get>( - url.toString(), + url, queryParameters: queryParameters, options: _createRequestOptions(idempotencyKey: idempotencyKey), ); @@ -204,12 +204,12 @@ class DioClient extends Client { /// Makes a GET request to the Stripe API, returns plain body @override Future getPlain( - final Uri url, { + final String url, { String? idempotencyKey, Map? queryParameters, }) async { final response = await dio.get( - url.toString(), + url, queryParameters: queryParameters, options: _createRequestOptions( idempotencyKey: idempotencyKey, @@ -222,12 +222,12 @@ class DioClient extends Client { /// Makes a get request to the Stripe API, returns body bytes. @override Future getBytes( - final Uri url, { + final String url, { String? idempotencyKey, Map? queryParameters, }) async { final response = await dio.get( - url.toString(), + url, queryParameters: queryParameters, options: _createRequestOptions( idempotencyKey: idempotencyKey, diff --git a/lib/src/resources/_resource.dart b/lib/src/resources/_resource.dart index 3beea2c..16aec32 100644 --- a/lib/src/resources/_resource.dart +++ b/lib/src/resources/_resource.dart @@ -14,7 +14,7 @@ abstract class Resource { @protected @visibleForOverriding - Uri makeUrl(String path) { - return Uri.parse(config.baseApiUrl).resolve(path); + String makeUrl(String path) { + return Uri.parse(config.baseApiUrl).resolve(path).toString(); } } diff --git a/lib/src/resources/file.dart b/lib/src/resources/file.dart index 5e546a6..c68b08a 100644 --- a/lib/src/resources/file.dart +++ b/lib/src/resources/file.dart @@ -37,7 +37,7 @@ class FileResource extends Resource { return bytes; } - Uri _makeFilesUrl(String path) { - return Uri.parse(config.baseFilesUrl).resolve(path); + String _makeFilesUrl(String path) { + return Uri.parse(config.baseFilesUrl).resolve(path).toString(); } } From dbdbee5012e43d4470efa8d5449420f727b1a9b9 Mon Sep 17 00:00:00 2001 From: solid-maksymtielnyi Date: Thu, 4 Sep 2025 05:11:32 +0300 Subject: [PATCH 15/22] Make ApiConfig public --- lib/src/{resources/_api_config.dart => api_config.dart} | 0 lib/src/resources/_resource.dart | 2 +- lib/src/resources/balance_transaction.dart | 2 +- lib/src/resources/charge.dart | 2 +- lib/src/resources/checkout_session.dart | 2 +- lib/src/resources/coupon.dart | 2 +- lib/src/resources/customer.dart | 2 +- lib/src/resources/customer_balance_transaction.dart | 2 +- lib/src/resources/file.dart | 2 +- lib/src/resources/invoice.dart | 2 +- lib/src/resources/payment_intent.dart | 2 +- lib/src/resources/portal_session.dart | 2 +- lib/src/resources/price.dart | 2 +- lib/src/resources/product.dart | 2 +- lib/src/resources/promotion_code.dart | 2 +- lib/src/resources/refund.dart | 2 +- lib/src/resources/sigma_query_run.dart | 2 +- lib/src/resources/sigma_scheduled_query_run.dart | 2 +- lib/src/resources/source.dart | 2 +- lib/src/resources/subscription.dart | 2 +- lib/src/resources/subscription_item.dart | 2 +- lib/src/resources/subscription_schedule.dart | 2 +- lib/stripe.dart | 2 +- test/resources/balance_transaction_test.dart | 2 +- test/resources/checkout_session_test.dart | 2 +- test/resources/customer_test.dart | 2 +- test/resources/payment_intent_test.dart | 2 +- test/resources/subscription_test.dart | 2 +- 28 files changed, 27 insertions(+), 27 deletions(-) rename lib/src/{resources/_api_config.dart => api_config.dart} (100%) diff --git a/lib/src/resources/_api_config.dart b/lib/src/api_config.dart similarity index 100% rename from lib/src/resources/_api_config.dart rename to lib/src/api_config.dart diff --git a/lib/src/resources/_resource.dart b/lib/src/resources/_resource.dart index 16aec32..1d8681f 100644 --- a/lib/src/resources/_resource.dart +++ b/lib/src/resources/_resource.dart @@ -1,5 +1,5 @@ import 'package:meta/meta.dart'; -import 'package:stripe/src/resources/_api_config.dart'; +import 'package:stripe/src/api_config.dart'; import '../../messages.dart'; import '../client.dart'; diff --git a/lib/src/resources/balance_transaction.dart b/lib/src/resources/balance_transaction.dart index 18def5e..5e1c804 100644 --- a/lib/src/resources/balance_transaction.dart +++ b/lib/src/resources/balance_transaction.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:stripe/messages.dart'; -import 'package:stripe/src/resources/_api_config.dart'; +import 'package:stripe/src/api_config.dart'; import '../client.dart'; import '_resource.dart'; diff --git a/lib/src/resources/charge.dart b/lib/src/resources/charge.dart index da37ea6..7a919a7 100644 --- a/lib/src/resources/charge.dart +++ b/lib/src/resources/charge.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:stripe/messages.dart'; -import 'package:stripe/src/resources/_api_config.dart'; +import 'package:stripe/src/api_config.dart'; import '../client.dart'; import '_resource.dart'; diff --git a/lib/src/resources/checkout_session.dart b/lib/src/resources/checkout_session.dart index 07af89e..6068579 100644 --- a/lib/src/resources/checkout_session.dart +++ b/lib/src/resources/checkout_session.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:stripe/messages.dart'; -import 'package:stripe/src/resources/_api_config.dart'; +import 'package:stripe/src/api_config.dart'; import '../client.dart'; import '_resource.dart'; diff --git a/lib/src/resources/coupon.dart b/lib/src/resources/coupon.dart index 52bf1dc..e0f2b90 100644 --- a/lib/src/resources/coupon.dart +++ b/lib/src/resources/coupon.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:stripe/messages.dart'; -import 'package:stripe/src/resources/_api_config.dart'; +import 'package:stripe/src/api_config.dart'; import '../client.dart'; import '_resource.dart'; diff --git a/lib/src/resources/customer.dart b/lib/src/resources/customer.dart index a67d44b..f01fa67 100644 --- a/lib/src/resources/customer.dart +++ b/lib/src/resources/customer.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:stripe/messages.dart'; -import 'package:stripe/src/resources/_api_config.dart'; +import 'package:stripe/src/api_config.dart'; import 'package:stripe/src/resources/source.dart'; import '../client.dart'; diff --git a/lib/src/resources/customer_balance_transaction.dart b/lib/src/resources/customer_balance_transaction.dart index 0daed72..d52f801 100644 --- a/lib/src/resources/customer_balance_transaction.dart +++ b/lib/src/resources/customer_balance_transaction.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:stripe/messages.dart'; -import 'package:stripe/src/resources/_api_config.dart'; +import 'package:stripe/src/api_config.dart'; import '../client.dart'; import '_resource.dart'; diff --git a/lib/src/resources/file.dart b/lib/src/resources/file.dart index c68b08a..3b56aad 100644 --- a/lib/src/resources/file.dart +++ b/lib/src/resources/file.dart @@ -1,7 +1,7 @@ import 'dart:typed_data'; +import 'package:stripe/src/api_config.dart'; import 'package:stripe/src/client.dart'; -import 'package:stripe/src/resources/_api_config.dart'; import '../../messages.dart'; import '_resource.dart'; diff --git a/lib/src/resources/invoice.dart b/lib/src/resources/invoice.dart index 81e0a6e..d879a93 100644 --- a/lib/src/resources/invoice.dart +++ b/lib/src/resources/invoice.dart @@ -1,8 +1,8 @@ import 'dart:async'; import 'package:stripe/messages.dart'; +import 'package:stripe/src/api_config.dart'; import 'package:stripe/src/expanded.dart'; -import 'package:stripe/src/resources/_api_config.dart'; import 'package:stripe/src/utils/expandable_field.dart'; import 'package:stripe/src/utils/expandable_fields/discounts_expandable_field.dart'; import 'package:stripe/src/utils/expandable_fields/payment_intent_expandable_field.dart'; diff --git a/lib/src/resources/payment_intent.dart b/lib/src/resources/payment_intent.dart index 1dcc11a..bd4f956 100644 --- a/lib/src/resources/payment_intent.dart +++ b/lib/src/resources/payment_intent.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'package:logging/logging.dart'; import 'package:stripe/messages.dart'; -import 'package:stripe/src/resources/_api_config.dart'; +import 'package:stripe/src/api_config.dart'; import '../client.dart'; import '_resource.dart'; diff --git a/lib/src/resources/portal_session.dart b/lib/src/resources/portal_session.dart index 26ecc47..82d49f1 100644 --- a/lib/src/resources/portal_session.dart +++ b/lib/src/resources/portal_session.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:stripe/messages.dart'; -import 'package:stripe/src/resources/_api_config.dart'; +import 'package:stripe/src/api_config.dart'; import '../client.dart'; import '_resource.dart'; diff --git a/lib/src/resources/price.dart b/lib/src/resources/price.dart index 14f6d88..39deccf 100644 --- a/lib/src/resources/price.dart +++ b/lib/src/resources/price.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:stripe/messages.dart'; -import 'package:stripe/src/resources/_api_config.dart'; +import 'package:stripe/src/api_config.dart'; import '../client.dart'; import '_resource.dart'; diff --git a/lib/src/resources/product.dart b/lib/src/resources/product.dart index cc23c8d..682357e 100644 --- a/lib/src/resources/product.dart +++ b/lib/src/resources/product.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:stripe/messages.dart'; -import 'package:stripe/src/resources/_api_config.dart'; +import 'package:stripe/src/api_config.dart'; import '../client.dart'; import '_resource.dart'; diff --git a/lib/src/resources/promotion_code.dart b/lib/src/resources/promotion_code.dart index c96fd37..1042c60 100644 --- a/lib/src/resources/promotion_code.dart +++ b/lib/src/resources/promotion_code.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:stripe/messages.dart'; -import 'package:stripe/src/resources/_api_config.dart'; +import 'package:stripe/src/api_config.dart'; import '../client.dart'; import '_resource.dart'; diff --git a/lib/src/resources/refund.dart b/lib/src/resources/refund.dart index 056dd90..084cdf5 100644 --- a/lib/src/resources/refund.dart +++ b/lib/src/resources/refund.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:stripe/messages.dart'; -import 'package:stripe/src/resources/_api_config.dart'; +import 'package:stripe/src/api_config.dart'; import '../client.dart'; import '_resource.dart'; diff --git a/lib/src/resources/sigma_query_run.dart b/lib/src/resources/sigma_query_run.dart index cffc410..656ed89 100644 --- a/lib/src/resources/sigma_query_run.dart +++ b/lib/src/resources/sigma_query_run.dart @@ -1,6 +1,6 @@ import 'package:stripe/messages.dart'; +import 'package:stripe/src/api_config.dart'; import 'package:stripe/src/client.dart'; -import 'package:stripe/src/resources/_api_config.dart'; import 'package:stripe/src/resources/_resource.dart'; class SigmaQueryRunResource extends Resource { diff --git a/lib/src/resources/sigma_scheduled_query_run.dart b/lib/src/resources/sigma_scheduled_query_run.dart index 7e6ad72..2a07991 100644 --- a/lib/src/resources/sigma_scheduled_query_run.dart +++ b/lib/src/resources/sigma_scheduled_query_run.dart @@ -1,6 +1,6 @@ import 'package:stripe/messages.dart'; +import 'package:stripe/src/api_config.dart'; import 'package:stripe/src/client.dart'; -import 'package:stripe/src/resources/_api_config.dart'; import 'package:stripe/src/resources/_resource.dart'; class SigmaScheduledQueryRunResource extends Resource { diff --git a/lib/src/resources/source.dart b/lib/src/resources/source.dart index 3fd4d66..91542b5 100644 --- a/lib/src/resources/source.dart +++ b/lib/src/resources/source.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:stripe/messages.dart'; -import 'package:stripe/src/resources/_api_config.dart'; +import 'package:stripe/src/api_config.dart'; import '../client.dart'; import '_resource.dart'; diff --git a/lib/src/resources/subscription.dart b/lib/src/resources/subscription.dart index b2b21dd..cd40fbb 100644 --- a/lib/src/resources/subscription.dart +++ b/lib/src/resources/subscription.dart @@ -1,8 +1,8 @@ import 'dart:async'; import 'package:stripe/messages.dart'; +import 'package:stripe/src/api_config.dart'; import 'package:stripe/src/expanded.dart'; -import 'package:stripe/src/resources/_api_config.dart'; import '../client.dart'; import '_resource.dart'; diff --git a/lib/src/resources/subscription_item.dart b/lib/src/resources/subscription_item.dart index eba616b..86830d2 100644 --- a/lib/src/resources/subscription_item.dart +++ b/lib/src/resources/subscription_item.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:stripe/messages.dart'; -import 'package:stripe/src/resources/_api_config.dart'; +import 'package:stripe/src/api_config.dart'; import '../client.dart'; import '_resource.dart'; diff --git a/lib/src/resources/subscription_schedule.dart b/lib/src/resources/subscription_schedule.dart index 6ced2e7..c9cfe93 100644 --- a/lib/src/resources/subscription_schedule.dart +++ b/lib/src/resources/subscription_schedule.dart @@ -1,4 +1,4 @@ -import 'package:stripe/src/resources/_api_config.dart'; +import 'package:stripe/src/api_config.dart'; import '../../messages.dart'; import '../client.dart'; diff --git a/lib/stripe.dart b/lib/stripe.dart index 3201649..3e76c27 100644 --- a/lib/stripe.dart +++ b/lib/stripe.dart @@ -1,6 +1,6 @@ library stripe; -import 'package:stripe/src/resources/_api_config.dart'; +import 'package:stripe/src/api_config.dart'; import 'src/client.dart'; import 'src/resources/balance_transaction.dart'; diff --git a/test/resources/balance_transaction_test.dart b/test/resources/balance_transaction_test.dart index 7b337ae..a0c5b8a 100644 --- a/test/resources/balance_transaction_test.dart +++ b/test/resources/balance_transaction_test.dart @@ -3,8 +3,8 @@ import 'dart:io'; import 'package:dio/dio.dart'; import 'package:stripe/messages.dart' show FeeDetails; +import 'package:stripe/src/api_config.dart'; import 'package:stripe/src/client.dart'; -import 'package:stripe/src/resources/_api_config.dart'; import 'package:stripe/src/resources/balance_transaction.dart'; import 'package:test/test.dart'; diff --git a/test/resources/checkout_session_test.dart b/test/resources/checkout_session_test.dart index 23ed093..28a3fca 100644 --- a/test/resources/checkout_session_test.dart +++ b/test/resources/checkout_session_test.dart @@ -3,8 +3,8 @@ import 'dart:io'; import 'package:dio/dio.dart'; import 'package:stripe/messages.dart'; +import 'package:stripe/src/api_config.dart'; import 'package:stripe/src/client.dart'; -import 'package:stripe/src/resources/_api_config.dart'; import 'package:stripe/src/resources/checkout_session.dart'; import 'package:test/test.dart'; diff --git a/test/resources/customer_test.dart b/test/resources/customer_test.dart index 21a4480..13a7db7 100644 --- a/test/resources/customer_test.dart +++ b/test/resources/customer_test.dart @@ -3,8 +3,8 @@ import 'dart:io'; import 'package:dio/dio.dart'; import 'package:stripe/messages.dart'; +import 'package:stripe/src/api_config.dart'; import 'package:stripe/src/client.dart'; -import 'package:stripe/src/resources/_api_config.dart'; import 'package:stripe/src/resources/customer.dart'; import 'package:test/test.dart'; diff --git a/test/resources/payment_intent_test.dart b/test/resources/payment_intent_test.dart index 356e220..76f90a9 100644 --- a/test/resources/payment_intent_test.dart +++ b/test/resources/payment_intent_test.dart @@ -9,8 +9,8 @@ import 'package:stripe/messages.dart' PaymentMethodType, SetupFutureUsage, ShippingSpecification; +import 'package:stripe/src/api_config.dart'; import 'package:stripe/src/client.dart'; -import 'package:stripe/src/resources/_api_config.dart'; import 'package:stripe/src/resources/payment_intent.dart'; import 'package:test/test.dart'; diff --git a/test/resources/subscription_test.dart b/test/resources/subscription_test.dart index 63ac799..dc9f96a 100644 --- a/test/resources/subscription_test.dart +++ b/test/resources/subscription_test.dart @@ -3,8 +3,8 @@ import 'dart:io'; import 'package:dio/dio.dart'; import 'package:stripe/messages.dart'; +import 'package:stripe/src/api_config.dart'; import 'package:stripe/src/client.dart'; -import 'package:stripe/src/resources/_api_config.dart'; import 'package:stripe/src/resources/subscription.dart'; import 'package:test/test.dart'; From 7750363d311e61fac3172916479c1afb69fa9c0b Mon Sep 17 00:00:00 2001 From: solid-maksymtielnyi Date: Thu, 4 Sep 2025 05:13:55 +0300 Subject: [PATCH 16/22] Export api_config.dart from stripe.dart --- lib/stripe.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/stripe.dart b/lib/stripe.dart index 3e76c27..afd41d9 100644 --- a/lib/stripe.dart +++ b/lib/stripe.dart @@ -24,6 +24,7 @@ import 'src/resources/subscription_item.dart'; import 'src/resources/subscription_schedule.dart'; export 'messages.dart'; +export 'src/api_config.dart'; export 'src/client.dart'; export 'src/exceptions.dart'; export 'src/expanded.dart'; From 4331a4c2581372e74ba0d6f357fc139d30ac4714 Mon Sep 17 00:00:00 2001 From: solid-maksymtielnyi Date: Thu, 4 Sep 2025 05:29:27 +0300 Subject: [PATCH 17/22] Remove apiKey from ApiConfig --- lib/src/api_config.dart | 2 -- lib/stripe.dart | 4 ++-- test/resources/balance_transaction_test.dart | 7 ++----- test/resources/checkout_session_test.dart | 7 ++----- test/resources/customer_test.dart | 7 ++----- test/resources/payment_intent_test.dart | 7 ++----- test/resources/subscription_test.dart | 7 ++----- 7 files changed, 12 insertions(+), 29 deletions(-) diff --git a/lib/src/api_config.dart b/lib/src/api_config.dart index 5afb882..87e4429 100644 --- a/lib/src/api_config.dart +++ b/lib/src/api_config.dart @@ -3,13 +3,11 @@ class ApiConfig { static const defaultApiUrl = 'https://api.stripe.com/v1/'; static const defaultFilesUrl = 'https://files.stripe.com/v1/'; - final String apiKey; final String version; final String baseApiUrl; final String baseFilesUrl; const ApiConfig({ - required this.apiKey, this.version = defaultVersion, this.baseApiUrl = defaultApiUrl, this.baseFilesUrl = defaultFilesUrl, diff --git a/lib/stripe.dart b/lib/stripe.dart index afd41d9..28be1b5 100644 --- a/lib/stripe.dart +++ b/lib/stripe.dart @@ -98,8 +98,8 @@ class Stripe { final FileResource file; factory Stripe(String apiKey) { - final config = ApiConfig(apiKey: apiKey); - final client = DioClient(apiKey: config.apiKey, version: config.version); + final config = ApiConfig(); + final client = DioClient(apiKey: apiKey, version: config.version); return Stripe.withClient(client, config); } diff --git a/test/resources/balance_transaction_test.dart b/test/resources/balance_transaction_test.dart index a0c5b8a..b788c43 100644 --- a/test/resources/balance_transaction_test.dart +++ b/test/resources/balance_transaction_test.dart @@ -11,15 +11,12 @@ import 'package:test/test.dart'; void main() { late DioClient client; late BalanceTransactionResource balanceTransactionResource; - final config = ApiConfig( - apiKey: 'sk_foobar', - baseApiUrl: 'http://void/', - ); + final config = ApiConfig(baseApiUrl: 'http://void/'); setUp(() { // We set the baseUrl to something unreachable, because we define // interceptors in the tests. client = DioClient( - apiKey: config.apiKey, + apiKey: 'sk_foobar', version: config.version, ); balanceTransactionResource = BalanceTransactionResource(client, config); diff --git a/test/resources/checkout_session_test.dart b/test/resources/checkout_session_test.dart index 28a3fca..a14fe74 100644 --- a/test/resources/checkout_session_test.dart +++ b/test/resources/checkout_session_test.dart @@ -11,14 +11,11 @@ import 'package:test/test.dart'; void main() { late DioClient client; late CheckoutSessionResource checkoutSessionResource; - final config = ApiConfig( - apiKey: 'sk_foobar', - baseApiUrl: 'http://void/', - ); + final config = ApiConfig(baseApiUrl: 'http://void/'); setUp(() { // We set the baseUrl to something unreachable, because we define // interceptors in the tests. - client = DioClient(apiKey: config.apiKey, version: config.version); + client = DioClient(apiKey: 'sk_foobar', version: config.version); checkoutSessionResource = CheckoutSessionResource(client, config); }); group('CheckoutSessionResource', () { diff --git a/test/resources/customer_test.dart b/test/resources/customer_test.dart index 13a7db7..2345943 100644 --- a/test/resources/customer_test.dart +++ b/test/resources/customer_test.dart @@ -11,14 +11,11 @@ import 'package:test/test.dart'; void main() { late DioClient client; late CustomerResource customerResource; - final config = ApiConfig( - apiKey: 'sk_foobar', - baseApiUrl: 'http://void/', - ); + final config = ApiConfig(baseApiUrl: 'http://void/'); setUp(() { // We set the baseUrl to something unreachable, because we define // interceptors in the tests. - client = DioClient(apiKey: config.apiKey, version: config.version); + client = DioClient(apiKey: 'sk_foobar', version: config.version); customerResource = CustomerResource(client, config); }); group('CustomerResource', () { diff --git a/test/resources/payment_intent_test.dart b/test/resources/payment_intent_test.dart index 76f90a9..22b7687 100644 --- a/test/resources/payment_intent_test.dart +++ b/test/resources/payment_intent_test.dart @@ -17,14 +17,11 @@ import 'package:test/test.dart'; void main() { late DioClient client; late PaymentIntentResource paymentIntentResource; - final config = ApiConfig( - apiKey: 'sk_foobar', - baseApiUrl: 'http://void/', - ); + final config = ApiConfig(baseApiUrl: 'http://void/'); setUp(() { // We set the baseUrl to something unreachable, because we define // interceptors in the tests. - client = DioClient(apiKey: config.apiKey, version: config.version); + client = DioClient(apiKey: 'sk_foobar', version: config.version); paymentIntentResource = PaymentIntentResource(client, config); }); group('PaymentIntentResource', () { diff --git a/test/resources/subscription_test.dart b/test/resources/subscription_test.dart index dc9f96a..360e6c7 100644 --- a/test/resources/subscription_test.dart +++ b/test/resources/subscription_test.dart @@ -11,14 +11,11 @@ import 'package:test/test.dart'; void main() { late DioClient client; late SubscriptionResource subscriptionResource; - final config = ApiConfig( - apiKey: 'sk_foobar', - baseApiUrl: 'http://void/', - ); + final config = ApiConfig(baseApiUrl: 'http://void/'); setUp(() { // We set the baseUrl to something unreachable, because we define // interceptors in the tests. - client = DioClient(apiKey: config.apiKey, version: config.version); + client = DioClient(apiKey: 'sk_foobar', version: config.version); subscriptionResource = SubscriptionResource(client, config); }); group('SubscriptionResource', () { From d78c3033f874430aab4f6b46054104bf9b66524b Mon Sep 17 00:00:00 2001 From: solid-maksymtielnyi Date: Thu, 4 Sep 2025 19:57:51 +0300 Subject: [PATCH 18/22] Add experimental POST sigma/scheduled_query_runs --- lib/src/resources/sigma_scheduled_query_run.dart | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/src/resources/sigma_scheduled_query_run.dart b/lib/src/resources/sigma_scheduled_query_run.dart index 2a07991..dc0b33b 100644 --- a/lib/src/resources/sigma_scheduled_query_run.dart +++ b/lib/src/resources/sigma_scheduled_query_run.dart @@ -9,6 +9,20 @@ class SigmaScheduledQueryRunResource extends Resource { SigmaScheduledQueryRunResource(Client client, ApiConfig config) : super(client, config); + // Added as an experiment since POST /v1/sigma/query_runs doesn't work + Future create( + CreateSigmaQueryRunRequest request, { + String? idempotencyKey, + }) async { + final map = await client.post( + makeUrl(_resourceName), + data: request.toJson(), + idempotencyKey: idempotencyKey, + ); + + return SigmaQueryRun.fromJson(map); + } + Future retrieve(String sigmaQueryRunId) async { final map = await client.get( makeUrl('$_resourceName/$sigmaQueryRunId'), From a6b9f6bdd403a86adaa03a01beb6a71e61fe70a8 Mon Sep 17 00:00:00 2001 From: solid-maksymtielnyi Date: Thu, 4 Sep 2025 19:59:44 +0300 Subject: [PATCH 19/22] Revert "Add experimental POST sigma/scheduled_query_runs" This reverts commit d78c3033f874430aab4f6b46054104bf9b66524b. --- lib/src/resources/sigma_scheduled_query_run.dart | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/lib/src/resources/sigma_scheduled_query_run.dart b/lib/src/resources/sigma_scheduled_query_run.dart index dc0b33b..2a07991 100644 --- a/lib/src/resources/sigma_scheduled_query_run.dart +++ b/lib/src/resources/sigma_scheduled_query_run.dart @@ -9,20 +9,6 @@ class SigmaScheduledQueryRunResource extends Resource { SigmaScheduledQueryRunResource(Client client, ApiConfig config) : super(client, config); - // Added as an experiment since POST /v1/sigma/query_runs doesn't work - Future create( - CreateSigmaQueryRunRequest request, { - String? idempotencyKey, - }) async { - final map = await client.post( - makeUrl(_resourceName), - data: request.toJson(), - idempotencyKey: idempotencyKey, - ); - - return SigmaQueryRun.fromJson(map); - } - Future retrieve(String sigmaQueryRunId) async { final map = await client.get( makeUrl('$_resourceName/$sigmaQueryRunId'), From fa3faad9d4cfa0524351160d341d6afae0b37a42 Mon Sep 17 00:00:00 2001 From: solid-maksymtielnyi Date: Thu, 11 Sep 2025 00:18:02 +0300 Subject: [PATCH 20/22] Add SigmaScheduledQueryRunEvent --- lib/messages.g.dart | 27 +++++++++++++++++++++++++++ lib/src/messages/event.dart | 25 +++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/lib/messages.g.dart b/lib/messages.g.dart index 505018e..a5f0660 100644 --- a/lib/messages.g.dart +++ b/lib/messages.g.dart @@ -831,6 +831,33 @@ Map _$CouponEventToJson(CouponEvent instance) => 'livemode': instance.livemode, }; +SigmaScheduledQueryRunEvent _$SigmaScheduledQueryRunEventFromJson( + Map json) => + SigmaScheduledQueryRunEvent( + object: $enumDecode(_$EventObjectEnumMap, json['object']), + id: json['id'] as String, + created: (json['created'] as num).toInt(), + type: json['type'] as String, + data: EventData.fromJson( + json['data'] as Map, + (value) => + SigmaScheduledQueryRun.fromJson(value as Map)), + livemode: json['livemode'] as bool, + ); + +Map _$SigmaScheduledQueryRunEventToJson( + SigmaScheduledQueryRunEvent instance) => + { + 'object': _$EventObjectEnumMap[instance.object]!, + 'id': instance.id, + 'created': instance.created, + 'data': instance.data.toJson( + (value) => value.toJson(), + ), + 'type': instance.type, + 'livemode': instance.livemode, + }; + File _$FileFromJson(Map json) => File( object: $enumDecode(_$_FileObjectEnumMap, json['object']), id: json['id'] as String, diff --git a/lib/src/messages/event.dart b/lib/src/messages/event.dart index bb073a6..3fd8a55 100644 --- a/lib/src/messages/event.dart +++ b/lib/src/messages/event.dart @@ -367,3 +367,28 @@ class CouponEvent extends Event { @override Map toJson() => _$CouponEventToJson(this); } + +@JsonSerializable() +class SigmaScheduledQueryRunEvent extends Event { + SigmaScheduledQueryRunEvent({ + required EventObject object, + required String id, + required int created, + required String type, + required EventData data, + required bool livemode, + }) : super( + object: object, + id: id, + created: created, + data: data, + type: type, + livemode: livemode, + ); + + factory SigmaScheduledQueryRunEvent.fromJson(Map json) => + _$SigmaScheduledQueryRunEventFromJson(json); + + @override + Map toJson() => _$SigmaScheduledQueryRunEventToJson(this); +} From b22a931575d0e1a2866f259a320cce976127c20c Mon Sep 17 00:00:00 2001 From: solid-maksymtielnyi Date: Thu, 11 Sep 2025 02:54:29 +0300 Subject: [PATCH 21/22] Rename name field to title in SigmaScheduledQueryRun --- lib/messages.g.dart | 4 ++-- lib/src/messages/sigma_scheduled_query_run.dart | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/messages.g.dart b/lib/messages.g.dart index a5f0660..e5c937b 100644 --- a/lib/messages.g.dart +++ b/lib/messages.g.dart @@ -3128,7 +3128,7 @@ SigmaScheduledQueryRun _$SigmaScheduledQueryRunFromJson( file: json['file'] == null ? null : File.fromJson(json['file'] as Map), - name: json['name'] as String?, + title: json['title'] as String?, error: json['error'] == null ? null : SigmaScheduledQueryRunError.fromJson( @@ -3157,7 +3157,7 @@ Map _$SigmaScheduledQueryRunToJson( writeNotNull('file', instance.file?.toJson()); val['sql'] = instance.sql; val['status'] = _$SigmaScheduledQueryRunStatusEnumMap[instance.status]!; - writeNotNull('name', instance.name); + writeNotNull('title', instance.title); val['created'] = const TimestampConverter().toJson(instance.created); writeNotNull('error', instance.error?.toJson()); val['livemode'] = instance.livemode; diff --git a/lib/src/messages/sigma_scheduled_query_run.dart b/lib/src/messages/sigma_scheduled_query_run.dart index 0b44bd7..5c8a744 100644 --- a/lib/src/messages/sigma_scheduled_query_run.dart +++ b/lib/src/messages/sigma_scheduled_query_run.dart @@ -23,7 +23,7 @@ class SigmaScheduledQueryRun extends Message { final File? file; final String sql; final SigmaScheduledQueryRunStatus status; - final String? name; + final String? title; @TimestampConverter() final DateTime created; @@ -43,7 +43,7 @@ class SigmaScheduledQueryRun extends Message { required this.livemode, this.dataLoadTime, this.file, - this.name, + this.title, this.error, this.resultAvailableUntil, }); From a197484705d0041e4e4cbcdf6c34f2f4e32cc248 Mon Sep 17 00:00:00 2001 From: solid-maksymtielnyi Date: Thu, 11 Sep 2025 16:25:29 +0300 Subject: [PATCH 22/22] Add scheduled_query_run to Event.fromJson --- lib/src/messages/event.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/src/messages/event.dart b/lib/src/messages/event.dart index 3fd8a55..282a551 100644 --- a/lib/src/messages/event.dart +++ b/lib/src/messages/event.dart @@ -60,6 +60,8 @@ abstract class Event extends Message { return InvoiceEvent.fromJson(json) as T; case 'coupon': return CouponEvent.fromJson(json) as T; + case 'scheduled_query_run': + return SigmaScheduledQueryRunEvent.fromJson(json) as T; default: throw FormatException( 'Unrecognized/unsupported Stripe object `${json['object']}` in event webhook');