diff --git a/IntegrationTests/Assets/APITests/PurchasesAPITests.cs b/IntegrationTests/Assets/APITests/PurchasesAPITests.cs
index 7587527b..7360c87d 100644
--- a/IntegrationTests/Assets/APITests/PurchasesAPITests.cs
+++ b/IntegrationTests/Assets/APITests/PurchasesAPITests.cs
@@ -228,7 +228,9 @@ private void Start()
.SetDiagnosticsEnabled(true)
.SetAutomaticDeviceIdentifierCollectionEnabled(false)
.SetPreferredUILocaleOverride("de_DE")
+ .SetProxyURL("https://proxy.revenuecat.com")
.Build();
+ string proxyURL = purchasesConfiguration.ProxyURL;
purchases.Configure(purchasesConfiguration);
purchases.RecordPurchase("product_id", (transaction, error) =>
{
diff --git a/IntegrationTests/Assets/Tests/EditMode/PurchasesCallTests.cs b/IntegrationTests/Assets/Tests/EditMode/PurchasesCallTests.cs
index 2e77ce78..9488e799 100644
--- a/IntegrationTests/Assets/Tests/EditMode/PurchasesCallTests.cs
+++ b/IntegrationTests/Assets/Tests/EditMode/PurchasesCallTests.cs
@@ -65,6 +65,42 @@ public void ConfigureForwardsEveryConfigurationValue()
Assert.That(invocation.Arguments[13], Is.EqualTo("de_DE"));
}
+ ///
+ /// The proxy URL has to reach the native SDK before it is configured, so this pins the order
+ /// rather than just the fact that both calls happen.
+ ///
+ [Test]
+ public void ConfigureSetsProxyUrlBeforeSettingUp()
+ {
+ var configuration = Purchases.PurchasesConfiguration.Builder
+ .Init("test_api_key")
+ .SetProxyURL("https://proxy.revenuecat.com")
+ .Build();
+
+ _purchases.Configure(configuration);
+
+ Assert.That(_wrapper.Invocations, Has.Count.EqualTo(2));
+ Assert.That(_wrapper.Invocations[0].Method, Is.EqualTo(nameof(IPurchasesWrapper.SetProxyURL)));
+ Assert.That(_wrapper.Invocations[0].Arguments[0], Is.EqualTo("https://proxy.revenuecat.com"));
+ Assert.That(_wrapper.Invocations[1].Method, Is.EqualTo(nameof(IPurchasesWrapper.Setup)));
+ }
+
+ ///
+ /// A configuration that carries no proxy URL must not call the wrapper at all, otherwise it would
+ /// clear a proxy URL already set through the inspector field on Purchases.
+ ///
+ [Test]
+ public void ConfigureWithoutProxyUrlDoesNotCallSetProxyUrl()
+ {
+ var configuration = Purchases.PurchasesConfiguration.Builder
+ .Init("test_api_key")
+ .Build();
+
+ _purchases.Configure(configuration);
+
+ AssertOnlyInvocation(nameof(IPurchasesWrapper.Setup), 14);
+ }
+
private PurchasesWrapperSpy.Invocation AssertOnlyInvocation(string method, int argumentCount)
{
Assert.That(_wrapper.Invocations, Has.Count.EqualTo(1));
diff --git a/IntegrationTests/Assets/Tests/EditMode/PurchasesConfigurationTests.cs b/IntegrationTests/Assets/Tests/EditMode/PurchasesConfigurationTests.cs
index cfa3625e..fd894604 100644
--- a/IntegrationTests/Assets/Tests/EditMode/PurchasesConfigurationTests.cs
+++ b/IntegrationTests/Assets/Tests/EditMode/PurchasesConfigurationTests.cs
@@ -36,6 +36,7 @@ public void BuildUsesBuilderDefaults()
Assert.That(configuration.DiagnosticsEnabled, Is.False);
Assert.That(configuration.AutomaticDeviceIdentifierCollectionEnabled, Is.True);
Assert.That(configuration.PreferredUILocaleOverride, Is.Null);
+ Assert.That(configuration.ProxyURL, Is.Null);
}
[Test]
@@ -56,6 +57,7 @@ public void BuildUsesConfiguredValues()
.SetDiagnosticsEnabled(true)
.SetAutomaticDeviceIdentifierCollectionEnabled(false)
.SetPreferredUILocaleOverride("de_DE")
+ .SetProxyURL("https://proxy.revenuecat.com")
.Build();
Assert.That(configuration.AppUserId, Is.EqualTo("app_user_id"));
@@ -70,6 +72,7 @@ public void BuildUsesConfiguredValues()
Assert.That(configuration.DiagnosticsEnabled, Is.True);
Assert.That(configuration.AutomaticDeviceIdentifierCollectionEnabled, Is.False);
Assert.That(configuration.PreferredUILocaleOverride, Is.EqualTo("de_DE"));
+ Assert.That(configuration.ProxyURL, Is.EqualTo("https://proxy.revenuecat.com"));
}
[Test]
diff --git a/RevenueCat/Scripts/Purchases.cs b/RevenueCat/Scripts/Purchases.cs
index 4a4174c7..1965f18d 100644
--- a/RevenueCat/Scripts/Purchases.cs
+++ b/RevenueCat/Scripts/Purchases.cs
@@ -92,8 +92,9 @@ public partial class Purchases : MonoBehaviour
[Header("Advanced")]
[Tooltip("Set this property to your proxy URL before configuring Purchases *only* if you've received " +
"a proxy key value from your RevenueCat contact.\n" +
- "NOTE: This value will be ignored if \"Use Runtime Setup\" is true. For Runtime Setup, you can configure " +
- "it through PurchasesConfiguration instead")]
+ "NOTE: Unlike the other fields here, this one is applied even when \"Use Runtime Setup\" is true. " +
+ "If you configure at runtime you can set it through " +
+ "PurchasesConfiguration.Builder.SetProxyURL instead.")]
public string proxyURL;
private IPurchasesWrapper _wrapper;
@@ -115,6 +116,11 @@ private void Start()
#else
SetWrapper(new PurchasesWrapperNoop());
#endif
+ // Deliberately applied above the early return, so it takes effect on both the inspector and the
+ // runtime-setup paths. That makes it the one inspector field runtime setup does not ignore: the
+ // others are read by Configure below, which runtime setup skips. Aligning it with them would stop
+ // runtime-setup apps from picking up an inspector-set proxy URL, silently sending their traffic
+ // straight to RevenueCat, so that change is deferred to the next major.
if (!string.IsNullOrEmpty(proxyURL))
{
_wrapper.SetProxyURL(proxyURL);
@@ -194,6 +200,14 @@ public void Setup(PurchasesConfiguration purchasesConfiguration)
///
public void Configure(PurchasesConfiguration purchasesConfiguration)
{
+ // Only forwarded when set, for two reasons: it mirrors how the inspector field is applied in
+ // Start, and it keeps a configuration that carries no proxy URL from clearing one that was
+ // already set through the inspector.
+ if (!string.IsNullOrEmpty(purchasesConfiguration.ProxyURL))
+ {
+ _wrapper.SetProxyURL(purchasesConfiguration.ProxyURL);
+ }
+
var dangerousSettings = purchasesConfiguration.DangerousSettings.Serialize().ToString();
_wrapper.Setup(gameObject.name, purchasesConfiguration.ApiKey, purchasesConfiguration.AppUserId,
purchasesConfiguration.PurchasesAreCompletedBy, purchasesConfiguration.StoreKitVersion, purchasesConfiguration.UserDefaultsSuiteName,
diff --git a/RevenueCat/Scripts/PurchasesConfiguration.cs b/RevenueCat/Scripts/PurchasesConfiguration.cs
index 9bfcbbc1..2547dcba 100644
--- a/RevenueCat/Scripts/PurchasesConfiguration.cs
+++ b/RevenueCat/Scripts/PurchasesConfiguration.cs
@@ -36,11 +36,12 @@ public class PurchasesConfiguration
public readonly bool DiagnosticsEnabled;
public readonly bool AutomaticDeviceIdentifierCollectionEnabled;
public readonly string PreferredUILocaleOverride;
+ public readonly string ProxyURL;
private PurchasesConfiguration(string apiKey, string appUserId, PurchasesAreCompletedBy purchasesAreCompletedBy, string userDefaultsSuiteName,
bool useAmazon, DangerousSettings dangerousSettings, StoreKitVersion storeKitVersion, bool shouldShowInAppMessagesAutomatically,
EntitlementVerificationMode entitlementVerificationMode, bool pendingTransactionsForPrepaidPlansEnabled, bool diagnosticsEnabled,
- bool automaticDeviceIdentifierCollectionEnabled, string preferredUILocaleOverride)
+ bool automaticDeviceIdentifierCollectionEnabled, string preferredUILocaleOverride, string proxyURL)
{
ApiKey = apiKey;
AppUserId = appUserId;
@@ -55,6 +56,7 @@ private PurchasesConfiguration(string apiKey, string appUserId, PurchasesAreComp
DiagnosticsEnabled = diagnosticsEnabled;
AutomaticDeviceIdentifierCollectionEnabled = automaticDeviceIdentifierCollectionEnabled;
PreferredUILocaleOverride = preferredUILocaleOverride;
+ ProxyURL = proxyURL;
}
///
@@ -91,6 +93,7 @@ public class Builder
private bool _diagnosticsEnabled;
private bool _automaticDeviceIdentifierCollectionEnabled = true;
private string _preferredUILocaleOverride;
+ private string _proxyURL;
private Builder(string apiKey)
{
@@ -108,7 +111,7 @@ public PurchasesConfiguration Build()
return new PurchasesConfiguration(_apiKey, _appUserId, _purchasesAreCompletedBy, _userDefaultsSuiteName,
_useAmazon, _dangerousSettings, _storeKitVersion, _shouldShowInAppMessagesAutomatically,
_entitlementVerificationMode, _pendingTransactionsForPrepaidPlansEnabled, _diagnosticsEnabled,
- _automaticDeviceIdentifierCollectionEnabled, _preferredUILocaleOverride);
+ _automaticDeviceIdentifierCollectionEnabled, _preferredUILocaleOverride, _proxyURL);
}
public Builder SetAppUserId(string appUserId)
@@ -197,6 +200,17 @@ public Builder SetPreferredUILocaleOverride(string preferredUILocaleOverride)
return this;
}
+ ///
+ /// Sets the proxy URL used for all RevenueCat network requests. Only set this if you have
+ /// received a proxy key value from your RevenueCat contact.
+ /// The proxy URL is applied before the SDK is configured.
+ ///
+ public Builder SetProxyURL(string proxyURL)
+ {
+ _proxyURL = proxyURL;
+ return this;
+ }
+
}
public override string ToString()
@@ -214,7 +228,8 @@ public override string ToString()
$"{nameof(PendingTransactionsForPrepaidPlansEnabled)}: {PendingTransactionsForPrepaidPlansEnabled}\n" +
$"{nameof(DiagnosticsEnabled)}: {DiagnosticsEnabled}\n" +
$"{nameof(AutomaticDeviceIdentifierCollectionEnabled)}: {AutomaticDeviceIdentifierCollectionEnabled}\n" +
- $"{nameof(PreferredUILocaleOverride)}: {PreferredUILocaleOverride}\n";
+ $"{nameof(PreferredUILocaleOverride)}: {PreferredUILocaleOverride}\n" +
+ $"{nameof(ProxyURL)}: {ProxyURL}\n";
}
}
}