Skip to content

Call flows

WeChat VoIP calling involves multiple parties; the sequence diagrams below are important for understanding who does what.

The diagrams label key English identifiers and parameters for cross-checking with the API documentation.

Scenario 1: Mini Program calls the device (before answer)

Mini Program calls device — sequence overview

Note: In this scenario, before answer, the device has not yet established a TiRTC connection to the Tange platform. Therefore, note the following:

  • Mini Program cancels the call

Because there is no TiRTC link to the platform yet, the Mini Program must ask the business server to notify the device to cancel.

  • Device rejects

User reject, device busy, or other pre-answer end paths should report the reason through the device-side service request TiRtcServiceRequest("/v1/wxvoip/reject", ...). At this point the device has not established a TiRTC connection, so it cannot use the command channel to send the hang-up command (cmdw=0x2001).

hangup_reason uses the same hang-up reason values as WeChat VoIP Calling Commands: use 5 for busy and 7 for user reject. Request body fields come from the wxa_join_voip_room payload delivered by the business server; see Device integration.

FAQ

  • Why is there “Mini Program cancels” but no “device cancels” in this scenario?

Here the Mini Program is the caller; the device only answers or rejects, it does not “cancel the outgoing call” in the same sense.

Scenario 2: Device calls the Mini Program (before answer)

Device calls Mini Program — sequence overview

Note: In this scenario, the device is the caller. The flow is:

  1. Device calls the business server POST /v1/voip/device/call, which internally calls WeChat iot/voip/call.
  2. The Mini Program rings; once the user answers, WeChat sends join_voip_room to the business server.
  3. The business server processes the callback and pushes call_incoming to the device.
  4. The device calls TiRtcWhipConnect to join the room; after connecting successfully, it receives cmdw=0x2000 (both sides established), and enters the call directly since WeChat has already set up the room.

Therefore:

  • Device aborts the call before answer: the device cancels locally (no TiRTC connection yet); after answer, the device sends the hang-up command (cmdw=0x2001).
  • Mini Program rejects: delivered by the cloud as the hang-up command (cmdw=0x2001) to the device.

In call (after answer)

The following applies whether the Mini Program or the device placed the call.

In call — media and hang-up
  • Connected: After TiRtcWhipConnect succeeds, the device receives cmdw=0x2000 from the platform, meaning both sides are established. This applies to both scenarios — whether the device is the callee or the caller.
  • Device hang-up during the call: Same pattern as device abort when the device was the caller.
  • Mini Program hang-up during the call: Same pattern as Mini Program reject when the device was the caller.

Media and stream_id

After connect, send and receive audio/video per Real-time audio and video.

WeChat VoIP calling stream_id convention:

  • Audio: stream_id = 10
  • Video: stream_id = 11

Next steps

Additional conventions

  • The caller may include custom fields in payload (e.g. wxa_from to identify the caller side, call_id as a unique call identifier). WeChat and Tange Cloud pass this through transparently without interpreting it. The device uses wxa_from to distinguish an incoming call from a callback ring.

Reference Implementation

tirtc-server-example is an open-source reference project built on top of these docs and the Tange Cloud SDK. It demonstrates the complete four-party interaction of WeChat VoIP calling and serves as a starting point for your own development:

ModuleDescription
voip-serverBusiness server (Go): handles WeChat callbacks, calls Tange Cloud Token API, MQTT device downlink
device-sim-c / device-sim-pyDevice simulator (C / Python): WHIP connection, signaling, G.711a audio streaming
weixin-mini-programWeChat Mini Program: VoIP plugin integration, device authorization binding, calling UI
user-server / device-serverUser & device management (Go): login, binding, MQTT credential issuance

The device communicates with the business server over an MQTT persistent connection, using ClientID sn_{device_id}. Key topics:

TopicQoSDescription
device/sn_{device_id}/cmd1Command channel: call_incoming (incoming call, device must reply ACK)
device/sn_{device_id}/notify1Notification channel: call_cancel, callers_update (authorization change)

The project covers both call scenarios (Mini Program initiated / device initiated), incoming call rejection, in-call hangup, and audio streaming — ready to run and debug.

WeChat VoIP calling