Skip to main content

Packages

A Package is the technical, purchasable unit in SolydFlow. While a Product defines your high-level offering, every transaction processed by the SDK, hosted checkout, or API is executed against a specific Package.

A Package supports one currency only. To sell the same Product across multiple countries or app stores, you configure multiple Packages under the same Product.


Package Data Model & Fields​

When you fetch packages via the SDK, SolydFlow returns SolydPackage objects containing:

FieldTypeDescription
identifierStringUnique SDK slug (e.g., pro_monthly_ngn, pro_yearly_usd).
nameStringDisplay title inherited from Product (e.g., Pro Monthly).
currencyStringISO currency code (NGN, KES, GHS, ZAR, USD, EUR).
amountMinorintBase price in the smallest currency unit (kobo/cents).
isUpgradebooltrue if customer has an active lower tier eligible for pro-rated credit.
calculatedAmountMinorintPro-rated upgrade price if isUpgrade == true.
durationStringBilling period (P1M, P1Y, P1W, or lifetime).
appleProductIdString?(Optional) StoreKit Product ID (e.g., com.app.pro.monthly).
googleProductIdString?(Optional) Google Play In-App Product ID.

Working with Packages in Code​

1. Fetching & Inspecting Packages​

When fetching offerings, inspect isUpgrade to display upgrade credits dynamically:

lib/screens/pricing_screen.dart
import 'package:flutter/material.dart';
import 'package:solydflow_flutter/solydflow_flutter.dart';

Future<void> displayOfferings() async {
List<SolydPackage> packages = await SolydFlow.getOfferings();

for (var pkg in packages) {
if (pkg.isUpgrade) {
final double upgradePrice = pkg.calculatedAmountMinor;
debugPrint("Upgrade to ${pkg.name} for ${pkg.currency} $upgradePrice");
} else {
final double standardPrice = pkg.amountMinor;
debugPrint("${pkg.name}: ${pkg.currency} $standardPrice / ${pkg.duration}");
}
}
}

2. Purchasing a Specific Package​

Pass the chosen package identifier directly to purchasePackage:

lib/screens/checkout.dart
Future<void> checkoutPackage(BuildContext context, String packageId) async {
try {
final CustomerInfo? info = await SolydFlow.purchasePackage(
context,
packageId, // e.g., "pro_monthly_ngn"
);

if (info?.activeEntitlements["pro_access"] == true) {
debugPrint("Access granted via package: $packageId");
}
} catch (e) {
debugPrint("Purchase failed: $e");
}
}

Automatic Geo-IP Package Resolution​

When your frontend requests offerings without specifying a package ID, SolydFlow's Smart Payment Router automatically resolves the customer's country via IP and serves the most relevant regional Package:

If a customer is outside your defined currency markets, SolydFlow automatically falls back to your base currency package (typically USD).