Repository navigation
Conversation
New task-first capability guide at voice/take-payments covering SWML pay, Relay call.pay, AI agents via FunctionResult.pay, the payment connector protocol, results, and PCI. Cross-link it from the voice overview, llms.txt, and the SWML, cXML, Relay, FunctionResult, content redaction, and record calls pages. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Merged
6 of 13 tasks
…n-Call-Guide # Conflicts: # fern/llms.txt
hey-august
requested changes
Nov 6, 2026
hey-august
left a comment
Collaborator
There was a problem hiding this comment.
Summary
Requesting changes. The guide is in good shape, but four statements contradict the platform, three code samples fail on first run, and two smaller items need a touch. Platform behavior below is verified against source.
Blocking
- Custom prompts do not replace SignalWire's retry prompts (
take-payments.mdx:1192). The sentence "Each entry inpromptsreplaces SignalWire's prompt for one step" holds only for the first attempt. Prompt selection weights any error-matched prompt above a plain one, so the built-in timeout and invalid-* prompts outrank a custom prompt with noerror_type. The page's own example, a plainpayment-card-numberprompt withmax_attempts: 3, plays the stock timeout prompt on retry. State that a prompt needs the matchingerror_typeto replace a retry prompt. - The HMAC is computed over the URL with credentials removed (
take-payments.mdx:115and:244). The page says the signature covers the URL "exactly as you passed it". The platform strips anyuser:password@before signing and sends those as Basic auth. A reader who protects the connector with basic auth and sets theCONNECTOR_URLvariable to the credentialed string gets a 403 on every request. One sentence fixes it. - The result table omits
validation-error(take-payments.mdx:1665). The table is introduced as the full set but leaves out thevalidation-errorvalue. The SWML reference this page links does list it. Add the row. - The reference defines
payment-connector-errordifferently from the guide (swml/.../pay/index.mdx:753). The reference says the connector returned an error. In practice a reachable connector that answers non-200 ends asinternal-error, andpayment-connector-errorsurvives only when the connector is unreachable, which is what the guide says at lines 643 and 1669. Align the reference with the guide. - The TypeScript connector corrupts multi-byte request bodies (
take-payments.mdx:320). The statementrawBody += chunkstringifies each Buffer on its own. A UTF-8 character split across two chunks becomes U+FFFD, and the HMAC check fails intermittently on non-ASCII descriptions. Callreq.setEncoding("utf8")before the loop, or collect Buffers and useBuffer.concat. - The stop timer leaves a promise rejection unhandled (
take-payments.mdx:1931). The callsetTimeout(() => void action.stop(), 120_000)discards the promise fromstop(). If the platform refuses the stop, Node 15 and later terminates the handler mid-call. Add.catch(() => {}). - The
call.paymethod raises rather than returning an error (take-payments.mdx:652). The troubleshooting text sayscall.payreturns an error. The Python SDK raises and the TypeScript SDK rejects, and neither Relay sample catches it. Anhttp://connector URL produces a traceback and a hung call. Reword the sentence, and consider wrappingcall.payin a try block in both samples.
Non-blocking
- The connector-body table should mark
parametersas optional (take-payments.mdx:205). The platform omits theparameterskey when none are set, the same asdescription. The sample body labeled as the Bayview fare body includesparameters, which the first run never sends. - The Python sample disables schema validation for the whole document (
take-payments.mdx:1576). The sample passesschema_validation=FalsetoSWMLService. Themdx-capability-guidesrule says to bypass validation for the one verb only. The TypeScript twin already does that withaddVerb.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #770. Part of #765.
Merge after #833. Both PRs edit the SWML
payand cXML<Pay>reference pages. This PR only adds a one-sentence backlink to each, so I'll rebase once #833 merges.Summary
voice/take-payments). It covers:FunctionResult.pay<Pay>is left out of the guide to keep the platform page SWML-native, and the<Pay>reference links to the guide instead.llms.txt"Secure payments" bullet now points to the guidepayreference, the cXML<Pay>reference, Relaycall.pay(Python and TypeScript),FunctionResult.pay(Python and TypeScript), the content redaction guide and Record callsNotes for reviewers
Relay
PayAction.wait()andon_completednever resolve forpayinsignalwire-sdk==3.4.1or@signalwire/sdk@2.0.5. The SDK waits for astatefield thatcalling.call.payevents don't carry. The guide's Relay samples wait for the finalcalling.call.payevent, the one carryingresult. The existing RelaypayandPayActionreference examples callaction.wait(), so they wait forever. That needs an upstream SDK fix and a reference update.A declined card still plays the "payment completed" prompt. The closing prompt plays on any HTTP 200 from the connector, so a decline returned as a 200 sounds like a success to the caller, while
pay_resultisinternal-errorwithpayment_error: card-declined. Worth raising with the platform team. The guide branches onpay_resultand doesn't rely on the prompt.REST:
calling.payandcalling.pay.stopwork throughPOST /api/calling/calls, but they aren't in the API spec, so the guide marks REST as unavailable. Adding them to the spec would be a follow-up.Connector signing and
token_id: the guide documents current platform behavior. Connector requests are signed withX-SignalWire-Signature, and the connector'stoken_idcomes back aspayment_token. Pay fixes (SWML + cXML) #833 currently says connector requests aren't signed; my review there suggests corrected wording. Both platform changes need changelog entries dated to when they shipped, which I'll add separately once the dates are confirmed.SWML
payreference errors that Pay fixes (SWML + cXML) #833 doesn't cover (not changed in this PR):security_codeis typed as a boolean, but the platform requires the strings"true"or"false".prompts[].attemptsshould beattempt.validation-erroris described as "Card details failed validation", but failed card checks end intoo-many-failed-attempts.Pay fixes (SWML + cXML) #833 already fixes the rest: the missing
parameters, the masked card in the connector request example, andpayment-completedbeing sent for declines.Other docs and SDK inconsistencies:
security_codeas a boolean, and the Python builder rejects"false"at runtime. The guide's "Skip the security code" example therefore usesadd_verb/addVerbfor that one field.security_codeandpostal_codeas booleans.validateWebhookSignaturereference page documents a function that@signalwire/sdk@2.0.5doesn't export. The TypeScript connector checks the signature withnode:crypto.Recording during collection: the guide doesn't claim that recordings pause automatically while card details are entered. It tells readers to pause recording and transcription themselves.
Rule drift:
.claude/rules/mdx-capability-guides.mdsaysplatform.ymllistspages/calling/pages explicitly. The voice folder is folder-driven now.Verification
yarn fern-md-check: all 2831 MDX files are valid. I didn't runyarn fern-check, since no yml or redirects changed.py_compileandpyflakesclean on all 12 files.tsc --strictclean on all 12 files, and each also passesnode --checkas.mjs.bash -n.slug:and every#anchorby hand. That includes the three guide anchors other pages link to:#build-a-payment-connector,#take-a-payment-from-an-ai-agentand#payments-and-pci-compliance.Preview URLs
/docs/platform/voice/take-payments/docs/platform/voice/docs/platform/voice/record-calls/docs/platform/ai/content-redaction/docs/swml/reference/calling/pay/docs/compatibility-api/cxml/reference/voice/pay/docs/server-sdks/reference/python/relay/call/pay/docs/server-sdks/reference/typescript/relay/call/pay/docs/server-sdks/reference/python/agents/function-result/pay/docs/server-sdks/reference/typescript/agents/function-result/pay🤖 Generated with Claude Code