Containers and platforms

How to set up HTTPS server domains for a WeChat Mini Program

By · Last verified

A WeChat Mini Program can call your API only if its domain, such as api.example.com, has an ICP filing, a trusted certificate with a complete chain and TLS 1.2 or later, and is registered as a server domain in the Mini Program console.

The rules come from the WeChat Mini Program documentation as of November 2026. The English pages are translations; where they read ambiguously, the steps follow the stricter interpretation.

Prerequisites

WeChat is stricter about server domains than a browser.

  • A domain with an ICP filing, for example api.example.com, with an A record pointing at your server, for example 203.0.113.10. ICP filing is a registration with China's Ministry of Industry and Information Technology, normally submitted through a hosting or cloud provider that operates in the Chinese mainland, and it takes time, so start early.
  • An API already reachable over HTTPS, with a certificate from a publicly trusted CA (Let's Encrypt and the free Alibaba Cloud or Tencent Cloud certificates all qualify). Self-signed certificates do not work.
  • Administrator or developer access to the Mini Program in the WeChat Official Accounts Platform (the Mini Program console).

Step 1: Check the chain and TLS 1.2

A missing intermediate certificate is the most common reason a Mini Program fails on phones while the same URL opens fine in a desktop browser, because desktop browsers often fill gaps in the chain themselves.

openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null | grep -E '^ *[0-9] s:'
openssl s_client -connect api.example.com:443 -servername api.example.com -tls1_2 </dev/null 2>/dev/null | grep -E 'Protocol|Cipher'

The first command should list at least two certificates (depth 0 and 1); the second should negotiate TLSv1.2. If the chain is short, fix it with install an intermediate certificate or build the file with the chain builder.

Step 2: Use a sound TLS configuration on the server

With Nginx, point ssl_certificate at the full chain and enable TLS 1.2 and 1.3:

server {
    listen 443 ssl;
    http2 on;    # nginx 1.25.1+; older versions use "listen 443 ssl http2;"
    server_name api.example.com;

    ssl_certificate     /etc/letsencrypt/live/api.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
    ssl_protocols       TLSv1.2 TLSv1.3;

    location / {
        proxy_pass http://127.0.0.1:3000;
    }
}

No certificate yet? Follow Nginx with Let's Encrypt or Tencent Cloud SSL certificate.

Step 3: Register the server domains

In the Mini Program console go to Development → Development Settings → Server Domains and edit the lists:

  • request domains: https://api.example.com
  • socket domains: wss://api.example.com, if you use WebSocket
  • uploadFile and downloadFile domains: as needed

The rules that catch people out:

  • Only https:// and wss:// entries are accepted, and IP addresses (other than the Mini Program's LAN IP, allowed from base library 2.4.0) and localhost are rejected.
  • If you configure a port, such as https://api.example.com:8443, only that exact origin works. If you configure none, the request URL must not include a port at all, not even :443. WSS entries need no port and allow any.
  • api.weixin.qq.com cannot be configured; call it from your server, not from the Mini Program.
  • Each change counts against a limited number of edits, shown in the console.

Step 4: Test on real phones

Test on real phones with domain and certificate validation turned on. The WeChat developer tools have a local setting that skips validation of legal domains, web-view (business) domains, TLS versions and HTTPS certificates; it exists for local debugging only. Clear it, then test with real-device debugging or a preview QR code on both an iPhone and an Android phone. iOS additionally applies Apple's App Transport Security rules and rejects self-signed certificates.

Verify

The API domain should show a complete chain, TLS 1.2 or 1.3 support and a future expiry date. Check it with the SSL checker, or from any terminal:

curl ssl.sh/api.example.com

Automatic renewal

Renewing the certificate changes nothing in the Mini Program console, because the domain stays the same. The real risk is expiry: once the certificate expires, every request from every user fails, and users get no warning they could click through. Three measures prevent that:

  • Renew automatically with Certbot, acme.sh or similar, and reload Nginx after each renewal; see renew certificates automatically.
  • Free cloud certificates are short-lived as well (Tencent Cloud's free certificate lasts 3 months) and all public certificates are capped at 200 days since March 15, 2026 and 47 days from March 15, 2029, so manual replacement will eventually slip.
  • Add the API domain to ssl.sh monitoring (in development) to get a warning before expiry.

Troubleshooting

  • request:fail url not in domain list: the domain is not registered, or the scheme or port differs; see the FAQ.
  • request:fail ssl hand shake error: incomplete chain, no TLS 1.2, an expired certificate or a name mismatch; see missing intermediate certificate and ERR_SSL_VERSION_OR_CIPHER_MISMATCH.
  • Works on Android, fails on iOS (or the reverse): almost always the chain; the platforms differ in how they complete missing intermediates.
  • Self-signed certificate: Mini Programs do not trust it; use a publicly trusted CA, see self-signed certificate in certificate chain.
  • Every request suddenly fails: the certificate expired; see NET::ERR_CERT_DATE_INVALID, then add automatic renewal and monitoring.

FAQ

Can I use a free Let's Encrypt certificate?

Yes. WeChat requires a valid certificate from a CA trusted by the phone, which Let's Encrypt and the free certificates from Alibaba Cloud or Tencent Cloud all are. What matters is a complete chain, TLS 1.2 or later, and fully automatic renewal, because an expired certificate breaks every request.

The domain is configured, but the phone still says url not in domain list. Why?

Check four things: the scheme and host match exactly (HTTPS and WSS are configured separately); the request uses a port that is not configured, or omits one that is; the Mini Program was reopened after the change; and the URL is a server domain, not a business domain used by web-view.

Do pages opened in web-view have the same rules?

Mostly. Pages loaded in web-view must be on a business domain, configured under Development Settings → Business Domains: HTTPS only, no IP addresses, ICP filing required, plus a verification file placed on the site. A newly filed domain can be added after 24 hours.

My API server is outside mainland China. Is ICP filing still required?

Yes. WeChat's documentation states that server domains must have ICP filing and makes no exception for servers abroad. Plan for the filing before launch; the domain itself is what the Mini Program console checks.

Sources

  1. WeChat Mini Program: Network usage instructions
  2. WeChat Mini Program: Business domains
  3. Let's Encrypt: Challenge Types
  4. nginx: Configuring HTTPS servers