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 +4 -0
- package/ios/RampKitModule.swift +120 -25
- package/package.json +1 -1
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
|
}
|
package/ios/RampKitModule.swift
CHANGED
|
@@ -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]
|
|
492
|
-
print("[RampKit]
|
|
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]
|
|
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]
|
|
583
|
-
print("[RampKit]
|
|
584
|
-
print("[RampKit] Total entitlements found:
|
|
585
|
-
print("[RampKit] Already sent
|
|
586
|
-
print("[RampKit] Skipped (renewal/revoked):
|
|
587
|
-
print("[RampKit] NEW events sent:
|
|
588
|
-
print("[RampKit]
|
|
589
|
-
|
|
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 (
|
|
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
|
-
|
|
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]
|
|
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