Skip to content

Commit

Permalink
Add implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
nilsreichardt committed Dec 7, 2023
1 parent 76cf923 commit d45cad9
Show file tree
Hide file tree
Showing 13 changed files with 1,203 additions and 52 deletions.
2 changes: 2 additions & 0 deletions app/lib/main/plugin_initializations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ class PluginInitializations {
'revenuecat_api_android_key': 'goog_EyqDtrZhkswSqMAcfqawHGAqZnX',
'firebase_messaging_vapid_key':
'BNT7Da6B6wi-mUBcGrt-9HxeIJZsPTsPpmR8cae_LhgJPcSFb5j0T8o-r-oFV1xAtXVXfRPIZlgUJR3tx8mLbbA',
'stripe_checkout_session_function_url':
'https://europe-west1-sharezone-c2bd8.cloudfunctions.net/createStripeCheckoutSession'
});

try {
Expand Down
9 changes: 9 additions & 0 deletions app/lib/main/sharezone_bloc_providers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,9 @@ import 'package:sharezone/util/notification_token_adder.dart';
import 'package:sharezone/util/platform_information_manager/flutter_platform_information_retreiver.dart';
import 'package:sharezone/util/platform_information_manager/get_platform_information_retreiver.dart';
import 'package:sharezone_common/references.dart';
import 'package:stripe_checkout_session/stripe_checkout_session.dart';
import 'package:user/user.dart';
import 'package:http/http.dart' as http;

import '../homework/parent/src/homework_page_bloc.dart' as old;
import '../notifications/is_firebase_messaging_supported.dart';
Expand Down Expand Up @@ -335,8 +337,15 @@ class _SharezoneBlocProvidersState extends State<SharezoneBlocProviders> {
),
ChangeNotifierProvider(
create: (context) => SharezonePlusPageController(
userId: UserId(api.uID),
purchaseService: RevenueCatPurchaseService(),
subscriptionService: subscriptionService,
stripeCheckoutSession: StripeCheckoutSession(
createCheckoutSessionFunctionUrl: widget
.blocDependencies.remoteConfiguration
.getString('stripe_checkout_session_function_url'),
client: http.Client(),
),
),
),
ChangeNotifierProvider(
Expand Down
28 changes: 19 additions & 9 deletions app/lib/sharezone_plus/page/sharezone_plus_page_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@

import 'dart:async';

import 'package:common_domain_models/common_domain_models.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:sharezone/sharezone_plus/subscription_service/revenue_cat_sharezone_plus_service.dart';
import 'package:sharezone/sharezone_plus/subscription_service/stripe_sharezone_plus_service.dart';
import 'package:sharezone/sharezone_plus/subscription_service/subscription_service.dart';
import 'package:sharezone_utils/platform.dart';
import 'package:stripe_checkout_session/stripe_checkout_session.dart';
import 'package:url_launcher/url_launcher.dart';

/// A fallback price if the price cannot be fetched from the backend.
Expand All @@ -28,22 +29,25 @@ class SharezonePlusPageController extends ChangeNotifier {
// ignore: unused_field
late SubscriptionService _subscriptionService;

late StripeSharezonePlusService _stripeService;
late StripeCheckoutSession _stripeCheckoutSession;
late UserId _userId;

StreamSubscription<bool>? _hasPlusSubscription;

SharezonePlusPageController({
required RevenueCatPurchaseService purchaseService,
required SubscriptionService subscriptionService,
required StripeSharezonePlusService stripeService,
required StripeCheckoutSession stripeCheckoutSession,
required UserId userId,
}) {
_purchaseService = purchaseService;
_subscriptionService = subscriptionService;
_stripeService = stripeService;
_stripeCheckoutSession = stripeCheckoutSession;
_userId = userId;

// Fake loading for development purposes.
Future.delayed(const Duration(seconds: 1)).then((value) {
hasPlus = true;
hasPlus = false;
price = fallbackPlusPrice;
notifyListeners();
});
Expand All @@ -66,20 +70,26 @@ class SharezonePlusPageController extends ChangeNotifier {
String? price;

Future<void> buySubscription() async {
hasPlus = true;

if (PlatformCheck.isWeb) {
await _buyOnWeb();
}

hasPlus = true;
notifyListeners();
}

Future<void> _buyOnWeb() async {
final checkoutUrl = await _stripeService.createCheckoutUrl();
final checkoutUrl = await _stripeCheckoutSession.create(
userId: '$_userId',
);

await launchUrl(
Uri.parse(checkoutUrl),
// TODO: Insert ticket for async link opening
// Since the request for creating the checkout session is asynchronous, we
// can't open the checkout in a new tab due to the browser security
// policy.
//
// See https://github.com/flutter/flutter/issues/78524.
webOnlyWindowName: "_self",
);
}
Expand Down

This file was deleted.

9 changes: 8 additions & 1 deletion app/pubspec.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions app/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ dependencies:
path: ../lib/common_domain_models
crash_analytics:
path: ../lib/crash_analytics
stripe_checkout_session:
path: ../lib/sharezone_plus/stripe_checkout_session
cupertino_icons: ^1.0.3
date:
path: ../lib/date
Expand Down Expand Up @@ -108,6 +110,7 @@ dependencies:
path: ../lib/hausaufgabenheft_logik
holidays:
path: ../lib/holidays
http: ^0.13.5
# Used so that we can select a minute interval (only either XX:00 or XX:30)
# for the homework reminder time picker.
interval_time_picker: ^2.0.0+5
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2023 Sharezone UG (haftungsbeschränkt)
# Licensed under the EUPL-1.2-or-later.
#
# You may obtain a copy of the Licence at:
# https://joinup.ec.europa.eu/software/page/eupl
#
# SPDX-License-Identifier: EUPL-1.2

include: package:sharezone_lints/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright (c) 2023 Sharezone UG (haftungsbeschränkt)
// Licensed under the EUPL-1.2-or-later.
//
// You may obtain a copy of the Licence at:
// https://joinup.ec.europa.eu/software/page/eupl
//
// SPDX-License-Identifier: EUPL-1.2

import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:retry/retry.dart';

class StripeCheckoutSession {
final String createCheckoutSessionFunctionUrl;
final http.Client client;

StripeCheckoutSession({
required this.client,
required this.createCheckoutSessionFunctionUrl,
});

/// Creates a new Stripe checkout session.
///
/// Either [userId] or [buysFor] must be passed to identify the user. [userId]
/// is the ID of the user who is buying the subscription. [buysFor] is the ID
/// of the user for whom the subscription is bought and is used for the
/// "Parents buy for their children" feature.
///
/// Returns the URL of the Stripe checkout session. The user must be
/// redirected to this URL to complete the payment.
Future<String> create({
String? userId,
String? buysFor,
}) async {
assert(
userId != null || buysFor != null,
'Either userId or buysFor must be passed',
);

return retry<String>(
() async {
final response = await client.post(
Uri.parse(createCheckoutSessionFunctionUrl),
headers: {
'Content-Type': 'application/json',
},
body: jsonEncode(
{
if (userId != null) 'userId': userId,
if (buysFor != null) 'buysFor': buysFor,
},
),
);

if (response.statusCode == 200) {
var responseData = jsonDecode(response.body);
final String? url = responseData['url'];

if (url == null) {
throw Exception('Could not found url in response');
}

return url;
} else {
throw Exception(
'Request failed with status: ${response.statusCode} (${response.body})',
);
}
},
maxAttempts: 3,
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) 2023 Sharezone UG (haftungsbeschränkt)
// Licensed under the EUPL-1.2-or-later.
//
// You may obtain a copy of the Licence at:
// https://joinup.ec.europa.eu/software/page/eupl
//
// SPDX-License-Identifier: EUPL-1.2

library stripe_checkout_session;

export 'src/stripe_checkout_session.dart';
Loading

0 comments on commit d45cad9

Please sign in to comment.