Skip to main content

Encrypting the Transact Launch URL

When Transact is opened from your CRM or another system, that system can pass details such as the payment amount, your reference and the customer's name in the launch URL. These are the known parameters, and they pre-fill the payment screen so your agent doesn't need to retype them.

Passing data in the URL isn't required. It's one of several ways to get details into Transact, and your agent can always enter them directly instead.

When values are passed in the URL, they are readable by default. With URL encryption enabled, your system encrypts them first, so the URL only ever contains scrambled data that is meaningless without your account's key.

Optional

URL encryption is entirely optional and is switched off by default. Transact works fully without it, and your launch URLs are always sent over HTTPS either way. It is only needed if your security policy requires launch data to be hidden in the URL itself, for example to keep customer details out of browser history or network logs. If that doesn't apply to you, you can skip this page.

Why Encrypt the Launch URL?​

URLs end up in more places than you might expect:

  • Browser history and bookmarks on the agent's machine.
  • Proxy, firewall and web server logs inside your network.
  • Screenshots, screen shares and support tickets, where a URL is easily copied or captured.

Encrypting the launch data means none of these places ever hold your customer's details in readable form. Only Transact, inside a signed-in agent session for your account, can turn the URL back into usable data.


How It Works​

How an encrypted launch URL works: your system encrypts the launch data and opens Transact with only data and iv in the URL. The browser of the signed-in agent sends these to Transact, which fetches the key for your account from Azure Key Vault, decrypts on the server and returns the fields that pre-fill the payment screen.

  1. Your system encrypts the launch data using your account's shared secret, then opens Transact with two parameters in the URL: data (the encrypted values) and iv (a random value used for that one encryption).
  2. The agent's browser sends data and iv to Transact. This only happens once the agent is signed in.
  3. Transact fetches your account's key from Azure Key Vault and decrypts the values on the server. The key is chosen from the signed-in agent's account. Nothing in the URL selects it.
  4. The decrypted values are returned to the agent's session and pre-fill the payment screen exactly as unencrypted parameters would.

Setting It Up​

  1. Contact Subphonic to enable URL encryption for your account. We will:
    • turn on query string decryption in your account configuration,
    • agree a shared secret with you, which is stored for your account in Azure Key Vault,
    • agree the contents of the encrypted payload and map those fields to Transact's parameters.
  2. Update your system to encrypt the launch data and build the URL, following the specification below.
  3. Test in your test environment before switching production over.
warning

Once URL encryption is enabled for an account, Transact expects every launch URL to be encrypted. Plain query string parameters are ignored, and a URL missing data or iv shows an error rather than an empty payment screen.


Encryption Specification​

This section is for the developers updating your system.

ItemValue
AlgorithmAES-256 in CBC mode
PaddingPKCS#7
KeyThe SHA-256 hash of your shared secret (UTF-8 encoded), giving a 32-byte key
IV16 random bytes, newly generated for every URL
EncodingStandard Base64 for both data and iv
URL parametersdata and iv, each URL-encoded
URL-encode the values

Standard Base64 can contain +, / and =, all of which have special meanings in a URL. Always URL-encode data and iv (for example with encodeURIComponent). If you skip this, a + arrives as a space and decryption fails.

Example (Node.js)​

This example uses only Node's built-in crypto module:

const crypto = require('crypto');

function encryptLaunchData(plaintext, sharedSecret) {
const key = crypto.createHash('sha256').update(sharedSecret, 'utf8').digest();
const iv = crypto.randomBytes(16); // new IV for every URL
const cipher = crypto.createCipheriv('aes-256-cbc', key, iv); // PKCS#7 padding by default
const data = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
return { data: data.toString('base64'), iv: iv.toString('base64') };
}

// The payload format is agreed with Subphonic during setup
const payload = JSON.stringify({ amount: '49.99', reference: 'INV-10442' });
const { data, iv } = encryptLaunchData(payload, process.env.TRANSACT_SHARED_SECRET);

const launchUrl =
`https://<your-transact-url>/?data=${encodeURIComponent(data)}&iv=${encodeURIComponent(iv)}`;

Any language with a standard AES library can produce the same output, as long as it follows the table above.


Security Details​

  • Only ciphertext travels in the URL. The key is never placed in the URL, sent to the browser, or exposed to the agent. The whole session also runs over HTTPS.
  • Decryption happens on the server, for signed-in users only. The decryption service only accepts requests from a signed-in agent or authenticated API credentials.
  • Your key is isolated to your account. Each account's secret is held separately in Azure Key Vault. Transact picks the key from the signed-in agent's account, so a link created for your account can't be decrypted by any other account.
  • Every URL is unique. A new random IV is used each time, so encrypting the same details twice produces two different URLs. Repeat payments can't be spotted by comparing links.
  • Failures stop safely. If decryption fails or data or iv is missing, Transact shows an error. It never falls back to reading unencrypted values from the URL.

Looking After the Shared Secret​

Your system needs the shared secret in order to encrypt, so treat it like any other production credential:

  • Store it in a secrets manager or key vault, never in source code or configuration files checked into version control.
  • Limit access to the systems and people that genuinely need it.
  • Use a long, randomly generated value.
  • If you think it has been exposed, contact Subphonic straight away to replace it. URLs encrypted with the old secret stop working once it has been replaced, so plan the change with us.
Docs AssistantAsk anything about our products