Skip to content

Commit e647100

Browse files
Merge pull request #241 from qonversion/release/8.0.0
Release/8.0.0
2 parents 0887ff8 + 756df00 commit e647100

20 files changed

+205
-47
lines changed

Editor/QonversionDependencies.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<dependencies>
33
<androidPackages>
4-
<androidPackage spec="io.qonversion.sandwich:sandwich:4.5.0" />
4+
<androidPackage spec="io.qonversion.sandwich:sandwich:5.0.3" />
55
<androidPackage spec="com.fasterxml.jackson.core:jackson-databind:2.11.1" />
66
<androidPackage spec="org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.61" />
77
</androidPackages>
88
<iosPods>
9-
<iosPod name="QonversionSandwich" version="4.5.0" />
9+
<iosPod name="QonversionSandwich" version="5.0.3" />
1010
</iosPods>
1111
</dependencies>

Runtime/Android/Plugins/com/qonversion/unitywrapper/QonversionWrapper.java

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import com.fasterxml.jackson.core.type.TypeReference;
1818
import com.fasterxml.jackson.databind.ObjectMapper;
1919

20-
import io.qonversion.sandwich.PurchaseResultListener;
2120
import io.qonversion.sandwich.QonversionSandwich;
2221
import io.qonversion.sandwich.ResultListener;
2322
import io.qonversion.sandwich.SandwichError;
@@ -117,7 +116,7 @@ public static synchronized void checkEntitlements(String unityCallbackName) {
117116
}
118117

119118
public static synchronized void purchase(String productId, @Nullable String offerId, boolean applyOffer, String unityCallbackName) {
120-
qonversionSandwich.purchase(productId, offerId, applyOffer, getPurchaseResultListener(unityCallbackName));
119+
qonversionSandwich.purchase(productId, offerId, applyOffer, getResultListener(unityCallbackName));
121120
}
122121

