Which approach should I use? #
Use the JS SDK guide in most cases. It is the preferred and easiest way to integrate server‑to‑server card payments for web apps.
Why the SDK is preferred:
– Collects browser data automatically and passes it to your backend.
– Opens our hosted bank authentication page with a lightbox/iframe/redirect, no extra code.
– Handles return navigation and cleans up query parameters.
– Provides simple callbacks: `createPayment`, `paymentComplete`, `paymentFailed`.
– Works with the same server‑side guarantees (finalisation and webhooks).
Use the API‑only guide instead when:
– Your environment forbids third‑party scripts or you have strict CSP policies.
– You need a fully custom UX that cannot use the SDK’s display modes.
– You’re building a non‑browser client or a kiosk environment.
Use this if you want to:
– Keep your own card form (PCI SAQ‑D) and process via your server
– Let our hosted authentication page handle bank (3DS) challenges
– Integrate using the TrustistEcommerce JavaScript SDK for a simpler UI flow
For a backend‑only approach without the SDK, see TrustistEcommerce Server-to-Server Card Payments Integration Guide.
Related docs: Trustist Ecommerce JavaScript SDK
Prerequisites #
– Your Trustist API credentials
– PCI SAQ‑D compliance (you collect raw card data)
– A backend endpoint that calls the TrustistEcommerce API
Include the SDK:
<!-- Sandbox -->
<script src="https://sdk-sandbox.trustistecommerce.com/js/sdk.js?client-id={{client_id}}" async></script>
<!-- Production (switch when going live) -->
<!-- <script src="https://sdk.trustistecommerce.com/js/sdk.js?client-id={{client_id}}" async></script> -->
How it works (SDK + your backend) #
1) Your frontend collects card details and calls the SDK component.
2) The SDK collects browser data and calls your backend `createPayment(browserData)`.
3) Your backend calls our API to create and process the payment in one request.
4) If the payment requires bank authentication, the SDK opens our hosted page (lightbox/iframe/redirect) and we complete processing.
5) The SDK notifies your app with `paymentComplete` or `paymentFailed` immediately; webhooks provide the final source of truth.
Frontend – minimal integration #
Add a container where the SDK will render a button:
<div id="trustistServerToServerPayment"></div>
Initialize once the SDK is ready:
<script>
window.trustistReadyCallback = function () {
trustist.ecommerce.ServerToServerPayment({
// The SDK passes browserData here. Include it in your server request.
createPayment: async (browserData) => {
// Gather card details from your form (examples only)
const cardNumber = document.getElementById('card-number').value.replace(/\s/g, '');
const [mm, yy] = document.getElementById('expiry').value.split('/');
const cvc = document.getElementById('cvc').value;
const payload = {
amount: 99.99,
reference: 'ORDER-12345',
payerEmail: 'customer@example.com',
cardDetails: {
number: cardNumber,
expiryMonth: mm,
expiryYear: yy.length === 2 ? `20${yy}` : yy,
cvc: cvc
},
browserData // IMPORTANT: pass through exactly as received
};
const resp = await fetch('/api/payments/server-to-server', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
// Your backend should return the raw TE API response shape
// { id, status: 'COMPLETE' | 'PENDING_ACTION', requiredAction?: { type: 'redirect', url } }
if (!resp.ok) {
const err = await resp.json().catch(() => ({ error: 'Payment creation failed' }));
throw new Error(err.error || 'Payment creation failed');
}
return await resp.json();
},
// Called when payment is complete (frictionless or after bank auth)
paymentComplete: (payment) => {
if (payment.status === 'COMPLETE') {
window.location.href = '/order-confirmation?payment=' + payment.id;
} else {
// Rare edge – treat as not complete
console.warn('Payment not complete:', payment);
}
},
// Optional: surface a friendly error to the customer
paymentFailed: (e) => {
const message = (e && e.reason) || (e && e.message) || 'Payment failed. Please try again.';
document.getElementById('error-message').textContent = message;
document.getElementById('error-message').style.display = 'block';
},
// Display options: 'lightbox' (default), 'iframe', or 'redirect'
challengeDisplayMode: 'lightbox',
// For redirect mode, you can set where to return (optional). If omitted, current page is used.
// redirectReturnUrl: 'https://merchant.example.com/checkout/return'
}).render('#trustistServerToServerPayment');
};
</script>
Notes:
– The SDK automatically collects browser data, passes it to your `createPayment`, and opens our hosted authentication page if required.
– No additional SDKs/scripts are needed for bank authentication.
– In `redirect` mode, the SDK appends `merchantOrigin` and `returnUrl` parameters and cleans up return query params after completion.
Backend – your endpoint #
Create an endpoint your frontend calls from `createPayment(browserData)`. It should forward the request to the TrustistEcommerce API and return the API’s JSON to the SDK.
Language‑agnostic pseudocode calling your own backend:
POST /api/payments/server-to-server
body: {
amount, reference, payerEmail,
cardDetails { number, expiryMonth, expiryYear, cvc },
billingAddress?,
browserData
}
// Validate and forward to TrustistEcommerce API with HMAC
POST https://api.trustistecommerce.com/v1/payments/server-to-server
-> returns one of:
{ id, status: “COMPLETE”, requiredAction: null }
{ id, status: “PENDING_ACTION”, requiredAction: { type: “redirect”, url } }
// On error, return a JSON shape the SDK can surface cleanly
HTTP 400 { error: “Invalid card number length or format” }
Important implementation details:
– The required action type is normalised to `redirect` and the URL is our hosted authentication page.
– Frictionless approvals are completed server‑side before the response – expect `status: “COMPLETE”` immediately.
– Error responses should be forwarded as `{ error: “message” }`.
Display modes #
– **lightbox (default)**: modal overlay with an embedded iframe
– **iframe**: inline iframe displayed in your page
– **redirect**: full‑page redirect to the hosted authentication page and then return
The SDK automatically:
– Adds `merchantOrigin` (and `returnUrl` in redirect mode)
– Listens for postMessage completion from our hosted page
– Cleans up redirect query parameters on return
Webhooks (source of truth) #
Use webhooks for order fulfilment and reliable status updates even if the customer closes their browser. See: Merchant Webhooks
Testing checklist #
– Frictionless card returns `status = COMPLETE`
– Challenge card opens hosted authentication and completes successfully
– Invalid card shows a friendly error from `{ error: “…” }`
– Webhooks received and order status updated
Troubleshooting #
– If no authentication appears when `requiredAction` is present, ensure your CSP allows our hosted authentication URL to load in an iframe/popup.
– For redirect mode, confirm your `redirectReturnUrl` (if set) is reachable and HTTPS in production.
– If you see repeated `PROCESSING`, wait briefly; if it persists, contact support.