Skip to main content

8.2.5 - ExternalPurchaseCustomLink API (iOS 18.1+)

· 3 min read
Hyo
Maintainer of flutter_inapp_purchase & expo-iap

flutter_inapp_purchase 8.2.5 adds support for Apple's ExternalPurchaseCustomLink API (iOS 18.1+) for apps using custom external purchase links.

New Features

The ExternalPurchaseCustomLink API enables apps to use custom external purchase links with token-based reporting to Apple. This is for apps that have been granted an entitlement to link out to external purchases.

Reference: ExternalPurchaseCustomLink Documentation

New APIs

isEligibleForExternalPurchaseCustomLinkIOS()

Check if your app is eligible to use the ExternalPurchaseCustomLink API.

import 'package:flutter_inapp_purchase/flutter_inapp_purchase.dart';

final iap = FlutterInappPurchase.instance;
final isEligible = await iap.isEligibleForExternalPurchaseCustomLinkIOS();
if (isEligible) {
// App can use custom external purchase links
}

getExternalPurchaseCustomLinkTokenIOS(tokenType)

Get an external purchase token for reporting to Apple's External Purchase Server API.

// For new customer acquisition
final acquisitionResult = await iap.getExternalPurchaseCustomLinkTokenIOS(
ExternalPurchaseCustomLinkTokenTypeIOS.Acquisition,
);
if (acquisitionResult.token != null) {
// Report to Apple's External Purchase Server API
await reportToApple(acquisitionResult.token!);
}

// For existing customer services
final servicesResult = await iap.getExternalPurchaseCustomLinkTokenIOS(
ExternalPurchaseCustomLinkTokenTypeIOS.Services,
);
if (servicesResult.token != null) {
await reportToApple(servicesResult.token!);
}

showExternalPurchaseCustomLinkNoticeIOS(noticeType)

Display the system disclosure notice sheet before linking out to external purchases.

final result = await iap.showExternalPurchaseCustomLinkNoticeIOS(
ExternalPurchaseCustomLinkNoticeTypeIOS.Browser,
);
if (result.continued) {
// User agreed to continue to external purchase
// Now open your external purchase link
await launchUrl(Uri.parse('https://your-store.com/checkout'));
} else {
// User cancelled
}

Updated: presentExternalPurchaseNoticeSheetIOS()

Now returns externalPurchaseToken when user continues to external purchase.

final result = await iap.presentExternalPurchaseNoticeSheetIOS();
if (result.result == ExternalPurchaseNoticeAction.Continue) {
print('Token: ${result.externalPurchaseToken}');
// Report this token to Apple's External Purchase Server API
}

New Types

// Token types for getExternalPurchaseCustomLinkTokenIOS
enum ExternalPurchaseCustomLinkTokenTypeIOS {
Acquisition('acquisition'),
Services('services');
}

// Notice types for showExternalPurchaseCustomLinkNoticeIOS
enum ExternalPurchaseCustomLinkNoticeTypeIOS {
Browser('browser');
}

// Result of token retrieval
class ExternalPurchaseCustomLinkTokenResultIOS {
final String? token;
final String? error;
}

// Result of showing notice
class ExternalPurchaseCustomLinkNoticeResultIOS {
final bool continued;
final String? error;
}
import 'dart:io';
import 'package:flutter_inapp_purchase/flutter_inapp_purchase.dart';
import 'package:url_launcher/url_launcher.dart';

class ExternalPurchaseCustomLinkExample {
final iap = FlutterInappPurchase.instance;
bool isEligible = false;

Future<void> checkEligibility() async {
if (!Platform.isIOS) return;
isEligible = await iap.isEligibleForExternalPurchaseCustomLinkIOS();
}

Future<void> handleExternalPurchase() async {
if (!isEligible) return;

// Step 1: Show disclosure notice
final noticeResult = await iap.showExternalPurchaseCustomLinkNoticeIOS(
ExternalPurchaseCustomLinkNoticeTypeIOS.Browser,
);
if (!noticeResult.continued) {
print('User cancelled');
return;
}

// Step 2: Get token for reporting
final tokenResult = await iap.getExternalPurchaseCustomLinkTokenIOS(
ExternalPurchaseCustomLinkTokenTypeIOS.Acquisition,
);
if (tokenResult.error != null) {
print('Failed to get token: ${tokenResult.error}');
return;
}

// Step 3: Open external purchase link
await launchUrl(Uri.parse('https://your-store.com/checkout'));

// Step 4: After purchase completes, report to Apple
if (tokenResult.token != null) {
await reportExternalPurchaseToApple(tokenResult.token!);
}
}
}

OpenIAP Updates

PackageVersion
openiap-gql1.3.16
openiap-apple1.3.14
openiap-google1.3.27

Installation

dependencies:
flutter_inapp_purchase: ^8.2.5

References

Questions or feedback? Reach out via GitHub issues.