@purchasely/cordova-plugin-purchasely 5.7.3 → 6.0.0-rc.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.
Files changed (33) hide show
  1. package/README.md +12 -8
  2. package/__tests__/Purchasely.test.js +307 -92
  3. package/example/config.xml +0 -10
  4. package/example/e2e/README.md +44 -0
  5. package/example/e2e/helpers/driver.js +70 -0
  6. package/example/e2e/package.json +19 -0
  7. package/example/e2e/specs/bridge.e2e.js +51 -0
  8. package/example/e2e/specs/dismiss.e2e.js +37 -0
  9. package/example/e2e/tools/ci_run_e2e.sh +49 -0
  10. package/example/e2e/tools/ci_run_e2e_ios.sh +46 -0
  11. package/example/e2e/wdio.android.conf.js +21 -0
  12. package/example/e2e/wdio.ios.conf.js +19 -0
  13. package/example/e2e/wdio.shared.conf.js +28 -0
  14. package/example/package-lock.json +52 -201
  15. package/example/package.json +5 -5
  16. package/example/www/index.html +1 -7
  17. package/example/www/js/index.js +113 -92
  18. package/package.json +1 -1
  19. package/plugin.xml +3 -22
  20. package/src/android/PurchaselyPlugin.kt +529 -440
  21. package/src/ios/CDVPurchasely+Events.h +1 -1
  22. package/src/ios/CDVPurchasely+UserAttributes.h +1 -1
  23. package/src/ios/CDVPurchasely+UserAttributes.m +2 -0
  24. package/src/ios/CDVPurchasely.h +21 -16
  25. package/src/ios/CDVPurchasely.m +493 -257
  26. package/www/Purchasely.js +208 -40
  27. package/src/android/PLYProductActivity.kt +0 -168
  28. package/src/android/PLYSubscriptionsActivity.java +0 -37
  29. package/src/android/activity_ply_product_activity.xml +0 -6
  30. package/src/android/activity_ply_subscriptions_activity.xml +0 -6
  31. package/src/android/theme_purchasely_fullscreen.xml +0 -6
  32. package/src/android/theme_purchasely_fullscreen_v23.xml +0 -6
  33. package/src/android/theme_purchasely_fullscreen_v23_light_status_bar.xml +0 -7