123122
public static synchronized void updatePurchase(
@@ -128,7 +127,7 @@ public static synchronized void updatePurchase(
128127
@Nullable String updatePolicyKey,
129128
String unityCallbackName
130129
) {
131-
qonversionSandwich.updatePurchase(productId, offerId, applyOffer, oldProductId, updatePolicyKey, getPurchaseResultListener(unityCallbackName));
130+
qonversionSandwich.updatePurchase(productId, offerId, applyOffer, oldProductId, updatePolicyKey, getResultListener(unityCallbackName));
132131
}
133132

134133
public static synchronized void restore(String unityCallbackName) {
@@ -180,6 +179,10 @@ public static synchronized void detachUserFromRemoteConfiguration(String remoteC
180179
qonversionSandwich.detachUserFromRemoteConfiguration(remoteConfigurationId, getResultListener(unityCallbackName));
181180
}
182181

182+
public static synchronized void isFallbackFileAccessible(String unityCallbackName) {
183+
qonversionSandwich.isFallbackFileAccessible(getResultListener(unityCallbackName));
184+
}
185+
183186
public static synchronized void checkTrialIntroEligibility(String productIds, String unityCallbackName) {
184187
try {
185188
ObjectMapper mapper = new ObjectMapper();
@@ -206,24 +209,6 @@ public void onError(@NonNull SandwichError error) {
206209
};
207210
}
208211

209-
private static PurchaseResultListener getPurchaseResultListener(@NotNull String methodName) {
210-
return new PurchaseResultListener() {
211-
@Override
212-
public void onSuccess(@NonNull Map<String, ?> data) {
213-
sendMessageToUnity(data, methodName);
214-
}
215-
216-
@Override
217-
public void onError(@NonNull SandwichError error, boolean isCancelled) {
218-
final ObjectMapper mapper = new ObjectMapper();
219-
final ObjectNode rootNode = Utils.createErrorNode(error);
220-
final JsonNode isCancelledNode = mapper.convertValue(isCancelled, JsonNode.class);
221-
rootNode.set("isCancelled", isCancelledNode);
222-
sendMessageToUnity(rootNode, methodName);
223-
}
224-
};
225-
}
226-
227212
private static ResultListener getRemoteConfigResultListener(@Nullable String contextKey, @NotNull String methodName) {
228213
return new ResultListener() {
229214
@Override

Runtime/Android/QonversionWrapperAndroid.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,11 @@ public void DetachUserFromRemoteConfiguration(string remoteConfigurationId, stri
183183
CallQonversion("detachUserFromRemoteConfiguration", remoteConfigurationId, callbackName);
184184
}
185185

186+
public void IsFallbackFileAccessible(string callbackName)
187+
{
188+
CallQonversion("isFallbackFileAccessible", callbackName);
189+
}
190+
186191
public void CheckTrialIntroEligibility(string productIdsJson, string callbackName)
187192
{
188193
CallQonversion("checkTrialIntroEligibility", productIdsJson, callbackName);

Runtime/Scripts/Dto/Eligibility.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ private EligibilityStatus FormatEligibilityStatus(object status)
2323
switch (value)
2424
{
2525
case "non_intro_or_trial_product":
26-
result = EligibilityStatus.NonIntroProduct;
26+
result = EligibilityStatus.NonIntroOrTrialProduct;
2727
break;
2828
case "intro_or_trial_ineligible":
2929
result = EligibilityStatus.Ineligible;

Runtime/Scripts/Dto/EligibilityStatus.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
public enum EligibilityStatus
44
{
55
Unknown,
6-
NonIntroProduct,
6+
NonIntroOrTrialProduct,
77
Ineligible,
88
Eligible
99
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace QonversionUnity
5+
{
6+
/// <summary>
7+
/// This class represents the details about the installment plan for a subscription product.
8+
/// </summary>
9+
public class ProductInstallmentPlanDetails
10+
{
11+
/// Committed payments count after a user signs up for this subscription plan.
12+
public readonly int CommitmentPaymentsCount;
13+
14+
/// Subsequent committed payments count after this subscription plan renews.
15+
///
16+
/// Returns 0 if the installment plan doesn't have any subsequent commitment,
17+
/// which means this subscription plan will fall back to a normal
18+
/// non-installment monthly plan when the plan renews.
19+
public readonly int SubsequentCommitmentPaymentsCount;
20+
21+
public ProductInstallmentPlanDetails(Dictionary<string, object> dict)
22+
{
23+
if (dict.TryGetValue("commitmentPaymentsCount", out object value)) CommitmentPaymentsCount = (int)(long)value;
24+
if (dict.TryGetValue("subsequentCommitmentPaymentsCount", out value)) SubsequentCommitmentPaymentsCount = (int)(long)value;
25+
}
26+
27+
public override string ToString()
28+
{
29+
return $"{nameof(CommitmentPaymentsCount)}: {CommitmentPaymentsCount}, " +
30+
$"{nameof(SubsequentCommitmentPaymentsCount)}: {SubsequentCommitmentPaymentsCount}";
31+
}
32+
}
33+
}

Runtime/Scripts/Dto/ProductStoreDetails/ProductInstallmentPlanDetails.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Runtime/Scripts/Dto/ProductStoreDetails/ProductOfferDetails.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ public class ProductOfferDetails
2929
/// A base plan phase details.
3030
[CanBeNull] public readonly ProductPricingPhase BasePlan;
3131

32+
/// Additional details of an installment plan, if exists.
33+
[CanBeNull] public readonly ProductInstallmentPlanDetails InstallmentPlanDetails;
34+
3235
/// A trial phase details, if exists.
3336
[CanBeNull] public readonly ProductPricingPhase IntroPhase;
3437

@@ -81,6 +84,11 @@ public ProductOfferDetails(Dictionary<string, object> dict)
8184
{
8285
BasePlan = new ProductPricingPhase(basePlan);
8386
}
87+
88+
if (dict.TryGetValue("installmentPlanDetails", out value) && value is Dictionary<string, object> installmentPlan)
89+
{
90+
InstallmentPlanDetails = new ProductInstallmentPlanDetails(installmentPlan);
91+
}
8492

8593
if (dict.TryGetValue("introPhase", out value) && value is Dictionary<string, object> introPhase)
8694
{
@@ -117,6 +125,7 @@ public override string ToString()
117125
$"{nameof(Tags)}: {tags}, " +
118126
$"{nameof(PricingPhases)}: {pricingPhases}, " +
119127
$"{nameof(BasePlan)}: {BasePlan}, " +
128+
$"{nameof(InstallmentPlanDetails)}: {InstallmentPlanDetails}, " +
120129
$"{nameof(IntroPhase)}: {IntroPhase}, " +
121130
$"{nameof(TrialPhase)}: {TrialPhase}, " +
122131
$"{nameof(HasTrial)}: {HasTrial}, " +

Runtime/Scripts/Dto/ProductStoreDetails/ProductStoreDetails.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ public class ProductStoreDetails
7474
/// they will need to make a new payment to extend their plan.
7575
public readonly bool IsPrepaid;
7676

77+
/// True, if the subscription product is installment, which means that users commit
78+
/// to pay for a specified amount of periods every month.
79+
public readonly bool IsInstallment;
80+
7781
public ProductStoreDetails(Dictionary<string, object> dict)
7882
{
7983
if (dict.TryGetValue("productId", out object value)) ProductId = value as string;
@@ -119,6 +123,7 @@ public ProductStoreDetails(Dictionary<string, object> dict)
119123
if (dict.TryGetValue("isInApp", out value)) IsInApp = (bool)value;
120124
if (dict.TryGetValue("isSubscription", out value)) IsSubscription = (bool)value;
121125
if (dict.TryGetValue("isPrepaid", out value)) IsPrepaid = (bool)value;
126+
if (dict.TryGetValue("isInstallment", out value)) IsInstallment = (bool)value;
122127
}
123128

124129
public override string ToString()
@@ -144,7 +149,8 @@ public override string ToString()
144149
$"{nameof(ProductType)}: {ProductType}, " +
145150
$"{nameof(IsInApp)}: {IsInApp}, " +
146151
$"{nameof(IsSubscription)}: {IsSubscription}, " +
147-
$"{nameof(IsPrepaid)}: {IsPrepaid}";
152+
$"{nameof(IsPrepaid)}: {IsPrepaid}" +
153+
$"{nameof(IsInstallment)}: {IsInstallment}";
148154
}
149155
}
150156
}

Runtime/Scripts/Dto/QonversionError.cs

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1+
using System;
12
using System.Collections.Generic;
23

34
namespace QonversionUnity
45
{
56
public class QonversionError
67
{
7-
public string Code;
8+
public QErrorCode Code;
89
public string Message;
910

1011
public QonversionError(Dictionary<string, object> dict)
1112
{
12-
if (dict.TryGetValue("code", out object value)) Code = value as string;
13+
if (dict.TryGetValue("code", out object value)) Code = FormatErrorCode(value);
1314
string message = "";
1415
if (dict.TryGetValue("description", out object description))
1516
{
@@ -27,7 +28,7 @@ public QonversionError(Dictionary<string, object> dict)
2728
Message = message;
2829
}
2930

30-
internal QonversionError(string code, string message)
31+
internal QonversionError(QErrorCode code, string message)
3132
{
3233
Code = code;
3334
Message = message;
@@ -38,5 +39,54 @@ public override string ToString()
3839
return $"{nameof(Code)}: {Code}, " +
3940
$"{nameof(Message)}: {Message}";
4041
}
42+
43+
private QErrorCode FormatErrorCode(object code)
44+
{
45+
return Enum.TryParse(code.ToString(), out QErrorCode parsedSource)
46+
? parsedSource
47+
: QErrorCode.Unknown;
48+
}
49+
}
50+
51+
public enum QErrorCode
52+
{
53+
Unknown, // Unknown error
54+
ApiRateLimitExceeded, // API requests rate limit exceeded
55+
AppleStoreError, // Apple Store error received
56+
BackendError, // There was a backend error
57+
BillingUnavailable, // The Billing service is unavailable on the device
58+
ClientInvalid, // Client is not allowed to issue the request, etc
59+
CloudServiceNetworkConnectionFailed, // The device could not connect to the network
60+
CloudServicePermissionDenied, // User is not allowed to access cloud service information
61+
CloudServiceRevoked, // User has revoked permission to use this cloud service
62+
FailedToReceiveData, // Could not receive data
63+
FeatureNotSupported, // The requested feature is not supported
64+
FraudPurchase, // Fraud purchase was detected
65+
IncorrectRequest, // Request failed
66+
InternalError, // Internal backend error
67+
InvalidClientUid, // Client Uid is invalid or not set
68+
InvalidCredentials, // Access token is invalid or not set
69+
InvalidStoreCredentials, // This account does not have access to the requested application
70+
LaunchError, // There was an error while launching Qonversion SDK
71+
NetworkConnectionFailed, // There was a network issue. Make sure that the Internet connection is available on the device
72+
OfferingsNotFound, // No offerings found
73+
PaymentInvalid, // Purchase identifier was invalid, etc.
74+
PaymentNotAllowed, // This device is not allowed to make the payment
75+
PlayStoreError, // There was an issue with the Play Store service
76+
PrivacyAcknowledgementRequired, // User needs to acknowledge Apple's privacy policy
77+
ProductAlreadyOwned, // Failed to purchase since item is already owned
78+
ProductNotFound, // Failed to purchase since the Qonversion product was not found
79+
ProductNotOwned, // Failed to consume purchase since item is not owned
80+
ProjectConfigError, // The project is not configured or configured incorrectly in the Qonversion Dashboard
81+
PurchaseCanceled, // User pressed back or canceled a dialog for purchase
82+
PurchaseInvalid, // Failure of purchase
83+
PurchasePending, // Purchase is pending
84+
PurchaseUnspecified, // Unspecified state of the purchase
85+
ReceiptValidationError, // Receipt validation error
86+
RemoteConfigurationNotAvailable, // Remote configuration is not available for the current user or for the provided context key
87+
ResponseParsingFailed, // A problem occurred while serializing or deserializing data
88+
StoreProductNotAvailable, // Requested product is not available for purchase or its product id was not found
89+
UnauthorizedRequestData, // App is attempting to use SKPayment's requestData property, but does not have the appropriate entitlement
90+
UnknownClientPlatform, // The current platform is not supported
4191
}
4292
}

0 commit comments

Comments
 (0)