ente/auth/lib/services/billing_service.dart

178 lines
4.7 KiB
Dart
Raw Normal View History

2022-11-01 06:13:06 +00:00
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:ente_auth/core/configuration.dart';
import 'package:ente_auth/core/errors.dart';
import 'package:ente_auth/core/network.dart';
import 'package:ente_auth/models/billing_plan.dart';
import 'package:ente_auth/models/subscription.dart';
import 'package:logging/logging.dart';
const kWebPaymentRedirectUrl = "https://payments.ente.io/frameRedirect";
const kWebPaymentBaseEndpoint = String.fromEnvironment(
"web-payment",
defaultValue: "https://payments.ente.io",
);
const kFamilyPlanManagementUrl = String.fromEnvironment(
"web-family",
defaultValue: "https://family.ente.io",
);
class BillingService {
BillingService._privateConstructor();
static final BillingService instance = BillingService._privateConstructor();
final _logger = Logger("BillingService");
final _dio = Network.instance.getDio();
final _config = Configuration.instance;
2023-04-10 04:17:45 +00:00
Subscription? _cachedSubscription;
2023-03-29 05:57:21 +00:00
2023-04-10 04:17:45 +00:00
Future<BillingPlans>? _future;
2022-11-01 06:13:06 +00:00
2023-03-29 05:57:21 +00:00
Future<void> init() async {}
2022-11-01 06:13:06 +00:00
void clearCache() {
_future = null;
}
Future<BillingPlans> getBillingPlans() {
_future ??= (_config.getToken() == null
? _fetchPublicBillingPlans()
: _fetchPrivateBillingPlans())
.then((response) {
return BillingPlans.fromMap(response.data);
});
2023-04-10 04:17:45 +00:00
return _future!;
2022-11-01 06:13:06 +00:00
}
Future<Response<dynamic>> _fetchPrivateBillingPlans() {
return _dio.get(
"${_config.getHttpEndpoint()}/billing/user-plans/",
2022-11-01 06:13:06 +00:00
options: Options(
headers: {
"X-Auth-Token": _config.getToken(),
},
),
);
}
Future<Response<dynamic>> _fetchPublicBillingPlans() {
return _dio.get("${_config.getHttpEndpoint()}/billing/plans/v2");
2022-11-01 06:13:06 +00:00
}
Future<Subscription> verifySubscription(
final productID,
final verificationData, {
final paymentProvider,
}) async {
try {
final response = await _dio.post(
"${_config.getHttpEndpoint()}/billing/verify-subscription",
2022-11-01 06:13:06 +00:00
data: {
"paymentProvider": paymentProvider ??
(Platform.isAndroid ? "playstore" : "appstore"),
"productID": productID,
"verificationData": verificationData,
},
options: Options(
headers: {
"X-Auth-Token": _config.getToken(),
},
),
);
return Subscription.fromMap(response.data["subscription"]);
} on DioException catch (e) {
2023-04-10 04:17:45 +00:00
if (e.response != null && e.response!.statusCode == 409) {
2022-11-01 06:13:06 +00:00
throw SubscriptionAlreadyClaimedError();
} else {
rethrow;
}
} catch (e, s) {
_logger.severe(e, s);
rethrow;
}
}
2023-03-29 05:57:21 +00:00
Future<Subscription> getSubscription() async {
if (_cachedSubscription == null) {
try {
final response = await _dio.get(
"${_config.getHttpEndpoint()}/billing/subscription",
2023-03-29 05:57:21 +00:00
options: Options(
headers: {
"X-Auth-Token": _config.getToken(),
},
),
);
_cachedSubscription =
Subscription.fromMap(response.data["subscription"]);
} on DioException catch (e, s) {
2023-03-29 05:57:21 +00:00
_logger.severe(e, s);
rethrow;
}
2022-11-01 06:13:06 +00:00
}
2023-04-10 04:17:45 +00:00
return _cachedSubscription!;
2022-11-01 06:13:06 +00:00
}
Future<Subscription> cancelStripeSubscription() async {
try {
final response = await _dio.post(
"${_config.getHttpEndpoint()}/billing/stripe/cancel-subscription",
2022-11-01 06:13:06 +00:00
options: Options(
headers: {
"X-Auth-Token": _config.getToken(),
},
),
);
final subscription = Subscription.fromMap(response.data["subscription"]);
return subscription;
} on DioException catch (e, s) {
2022-11-01 06:13:06 +00:00
_logger.severe(e, s);
rethrow;
}
}
Future<Subscription> activateStripeSubscription() async {
try {
final response = await _dio.post(
"${_config.getHttpEndpoint()}/billing/stripe/activate-subscription",
2022-11-01 06:13:06 +00:00
options: Options(
headers: {
"X-Auth-Token": _config.getToken(),
},
),
);
final subscription = Subscription.fromMap(response.data["subscription"]);
return subscription;
} on DioException catch (e, s) {
2022-11-01 06:13:06 +00:00
_logger.severe(e, s);
rethrow;
}
}
Future<String> getStripeCustomerPortalUrl({
String endpoint = kWebPaymentRedirectUrl,
}) async {
try {
final response = await _dio.get(
"${_config.getHttpEndpoint()}/billing/stripe/customer-portal",
2022-11-01 06:13:06 +00:00
queryParameters: {
"redirectURL": kWebPaymentRedirectUrl,
},
options: Options(
headers: {
"X-Auth-Token": _config.getToken(),
},
),
);
return response.data["url"];
} on DioException catch (e, s) {
2022-11-01 06:13:06 +00:00
_logger.severe(e, s);
rethrow;
}
}
}