With Google now requiring a way to cancel subscriptions in the app, we had to add a REST call to our Flutter app (using the endpoint from here), as this isn’t supported by purchases_flutter.
When we call, though, we get a 401 with a response of {“code”: 7225, “message”:”Invalid API Key”}
.
static Future<bool> cancelSubscription(Package package) async {
try {
var options = Options(headers: {
'Accept': 'application/json',
'Authorization': 'Bearer $apiKey',
'Content-Type': 'application/json',
});
var response = await Dio().post('https://api.revenuecat.com/v1/subscribers/$appUserId/subscriptions/${package.product.identifier}/revoke', options: options);
return response.statusCode != null && response.statusCode == 200;
}
catch (ex) {
if (kDebugMode) print(ex);
}
return false;
}
I can recreate this easily in cURL as well.
curl --request POST --url https://api.revenuecat.com/v1/subscribers/zzzzzzzzzzzzzzzzzzz/subscriptions/chip_subscription_1m/revoke --header "Accept: application/json" --header "Authorization: Bearer goog_Oxxxxxxxxxxxxxxxxxxxxxxxxxx" --header "Content-Type: application/json"
The key being sent in the header is the same as used in the initialization of the flutter library:
static Future<void> init(String playerId) async {
apiKey = Platform.isAndroid
? dotenv.get('revenuecat_api_android')
: dotenv.get('revenuecat_api_ios');
appUserId = playerId;
await Purchases.setDebugLogsEnabled(kDebugMode);
await Purchases.setup(apiKey, appUserId: playerId);
}
Since it works for the library, I would kind of expect it to be work for the REST interface. Does it need to be encoded or anything strange?
Figured it out - RevenueCat has two kinds of API Keys. There are app-specific API Keys, and Secret API Keys (used to "access additional API functions"), Just needed to create one of the latter (and add it to the keystore). Not sure why they chose to let you create with one API Key, and have to cancel with a different one . . .