Create the trunk
Your number must be on an Elastic SIP trunk, not Programmable Voice (why). Connect a trunk to LiveKit with LiveKit’s Twilio guide, then set these on it:cURL
sip:<your-livekit-sip-host>;transport=tls, using your LiveKit SIP host. With Secure Trunking on, Twilio refuses any unencrypted call.
Create the LiveKit inbound trunk
One inbound trunk takes both new calls and returning callers, so list your number and the return user from yourreturnTarget, and turn on media encryption.
Transfer the caller
When the caller is ready to pay, create the voice session with yourreturnTarget, then cold transfer the caller to its dialUri.
dialUri exactly as returned. If creating the session or the transfer fails, offer the caller the checkout link instead. Your agent leaves the call only once your carrier accepts the transfer.
Recognize returning callers
When the payment is done, Natural asks Twilio to transfer the caller to yourreturnTarget. The caller arrives in a new room, addressed to pay-return instead of your phone number, and LiveKit puts that address in the caller’s sip.trunkPhoneNumber attribute. Use the caller’s own number, in sip.phoneNumber, to find the conversation, and accept the match only if you handed that caller to Natural within the last 30 minutes, the longest a payment call can run, since caller ID alone can be faked.
payment.outcome, and if it’s paid, don’t offer another transfer. If the caller’s number is withheld or matches no conversation, greet them as a new caller.
Why not Programmable Voice
A number on Programmable Voice (TwiML or a Twilio voice app) can’t hand a phone caller to Natural without staying on the call. Twilio’s<Refer> only works on calls that arrived over SIP, so a caller from the phone network can only be connected with <Dial>, which bridges the caller through your app. Your app then stays on the line and can record or stream the call while the caller reads their card.