Skip to content

Pay fixes (SWML + cXML) - #833

Merged
hey-august merged 12 commits into
mainfrom
august-20261023-pay-fixes
Oct 28, 2026
Merged

hey-august merged 12 commits into
mainfrom
august-20261023-pay-fixes

Conversation

@hey-august

@hey-august hey-august commented Oct 23, 2026 •

Copy link
Copy Markdown
Collaborator

Description

Brings the cXML <Pay> and SWML pay reference pages in line with the platform, verified against the platform and the API spec. Tokenization is the main fix: the pages now say plainly that the connector's token_id comes back as PaymentToken / pay_payment_results.payment_token.

cXML <Pay>

  • Tokenization: removed ProfileId (never sent), described PaymentToken and PaymentConfirmationCode precisely, rewrote the broken <Note>, and added a "Tokenize a card end to end" example.
  • action parameters: renamed to what's sent (PayResult, PaymentCardExpirationDate, PaymentCardSecurityCode, PaymentErrorCode, PaymentConnectorError), and added PaymentConnectorErrorCode and BankAccountType.
  • Connector request: merged the two tabs (charges and tokenization send the same fields), corrected chargeAmount (string, not amount) and parameters (an array of single-key objects), and used an unmasked test card in the example.
  • statusCallback: completed the For values, merged the duplicate events table into them, and noted that payment-completed is also sent for declines.
  • Attributes: minPostalCodeLength and securityCode are optional (defaults 0 / true), and paymentConnectorUrl must be HTTPS.
  • Replaced "Security best practices" with "Securing your payment connector": connector requests aren't signed, so put a secret in the URL.
  • Example fixes: a stray </Pay>, <Prompt name= → for=, and garbled characters.

SWML pay

  • Same connector request, token variable and security fixes as cXML. parameters was missing from the request body.
  • params.for now lists its values, with the same payment-completed caveat.

Spec

  • pay/main.tsp: the doc links now point to /docs/swml/reference/calling/pay. The regenerated output changes only those two links.

Notes for reviewers

  • The tokenization example and the PaymentToken / payment_token descriptions describe intended behavior. A platform fix that returns token_id there is approved but not yet deployed.
  • Left as they were: cXML examples that leave out paymentConnectorUrl, the undocumented bankAccountType / voice attributes and ACH connector fields, and legacy heading styles.

Preview:

  • /docs/compatibility-api/cxml/reference/voice/pay
  • /docs/swml/reference/calling/pay

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Code cleanup / refactor

Related Issues

Closes #832
See also: signalwire/cloud-product#21804

Testing

  • Added/updated unit tests
  • Tested manually
  • Tested with live SignalWire credentials (if applicable)

Checklist

  • I have read the CONTRIBUTING guidelines
  • My code follows the project's style guidelines
  • I have added tests for my changes (if applicable)
  • I have updated documentation (if applicable)
  • All existing tests pass

@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

@Manny-r31 Manny-r31 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this, it clears up a lot on both pages. Two things have changed on the platform since this was written:

  1. Payment connector requests are now signed. SignalWire signs the request to the payment connector the same way it signs JSON webhooks:

    • X-SignalWire-Signature is the lowercase hex HMAC-SHA1 of the connector URL (with any user:pass@ removed) followed by the raw request body, keyed with the project's Signing Key.
    • X-SignalWire-SHA256-Signature carries the HMAC-SHA256.

    This applies to <Pay> too, and it is not the form-parameter scheme the other cXML webhooks use, so a cXML user's usual validator won't match. Credentials in the URL still arrive as Basic auth, so they become an optional second layer. I left inline suggestions on the three places that say the request isn't signed.

  2. The token_id fix has landed. The connector's token_id now comes back as PaymentToken / pay_payment_results.payment_token. The page text already states this as current behavior, so it only needs the "approved but not yet deployed" note dropped from the PR description.

Both platform changes need changelog entries dated to when they reached customers. I'm confirming the deploy dates and will add them separately, so this PR doesn't need to.

#867 (the new Take payments on a call guide) adds one-sentence backlinks to both of these pages. It should merge after this one, and I'll rebase it.

@hey-august
hey-august merged commit 28468a6 into main Oct 28, 2026
2 checks passed
@hey-august
hey-august deleted the august-20261023-pay-fixes branch October 28, 2026 14:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Pay (cXML and SWML): correct tokenization, parameter names, and connector request docs

2 participants