@@ -41,12 +41,13 @@ function onDeviceReady() {
41
41
  document.getElementById('deviceready').classList.add('ready');
42
42
 
43
43
  Purchasely.start(
44
- 'fcb39be4-2ba4-4db7-bde3-2a5a1e20745d',
45
- ['Google'],
46
- false,
47
- null,
48
- Purchasely.LogLevel.DEBUG,
49
- Purchasely.RunningMode.full,
44
+ {
45
+ apiKey: 'fcb39be4-2ba4-4db7-bde3-2a5a1e20745d',
46
+ stores: [Purchasely.Store.google],
47
+ storeKit1: false,
48
+ logLevel: Purchasely.LogLevel.DEBUG,
49
+ runningMode: Purchasely.RunningMode.full
50
+ },
50
51
  (isConfigured) => {
51
52
  if(isConfigured) onPurchaselySdkReady();
52
53
  },
@@ -60,14 +61,13 @@ function onDeviceReady() {
60
61
 
61
62
  document.getElementById("openPresentation").addEventListener("click", openPresentation);
62
63
  document.getElementById("fetchPresentation").addEventListener("click", fetchPresentation);
63
- document.getElementById("presentSubscriptions").addEventListener("click", presentSubscriptions);
64
- document.getElementById("showPresentation").addEventListener("click", showPresentation);
65
- document.getElementById("hidePresentation").addEventListener("click", hidePresentation);
64
+ document.getElementById("backPresentation").addEventListener("click", backPresentation);
66
65
  document.getElementById("closePresentation").addEventListener("click", closePresentation);
67
66
  document.getElementById("purchaseWithPlanVendorId").addEventListener("click", purchaseWithPlanVendorId);
68
67
  document.getElementById("restore").addEventListener("click", restore);
69
68
  document.getElementById("silentRestore").addEventListener("click", silentRestore);
70
69
  document.getElementById("processToPayment").addEventListener("click", processToPayment);
70
+ document.getElementById("openDeeplink").addEventListener("click", openDeeplink);
71
71
 
72
72
  }
73
73
 
@@ -139,7 +139,7 @@ function onPurchaselySdkReady() {
139
139
  Purchasely.setAttribute(Purchasely.Attribute.BATCH_CUSTOM_USER_ID, "batch_custom_user_id");
140
140
  Purchasely.setAttribute(Purchasely.Attribute.BATCH_INSTALLATION_ID, "testBatch1");
141
141
 
142
- Purchasely.readyToOpenDeeplink(true);
142
+ Purchasely.allowDeeplink(true);
143
143
 
144
144
  Purchasely.planWithIdentifier('PURCHASELY_PLUS_MONTHLY', (plan) => {
145
145
  console.log(' ==> Plan');
@@ -157,16 +157,16 @@ function onPurchaselySdkReady() {
157
157
  console.log(error);
158
158
  });
159
159
 
160
- Purchasely.setDefaultPresentationResultHandler(callback => {
161
- console.log(callback);
160
+ Purchasely.setDefaultPresentationDismissHandler(callback => {
161
+ console.log('[setDefaultPresentationDismissHandler] onDismissed — purchaseResult=' + callback.purchaseResult + ' closeReason=' + callback.closeReason + ' — outcome: ' + safeStringify(callback));
162
162
  if(callback.result == Purchasely.PurchaseResult.CANCELLED) {
163
- console.log("User cancelled purchased");
164
- } else {
163
+ console.log("User cancelled purchase - close reason " + callback.closeReason);
164
+ } else if (callback.plan) {
165
165
  console.log("User purchased " + callback.plan.vendorId);
166
166
  }
167
167
  },
168
168
  (error) => {
169
- console.log("Error with purchase : " + error);
169
+ console.log("[setDefaultPresentationDismissHandler] error: " + error);
170
170
  });
171
171
 
172
172
  Purchasely.setUserAttributeWithString("key_string", "value_string", Purchasely.DataProcessingLegalBasis.essential);
@@ -238,53 +238,58 @@ function onPurchaselySdkReady() {
238
238
 
239
239
  Purchasely.removeUserAttributeListener();
240
240
 
241
- Purchasely.setPaywallActionInterceptor((result) => {
242
- console.log(result);
243
- console.log('Received action from paywall ' + result.info.presentationId);
244
-
245
- if (result.action === Purchasely.PaywallAction.navigate) {
246
- console.log(
247
- 'User wants to navigate to website ' +
248
- result.parameters.title +
249
- ' ' +
250
- result.parameters.url
251
- );
252
- console.log('prevent Purchasely SDK to navigate to website');
253
- Purchasely.onProcessAction(true);
254
- } else if (result.action === Purchasely.PaywallAction.close) {
255
- console.log('User wants to close paywall - close reason ' + result.parameters.closeReason);
256
- Purchasely.onProcessAction(true);
257
- } else if (result.action === Purchasely.PaywallAction.close_all) {
258
- console.log('User wants to close all paywalls');
259
- Purchasely.onProcessAction(true);
260
- } else if (result.action === Purchasely.PaywallAction.login) {
261
- console.log('User wants to login');
262
- //Present your own screen for user to log in
263
- Purchasely.closePaywall();
264
- Purchasely.userLogin('MY_USER_ID');
265
- //Call this method to update Purchasely Paywall
266
- Purchasely.onProcessAction(true);
267
- } else if (result.action === Purchasely.PaywallAction.open_presentation) {
268
- console.log('User wants to open a new paywall');
269
- Purchasely.onProcessAction(true);
270
- } else if (result.action === Purchasely.PaywallAction.open_placement) {
271
- console.log('User wants to open a new placement');
272
- Purchasely.onProcessAction(true);
273
- } else if (result.action === Purchasely.PaywallAction.purchase) {
274
- console.log('User wants to purchase');
275
- //If you want to intercept it, close paywall and display your screen
276
- Purchasely.hidePresentation();
277
- } else if (result.action === Purchasely.PaywallAction.web_checkout) {
278
- console.log('User wants to proceed to web checkout');
279
- console.log('web checkout url: ' + result.parameters.url);
280
- console.log('web checkout provider: ' + result.parameters.webCheckoutProvider);
281
- console.log('web checkout client reference id: ' + result.parameters.clientReferenceId);
282
- console.log('web checkout query parameter key: ' + result.parameters.queryParameterKey);
283
- Purchasely.onProcessAction(true);
284
- } else {
285
- console.log('Action unknown ' + result.action);
286
- Purchasely.onProcessAction(true);
287
- }
241
+ // Purchasely 6.0: per-action interceptor. Register a handler per action kind; each
242
+ // handler receives (info, parameters) and returns a Purchasely.InterceptResult telling
243
+ // the SDK how it was handled (notHandled = let the SDK proceed, success = app handled it).
244
+ Purchasely.removeAllActionInterceptors();
245
+
246
+ // NOTE: `info` and `parameters` can be null depending on the action and the
247
+ // platform (e.g. on iOS the `close` action carries no parameters). Always log
248
+ // them with safeStringify (null-safe) rather than reading fields directly, or
249
+ // a thrown handler is reported to the SDK as `failed` and the action (e.g.
250
+ // close) will NOT be performed.
251
+ Purchasely.interceptAction(Purchasely.PresentationAction.navigate, (info, parameters) => {
252
+ console.log('[interceptAction] navigate — info: ' + safeStringify(info) + ' — parameters: ' + safeStringify(parameters));
253
+ return Purchasely.InterceptResult.notHandled;
254
+ });
255
+
256
+ Purchasely.interceptAction(Purchasely.PresentationAction.close, (info, parameters) => {
257
+ console.log('[interceptAction] close — info: ' + safeStringify(info) + ' — parameters: ' + safeStringify(parameters));
258
+ return Purchasely.InterceptResult.notHandled;
259
+ });
260
+
261
+ Purchasely.interceptAction(Purchasely.PresentationAction.close_all, (info, parameters) => {
262
+ console.log('[interceptAction] close_all — info: ' + safeStringify(info) + ' — parameters: ' + safeStringify(parameters));
263
+ return Purchasely.InterceptResult.notHandled;
264
+ });
265
+
266
+ Purchasely.interceptAction(Purchasely.PresentationAction.login, (info, parameters) => {
267
+ console.log('[interceptAction] login — info: ' + safeStringify(info) + ' — parameters: ' + safeStringify(parameters));
268
+ // Present your own screen for the user to log in, then report success so the paywall refreshes.
269
+ Purchasely.closePresentation();
270
+ Purchasely.userLogin('MY_USER_ID');
271
+ return Purchasely.InterceptResult.success;
272
+ });
273
+
274
+ Purchasely.interceptAction(Purchasely.PresentationAction.open_presentation, (info, parameters) => {
275
+ console.log('[interceptAction] open_presentation — info: ' + safeStringify(info) + ' — parameters: ' + safeStringify(parameters));
276
+ return Purchasely.InterceptResult.notHandled;
277
+ });
278
+
279
+ Purchasely.interceptAction(Purchasely.PresentationAction.open_placement, (info, parameters) => {
280
+ console.log('[interceptAction] open_placement — info: ' + safeStringify(info) + ' — parameters: ' + safeStringify(parameters));
281
+ return Purchasely.InterceptResult.notHandled;
282
+ });
283
+
284
+ Purchasely.interceptAction(Purchasely.PresentationAction.purchase, (info, parameters) => {
285
+ console.log('[interceptAction] purchase — info: ' + safeStringify(info) + ' — parameters: ' + safeStringify(parameters));
286
+ // Let the SDK proceed with the purchase.
287
+ return Purchasely.InterceptResult.notHandled;
288
+ });
289
+
290
+ Purchasely.interceptAction(Purchasely.PresentationAction.web_checkout, (info, parameters) => {
291
+ console.log('[interceptAction] web_checkout — info: ' + safeStringify(info) + ' — parameters: ' + safeStringify(parameters));
292
+ return Purchasely.InterceptResult.notHandled;
288
293
  });
289
294
 
290
295
  Purchasely.clearBuiltInAttributes();
@@ -294,19 +299,38 @@ function openPresentation() {
294
299
  Purchasely.presentPresentationForPlacement(
295
300
  'ONBOARDING', //placementId
296
301
  null, //contentId
297
- true, //fullscreen
302
+ Purchasely.TransitionType.fullScreen, //display mode (string) — or a transition object, see below
298
303
  (callback) => {
299
- console.log(callback);
304
+ console.log('[openPresentation] onDismissed — purchaseResult=' + callback.purchaseResult + ' — outcome: ' + safeStringify(callback));
300
305
  if(callback.result == Purchasely.PurchaseResult.CANCELLED) {
301
- console.log("User cancelled purchased");
306
+ console.log("User cancelled purchased - close reason " + callback.closeReason);
302
307
  } else {
303
- console.log("User purchased " + callback.plan.name);
308
+ console.log("User purchased " + (callback.plan ? callback.plan.name : ''));
304
309
  }
305
310
  },
306
311
  (error) => {
307
- console.log("Error with purchase : " + error);
312
+ console.log("[openPresentation] error: " + error);
313
+ },
314
+ // Purchasely 6.0: optional per-request lifecycle callbacks.
315
+ {
316
+ onPresented: (presentation, error) => {
317
+ console.log('[openPresentation] onPresented — ' + (presentation ? presentation.screenId : '') + (error ? ' error=' + error : ''));
318
+ },
319
+ onCloseRequested: () => {
320
+ console.log('[openPresentation] onCloseRequested');
321
+ }
308
322
  }
309
323
  );
324
+
325
+ // Purchasely 6.0 also supports:
326
+ // - a rich transition object for drawer/popin sizing (see fetchPresentation below):
327
+ // { type: Purchasely.TransitionType.drawer, dismissible: true,
328
+ // height: { type: Purchasely.DimensionType.percentage, value: 0.8 }, backgroundColor: '#000000' }
329
+ // - the default (audience-targeted) presentation:
330
+ // Purchasely.presentPresentationForDefault(null, Purchasely.TransitionType.fullScreen, ok, err);
331
+ // Purchasely.fetchPresentationForDefault(null, onLoaded, err);
332
+ // - stopping campaign/deeplink dismiss outcomes:
333
+ // Purchasely.removeDefaultPresentationDismissHandler();
310
334
  }
311
335
 
312
336
  function fetchPresentation() {
@@ -314,50 +338,47 @@ function fetchPresentation() {
314
338
  'flow_demo', //placementId
315
339
  null, //contentId
316
340
  (presentation) => {
317
- console.log(safeStringify(presentation));
318
- Purchasely.presentPresentation(presentation, false, null,
341
+ console.log('[fetchPresentation] onFetched — presentation: ' + safeStringify(presentation));
342
+ // Rich transition object: drawer at 80% height, dismissible. (iOS applies the
343
+ // percentage height + dismissible; Android also supports pixel + popin width.)
344
+ Purchasely.presentPresentation(presentation, {
345
+ type: Purchasely.TransitionType.drawer,
346
+ dismissible: true,
347
+ height: { type: Purchasely.DimensionType.percentage, value: 0.8 }
348
+ }, null,
319
349
  (callback) => {
320
- console.log(callback);
350
+ console.log('[fetchPresentation → presentPresentation] onDismissed — purchaseResult=' + callback.purchaseResult + ' — outcome: ' + safeStringify(callback));
321
351
  if(callback.result == Purchasely.PurchaseResult.CANCELLED) {
322
- console.log("User cancelled purchased");
352
+ console.log("User cancelled purchased - close reason " + callback.closeReason);
323
353
  } else {
324
- console.log("User purchased " + callback.plan.name);
354
+ console.log("User purchased " + (callback.plan ? callback.plan.name : ''));
325
355
  }
326
356
  }, (error) => {
327
- console.log("Error with present : " + error);
357
+ console.log("[fetchPresentation → presentPresentation] error: " + error);
328
358
  });
329
359
  },
330
360
  (error) => {
331
- console.log("Error with purchase : " + error);
361
+ console.log("[fetchPresentation] error: " + error);
332
362
  }
333
363
  );
334
364
  }
335
365
 
336
- function presentSubscriptions() {
337
- Purchasely.presentSubscriptions();
338
- }
339
-
340
366
  function purchaseWithPlanVendorId() {
341
367
  Purchasely.purchaseWithPlanVendorId("PURCHASELY_PLUS_MONTHLY");
342
368
  }
343
369
 
344
370
  function processToPayment() {
345
- // Call this method open paywall again
346
- Purchasely.showPresentation();
347
-
348
- // Call this method in paywallObserver mode to synchronize purchases with Purchasely
349
- // Purchasely.synchronize();
350
-
351
- // Call this method to process to payment or false if you handled it
352
- Purchasely.onProcessAction(true);
353
- }
371
+ // Call this method in observer mode to synchronize purchases with Purchasely
372
+ // Purchasely.synchronize((ok) => console.log("synchronized " + ok), (e) => console.log(e));
354
373
 
355
- function showPresentation() {
356
- Purchasely.showPresentation();
374
+ // Purchasely 6.0: with the per-action interceptor (interceptAction), each handler returns
375
+ // its own Purchasely.InterceptResult, so there is no separate "process action" step.
376
+ // Kept as a no-op for the example's existing button wiring.
377
+ console.log('processToPayment: no-op in v6 — interceptAction handlers report their own result');
357
378
  }
358
379
 
359
- function hidePresentation() {
360
- Purchasely.hidePresentation();
380
+ function backPresentation() {
381
+ Purchasely.backPresentation();
361
382
  }
362
383
 
363
384
  function closePresentation() {
@@ -416,7 +437,7 @@ function signPromotionalOffer() {
416
437
  }
417
438
 
418
439
  function openDeeplink() {
419
- Purchasely.isDeeplinkHandled(
440
+ Purchasely.handleDeeplink(
420
441
  "purchasely://ply/presentations/CAROUSEL",
421
442
  isHandled => {
422
443
  console.log("Deeplink is handled ? " + isHandled)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@purchasely/cordova-plugin-purchasely",
3
- "version": "5.7.3",
3
+ "version": "6.0.0-rc.1",
4
4
  "description": "Purchasely is a solution to ease the integration and boost your In-App Purchases & Subscriptions on the App Store, Google Play Store, Amazon Appstore and Huawei App Gallery.",
5
5
  "cordova": {
6
6
  "id": "@purchasely/cordova-plugin-purchasely",
package/plugin.xml CHANGED
@@ -1,5 +1,5 @@
1
1
  <?xml version='1.0' encoding='utf-8'?>
2
- <plugin id="@purchasely/cordova-plugin-purchasely" version="5.7.3" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
2
+ <plugin id="@purchasely/cordova-plugin-purchasely" version="6.0.0-rc.1" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
3
3
  <name>Purchasely</name>
4
4
  <js-module name="Purchasely" src="www/Purchasely.js">
5
5
  <clobbers target="Purchasely" />
@@ -38,7 +38,7 @@
38
38
  <source url="https://github.com/CocoaPods/Specs.git"/>
39
39
  </config>
40
40
  <pods use-frameworks="true">
41
- <pod name="Purchasely" spec="5.7.4"/>
41
+ <pod name="Purchasely" spec="6.0.0-rc.2"/>
42
42
  </pods>
43
43
  </podspec>
44
44
  </platform>
@@ -51,27 +51,8 @@
51
51
  <preference name="GradlePluginKotlinEnabled" value="true" />
52
52
  <preference name="GradlePluginKotlinCodeStyle" value="official" />
53
53
  </config-file>
54
- <config-file parent="/manifest/application" target="AndroidManifest.xml">
55
- <activity
56
- android:label="PLYProductActivity"
57
- android:name="cordova.plugin.purchasely.PLYProductActivity"
58
- android:theme="@style/Theme.AppCompat.Light.NoActionBar">
59
- </activity>
60
- <activity
61
- android:label="PLYSubscriptionsActivity"
62
- android:name="cordova.plugin.purchasely.PLYSubscriptionsActivity"
63
- android:theme="@style/Theme.AppCompat.Light.NoActionBar">
64
- </activity>
65
- </config-file>
66
54
  <framework src="src/android/build-extras.gradle" custom="true" type="gradleReference" />
67
- <framework src="io.purchasely:core:5.7.4" />
55
+ <framework src="io.purchasely:core:6.0.0-rc.2" />
68
56
  <source-file src="src/android/PurchaselyPlugin.kt" target-dir="java/cordova/plugin/purchasely" />
69
- <source-file src="src/android/PLYProductActivity.kt" target-dir="java/cordova/plugin/purchasely" />
70
- <source-file src="src/android/PLYSubscriptionsActivity.java" target-dir="src/cordova/plugin/purchasely" />
71
- <source-file src="src/android/activity_ply_product_activity.xml" target-dir="res/layout"/>
72
- <source-file src="src/android/activity_ply_subscriptions_activity.xml" target-dir="res/layout"/>
73
- <source-file src="src/android/theme_purchasely_fullscreen.xml" target-dir="res/values"/>
74
- <source-file src="src/android/theme_purchasely_fullscreen_v23_light_status_bar.xml" target-dir="res/values-v23"/>
75
- <source-file src="src/android/theme_purchasely_fullscreen_v23.xml" target-dir="res/values-v23"/>
76
57
  </platform>
77
58
  </plugin>