[go: nahoru, domu]

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

in_app_purchases codelab: Dart Server implementation #1493

Merged
merged 38 commits into from
Apr 18, 2023
Merged
Changes from 1 commit
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
ab0c9da
copy app_rest complete to step 00
miquelbeltran Mar 7, 2023
3d89140
cleanup step_00
miquelbeltran Mar 7, 2023
f013cc5
add template firebase_options.dart
miquelbeltran Mar 7, 2023
51458de
remove unused firebase functions dependency
miquelbeltran Mar 8, 2023
3170883
copy step_00 to step_07
miquelbeltran Mar 8, 2023
d717490
Step_07 app_rest complete
miquelbeltran Mar 10, 2023
503cedf
copy app_rest from step_07 to step_08
miquelbeltran Mar 10, 2023
5f638ed
step_08 update lib/model/purchasable_product.dart
miquelbeltran Mar 10, 2023
7601d3a
step_08 update lib/logic/dash_purchases.dart
miquelbeltran Mar 10, 2023
5b5efb2
updated dash_purchases.dart
miquelbeltran Mar 13, 2023
64ed802
copy app_rest from step_08 to step_09
miquelbeltran Mar 14, 2023
053e81f
copy firebase-backend-dart from complete to step_00
miquelbeltran Mar 14, 2023
199d173
removed code from starter backend
miquelbeltran Mar 14, 2023
3fcdf5c
renamed firebase-backend-dart to dart-backend
miquelbeltran Mar 14, 2023
c58a834
renamed firebase-backend-dart to dart-backend
miquelbeltran Mar 14, 2023
21f0925
copied dart backend from step_00 into steps 7 8 and 9
miquelbeltran Mar 14, 2023
81ab1fd
add auth to step 09
miquelbeltran Mar 15, 2023
1fafb4f
app rest code to verify purchases in step 09
miquelbeltran Mar 15, 2023
7c8e607
add abstract purchase_handler to step 09
miquelbeltran Mar 15, 2023
742e090
add purchase handlers to step 09
miquelbeltran Mar 16, 2023
7a33b4b
add purchase handlers to server.dart in step 09
miquelbeltran Mar 16, 2023
8b2b109
copy files from step 09 to step 10
miquelbeltran Mar 17, 2023
f6ec774
remove old firebase-backend files
miquelbeltran Mar 17, 2023
a179519
remove old firebase function app
miquelbeltran Mar 17, 2023
3db2cab
renamed app_rest to app
miquelbeltran Mar 17, 2023
2d1e509
Google pub/sub config
miquelbeltran Mar 17, 2023
3b2a145
complete step 10
miquelbeltran Mar 20, 2023
e9b25f9
Merge branch 'main' into mb-in-app-payments-codelab
miquelbeltran Mar 20, 2023
02ad097
enable beta ci
miquelbeltran Mar 21, 2023
28d96f6
add placeholder firebase_options.dart
miquelbeltran Mar 21, 2023
cff3faa
add constants.dart placeholder to git
miquelbeltran Mar 21, 2023
f016e92
removed print statements
miquelbeltran Mar 21, 2023
e1ab916
formatting
miquelbeltran Mar 22, 2023
6302105
ignore beta ci
miquelbeltran Mar 27, 2023
d6b69d9
Merge branch 'main' into mb-in-app-payments-codelab
miquelbeltran Mar 27, 2023
aba88ef
Make `sdk` constraints wide enough for Dart 3
domesticmouse Mar 28, 2023
a1b6f7e
cleanup beatufiedDash variable
miquelbeltran Mar 28, 2023
5563310
Merge branch 'main' into mb-in-app-payments-codelab
miquelbeltran Apr 18, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add purchase handlers to server.dart in step 09
  • Loading branch information
miquelbeltran committed Mar 16, 2023
commit 7a33b4b9512365d1054410baa49724875071fcbb
89 changes: 89 additions & 0 deletions in_app_purchases/step_09/dart-backend/bin/server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,101 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:convert';
import 'dart:io';

import 'package:firebase_backend_dart/app_store_purchase_handler.dart';
import 'package:firebase_backend_dart/google_play_purchase_handler.dart';
import 'package:firebase_backend_dart/helpers.dart';
import 'package:firebase_backend_dart/iap_repository.dart';
import 'package:firebase_backend_dart/products.dart';
import 'package:firebase_backend_dart/purchase_handler.dart';
import 'package:googleapis/androidpublisher/v3.dart' as ap;
import 'package:googleapis/firestore/v1.dart' as fs;
import 'package:googleapis_auth/auth_io.dart' as auth;
import 'package:shelf/shelf.dart';
import 'package:shelf_router/shelf_router.dart';

/// Creates the Google Play and Apple Store [PurchaseHandler]
/// and their dependencies
Future<Map<String, PurchaseHandler>> _createPurchaseHandlers() async {
// Configure Android Publisher API access
final serviceAccountGooglePlay =
File('assets/service-account-google-play.json').readAsStringSync();
final clientCredentialsGooglePlay =
auth.ServiceAccountCredentials.fromJson(serviceAccountGooglePlay);
final clientGooglePlay =
await auth.clientViaServiceAccount(clientCredentialsGooglePlay, [
ap.AndroidPublisherApi.androidpublisherScope,
]);
final androidPublisher = ap.AndroidPublisherApi(clientGooglePlay);

// Configure Firestore API access
final serviceAccountFirebase =
File('assets/service-account-firebase.json').readAsStringSync();
final clientCredentialsFirebase =
auth.ServiceAccountCredentials.fromJson(serviceAccountFirebase);
final clientFirebase =
await auth.clientViaServiceAccount(clientCredentialsFirebase, [
fs.FirestoreApi.cloudPlatformScope,
]);
final firestoreApi = fs.FirestoreApi(clientFirebase);
final dynamic json = jsonDecode(serviceAccountFirebase);
final projectId = json['project_id'] as String;
final iapRepository = IapRepository(firestoreApi, projectId);

return {
'google_play': GooglePlayPurchaseHandler(
androidPublisher,
iapRepository,
),
'app_store': AppStorePurchaseHandler(
iapRepository,
),
};
}

Future<void> main() async {
final router = Router();

final purchaseHandlers = await _createPurchaseHandlers();

/// Warning: This endpoint has no security
/// and does not implement user authentication.
/// Production applications should implement authentication.
// ignore: avoid_types_on_closure_parameters
router.post('/verifypurchase', (Request request) async {
final dynamic payload = json.decode(await request.readAsString());

// NOTE: userId should be obtained using authentication methods.
final userId = payload['userId'] as String;

// Value from PurchaseDetails.verificationData.source
final source = payload['source'] as String;

// Obtain product data based on the productId
final productData = productDataMap[payload['productId']]!;

// Value from PurchaseDetails.verificationData.serverVerificationData
final token = payload['verificationData'] as String;

// Will call to verifyPurchase on
// [GooglePlayPurchaseHandler] or [AppleStorePurchaseHandler]
final result = await purchaseHandlers[source]!.verifyPurchase(
userId: userId,
productData: productData,
token: token,
);

if (result) {
// Note: Better success response recommended
return Response.ok('all good!');
} else {
// Note: Better error handling recommended
return Response.internalServerError();
}
});

// Start service
await serveHandler(router);
}