feat(stripe_api): add ability to fetch billing meters (#3372)
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
export 'stripe_billing_meter.dart';
|
||||
export 'stripe_checkout_session.dart';
|
||||
export 'stripe_customer.dart';
|
||||
export 'stripe_event.dart';
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'stripe_billing_meter.g.dart';
|
||||
|
||||
/// {@template stripe_billing_meter}
|
||||
/// A billing meter in Stripe.
|
||||
///
|
||||
/// See https://docs.stripe.com/api/billing/meter/object
|
||||
/// {@endtemplate}
|
||||
@JsonSerializable(createToJson: false)
|
||||
class StripeBillingMeter {
|
||||
/// {@macro stripe_billing_meter}
|
||||
StripeBillingMeter({
|
||||
required this.id,
|
||||
required this.displayName,
|
||||
required this.eventName,
|
||||
});
|
||||
|
||||
/// Converts a JSON object to a [StripeBillingMeter].
|
||||
factory StripeBillingMeter.fromJson(Map<String, dynamic> json) =>
|
||||
_$StripeBillingMeterFromJson(json);
|
||||
|
||||
/// The unique identifier for this object.
|
||||
final String id;
|
||||
|
||||
/// The meter's name.
|
||||
final String displayName;
|
||||
|
||||
/// The name of the meter event to record usage for. Corresponds with the
|
||||
/// event_name field on meter events.
|
||||
final String eventName;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
// ignore_for_file: implicit_dynamic_parameter, require_trailing_commas, cast_nullable_to_non_nullable, lines_longer_than_80_chars, unnecessary_lambdas
|
||||
|
||||
part of 'stripe_billing_meter.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
StripeBillingMeter _$StripeBillingMeterFromJson(Map<String, dynamic> json) =>
|
||||
$checkedCreate(
|
||||
'StripeBillingMeter',
|
||||
json,
|
||||
($checkedConvert) {
|
||||
final val = StripeBillingMeter(
|
||||
id: $checkedConvert('id', (v) => v as String),
|
||||
displayName: $checkedConvert('display_name', (v) => v as String),
|
||||
eventName: $checkedConvert('event_name', (v) => v as String),
|
||||
);
|
||||
return val;
|
||||
},
|
||||
fieldKeyMap: const {
|
||||
'displayName': 'display_name',
|
||||
'eventName': 'event_name',
|
||||
},
|
||||
);
|
||||
@@ -65,6 +65,16 @@ class StripeApi {
|
||||
);
|
||||
}
|
||||
|
||||
/// Retrieves all [StripeBillingMeter]s associated with the Stripe account.
|
||||
Future<List<StripeBillingMeter>> fetchActiveBillingMeters() async {
|
||||
return _fetchAllPages(
|
||||
path: 'billing/meters',
|
||||
queryParameters: {'status': 'active'},
|
||||
fromJson: StripeBillingMeter.fromJson,
|
||||
getId: (e) => e.id,
|
||||
);
|
||||
}
|
||||
|
||||
/// Creates a new meter event for the given [customerId].
|
||||
/// See https://docs.stripe.com/api/billing/meter-event
|
||||
Future<void> createMeterEvent({
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"object": "list",
|
||||
"data": [
|
||||
{
|
||||
"id": "mtr_test_61QvSUDTnLya5cdwG41HSA9cXarIc144",
|
||||
"object": "billing.meter",
|
||||
"created": 1723254937,
|
||||
"customer_mapping": {
|
||||
"event_payload_key": "stripe_customer_id",
|
||||
"type": "by_id"
|
||||
},
|
||||
"default_aggregation": {
|
||||
"formula": "sum"
|
||||
},
|
||||
"display_name": "Patch Installs",
|
||||
"event_name": "patch_installs",
|
||||
"event_time_window": null,
|
||||
"livemode": false,
|
||||
"status": "active",
|
||||
"status_transitions": {
|
||||
"deactivated_at": null
|
||||
},
|
||||
"updated": 1723254937,
|
||||
"value_settings": {
|
||||
"event_payload_key": "value"
|
||||
}
|
||||
}
|
||||
],
|
||||
"has_more": true,
|
||||
"url": "/v1/billing/meters"
|
||||
}
|
||||
@@ -3,6 +3,13 @@ import 'dart:io';
|
||||
|
||||
const stripeJsonPath = 'test/fixtures/stripe/json';
|
||||
|
||||
String get billingMetersPageJsonString => File(
|
||||
'$stripeJsonPath/billing_meters_page.json',
|
||||
).readAsStringSync();
|
||||
|
||||
Map<String, dynamic> get billingMetersPageJson =>
|
||||
jsonDecode(billingMetersPageJsonString) as Map<String, dynamic>;
|
||||
|
||||
String get checkoutSessionCompletedEventJsonString => File(
|
||||
'$stripeJsonPath/checkout_session_completed_event.json',
|
||||
).readAsStringSync();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
@@ -215,6 +216,53 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
group('fetchBillingMeters', () {
|
||||
const meterId = 'mtr_test_61QvSUDTnLya5cdwG41HSA9cXarIc144';
|
||||
setUp(() {
|
||||
when(
|
||||
() => httpClient.get(
|
||||
Uri.parse(
|
||||
'https://api.stripe.com/v1/billing/meters?status=active&limit=100',
|
||||
),
|
||||
headers: any(named: 'headers'),
|
||||
),
|
||||
).thenAnswer(
|
||||
(_) async => http.Response(
|
||||
billingMetersPageJsonString,
|
||||
HttpStatus.ok,
|
||||
),
|
||||
);
|
||||
|
||||
when(
|
||||
() => httpClient.get(
|
||||
Uri.parse(
|
||||
'https://api.stripe.com/v1/billing/meters?status=active&limit=100&starting_after=$meterId',
|
||||
),
|
||||
headers: any(named: 'headers'),
|
||||
),
|
||||
).thenAnswer(
|
||||
(_) async => http.Response(
|
||||
jsonEncode({
|
||||
'object': 'list',
|
||||
'data': <Map<String, dynamic>>[],
|
||||
'has_more': false,
|
||||
}),
|
||||
HttpStatus.ok,
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
test('returns a billing meter on successful request', () async {
|
||||
final billingMeters = await stripeApi.fetchActiveBillingMeters();
|
||||
expect(billingMeters, hasLength(1));
|
||||
|
||||
final billingMeter = billingMeters.first;
|
||||
expect(billingMeter.id, meterId);
|
||||
expect(billingMeter.displayName, 'Patch Installs');
|
||||
expect(billingMeter.eventName, 'patch_installs');
|
||||
});
|
||||
});
|
||||
|
||||
group('createMeterEvent', () {
|
||||
final uri = Uri.parse('https://api.stripe.com/v1/billing/meter_events');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user