rampkit-expo-dev 0.0.71 → 0.0.72

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.
package/build/RampKit.js CHANGED
@@ -297,6 +297,8 @@ class RampKitCore {
297
297
  var _a;
298
298
  // Track onboarding completed - trigger: finished
299
299
  EventManager_1.eventManager.trackOnboardingCompleted("finished", screens.length, screens.length, onboardingId);
300
+ // Auto-recheck transactions after onboarding finishes (catches purchases made during onboarding)
301
+ RampKitNative_1.TransactionObserver.recheck().catch(() => { });
300
302
  try {
301
303
  (_a = this.onOnboardingFinished) === null || _a === void 0 ? void 0 : _a.call(this, payload);
302
304
  }
@@ -323,6 +325,8 @@ class RampKitCore {
323
325
  onCloseAction: (screenIndex, _screenId) => {
324
326
  // Track onboarding completed - trigger: closed
325
327
  EventManager_1.eventManager.trackOnboardingCompleted("closed", screenIndex + 1, screens.length, onboardingId);
328
+ // Auto-recheck transactions after onboarding closes (catches purchases made before closing)
329
+ RampKitNative_1.TransactionObserver.recheck().catch(() => { });
326
330
  },
327
331
  });
328
332
  }
@@ -486,10 +486,25 @@ public class RampKitModule: Module {
486
486
  /// Check all current entitlements and track any we haven't seen before
487
487
  /// This catches purchases made by Superwall/RevenueCat before our observer started
488
488
  /// Returns a dictionary with the results for JavaScript logging
489
+ ///
490
+ /// IMPORTANT: "Already sent" means we previously sent this transaction to the backend
491
+ /// and received a successful HTTP 2xx response. The originalTransactionId is stored
492
+ /// in UserDefaults ONLY after a successful send.
489
493
  @available(iOS 15.0, *)
490
494
  private func checkAndTrackCurrentEntitlements() async -> [String: Any] {
491
- print("[RampKit] 🔍 Checking current entitlements for missed purchases...")
492
- print("[RampKit] 📚 Currently have \(trackedTransactionIds.count) tracked transaction IDs in storage")
495
+ print("[RampKit] ")
496
+ print("[RampKit] ════════════════════════════════════════════════════════════")
497
+ print("[RampKit] 🔍 CHECKING ENTITLEMENTS FOR UNSENT PURCHASES")
498
+ print("[RampKit] ════════════════════════════════════════════════════════════")
499
+ print("[RampKit] ")
500
+ print("[RampKit] 📚 Tracked transaction IDs in storage: \(trackedTransactionIds.count)")
501
+ if !trackedTransactionIds.isEmpty {
502
+ print("[RampKit] These IDs were SUCCESSFULLY sent to backend (HTTP 2xx):")
503
+ for id in trackedTransactionIds {
504
+ print("[RampKit] - \(id)")
505
+ }
506
+ }
507
+ print("[RampKit] ")
493
508
 
494
509
  let formatter = ISO8601DateFormatter()
495
510
  formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
@@ -537,11 +552,17 @@ public class RampKitModule: Module {
537
552
  print("[RampKit] - purchaseDate: \(formatter.string(from: transaction.purchaseDate))")
538
553
 
539
554
  // Check if we've already tracked this transaction
555
+ // "Tracked" means we successfully sent a purchase_completed event to the backend
556
+ // and received an HTTP 2xx response. We store the originalTransactionId after success.
540
557
  if trackedTransactionIds.contains(originalId) {
541
558
  trackedCount += 1
542
559
  txDetails["status"] = "already_sent"
543
560
  alreadyTrackedDetails.append(txDetails)
544
- print("[RampKit] ✅ STATUS: Already sent to backend (originalTransactionId in tracked set)")
561
+ print("[RampKit] ✅ STATUS: ALREADY SENT TO BACKEND")
562
+ print("[RampKit] (originalTransactionId \(originalId) is in our sent-transactions storage)")
563
+ print("[RampKit] This means we previously sent a purchase_completed event")
564
+ print("[RampKit] and received a successful HTTP 2xx response.")
565
+ print("[RampKit] ")
545
566
  continue
546
567
  }
547
568
 
@@ -578,15 +599,19 @@ public class RampKitModule: Module {
578
599
  }
579
600
 
580
601
  print("[RampKit] ")
581
- print("[RampKit] 🔍 ═══════════════════════════════════════════")
582
- print("[RampKit] 🔍 ENTITLEMENT CHECK SUMMARY:")
583
- print("[RampKit] 🔍 ═══════════════════════════════════════════")
584
- print("[RampKit] Total entitlements found: \(foundCount)")
585
- print("[RampKit] Already sent to backend: \(trackedCount)")
586
- print("[RampKit] Skipped (renewal/revoked): \(skippedReasons.count)")
587
- print("[RampKit] NEW events sent: \(newCount)")
588
- print("[RampKit] Tracked IDs in storage: \(trackedTransactionIds.count)")
589
- print("[RampKit] 🔍 ═══════════════════════════════════════════")
602
+ print("[RampKit] ════════════════════════════════════════════════════════════")
603
+ print("[RampKit] 📊 ENTITLEMENT CHECK SUMMARY")
604
+ print("[RampKit] ════════════════════════════════════════════════════════════")
605
+ print("[RampKit] Total entitlements found: \(foundCount)")
606
+ print("[RampKit] Already sent (HTTP 2xx): \(trackedCount) (no action needed)")
607
+ print("[RampKit] Skipped (renewal/revoked): \(skippedReasons.count) (backend gets via S2S)")
608
+ print("[RampKit] NEW events sent this session: \(newCount)")
609
+ print("[RampKit] Total tracked IDs in storage: \(trackedTransactionIds.count)")
610
+ if newCount == 0 && foundCount > 0 {
611
+ print("[RampKit] ")
612
+ print("[RampKit] â„šī¸ All purchases already sent or skipped - nothing new to send")
613
+ }
614
+ print("[RampKit] ════════════════════════════════════════════════════════════")
590
615
 
591
616
  return [
592
617
  "totalFound": foundCount,
@@ -914,8 +939,8 @@ public class RampKitModule: Module {
914
939
  }
915
940
  }
916
941
 
917
- private func sendPurchaseEvent(appId: String, userId: String, eventName: String, properties: [String: Any]) async {
918
- let _ = await sendPurchaseEventWithResult(appId: appId, userId: userId, eventName: eventName, properties: properties)
942
+ private func sendPurchaseEvent(appId: String, userId: String, eventName: String, properties: [String: Any], paywallId: String? = nil) async {
943
+ let _ = await sendPurchaseEventWithResult(appId: appId, userId: userId, eventName: eventName, properties: properties, paywallId: paywallId)
919
944
  }
920
945
 
921
946
  private struct SendEventResult {
@@ -924,7 +949,16 @@ public class RampKitModule: Module {
924
949
  let error: String?
925
950
  }
926
951
 
927
- private func sendPurchaseEventWithResult(appId: String, userId: String, eventName: String, properties: [String: Any]) async -> SendEventResult {
952
+ private func sendPurchaseEventWithResult(appId: String, userId: String, eventName: String, properties: [String: Any], paywallId: String? = nil) async -> SendEventResult {
953
+ // Build context with optional paywallId for attribution
954
+ var context: [String: Any] = [
955
+ "locale": Locale.current.identifier,
956
+ "regionCode": Locale.current.regionCode as Any
957
+ ]
958
+ if let paywallId = paywallId {
959
+ context["paywallId"] = paywallId
960
+ }
961
+
928
962
  let event: [String: Any] = [
929
963
  "appId": appId,
930
964
  "appUserId": userId,
@@ -937,17 +971,53 @@ public class RampKitModule: Module {
937
971
  "platformVersion": UIDevice.current.systemVersion,
938
972
  "deviceModel": getDeviceModelIdentifier(),
939
973
  "sdkVersion": "1.0.0",
940
- "appVersion": Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String,
941
- "buildNumber": Bundle.main.infoDictionary?["CFBundleVersion"] as? String
942
- ],
943
- "context": [
944
- "locale": Locale.current.identifier,
945
- "regionCode": Locale.current.regionCode
974
+ "appVersion": Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "unknown",
975
+ "buildNumber": Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "unknown"
946
976
  ],
977
+ "context": context,
947
978
  "properties": properties
948
979
  ]
949
980
 
981
+ // DETAILED LOGGING: Log the full request body
982
+ print("[RampKit] ")
983
+ print("[RampKit] ════════════════════════════════════════════════════════════")
984
+ print("[RampKit] 📤 SENDING PURCHASE EVENT TO BACKEND")
985
+ print("[RampKit] ════════════════════════════════════════════════════════════")
986
+ print("[RampKit] URL: https://uustlzuvjmochxkxatfx.supabase.co/functions/v1/app-user-events")
987
+ print("[RampKit] Method: POST")
988
+ print("[RampKit] ")
989
+ print("[RampKit] 📋 REQUEST BODY:")
990
+ print("[RampKit] appId: \(appId)")
991
+ print("[RampKit] appUserId: \(userId)")
992
+ print("[RampKit] eventName: \(eventName)")
993
+ if let originalTxId = properties["originalTransactionId"] {
994
+ print("[RampKit] properties.originalTransactionId: \(originalTxId) ✓ (CRITICAL for attribution)")
995
+ } else {
996
+ print("[RampKit] âš ī¸ WARNING: properties.originalTransactionId is MISSING!")
997
+ }
998
+ if let productId = properties["productId"] {
999
+ print("[RampKit] properties.productId: \(productId)")
1000
+ }
1001
+ if let amount = properties["amount"], let currency = properties["currency"] {
1002
+ print("[RampKit] properties.amount: \(amount) \(currency)")
1003
+ }
1004
+ if let paywallId = paywallId {
1005
+ print("[RampKit] context.paywallId: \(paywallId) ✓")
1006
+ }
1007
+
1008
+ // Log full JSON for debugging
1009
+ if let jsonData = try? JSONSerialization.data(withJSONObject: event, options: .prettyPrinted),
1010
+ let jsonString = String(data: jsonData, encoding: .utf8) {
1011
+ print("[RampKit] ")
1012
+ print("[RampKit] 📄 FULL JSON PAYLOAD:")
1013
+ for line in jsonString.components(separatedBy: "\n") {
1014
+ print("[RampKit] \(line)")
1015
+ }
1016
+ }
1017
+ print("[RampKit] ════════════════════════════════════════════════════════════")
1018
+
950
1019
  guard let url = URL(string: "https://uustlzuvjmochxkxatfx.supabase.co/functions/v1/app-user-events") else {
1020
+ print("[RampKit] ❌ SEND FAILED: Invalid URL")
951
1021
  return SendEventResult(success: false, statusCode: 0, error: "Invalid URL")
952
1022
  }
953
1023
 
@@ -959,15 +1029,40 @@ public class RampKitModule: Module {
959
1029
 
960
1030
  do {
961
1031
  request.httpBody = try JSONSerialization.data(withJSONObject: event)
962
- let (_, response) = try await URLSession.shared.data(for: request)
1032
+ let (data, response) = try await URLSession.shared.data(for: request)
1033
+
963
1034
  if let httpResponse = response as? HTTPURLResponse {
964
- print("[RampKit] Purchase event sent: \(eventName) - Status: \(httpResponse.statusCode)")
965
1035
  let success = httpResponse.statusCode >= 200 && httpResponse.statusCode < 300
966
- return SendEventResult(success: success, statusCode: httpResponse.statusCode, error: success ? nil : "HTTP \(httpResponse.statusCode)")
1036
+ let responseBody = String(data: data, encoding: .utf8) ?? "(empty)"
1037
+
1038
+ // DETAILED LOGGING: Log the response
1039
+ print("[RampKit] ")
1040
+ print("[RampKit] đŸ“Ĩ RESPONSE FROM BACKEND:")
1041
+ print("[RampKit] HTTP Status: \(httpResponse.statusCode)")
1042
+ print("[RampKit] Success: \(success ? "✅ YES" : "❌ NO")")
1043
+ print("[RampKit] Response Body: \(responseBody)")
1044
+
1045
+ if success {
1046
+ print("[RampKit] ")
1047
+ print("[RampKit] ✅ EVENT SENT SUCCESSFULLY!")
1048
+ print("[RampKit] originalTransactionId \(properties["originalTransactionId"] ?? "unknown") will be marked as SENT")
1049
+ print("[RampKit] ════════════════════════════════════════════════════════════")
1050
+ } else {
1051
+ print("[RampKit] ")
1052
+ print("[RampKit] ❌ EVENT SEND FAILED!")
1053
+ print("[RampKit] Will retry on next app launch")
1054
+ print("[RampKit] ════════════════════════════════════════════════════════════")
1055
+ }
1056
+
1057
+ return SendEventResult(success: success, statusCode: httpResponse.statusCode, error: success ? nil : "HTTP \(httpResponse.statusCode): \(responseBody)")
967
1058
  }
1059
+ print("[RampKit] ❌ SEND FAILED: No HTTP response")
968
1060
  return SendEventResult(success: false, statusCode: 0, error: "No HTTP response")
969
1061
  } catch {
970
- print("[RampKit] Failed to send purchase event: \(error)")
1062
+ print("[RampKit] ")
1063
+ print("[RampKit] ❌ SEND FAILED: Network error")
1064
+ print("[RampKit] Error: \(error.localizedDescription)")
1065
+ print("[RampKit] ════════════════════════════════════════════════════════════")
971
1066
  return SendEventResult(success: false, statusCode: 0, error: error.localizedDescription)
972
1067
  }
973
1068
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rampkit-expo-dev",
3
- "version": "0.0.71",
3
+ "version": "0.0.72",
4
4
  "description": "The Expo SDK for RampKit. Build, test, and personalize app onboardings with instant updates.",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",