# 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](https://docs.forter.com/forter-managed#end-to-end-flow) End-to-End Flow

Decline

Approve

Yes

No

Yes

No

No

Yes

Customer enters card details

Hosted Fields tokenizes card

Create Payment via API

Fraud Check

Transaction Rejected

3DS Required?

Execute 3DS Challenge

Challenge Success?

Route to Optimal PSP

Authorization Success?

PPR Retry with Next PSP

Payment Captured

Webhook Notification

```mermaid
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](https://docs.forter.com/forter-managed#integration-steps) Integration Steps

1. ### [Add Hosted Fields SDK](https://docs.forter.com/forter-managed#add-hosted-fields-sdk) 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.
   
   ```html
   <script type="text/javascript" data-site-id="YOUR_SITE_ID" id="checkoutTools__script" src="https://sdk.checkouttools.com/v1.2/full.js"></script>
   ```

2. ### [Generate an Auth Token](https://docs.forter.com/forter-managed#generate-an-auth-token) 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**
   ```json
   {
     "ttlMinutes": 60
   }
   ```
   
   **Example Response**
   ```json
   {
     "clientKey": "TOKEN_VALUE"
   }
   ```

3. ### [Tokenize Card Data Using Hosted Fields SDK](https://docs.forter.com/forter-managed#tokenize-card-data-using-hosted-fields-sdk) 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:
   
   ```javascript
   const forterCollect = await window.checkoutTools.collect.init({
       environment: 'sandbox',
       authToken: 'TOKEN.VALUE'
   });
   ```
   
   **Add Hosted Fields placeholders to the checkout page form**
   ```html
   <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**
   ```javascript
   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:
   ```javascript
   const tokenResult = await forterCollect.submit();
   console.log(tokenResult);
   ```
   
   **Response Example:**
   ```json
   {
     "success": true,
     "token": "ftr12d4e830283b647d4b3b2a3d65f02b8ab"
   }
   ```

4. ### [Upgrade Token (Optional)](https://docs.forter.com/forter-managed#upgrade-token-optional) 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.
   **Example Request**
   ```json
   {
     "token": "ftr1d8a56cfa6b3745a39e4a42d5ab1048c8",
     "networkToken": {
         "provision": true
     }
   }
   ```
   
   **Example Response**
   ```json
   {
     "token": "ftr1efsdfew54wetg54ugdn58ns0482ko",
     "networkTokenStatus": {
         "created": true
     }
   }
   ```

5. ### [Create Payment](https://docs.forter.com/forter-managed#create-payment) Create Payment
   Include a unique idempotency-key header (e.g. a UUID) on each request. Reusing the same key for a retry ensures we return the original result instead of executing the operation again.
   - `orderId` is a required field — pass the merchant order ID to link the payment to fraud assessment
   - `forterTokenString` is the token generated in the previous section
   - `amount` field is expressed in cents
   - Set `confirm: true` for immediate capture
   - Set `captureMethod` to automatic or manual

6. ### [Execute 3DS (If Required)](https://docs.forter.com/forter-managed#execute-3ds-if-required) Execute 3DS (If Required)
   If Forter determines that 3DS is recommended or required, the payment create response will include a 3DS SDK token. You'll need to pass this token to the frontend so it can run the 3DS flow.
   
   **Example Response (With 3DS SDK token)**
   ```json
   {
     "status": "requires_action",
     "nextAction": {
         "type": "use_sdk",
         "useSdk": {
             "token": "sdk_token_123"
         }
     }
   }
   ```
   
   **3DS SDK Usage**
   ```javascript
   await window.checkoutTools.managedOrders.manageOrder(
       managedOrderToken,
       {
           challengeContainer: () => {
               return htmlElement; // can be null to render Forter's default modal
           }
       }
   );
   ```

7. ### [Authorize Payment](https://docs.forter.com/forter-managed#authorize-payment) Authorize Payment
   **POST /api/payments/:id/confirm**
   Used in case of `confirm: false`.
   **Example Response**
   ```json
   {
     "id": "string",
     "amount": 9876,
     "amountReceived": 9876,
     "created": "2025-07-14T12:34:56.789Z",
     "currency": "AUD",
     "status": "succeeded",
     "connector": "adyen",
     "captureMethod": "automatic",
     "paymentMethod": "card",
     "paymentMethodType": "string"
   }
   ```
   
   In case 3DS is required before another authorization, the confirm response will include a 3DS SDK token.

8. ### [Cancel Payment](https://docs.forter.com/forter-managed#cancel-payment) Cancel Payment
   **POST /api/payments/:id/cancel**
   Cancel a payment that has not yet been captured. The reason field is optional.
   **Example Request**
   ```json
   {
     "reason": "requested_by_customer"
   }
   ```

9. ### [Capture Payment](https://docs.forter.com/forter-managed#capture-payment) Capture Payment
   **POST /api/payments/:id/capture**
   Used only if `captureMethod` was set to manual in /api/payments. The `amountToCapture` is optional and should be provided only for partial captures.
   **Example Request**
   ```json
   {
     "amountToCapture": 1000
   }
   ```
   
   **Example Response**
   ```json
   {
     "id": "string",
     "amount": 9876,
     "amountReceived": 9876,
     "created": "2025-07-14T12:34:56.789Z",
     "currency": "AUD",
     "status": "succeeded",
     "connector": "adyen",
     "captureMethod": "automatic",
     "paymentMethod": "card",
     "paymentMethodType": "string"
   }
   ```

## [Refunds](https://docs.forter.com/forter-managed#refunds) Refunds

**Full Refund**
Issue a reversal for a captured payment. Omit amount for a full refund.

**Partial Refund**
To issue a partial refund, include the `amount` field in your request. Forter will apply the same settlement-status check — if the transaction has settled, the partial refund is processed normally. If the transaction has not yet settled, partial refunds are not possible and Forter will return an error.
   
   **Example Request**
   ```json
   {
     "paymentId": "{{paymentId}}",
     "amount": 500,
     "reason": "requested_by_customer"
   }
   ```
   
   **Example Response**
   ```json
   {
     "id": "ref_abc123",
     "amount": 500,
     "currency": "USD",
     "status": "succeeded",
     "reason": "requested_by_customer",
     "createdAt": "2025-07-14T12:34:56.789Z"
   }
   ```

## [Automatic Retry Logic – Predictive Payment Routing (PPR)](https://docs.forter.com/forter-managed#automatic-retry-logic-predictive-payment-routing-p) Automatic Retry Logic – Predictive Payment Routing (PPR)
If the selected PSP declines or fails, Forter automatically generates a new routing recommendation:
1. The previous PSP + failure reason is sent to PPR
2. The next best PSP is returned based on live success metrics
3. Forter retries authorization with the new PSP transparently
4. Retries are idempotent and bounded by configurable limits
This is an internal process and does not require any merchant action.

## [Webhooks](https://docs.forter.com/forter-managed#webhooks) Webhooks
Forter delivers asynchronous updates for every lifecycle event:

| Event Type                | Description                                   |
|---------------------------|-----------------------------------------------|
| payment.authorized        | Payment successfully authorized                |
| payment.captured         | Funds successfully captured                    |
| payment.failed            | Payment or capture failed                      |
| payment.cancelled         | Payment was cancelled (by merchant or by Forter) |
| refund.succeeded          | Refund processed successfully                  |
| refund.failed             | Refund failed to process                      |

**Example Webhook Payload**

```json
{
  "type": "payment.authorized",
  "eventId": "123456",
  "timestamp": "2024-11-07T05:31:56Z",
  "data": {
    "paymentId": "PAY-9981",
    "processor": "adyen"
  }
}
```

Forter webhooks include x-forter-signature and x-forter-timestamp headers for validation.

## [Implementation Notes](https://docs.forter.com/forter-managed#implementation-notes) Implementation Notes
- Forter's Hosted Fields must be used for PCI compliance - merchants are never exposed to raw PCI data
- Single-use Forter Token expires within a maximum of 24 hours. In case the customer chooses to store the payment method, you can upgrade to a long-lived token using the Forter Tokenization API
- Each transaction is idempotent by idempotency key to prevent double charges.
