Skip to main content

Hello everybody,

After the incident of a few days ago where RevenueCat was not accessible in China, we have deployed the recommended fix as quickly as possible, however it doesn’t seem to be working.

We keep receiving messages from users that they cannot access paid features nor see the paywall because of a “network error”. Our error reporting tool logs error related to the SSL verification:

Error Domain=RevenueCat.ErrorCode Code=10 "A network error has occurred. 请求超时。" UserInfo={source_function=init(_:dnsChecker:), NSLocalizedDescription=A network error has occurred. 请求超时。, NSUnderlyingError=0x300e8b120 {Error Domain=NSURLErrorDomain Code=-1001 "请求超时。" UserInfo={_kCFStreamErrorCodeKey=-2103, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <8F169AC4-0EF6-4C8D-85B4-001912B77290>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "LocalDataTask <8F169AC4-0EF6-4C8D-85B4-001912B77290>.<1>"
), NSLocalizedDescription=请求超时。, NSErrorFailingURLStringKey=https://api.revenuecat.com/v1/subscribers/CN_1612641B-6FFB-4BCE-9B5D-529303B6AD6F/offerings, NSErrorFailingURLKey=https://api.revenuecat.com/v1/subscribers/CN_1612641B-6FFB-4BCE-9B5D-529303B6AD6F/offerings, _kCFStreamErrorDomainKey=4}}, readable_error_code=NETWORK_ERROR, source_file=RevenueCat/HTTPClient.swift:791}


I already opened a ticket with the RevenueCat support but I haven’t received a response. I understand the timing is unfortunate, considering the Christmas break, but I hope we can figure something out quickly.

I’m bringing this problem up here as well in case anybody else has the same issue.

Replying to my own post in case anybody else has the same problem.

The RevenueCat support team has replied and they cannot see any problem on their side, so I guess this SSL issue only affects some users. During the high peak, we were seeing about 100-200 error reports per day over different users, with some seeing the same error multiple times and others only seeing it once or twice.

We ended up deploying our own proxy solution and that worked. We have seen zero reports since we released this update.

 

In case anybody is facing the same issue and would also like to deploy a custom proxy, here’s a high-level overview of how to do it, as there is no documentation from RevenueCat.

  1. Find a service that can deploy to China. We chose Cloudflare, because we were already using it, but you can also use AWS China or Azure China (be aware that deploying Internet services to China has some legal implications).
  2. Write a simple proxy service that takes any request and passes it to the RevenueCat API.
    1. If you’re using Cloudflare, there’s a code sample below.
  3. Connect a subdomain of your own domain to the proxy service.
    1. On Cloudflare, you can do that using Worker Routes after configuring a CNAME alias on your main domain (assuming that’s handled by Cloudflare). For example, if your domain is example.com, you can configure a DNS CNAME entry for proxy.example.com.
  4. Update the proxyURL field of the SDK before initializing it to point to your subdomain.

  5. Release an update of the app and monitor new errors.

Example proxy function for Cloudflare

This example works in a Cloudflare worker and it also implements a retry policy before failing. It expects an environment variable called REVENUECAT_HOST to be defined and point to api.revenuecat.com.

export default {
// This function is invoked when the route associated to this worker is hit.
// In this case, the route is proxy.linearity.io.
async fetch(request, env, ctx) {
// We could use a different URL depending on whether the user is in China or
// not, but the URL that RevenueCat provides for China doesn't work anyway,
// so for now we can always proxy to the same URL.
// const isFromChina = request.cf && request.cf.country === "CN";
const revenueCatHostname = env.REVENUECAT_HOST;

// Add the proxied header so that RevenueCat knows this request
// has been proxied.
const modifiedHeaders = new Headers(request.headers);
modifiedHeaders.set("X-Forwarded-For", request.headers.get("CF-Connecting-IP"));

// Replace the original hostname with the RevenueCat hostname
// without changing anything else.
var forwardedRequestURL = request.url;
try {
var requestURL = new URL(request.url);
requestURL.hostname = revenueCatHostname;

forwardedRequestURL = requestURL;
} catch {
return new Response("Invalid request URL.", { status: 400 })
}

try {
// Perform the request and retry a limited amount of times if it fails.
const response = await fetchWithRetry(forwardedRequestURL, {
method: request.method,
headers: modifiedHeaders,
body: request.body,
});

// Return the same response that RevenueCat sent.
return new Response(response.body, {
status: response.status,
headers: response.headers,
});
} catch (error) {
// Fail gracefully if the request cannot be proxied.
return new Response("Service unavailable. Please try again later. Request failed with error: " + error, { status: 503 });
}
},
};

async function fetchWithRetry(url, options, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
return await fetch(url, options);
} catch (err) {
if (i === retries - 1) throw err;
}
}
}

Hi ​@alessio-linearity,

We have been unblocked by China for some days now and we are seeing traffic going back to normal.

While it’s recommended using the proxy, now the service it’s restore and the same as before.

Best,


Hi ​@alessio-linearity,

We have been unblocked by China for some days now and we are seeing traffic going back to normal.

While it’s recommended using the proxy, now the service it’s restore and the same as before.

Best,

Hi Joan,

I just wanted to highlight that while this problem is no longer widespread, it still exists. Your domains (both the main one and the proxy one) are still subject to DNS poisoning in China with some specific ISPs.

I already highlighted this with your customer support and provided multiple examples of users that are still unable to purchase and/or use the paid features.

Specifically, we’re still seeing about ~100 unique users over the past few days who face the “SSL connection issue” and are hence unable to use the app.

I’d recommend anybody that is looking into RevenueCat and has a significant user base in China to also consider using StoreKit directly, at least until RevenueCat opens a legal entity in China (or deploys an alternative solution, such as a proxy using the Cloudflare China Network).

RevenueCat remains an excellent product for the rest of the world, but it just cannot be trusted at this stage for China. Users that face connectivity issues are either stuck on the paywall unable to convert or (worse) unable to access paid features, because the SDK cannot download the entitlements.