Forter Managed
Forter's Orchestration service provides one unified integration that unlocks multiple services - Fraud Prevention, Predictive Payment Routing (PPR), and Payment Orchestration. Each service can be enabled independently or combined, with no additional engineering work, allowing merchants to start with any capability and expand seamlessly over time.
End-to-End Flow
flowchart TD
A["Customer enters card details"] --> B["Hosted Fields tokenizes card"]
B --> C["Create Payment via API"]
C --> D{"Fraud Check"}
D -- Decline --> E["Transaction Rejected"]
D -- Approve --> F{"3DS Required?"}
F -- Yes --> G["Execute 3DS Challenge"]
G --> H{"Challenge Success?"}
H -- No --> E
H -- Yes --> I["Route to Optimal PSP"]
F -- No --> I
I --> J{"Authorization Success?"}
J -- No --> K["PPR Retry with Next PSP"]
K --> J
J -- Yes --> L["Payment Captured"]
L --> M["Webhook Notification"]Integration Steps
Add Hosted Fields SDK
Add Forter's checkoutTools library to your checkout page, wherever the card entry iframe is located. The script should be pasted directly before the closing HTML </body> tag.
<script
type="text/javascript"
data-site-id="YOUR_SITE_ID"
id="checkoutTools__script"
src="https://sdk.checkouttools.com/v1.2/full.js">
</script>Generate an Auth Token
Before using the Forter Hosted Fields SDK, your backend must generate a temporary authentication token.
Make a request from your backend to /v1/tokenization/client-key endpoint in the Tokenization API, including the required authentication headers.
Example Request
{
"ttlMinutes": 60
}Example Response
{
"clientKey": "TOKEN_VALUE"
}Tokenize Card Data Using Hosted Fields SDK
Initialize the SDK
Call the init method on the hosted fields SDK, passing in the auth token you received in the previous step:
const forterCollect = await window.checkoutTools.collect.init({
environment: 'sandbox',
authToken: 'TOKEN.VALUE'
});Add Hosted Fields placeholders to the checkout page form
<form>
<div id="cc-holder"></div>
<div id="cc-number"></div>
<div id="cc-exp"></div>
<div id="cc-cvc"></div>
</form>Initialize the Hosted Fields using the SDK instance
forterCollect.addFields({
'cc-holder': {
type: 'CARD_HOLDER_NAME'
},
'cc-number': {
type: 'CARD_NUMBER',
},
'cc-exp': {
type: 'CARD_EXPIRATION_DATE',
},
'cc-cvc': {
type: 'CARD_CVC',
}
});Submit the form & receive a token
When the customer submits the form, call the submit() method to receive a single-use token:
const tokenResult = await forterCollect.submit();
console.log(tokenResult);Response Example:
{
"success": true,
"token": "ftr12d4e830283b647d4b3b2a3d65f02b8ab"
}Upgrade Token (Optional)
If you need to store the payment method and/or provision a network token for it, you must use the /upgrade endpoint.
Calling this endpoint creates a new multi-use token and invalidates the existing single-use token along with its CVC. You can also choose to provision a network token during the upgrade, allowing Forter to use it later during authorization.
Example Request
{
"token": "ftr1d8a56cfa6b3745a39e4a42d5ab1048c8",
"networkToken": {
"provision": true
}
}Example Response
{
"token": "ftr1efsdfew54wetg54ugdn58ns0482ko",
"networkTokenStatus": {
"created": true
}
}Create Payment
POST /api/payments
Initiates a payment. Forter runs the fraud check, decides whether 3DS is needed, selects the processor, and authorizes the payment.
Every POST request must include a unique Idempotency-Key header, for example a UUID. If a request times out, retry it with the same key: Forter returns the original result instead of charging the customer twice. See Idempotency.
- orderId is required. Pass your order ID to link the payment to Forter's fraud assessment.
- paymentMethod.forterTokenString is the token from the previous step.
- amount is an integer in the currency's minor unit, for example 1099 for $10.99. See Amounts and Currencies.
- Set confirm: true to authorize immediately, or false to create the payment first and call confirm later.
- Set captureMethod to automatic (default) to capture right after authorization, or manual to capture later.
Example Request
{
"orderId": "order-abc-123",
"amount": 1099,
"currency": "USD",
"captureMethod": "automatic",
"confirm": true,
"paymentMethod": {
"type": "token",
"forterTokenString": "ftr12d4e830283b647d4b3b2a3d65f02b8ab"
},
"connectionInformation": {
"customerIP": "203.0.113.10"
},
"browserInfo": {
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
},
"cartItems": [
{
"name": "Gift card",
"price": 1099,
"quantity": 1,
"type": "non_tangible"
}
],
"shipping": {
"deliveryMethod": "Email",
"deliveryType": "digital"
},
"customer": {
"email": "[email protected]",
"firstName": "John",
"lastName": "Smith"
}
}Example Response
{
"id": "pi_v1r1a3f9c2e4b5d6478a9b0c1d2e3f4a5b6c",
"orderId": "order-abc-123",
"amount": 1099,
"capturedAmount": 1099,
"currency": "USD",
"status": "succeeded",
"captureMethod": "automatic",
"createdAt": "2026-07-14T12:34:56.789Z",
"authorizedAt": "2026-07-14T12:34:57.912Z",
"capturedAt": "2026-07-14T12:34:58.204Z",
"paymentMethod": {
"type": "card",
"card": {
"brand": "visa",
"last4": "4242",
"expirationMonth": "03",
"expirationYear": "2030"
}
},
"processor": {
"name": "stripe",
"transactionId": "pi_3PqLmK2eZvKYlo2C1abcDEFg"
},
"charges": [
{
"id": "charge_6f1d2c3b4a5948e7b6c5d4e3f2a1b0c9",
"amount": 1099,
"status": "succeeded",
"capturedAt": "2026-07-14T12:34:58.204Z"
}
],
"authorization": {
"authorizationCode": "123456",
"processorResponseCode": "approved"
},
"fraud": {
"preAuth": { "decision": "approve" }
}
}Check status to determine the outcome. A declined payment is returned with status failed, not as an HTTP error. See Payment Lifecycle and Declines and Retries.
Execute 3DS (If Required)
If Forter determines that 3DS is required, the create response has status requires_action and includes a 3DS SDK token. Pass this token to your front end so it can run the 3DS flow.
Example Response (With 3DS SDK Token)
{
"id": "pi_v1r1a3f9c2e4b5d6478a9b0c1d2e3f4a5b6c",
"status": "requires_action",
"nextAction": {
"type": "use_sdk",
"useSdk": {
"token": "sdk_token_123"
}
}
}3DS SDK Usage
await window.checkoutTools.managedOrders.manageOrder(
managedOrderToken, // nextAction.useSdk.token
{
challengeContainer: () => {
// render custom container for challenge modal if needed
return htmlElement; // can be null to render Forter's default modal
}
}
);When the SDK flow completes, call Confirm Payment (next step) to authorize the payment.
Confirm Payment
POST /api/payments/:id/confirm
Authorizes a payment that is in status requires_confirmation (created with confirm: false) or requires_action (after the customer completes 3DS). No request body is needed.
The response is the full payment object, as in the Create Payment step. Its status is succeeded for automatic capture, requires_capture for manual capture, or failed if authorization was declined.
If 3DS authentication fails, confirm returns a 400 error with errorCode 3DS_FAILED and the payment is canceled. See Declines and Retries.
Capture Payment
POST /api/payments/:id/capture
Only needed if captureMethod was set to manual. amount is optional: omit it to capture the full authorized amount, or provide a smaller amount for a partial capture.
Example Request
{
"amount": 1000
}The response is the payment object, with status: succeeded and the capture listed in charges. Capture before authorizationExpiresAt, or extend the authorization with reauthorize. See Payment Lifecycle.
Cancel Payment
POST /api/payments/:id/cancel
Cancels a payment that has not been captured and releases the authorization. reason is optional.
Example Request
{
"reason": "requested_by_customer"
}Refunds
POST /api/payments/:id/refunds
Refunds a captured payment. Omit amount for a full refund, or include it for a partial refund. You can issue several partial refunds against the same payment.
Example Request
{
"amount": 500,
"reason": "requested_by_customer"
}Example Response
{
"id": "refund_9b8a7c6d5e4f43a2b1c0d9e8f7a6b5c4",
"amount": 500,
"currency": "USD",
"status": "pending",
"reason": "requested_by_customer",
"chargeId": "charge_6f1d2c3b4a5948e7b6c5d4e3f2a1b0c9",
"createdAt": "2026-07-15T09:12:00.000Z"
}Most processors complete refunds asynchronously, so a new refund is usually pending. You'll receive a refund_succeeded or refund_failed webhook when the processor finishes it.
Forter handles settlement for you. If a full refund is requested before the processor has settled the capture, Forter voids the sale instead and returns the refund with status voided. A partial refund of an unsettled capture is only possible on some processors. Otherwise Forter returns an error, and you can retry after settlement. See Refunds.
Retrieve a refund with GET /api/refunds/{id}, or list the refunds for a payment with GET /api/refunds?paymentId={paymentId}.
Automatic Retries with Predictive Payment Routing
If the selected processor declines or fails the authorization, Forter can automatically retry it with the next-best processor recommended by Predictive Payment Routing, within the same request. The response reflects the final attempt, and no merchant action is required. See Declines and Retries.
Webhooks
Webhooks need two registrations:
- With your processors: where the processor offers webhooks, register Forter's endpoint in its dashboard so Forter can track asynchronous outcomes.
- With Forter: register your endpoint for Payment Orchestration Update notifications to receive payment and refund updates, such as payment_captured and refund_succeeded.
See Webhooks for setup, event types, payload format and request verification.
Implementation Notes
- Forter's Hosted Fields must be used for PCI compliance. Merchants are never exposed to raw card data.
- A single-use Forter token expires within 24 hours at most. If the customer chooses to store the payment method, upgrade it to a multi-use token using the Forter Tokenization API.
- Every POST request requires an Idempotency-Key header. See Idempotency.
- Handle errors as described in Errors, and see API Basics for environments, authentication and request conventions.