Documentation Index
Fetch the complete documentation index at: https://docs.ozura.com/llms.txt
Use this file to discover all available pages before exploring further.
XML Proxy Requests
Forward XML/SOAP requests to payment processors like Worldpay.
For XML requests, pass metadata via headers:
POST /proxy/transaction
Content-Type: text/xml
X-Token: tok_a1b2c3d4e5f6
X-Proxy-URL: https://secure.worldpay.com/jsp/merchant/xml/paymentService.jsp
X-CVC-Session-ID: 550e8400-e29b-41d4-a716-446655440000
<?xml version="1.0" encoding="UTF-8"?>
<paymentService version="1.4" merchantCode="YOUR_MERCHANT">
<submit>
<order orderCode="order123">
<amount value="1000" currencyCode="USD"/>
<paymentDetails>
<CARD-SSL>
<cardNumber>${cardNumber}</cardNumber>
<expiryDate>
<date month="${expirationMonth}" year="${expirationYear}"/>
</expiryDate>
<cardHolderName>John Doe</cardHolderName>
<cvc>${cvv}</cvc>
</CARD-SSL>
</paymentDetails>
</order>
</submit>
</paymentService>
| Header | Required | Description |
|---|
Content-Type | Yes | text/xml or application/xml |
X-Token | Yes | Token to use |
X-Proxy-URL | Yes | Target endpoint |
X-CVC-Session-ID | No | CVC session for CVV |
Authorization | Varies | If PSP requires auth |
Placeholders
Same placeholders work in XML:
<cardNumber>${cardNumber}</cardNumber>
<expiryMonth>${expirationMonth}</expiryMonth>
<expiryYear>${expirationYear}</expiryYear>
<cvv>${cvv}</cvv>
Examples
Worldpay
curl -X POST https://pci-vault-hrhwdgc4akhse3bs.eastus-01.azurewebsites.net/proxy/transaction \
-H "Content-Type: text/xml" \
-H "X-API-Key: YOUR_OZURA_API_KEY" \
-H "X-Token: tok_a1b2c3d4e5f6" \
-H "X-Proxy-URL: https://secure.worldpay.com/jsp/merchant/xml/paymentService.jsp" \
-H "X-CVC-Session-ID: session_xyz" \
-H "Authorization: Basic YOUR_WORLDPAY_CREDENTIALS" \
-d '<?xml version="1.0" encoding="UTF-8"?>
<paymentService version="1.4" merchantCode="YOURMERCHANT">
<submit>
<order orderCode="ORDER123">
<description>Test Order</description>
<amount value="1000" currencyCode="USD" exponent="2"/>
<paymentDetails>
<CARD-SSL>
<cardNumber>${cardNumber}</cardNumber>
<expiryDate>
<date month="${expirationMonth}" year="${expirationYear}"/>
</expiryDate>
<cardHolderName>John Doe</cardHolderName>
<cvc>${cvv}</cvc>
</CARD-SSL>
</paymentDetails>
</order>
</submit>
</paymentService>'
Cybersource (SOAP)
curl -X POST https://pci-vault-hrhwdgc4akhse3bs.eastus-01.azurewebsites.net/proxy/transaction \
-H "Content-Type: text/xml" \
-H "X-API-Key: YOUR_OZURA_API_KEY" \
-H "X-Token: tok_a1b2c3d4e5f6" \
-H "X-Proxy-URL: https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor" \
-H "X-CVC-Session-ID: session_xyz" \
-d '<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>YOUR_MERCHANT_ID</wsse:Username>
<wsse:Password>YOUR_TRANSACTION_KEY</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<requestMessage xmlns="urn:schemas-cybersource-com:transaction-data-1.0">
<merchantID>YOUR_MERCHANT_ID</merchantID>
<card>
<accountNumber>${cardNumber}</accountNumber>
<expirationMonth>${expirationMonth}</expirationMonth>
<expirationYear>${expirationYear}</expirationYear>
<cvNumber>${cvv}</cvNumber>
</card>
<ccAuthService run="true"/>
<purchaseTotals>
<currency>USD</currency>
<grandTotalAmount>10.00</grandTotalAmount>
</purchaseTotals>
</requestMessage>
</soapenv:Body>
</soapenv:Envelope>'
Response
XML responses are returned directly:
{
"success": true,
"proxy_response": {
"status_code": 200,
"headers": {
"content-type": "text/xml"
},
"body": "<?xml version=\"1.0\"?><paymentService>...</paymentService>"
}
}
Parsing XML Response
const response = await fetch('/proxy/transaction', { ... });
const data = await response.json();
if (data.success && data.proxy_response.status_code === 200) {
// Parse the XML body
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(data.proxy_response.body, "text/xml");
// Extract values
const status = xmlDoc.querySelector('lastEvent').textContent;
}
Error Handling
SOAP Faults
<soapenv:Fault>
<faultcode>Client</faultcode>
<faultstring>Invalid card number</faultstring>
</soapenv:Fault>
Connection Errors
{
"success": false,
"message": "Failed to proxy request",
"error": {
"code": "CONNECTION_FAILED",
"details": "SSL handshake failed"
}
}
XML Encoding
Special characters are preserved:
| Character | In XML |
|---|
< | < |
> | > |
& | & |
" | " |
' | ' |
Card numbers don’t contain these characters, but if your XML contains them elsewhere, ensure proper encoding.
Namespaces
Preserve XML namespaces in your request:
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:pay="urn:payment-schema">
...
</soapenv:Envelope>
Best Practices
1. Validate XML Before Sending
Ensure your XML is well-formed:
function isValidXML(xmlString) {
const parser = new DOMParser();
const doc = parser.parseFromString(xmlString, 'text/xml');
return !doc.querySelector('parsererror');
}
2. Use CDATA for Complex Values
<description><![CDATA[Special & Complex "Value"]]></description>
Different PSPs have different XML schemas. Always refer to their documentation.
Next Steps