Skip to main content

gemicore_flutter 0.4.0 copy "gemicore_flutter: ^0.4.0" to clipboard
gemicore_flutter: ^0.4.0 copied to clipboard

Purchases for Flutter: App Store and Google Play subscriptions, offerings and paywalls, card, Apple Pay and Google Pay payments, and entitlements with one API key.

0.4.0 #

  • One package: the Apple Pay and Google Pay sheet that shipped separately as gemicore_flutter_stripe is part of gemicore_flutter now. GemicoreStripePaySheet is exported from here and is the default for payWithSheet, so Gemicore.configure(apiKey: ...) is the whole setup and nativePaySheet is only for replacing it. flutter_stripe ^14.2.0 is a dependency, which means every app needs iOS 15 or higher and the Android settings listed in the README (compileSdk 36, Java 17); the Apple Pay capability, FlutterFragmentActivity and an AppCompat theme are needed only to show the sheet.
  • Removed GemicoreErrorCode.nativePayNotConfigured: there is always a sheet now.

0.3.0 #

  • Customer attributes: setAttributes(Map<String, String?>) (a null value deletes the key), setEmail, setDisplayName and setPhoneNumber. The server limits are checked before the request (50 keys per call, key pattern, 256 characters, only the reserved $ names) and fail with GemicoreErrorCode.invalidAttributes; the server's own refusal is GemicoreErrorCode.attributesInvalid. Values are never logged and never put in an error.
  • Context headers on every request: x-gemicore-app-version (from package_info_plus, or the new appVersionProvider of configure; left out when the lookup fails, as it does under flutter test unless a provider is passed) and x-gemicore-country (the device locale's two letter country code, upper case, left out when there is none), next to x-gemicore-platform. The API key is still the only required setting.
  • Placements: getOfferings(placement:) and presentPaywall(context, placement:). Offerings.placement says how the server resolved it (PlacementResolution: identifier, source, and the experiment identifier and variant). Each placement has its own five minute memory copy and its own copy on the device. A placement the server does not know or rejects gives the app's current offering. Experiments need no extra call: reading the placement enrolls the customer on the server.
  • Android default offer: when a Google subscription is bought with no explicit offer, the offer named by the product's defaultGoogleOfferId is bought if Play lists it for the base plan (Play lists only the offers the customer is eligible for), otherwise the plain base plan as before. {{package.trial}} on Android now shows the trial of that offer. New fields: GemicoreProduct.defaultGoogleOfferId and defaultOfferDetails, ProductOffer.isDefault.
  • Customer Center: getCustomerCenter(), CustomerCenterView and CustomerCenterConfig (strings by locale with built in English for every label, see customerCenterEnglish), the GemicoreCustomerCenter widget and presentCustomerCenter(context), which returns false without showing anything while the dashboard has it off. It summarizes the active entitlements and subscriptions, opens the store page that manages a subscription, restores purchases, opens the store's own refund help (Apple Report a Problem or Google order history, by the store of the purchase), reaches support, and runs the cancel flow: survey, then an eligible retention offer through the normal promotional offer purchase, then the store's management page. It never cancels anything itself; cancellation happens in the store. sendCancelFeedback posts the survey answer, and a failure there never blocks the customer.
  • ExternalUrlOpener (implemented by the default opener): the Customer Center opens store pages and mailto links outside the app when the opener can, and Gemicore.openExternalUrl and Gemicore.platform are new.
  • Offerings copies belong to the customer: logIn, logOut and setAttributes drop the memory copy (and setAttributes the device copy of what was read), and a device copy saved for another customer is ignored. An offline first read of a placement falls back to the app's saved offerings.
  • Customer Center details: retention offers are shown for App Store subscriptions only (a Google Play offer needs a replacement purchase, not built yet); a pending purchase shows retention_pending and is sent as not accepted; the screen reloads the server's view after an offer or a retry; the survey answer is sent in the background and not at all when the offer dialog is dismissed; the capitalised store name has its own key store_app_store_title; a malformed support url says error_generic. Gemicore.openExternalUrl takes an optional opener.
  • The default app version lookup no longer holds configure and no longer checks FLUTTER_TEST; a provider passed to configure is still awaited, for up to three seconds.
  • Adds the package_info_plus dependency.

0.2.0 #

  • Offerings: getOfferings() (cached in memory for five minutes and kept on the device for an offline start), currentOffering, Offering and Package models with store prices merged in, and purchasePackage(package).
  • Paywalls: the GemicorePaywall widget draws the paywall designed in the dashboard (every node type, theme, strings by device locale, store price variables, text scale, semantics, right to left, https images, injectable link opener) and presentPaywall(context) shows it full screen and returns a PaywallResult. Unknown or malformed nodes are left out and never throw.
  • Promotions: getEligibleOffers(product) and purchase(product, offer:) for App Store promotional and win-back offers and Google Play base plan offers. Server side introductory offer eligibility is available as the opt in useServerIntroEligibility.
  • Refund reviews: setConsumptionConsent(bool), with the answer kept in CustomerInfo.consumptionConsent.
  • Native pay: the NativePaySheet interface, the nativePaySheet parameter of configure and payWithSheet(product, email:); the sheet itself is in the gemicore_flutter_stripe package.
  • Breaking for custom store bridges: StoreBridge.buy takes an optional offer, and StoreProductDetails has offerId, subscriptionPeriod and trialPeriod. basePlanId is now set on Google Play offer entries too; the plain base plan is the entry with no offerId.
  • Adds the intl dependency, for the per month price on paywalls.
  • Verified identity: the optional userTokenProvider of configure sends x-user-token when a customer is linked to an app user id (configure(appUserId:) and logIn).
  • Store updates are held until configure has the customer token, and a purchase the server could not take is retried on a timer, on resume and after logIn.
  • A failed configure closes the instance it started, so a retry does not run two store listeners.
  • A failing cache write (locked Keychain) no longer fails a recorded purchase or a customer refresh.
  • hasEntitlement no longer reports an entitlement active after its expiry, grace period aside.
  • A store that was unavailable once is asked again, and a failed availability check no longer sends a test key to the test store.
  • Card and sheet polling: no stream emit or cache write for unchanged data, an optional cancel: future, and a failed, expired or refunded payment throws GemicoreErrorCode.paymentFailed instead of returning a cancelled result.
  • restorePurchases() called while a restore runs returns that restore.
  • Card sale declaration: the server refuses card checkout for a product whose card price was never declared as physical goods or a real world service (422 PURCHASE_NOT_FOR_CARD, reason card_sale_kind_missing). payWithCard and payWithSheet throw GemicoreErrorCode.cardSaleNotDeclared for it, with a message that says what to declare in the dashboard. A product with no card price at all still throws notForCard.
  • NativePayRequest.merchantDisplayName (the app's name, from the card intent) for the payment sheet; empty from a server that does not send it.
  • presentPaywall keeps the paywall open and shows the message for a network error or a purchase already in progress; hero images are decoded at the drawn width.

0.1.0 #

  • First release: Gemicore.configure(apiKey:) as the only setup, anonymous customers with log in and log out, the dashboard product catalog with store prices, App Store and Google Play purchases recorded with Gemicore before the store transaction is finished, restore, one-time card, Apple Pay and Google Pay payments through the app's gateway, customer info with an offline cache and a change stream, and the Gemicore test store for test keys.
0
likes
140
points
--
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Purchases for Flutter: App Store and Google Play subscriptions, offerings and paywalls, card, Apple Pay and Google Pay payments, and entitlements with one API key.

Homepage
Repository (GitHub)
View/report issues

Topics

#in-app-purchase #subscriptions #paywall #payments #monetization

License

Apache-2.0 (license)

Dependencies

flutter, flutter_secure_storage, flutter_stripe, http, in_app_purchase, in_app_purchase_android, in_app_purchase_storekit, intl, package_info_plus, url_launcher

More

Packages that depend on gemicore_flutter