puma_pay
This package allows you app to manage in-app products and subscriptions.
Installation
-
Add the following in you
pubspec.yaml
file underdependencies
:puma_pay: ^2.0.1
-
Add the Puma Pay middleware in your app (
src/main.dart
):final store = Store<MainState>( mainReducer, initialState: initialState, middleware: [ PumaPayMiddleware<MainState>().createMiddleware(), mainMiddleware(), ], );
-
Add the Puma Pay reducer in your app main reducer (
src/redux/mainReducer.dart
):final mainReducer = combineReducers<MainState>([ kitReducers, ]); MainState kitReducers(MainState state, action) { return state.rebuild((b) => b ..pumaPayState.replace(pumaPayReducer(state.pumaPayState, action)) ..accountKitState .replace(accountKitReducer(state.accountKitState, action))); }
-
Add PumaPayState in your mainState (
src/redux/mainState.dart
):PumaPayState get pumaPayState;
Don't forget to init pumaPayState in the mainState initial() function:
static MainState initial() { final builder = MainStateBuilder(); builder.pumaPayState = PumaPayState.initial().toBuilder(); return new MainState((b) => b ..pumaPayState.replace(PumaPayState.initial()) // other stuff ); }
Getting Started
1. Init the package
On your src/app.dart
you should init Puma Pay (using the StoreConnector onInitialBuild handler for example). You just need to dispatch the action InitPayAction
.
The InitPayAction
contains 4 parameters:
-
`productsID` List\<String\>: Id of your products (Make sure the IDS are the same on iOS and Android).
-
verifyEndpoint
String?: All restored products should be verified by Apple or Google because we cannot trust the restored product list provided by the packagein-app-purchase
. That is why your API should implement an endpoint that query /verifyReceipt for Apple or GET purchases.subscriptions for Google. Your endpoint must be a POST that accepts body like this:```dart { "productID": STRING, "storeName": "android" || "ios" "data": STRING } ```
-
appleAppStorePassword
: String?: If you don't use an endpoint on your backend. You still could query the Apple/verifyReceipt
even if it is not recommended. In that case, this field is required to perform the API call. -
appStoreSandbox
: Bool?: If you don't use an endpoint on your backend and if you want to use the AppStore Sandbox.
As soon as you dispatch the action, the package will init and fetch all products provided on the productsID
list on the different stores.
2. PumaPayState
Your MainState includes a PumaPayState
that contains all you need:
4 Flags :
storeAvailable
boolean
: Whether the device store is available or not (AppStore or Google Play).productsLoading
boolean
: Descibes if the app is still fetching the full products on the stores.restoringPurchase
boolean
: Descibes if the app is restoring all the purchases.purchasePending
boolean
: Descibes if a products is being purchased.
1 list :
products
Product: list of fetched products.
A Product
has the following shape:
String get id;
String get title;
String get description;
String get price;
double get rawPrice;
String get currencySymbol;
String get currencyCode;
BuiltList<PurchaseDetail> get purchaseDetails;
The PurchaseDetail
is filled if you perform a restorePurchaseAction
and will put all related items on this list. The object has this shape:
String? get purchaseID;
String get productID;
String? get transactionDate;
String get status;
bool? get valid;
Note that the valid
boolean is nullable
. You should interpret its value like this:
true
: Your backend has verified the integratity of the purchase. You can safely deliver the related content to the end user.false
: Your backend has rejected the integratity of the purchase (Could be expired or fraudulent). You should not deliver the content.null
: If you have a backend, your backend is verifying it (response expected soon). You should wait before deliver the content. If you DON'T have a backend, you can consider that the purchase is valid (the authenticity cannot be garanteed though).
3. Actions
GetProductsAction
: Query the stores to get the Produc's object.RestorePurchaseAction
: Restore the products and query your backend if any to verify the integrity.PurchaseProductAction
: Purchase the product (productID needed).
4. Extensions
extensions/extProduct.dart
: This extension allows you to know if a given product is valid right away:
import 'package:puma_pay/extensions/extProduct.dart';
...
final myProduct = store.state.pumaPayState.products.first;
if (myProduct.isValid()) {
// do stuff
}
5. Debug Page
The package comes with a complete debug page: PumaPayDebugContainer
.
You can add this container to your app abd view the important part of PumaPayState.
Libraries
- constants
- entities/appStoreReceipt/appStoreReceipt
- entities/appStoreReceiptValidationResult/appStoreReceiptValidationResult
- entities/product/product
- entities/purchaseDetail/purchaseDetail
- extensions/extAppStoreReceipt
- extensions/extProduct
- extensions/extProductDetail
- extensions/extPurchaseDetail
- extensions/extPurchaseDetails
- helpers/appStore
- paymentService
- puma_pay
- redux/pumaPayActions
- redux/pumaPayMiddleware
- redux/pumaPayReducer
- redux/pumaPayState
- serializers
- streamSubscriptionSingleton
- ui/atoms/appStoreReceiptTile
- ui/atoms/purchaseDetailTile
- ui/templates/PumaPayDebugTemplate
- ui/templates/purchaseDetailTemplate