@revenuecat/purchases-capacitor 6.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,699 @@
1
+ package com.revenuecat.purchases.capacitor
2
+
3
+ import android.app.Activity
4
+ import android.util.Log
5
+ import com.getcapacitor.JSArray
6
+ import com.getcapacitor.JSObject
7
+ import com.getcapacitor.Plugin
8
+ import com.getcapacitor.PluginCall
9
+ import com.getcapacitor.PluginMethod
10
+ import com.getcapacitor.annotation.CapacitorPlugin
11
+ import com.revenuecat.purchases.CustomerInfo
12
+ import com.revenuecat.purchases.Purchases
13
+ import com.revenuecat.purchases.Store
14
+ import com.revenuecat.purchases.common.PlatformInfo
15
+ import com.revenuecat.purchases.hybridcommon.ErrorContainer
16
+ import com.revenuecat.purchases.hybridcommon.OnResult
17
+ import com.revenuecat.purchases.hybridcommon.OnResultAny
18
+ import com.revenuecat.purchases.hybridcommon.OnResultList
19
+ import com.revenuecat.purchases.hybridcommon.configure
20
+ import com.revenuecat.purchases.hybridcommon.getProductInfo
21
+ import com.revenuecat.purchases.hybridcommon.mappers.convertToMap
22
+ import com.revenuecat.purchases.hybridcommon.mappers.map
23
+ import com.revenuecat.purchases.hybridcommon.purchaseProduct
24
+ import com.revenuecat.purchases.interfaces.UpdatedCustomerInfoListener
25
+ import com.revenuecat.purchases.hybridcommon.canMakePayments as canMakePaymentsCommon
26
+ import com.revenuecat.purchases.hybridcommon.checkTrialOrIntroductoryPriceEligibility as checkTrialOrIntroductoryPriceEligibilityCommon
27
+ import com.revenuecat.purchases.hybridcommon.collectDeviceIdentifiers as collectDeviceIdentifiersCommon
28
+ import com.revenuecat.purchases.hybridcommon.getAppUserID as getAppUserIDCommon
29
+ import com.revenuecat.purchases.hybridcommon.getCustomerInfo as getCustomerInfoCommon
30
+ import com.revenuecat.purchases.hybridcommon.getOfferings as getOfferingsCommon
31
+ import com.revenuecat.purchases.hybridcommon.invalidateCustomerInfoCache as invalidateCustomerInfoCacheCommon
32
+ import com.revenuecat.purchases.hybridcommon.isAnonymous as isAnonymousCommon
33
+ import com.revenuecat.purchases.hybridcommon.logIn as logInCommon
34
+ import com.revenuecat.purchases.hybridcommon.logOut as logOutCommon
35
+ import com.revenuecat.purchases.hybridcommon.purchasePackage as purchasePackageCommon
36
+ import com.revenuecat.purchases.hybridcommon.purchaseSubscriptionOption as purchaseSubscriptionOptionCommon
37
+ import com.revenuecat.purchases.hybridcommon.restorePurchases as restorePurchasesCommon
38
+ import com.revenuecat.purchases.hybridcommon.setAd as setAdCommon
39
+ import com.revenuecat.purchases.hybridcommon.setAdGroup as setAdGroupCommon
40
+ import com.revenuecat.purchases.hybridcommon.setAdjustID as setAdjustIDCommon
41
+ import com.revenuecat.purchases.hybridcommon.setAirshipChannelID as setAirshipChannelIDCommon
42
+ import com.revenuecat.purchases.hybridcommon.setAppsflyerID as setAppsflyerIDCommon
43
+ import com.revenuecat.purchases.hybridcommon.setAttributes as setAttributesCommon
44
+ import com.revenuecat.purchases.hybridcommon.setCampaign as setCampaignCommon
45
+ import com.revenuecat.purchases.hybridcommon.setCleverTapID as setCleverTapIDCommon
46
+ import com.revenuecat.purchases.hybridcommon.setCreative as setCreativeCommon
47
+ import com.revenuecat.purchases.hybridcommon.setDisplayName as setDisplayNameCommon
48
+ import com.revenuecat.purchases.hybridcommon.setEmail as setEmailCommon
49
+ import com.revenuecat.purchases.hybridcommon.setFBAnonymousID as setFBAnonymousIDCommon
50
+ import com.revenuecat.purchases.hybridcommon.setFinishTransactions as setFinishTransactionsCommon
51
+ import com.revenuecat.purchases.hybridcommon.setFirebaseAppInstanceID as setFirebaseAppInstanceIDCommon
52
+ import com.revenuecat.purchases.hybridcommon.setKeyword as setKeywordCommon
53
+ import com.revenuecat.purchases.hybridcommon.setLogHandler as setLogHandlerCommon
54
+ import com.revenuecat.purchases.hybridcommon.setLogLevel as setLogLevelCommon
55
+ import com.revenuecat.purchases.hybridcommon.setMediaSource as setMediaSourceCommon
56
+ import com.revenuecat.purchases.hybridcommon.setMixpanelDistinctID as setMixpanelDistinctIDCommon
57
+ import com.revenuecat.purchases.hybridcommon.setMparticleID as setMparticleIDCommon
58
+ import com.revenuecat.purchases.hybridcommon.setOnesignalID as setOnesignalIDCommon
59
+ import com.revenuecat.purchases.hybridcommon.setPhoneNumber as setPhoneNumberCommon
60
+ import com.revenuecat.purchases.hybridcommon.setProxyURLString as setProxyURLStringCommon
61
+ import com.revenuecat.purchases.hybridcommon.setPushToken as setPushTokenCommon
62
+ import com.revenuecat.purchases.hybridcommon.syncPurchases as syncPurchasesCommon
63
+
64
+ @Suppress("unused")
65
+ @CapacitorPlugin(name = "Purchases")
66
+ class PurchasesPlugin : Plugin() {
67
+ private val customerInfoListeners = mutableListOf<String>()
68
+ private val lastSeenCustomerInfo: CustomerInfo? = null
69
+ private var logHandlerCallbackId: String? = null
70
+
71
+ companion object {
72
+ private const val PLATFORM_NAME = "capacitor"
73
+ private const val PLUGIN_VERSION = "6.0.0-beta.1"
74
+
75
+ private const val CUSTOMER_INFO_KEY = "customerInfo"
76
+ }
77
+
78
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
79
+ fun configure(call: PluginCall) {
80
+ val apiKey = call.getStringOrReject("apiKey") ?: return
81
+ val appUserID = call.getString("appUserID")
82
+ val observerMode = call.getBoolean("observerMode")
83
+ val useAmazon = call.getBoolean("useAmazon")
84
+ val store = if (useAmazon == true) Store.AMAZON else Store.PLAY_STORE
85
+ val platformInfo = PlatformInfo(PLATFORM_NAME, PLUGIN_VERSION)
86
+ configure(
87
+ context.applicationContext,
88
+ apiKey,
89
+ appUserID,
90
+ observerMode,
91
+ platformInfo,
92
+ store,
93
+ )
94
+ Purchases.sharedInstance.updatedCustomerInfoListener = UpdatedCustomerInfoListener { customerInfo ->
95
+ for (callbackId in customerInfoListeners) {
96
+ bridge.getSavedCall(callbackId)?.resolveWithMap(customerInfo.map())
97
+ }
98
+ }
99
+ call.resolve()
100
+ }
101
+
102
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
103
+ fun setFinishTransactions(call: PluginCall) {
104
+ if (rejectIfNotConfigured(call)) return
105
+ val finishTransactions = call.getBooleanOrReject("finishTransactions") ?: return
106
+ setFinishTransactionsCommon(finishTransactions)
107
+ call.resolve()
108
+ }
109
+
110
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
111
+ fun setSimulatesAskToBuyInSandbox(call: PluginCall) {
112
+ logNotSupportedFunctionalityInAndroid("setSimulatesAskToBuyInSandbox")
113
+ call.resolve()
114
+ }
115
+
116
+ @PluginMethod(returnType = PluginMethod.RETURN_CALLBACK)
117
+ fun addCustomerInfoUpdateListener(call: PluginCall) {
118
+ if (rejectIfNotConfigured(call)) return
119
+ customerInfoListeners.add(call.callbackId)
120
+ call.setKeepAlive(true)
121
+ lastSeenCustomerInfo?.let { call.resolveWithMap(it.map()) }
122
+ }
123
+
124
+ @PluginMethod(returnType = PluginMethod.RETURN_PROMISE)
125
+ fun removeCustomerInfoUpdateListener(call: PluginCall) {
126
+ if (rejectIfNotConfigured(call)) return
127
+ val callbackIDToRemove = call.getStringOrReject("callbackID") ?: return
128
+ val wasRemoved = customerInfoListeners.remove(callbackIDToRemove)
129
+ bridge?.getSavedCall(callbackIDToRemove)?.setKeepAlive(false)
130
+ call.resolveWithMap(mapOf("wasRemoved" to wasRemoved))
131
+ }
132
+
133
+ @PluginMethod(returnType = PluginMethod.RETURN_PROMISE)
134
+ fun getOfferings(call: PluginCall) {
135
+ if (rejectIfNotConfigured(call)) return
136
+ getOfferingsCommon(getOnResult(call))
137
+ }
138
+
139
+ @PluginMethod(returnType = PluginMethod.RETURN_PROMISE)
140
+ fun getProducts(call: PluginCall) {
141
+ if (rejectIfNotConfigured(call)) return
142
+ val productIdentifiers = call.getArrayOrReject("productIdentifiers") ?: return
143
+ val type = call.getString("type") ?: "SUBSCRIPTION"
144
+ getProductInfo(productIdentifiers.toList(), type, object : OnResultList {
145
+ override fun onReceived(map: List<Map<String, Any?>>) {
146
+ val ret = JSObject()
147
+ ret.put("products", convertListToJSArray(map))
148
+ call.resolve(ret)
149
+ }
150
+
151
+ override fun onError(errorContainer: ErrorContainer) {
152
+ rejectWithErrorContainer(call, errorContainer)
153
+ }
154
+ })
155
+ }
156
+
157
+ @PluginMethod(returnType = PluginMethod.RETURN_PROMISE)
158
+ fun purchaseStoreProduct(call: PluginCall) {
159
+ if (rejectIfNotConfigured(call)) return
160
+ val storeProduct = call.getObjectOrReject("product") ?: return
161
+ val productIdentifier = storeProduct.getStringOrReject(call, "identifier") ?: return
162
+ val type = storeProduct.getStringOrReject(call, "productCategory") ?: return
163
+ val presentedOfferingIdentifier = storeProduct.getString("presentedOfferingIdentifier")
164
+ val optionalPurchaseParams = PurchaseOptionalInfoParams.fromCall(call)
165
+ purchaseProduct(
166
+ activity,
167
+ productIdentifier,
168
+ type,
169
+ googleBasePlanId = null,
170
+ optionalPurchaseParams.oldProductIdentifier,
171
+ optionalPurchaseParams.prorationMode,
172
+ optionalPurchaseParams.isPersonalizedPrice,
173
+ presentedOfferingIdentifier,
174
+ getOnResult(call),
175
+ )
176
+ }
177
+
178
+ @PluginMethod(returnType = PluginMethod.RETURN_PROMISE)
179
+ fun purchaseDiscountedProduct(call: PluginCall) {
180
+ rejectNotSupportedInAndroid(call, "purchaseDiscountedProduct")
181
+ }
182
+
183
+ @PluginMethod(returnType = PluginMethod.RETURN_PROMISE)
184
+ fun purchaseDiscountedPackage(call: PluginCall) {
185
+ rejectNotSupportedInAndroid(call, "purchaseDiscountedPackage")
186
+ }
187
+
188
+ @PluginMethod(returnType = PluginMethod.RETURN_PROMISE)
189
+ fun purchasePackage(call: PluginCall) {
190
+ if (rejectIfNotConfigured(call)) return
191
+ val packageToPurchase = call.getObjectOrReject("aPackage") ?: return
192
+ val packageIdentifier = packageToPurchase.getStringOrReject(call, "identifier") ?: return
193
+ val offeringIdentifier = packageToPurchase.getStringOrReject(call, "offeringIdentifier") ?: return
194
+ val optionalPurchaseParams = PurchaseOptionalInfoParams.fromCall(call)
195
+
196
+ purchasePackageCommon(
197
+ activity,
198
+ packageIdentifier,
199
+ offeringIdentifier,
200
+ optionalPurchaseParams.oldProductIdentifier,
201
+ optionalPurchaseParams.prorationMode,
202
+ optionalPurchaseParams.isPersonalizedPrice,
203
+ getOnResult(call),
204
+ )
205
+ }
206
+
207
+ @PluginMethod(returnType = PluginMethod.RETURN_PROMISE)
208
+ fun purchaseSubscriptionOption(call: PluginCall) {
209
+ if (rejectIfNotConfigured(call)) return
210
+ val subscriptionOption = call.getObjectOrReject("subscriptionOption") ?: return
211
+ val productId = subscriptionOption.getStringOrReject(call, "productId") ?: return
212
+ val subscriptionOptionId = subscriptionOption.getStringOrReject(call, "id") ?: return
213
+ val presentedOfferingIdentifier = subscriptionOption.getString("presentedOfferingIdentifier")
214
+ val optionalPurchaseParams = PurchaseOptionalInfoParams.fromCall(call)
215
+
216
+ purchaseSubscriptionOptionCommon(
217
+ activity,
218
+ productId,
219
+ subscriptionOptionId,
220
+ optionalPurchaseParams.oldProductIdentifier,
221
+ optionalPurchaseParams.prorationMode,
222
+ optionalPurchaseParams.isPersonalizedPrice,
223
+ presentedOfferingIdentifier,
224
+ getOnResult(call),
225
+ )
226
+ }
227
+
228
+ @PluginMethod(returnType = PluginMethod.RETURN_PROMISE)
229
+ fun restorePurchases(call: PluginCall) {
230
+ if (rejectIfNotConfigured(call)) return
231
+ restorePurchasesCommon(getOnResult(call, CUSTOMER_INFO_KEY))
232
+ }
233
+
234
+ @PluginMethod(returnType = PluginMethod.RETURN_PROMISE)
235
+ fun getAppUserID(call: PluginCall) {
236
+ if (rejectIfNotConfigured(call)) return
237
+ call.resolveWithMap(mapOf("appUserID" to getAppUserIDCommon()))
238
+ }
239
+
240
+ @PluginMethod(returnType = PluginMethod.RETURN_PROMISE)
241
+ fun logIn(call: PluginCall) {
242
+ if (rejectIfNotConfigured(call)) return
243
+ val appUserID = call.getStringOrReject("appUserID") ?: return
244
+ logInCommon(appUserID, getOnResult(call))
245
+ }
246
+
247
+ @PluginMethod(returnType = PluginMethod.RETURN_PROMISE)
248
+ fun logOut(call: PluginCall) {
249
+ if (rejectIfNotConfigured(call)) return
250
+ logOutCommon(getOnResult(call, CUSTOMER_INFO_KEY))
251
+ }
252
+
253
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
254
+ fun setLogLevel(call: PluginCall) {
255
+ val logLevel = call.getStringOrReject("level") ?: return
256
+ setLogLevelCommon(logLevel)
257
+ }
258
+
259
+ @PluginMethod(returnType = PluginMethod.RETURN_CALLBACK)
260
+ fun setLogHandler(call: PluginCall) {
261
+ bridge.getSavedCall(logHandlerCallbackId)?.setKeepAlive(false)
262
+ call.setKeepAlive(true)
263
+ logHandlerCallbackId = call.callbackId
264
+ setLogHandlerCommon {
265
+ call.resolve(convertMapToJSObject(it))
266
+ }
267
+ }
268
+
269
+ @PluginMethod(returnType = PluginMethod.RETURN_PROMISE)
270
+ fun getCustomerInfo(call: PluginCall) {
271
+ if (rejectIfNotConfigured(call)) return
272
+ getCustomerInfoCommon(getOnResult(call, CUSTOMER_INFO_KEY))
273
+ }
274
+
275
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
276
+ fun syncPurchases(call: PluginCall) {
277
+ if (rejectIfNotConfigured(call)) return
278
+ syncPurchasesCommon()
279
+ call.resolve()
280
+ }
281
+
282
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
283
+ fun syncObserverModeAmazonPurchase(call: PluginCall) {
284
+ if (rejectIfNotConfigured(call)) return
285
+ val productID = call.getStringOrReject("productID") ?: return
286
+ val receiptID = call.getStringOrReject("receiptID") ?: return
287
+ val amazonUserID = call.getStringOrReject("amazonUserID") ?: return
288
+ val isoCurrencyCode = call.getString("isoCurrencyCode")
289
+ val price = call.getDouble("price")
290
+ Purchases.sharedInstance.syncObserverModeAmazonPurchase(
291
+ productID,
292
+ receiptID,
293
+ amazonUserID,
294
+ isoCurrencyCode,
295
+ price,
296
+ )
297
+ call.resolve()
298
+ }
299
+
300
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
301
+ fun enableAdServicesAttributionTokenCollection(call: PluginCall) {
302
+ logNotSupportedFunctionalityInAndroid("enableAdServicesAttributionTokenCollection")
303
+ call.resolve()
304
+ }
305
+
306
+ @PluginMethod(returnType = PluginMethod.RETURN_PROMISE)
307
+ fun isAnonymous(call: PluginCall) {
308
+ if (rejectIfNotConfigured(call)) return
309
+ call.resolveWithMap(mapOf("isAnonymous" to isAnonymousCommon()))
310
+ }
311
+
312
+ @PluginMethod(returnType = PluginMethod.RETURN_PROMISE)
313
+ fun checkTrialOrIntroductoryPriceEligibility(call: PluginCall) {
314
+ if (rejectIfNotConfigured(call)) return
315
+ val productIdentifiers = call.getArrayOrReject("productIdentifiers") ?: return
316
+ val eligibilityMap = checkTrialOrIntroductoryPriceEligibilityCommon(productIdentifiers.toList())
317
+ call.resolveWithMap(eligibilityMap)
318
+ }
319
+
320
+ @PluginMethod(returnType = PluginMethod.RETURN_PROMISE)
321
+ fun getPromotionalOffer(call: PluginCall) {
322
+ logNotSupportedFunctionalityInAndroid("getPromotionalOffer")
323
+ call.resolve()
324
+ }
325
+
326
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
327
+ fun invalidateCustomerInfoCache(call: PluginCall) {
328
+ if (rejectIfNotConfigured(call)) return
329
+ invalidateCustomerInfoCacheCommon()
330
+ call.resolve()
331
+ }
332
+
333
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
334
+ fun presentCodeRedemptionSheet(call: PluginCall) {
335
+ logNotSupportedFunctionalityInAndroid("presentCodeRedemptionSheet")
336
+ call.resolve()
337
+ }
338
+
339
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
340
+ fun setAttributes(call: PluginCall) {
341
+ if (rejectIfNotConfigured(call)) return
342
+ val attributes = call.getObject("attributes")?.convertToMap() ?: emptyMap()
343
+ setAttributesCommon(attributes)
344
+ call.resolve()
345
+ }
346
+
347
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
348
+ fun setEmail(call: PluginCall) {
349
+ if (rejectIfNotConfigured(call)) return
350
+ val email = call.getString("email")
351
+ setEmailCommon(email)
352
+ call.resolve()
353
+ }
354
+
355
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
356
+ fun setPhoneNumber(call: PluginCall) {
357
+ if (rejectIfNotConfigured(call)) return
358
+ val phoneNumber = call.getString("phoneNumber")
359
+ setPhoneNumberCommon(phoneNumber)
360
+ call.resolve()
361
+ }
362
+
363
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
364
+ fun setDisplayName(call: PluginCall) {
365
+ if (rejectIfNotConfigured(call)) return
366
+ val displayName = call.getString("displayName")
367
+ setDisplayNameCommon(displayName)
368
+ call.resolve()
369
+ }
370
+
371
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
372
+ fun setPushToken(call: PluginCall) {
373
+ if (rejectIfNotConfigured(call)) return
374
+ val pushToken = call.getString("pushToken")
375
+ setPushTokenCommon(pushToken)
376
+ call.resolve()
377
+ }
378
+
379
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
380
+ fun setProxyURL(call: PluginCall) {
381
+ if (rejectIfNotConfigured(call)) return
382
+ val urlString = call.getString("url")
383
+ setProxyURLStringCommon(urlString)
384
+ call.resolve()
385
+ }
386
+
387
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
388
+ fun collectDeviceIdentifiers(call: PluginCall) {
389
+ if (rejectIfNotConfigured(call)) return
390
+ collectDeviceIdentifiersCommon()
391
+ call.resolve()
392
+ }
393
+
394
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
395
+ fun setAdjustID(call: PluginCall) {
396
+ if (rejectIfNotConfigured(call)) return
397
+ val adjustID = call.getString("adjustID")
398
+ setAdjustIDCommon(adjustID)
399
+ call.resolve()
400
+ }
401
+
402
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
403
+ fun setAppsflyerID(call: PluginCall) {
404
+ if (rejectIfNotConfigured(call)) return
405
+ val appsflyerID = call.getString("appsflyerID")
406
+ setAppsflyerIDCommon(appsflyerID)
407
+ call.resolve()
408
+ }
409
+
410
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
411
+ fun setFBAnonymousID(call: PluginCall) {
412
+ if (rejectIfNotConfigured(call)) return
413
+ val fbAnonymousID = call.getString("fbAnonymousID")
414
+ setFBAnonymousIDCommon(fbAnonymousID)
415
+ call.resolve()
416
+ }
417
+
418
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
419
+ fun setMparticleID(call: PluginCall) {
420
+ if (rejectIfNotConfigured(call)) return
421
+ val mparticleID = call.getString("mparticleID")
422
+ setMparticleIDCommon(mparticleID)
423
+ call.resolve()
424
+ }
425
+
426
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
427
+ fun setCleverTapID(call: PluginCall) {
428
+ if (rejectIfNotConfigured(call)) return
429
+ val cleverTapID = call.getString("cleverTapID")
430
+ setCleverTapIDCommon(cleverTapID)
431
+ call.resolve()
432
+ }
433
+
434
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
435
+ fun setMixpanelDistinctID(call: PluginCall) {
436
+ if (rejectIfNotConfigured(call)) return
437
+ val mixpanelDistinctID = call.getString("mixpanelDistinctID")
438
+ setMixpanelDistinctIDCommon(mixpanelDistinctID)
439
+ call.resolve()
440
+ }
441
+
442
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
443
+ fun setFirebaseAppInstanceID(call: PluginCall) {
444
+ if (rejectIfNotConfigured(call)) return
445
+ val firebaseAppInstanceID = call.getString("firebaseAppInstanceID")
446
+ setFirebaseAppInstanceIDCommon(firebaseAppInstanceID)
447
+ call.resolve()
448
+ }
449
+
450
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
451
+ fun setOnesignalID(call: PluginCall) {
452
+ if (rejectIfNotConfigured(call)) return
453
+ val onesignalID = call.getString("onesignalID")
454
+ setOnesignalIDCommon(onesignalID)
455
+ call.resolve()
456
+ }
457
+
458
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
459
+ fun setAirshipChannelID(call: PluginCall) {
460
+ if (rejectIfNotConfigured(call)) return
461
+ val airshipChannelID = call.getString("airshipChannelID")
462
+ setAirshipChannelIDCommon(airshipChannelID)
463
+ call.resolve()
464
+ }
465
+
466
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
467
+ fun setMediaSource(call: PluginCall) {
468
+ if (rejectIfNotConfigured(call)) return
469
+ val mediaSource = call.getString("mediaSource")
470
+ setMediaSourceCommon(mediaSource)
471
+ call.resolve()
472
+ }
473
+
474
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
475
+ fun setCampaign(call: PluginCall) {
476
+ if (rejectIfNotConfigured(call)) return
477
+ val campaign = call.getString("campaign")
478
+ setCampaignCommon(campaign)
479
+ call.resolve()
480
+ }
481
+
482
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
483
+ fun setAdGroup(call: PluginCall) {
484
+ if (rejectIfNotConfigured(call)) return
485
+ val adGroup = call.getString("adGroup")
486
+ setAdGroupCommon(adGroup)
487
+ call.resolve()
488
+ }
489
+
490
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
491
+ fun setAd(call: PluginCall) {
492
+ if (rejectIfNotConfigured(call)) return
493
+ val ad = call.getString("ad")
494
+ setAdCommon(ad)
495
+ call.resolve()
496
+ }
497
+
498
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
499
+ fun setKeyword(call: PluginCall) {
500
+ if (rejectIfNotConfigured(call)) return
501
+ val keyword = call.getString("keyword")
502
+ setKeywordCommon(keyword)
503
+ call.resolve()
504
+ }
505
+
506
+ @PluginMethod(returnType = PluginMethod.RETURN_NONE)
507
+ fun setCreative(call: PluginCall) {
508
+ if (rejectIfNotConfigured(call)) return
509
+ val creative = call.getString("creative")
510
+ setCreativeCommon(creative)
511
+ call.resolve()
512
+ }
513
+
514
+ @PluginMethod(returnType = PluginMethod.RETURN_PROMISE)
515
+ fun canMakePayments(call: PluginCall) {
516
+ if (rejectIfNotConfigured(call)) return
517
+ val features = call.getArray("features")?.toList<Int>() ?: emptyList()
518
+ canMakePaymentsCommon(
519
+ activity,
520
+ features,
521
+ object : OnResultAny<Boolean> {
522
+ override fun onError(errorContainer: ErrorContainer?) {
523
+ if (errorContainer == null) call.reject("Unknown error calculating if payments can be performed")
524
+ else rejectWithErrorContainer(call, errorContainer)
525
+ }
526
+
527
+ override fun onReceived(result: Boolean) {
528
+ call.resolveWithMap(mapOf("canMakePayments" to result))
529
+ }
530
+ }
531
+ )
532
+ }
533
+
534
+ @PluginMethod(returnType = PluginMethod.RETURN_PROMISE)
535
+ fun beginRefundRequestForActiveEntitlement(call: PluginCall) {
536
+ rejectNotSupportedInAndroid(call, "beginRefundRequestForActiveEntitlement")
537
+ }
538
+
539
+ @PluginMethod(returnType = PluginMethod.RETURN_PROMISE)
540
+ fun beginRefundRequestForEntitlement(call: PluginCall) {
541
+ rejectNotSupportedInAndroid(call, "beginRefundRequestForEntitlement")
542
+ }
543
+
544
+ @PluginMethod(returnType = PluginMethod.RETURN_PROMISE)
545
+ fun beginRefundRequestForProduct(call: PluginCall) {
546
+ rejectNotSupportedInAndroid(call, "beginRefundRequestForProduct")
547
+ }
548
+
549
+ @PluginMethod(returnType = PluginMethod.RETURN_PROMISE)
550
+ fun isConfigured(call: PluginCall) {
551
+ call.resolveWithMap(mapOf("isConfigured" to Purchases.isConfigured))
552
+ }
553
+
554
+ //================================================================================
555
+ // Private methods
556
+ //================================================================================
557
+
558
+ private val activity: Activity
559
+ get() = bridge.activity
560
+
561
+ private fun getOnResult(call: PluginCall, wrapperKey: String? = null): OnResult {
562
+ return object : OnResult {
563
+ override fun onReceived(map: Map<String, *>) {
564
+ val mapToConvert = wrapperKey?.let { mapOf(wrapperKey to map) } ?: map
565
+ call.resolve(convertMapToJSObject(mapToConvert))
566
+ }
567
+
568
+ override fun onError(errorContainer: ErrorContainer) {
569
+ rejectWithErrorContainer(call, errorContainer)
570
+ }
571
+ }
572
+ }
573
+
574
+ @Suppress("UNCHECKED_CAST")
575
+ private fun convertMapToJSObject(readableMap: Map<String, Any?>): JSObject {
576
+ val jsObject = JSObject()
577
+ for ((key, value) in readableMap) {
578
+ when (value) {
579
+ null -> jsObject.put(key, JSObject.NULL)
580
+ is Map<*, *> -> jsObject.put(key, convertMapToJSObject(value as Map<String, Any?>))
581
+ is List<*> -> jsObject.put(key, convertListToJSArray(value))
582
+ else -> jsObject.put(key, value)
583
+ }
584
+ }
585
+ return jsObject
586
+ }
587
+
588
+ @Suppress("UNCHECKED_CAST")
589
+ private fun convertListToJSArray(array: List<*>): JSArray {
590
+ val writableArray = JSArray()
591
+ for (item in array) {
592
+ when (item) {
593
+ null -> writableArray.put(JSObject.NULL)
594
+ is Map<*, *> -> writableArray.put(convertMapToJSObject(item as Map<String, *>))
595
+ is List<*> -> writableArray.put(convertListToJSArray(item))
596
+ else -> writableArray.put(item)
597
+ }
598
+ }
599
+ return writableArray
600
+ }
601
+
602
+ private fun logNotSupportedFunctionalityInAndroid(functionName: String) {
603
+ Log.e(
604
+ "PurchasesCapacitor",
605
+ "Functionality not supported in Android. Function: $functionName"
606
+ )
607
+ }
608
+
609
+ private fun rejectIfNotConfigured(call: PluginCall): Boolean {
610
+ val isConfigured = Purchases.isConfigured
611
+ if (!isConfigured) {
612
+ call.reject("Purchases must be configured before calling this function")
613
+ }
614
+ return !isConfigured
615
+ }
616
+
617
+ private fun rejectWithErrorContainer(call: PluginCall, errorContainer: ErrorContainer) {
618
+ call.reject(
619
+ errorContainer.message,
620
+ errorContainer.code.toString(),
621
+ convertMapToJSObject(errorContainer.info)
622
+ )
623
+ }
624
+
625
+ private fun rejectNotSupportedInAndroid(call: PluginCall, functionName: String) {
626
+ logNotSupportedFunctionalityInAndroid(functionName)
627
+ call.reject("This operation is not supported in Android",
628
+ "NOT_SUPPORTED",
629
+ UnsupportedOperationException(),
630
+ )
631
+ }
632
+
633
+ private fun PluginCall.resolveWithMap(map: Map<String, *>) {
634
+ resolve(convertMapToJSObject(map))
635
+ }
636
+
637
+ private fun PluginCall.getStringOrReject(key: String): String? {
638
+ val value = getString(key)
639
+ if (value == null) {
640
+ reject("Missing $key parameter")
641
+ return null
642
+ }
643
+ return value
644
+ }
645
+
646
+ private fun PluginCall.getObjectOrReject(key: String): JSObject? {
647
+ val value = getObject(key)
648
+ if (value == null) {
649
+ reject("Missing $key parameter")
650
+ return null
651
+ }
652
+ return value
653
+ }
654
+
655
+ private fun PluginCall.getArrayOrReject(key: String): JSArray? {
656
+ val value = getArray(key)
657
+ if (value == null) {
658
+ reject("Missing $key parameter")
659
+ return null
660
+ }
661
+ return value
662
+ }
663
+
664
+ private fun PluginCall.getBooleanOrReject(key: String): Boolean? {
665
+ val value = getBoolean(key)
666
+ if (value == null) {
667
+ reject("Missing $key parameter")
668
+ return null
669
+ }
670
+ return value
671
+ }
672
+
673
+ private fun JSObject.getStringOrReject(call: PluginCall, key: String): String? {
674
+ val value = getString(key)
675
+ if (value == null) {
676
+ call.reject("Missing $key parameter in $this")
677
+ return null
678
+ }
679
+ return value
680
+ }
681
+
682
+ private data class PurchaseOptionalInfoParams(
683
+ val oldProductIdentifier: String?,
684
+ val prorationMode: Int?,
685
+ val isPersonalizedPrice: Boolean?,
686
+ ) {
687
+ companion object {
688
+ fun fromCall(call: PluginCall): PurchaseOptionalInfoParams {
689
+ val googleProductChangeInfo = call.getObject("googleProductChangeInfo")
690
+ val googleIsPersonalizedPrice = call.getBoolean("googleIsPersonalizedPrice")
691
+ return PurchaseOptionalInfoParams(
692
+ oldProductIdentifier = googleProductChangeInfo?.getString("oldProductIdentifier"),
693
+ prorationMode = googleProductChangeInfo?.getInteger("prorationMode"),
694
+ isPersonalizedPrice = googleIsPersonalizedPrice,
695
+ )
696
+ }
697
+ }
698
+ }
699
+ }
File without changes