---
title: PayPal Controller
slug: extensions/Izn8PQRW5yVohBMJbiUwp
docTags: 
createdAt: 2025-12-14T14:23:41.918Z
---

## Overview

The Forter cartridge has built-in functionality for saving the PayPal API responses including the following responses:

- transaction details
- capture
- void
- authorization
- expresscheckout

The data is stored as a JSON string in a custom attribute called the **Order Payment Instrument** object. Each response is saved to a dedicated custom attribute. The recommended type for these custom attributes is Text since in some cases the response is over 4K characters. In order to save the PayPal response, a script node must be added to anywhere the required data exists.

For example PayPal transaction details may be saved right after a call to `PaypPal-GetTransactionDetails` and passed into the int\_forter\:pipelets/forter/ForterCallStoreResponse.ds script.
In the script, **Dictionary Input**, the `“paypal_transaction_details_response”` is actually the custom attribute response from the, `PaypalTransactionDetails`.

This data point is an object that contains information about the current transaction and `PaymentInstrument` is your current payment instrument.

## Error Handling

:::ExpandableHeading
### Error on Extension Called Via hooks (main site built on controllers)

To handle the customized error message in your Forter business manager for scenarios where the PayPal payment processor is called via hooks (specically for storefronts built on controllers) update the following script:

```javascript
int_paypal/cartridge/scripts/payment/processor/PAYPAL_EXPRESS.js
```

This should check if any error exists in `pdict`. For example, the `if` statement below checks for this type of error:

```javascript
if (!empty(pdict.ForterResponse.PlaceOrderError)){}:
```

**Ex 2.1**

![](https://api.archbee.com/api/optimize/dYhsqkppjaUNAqFmds_Ny-GzuROGFfaYQZXskn6TJkb-20250724-184338.png)
:::

:::ExpandableHeading
### Error on Extension Called on AuthorizationResult

To handle the error message configured in your Forter business manager extension, adjust the \`COPlaceOrder.js\` to check if an error exists in the \`authorizationResult\` variable within the \`handlePayments(order)\` function.

```javascript
if (authorizationResult.not_supported || authorizationResult.error) {
    if (!empty(authorizationResult.forterErrorCode)) {
        return {
            error           : true,
            forterErrorCode : authorizationResult.forterErrorCode
        };
    } else {
        return {error : true};
    }
}
```

**Ex. 2.2**

![](https://api.archbee.com/api/optimize/dYhsqkppjaUNAqFmds_Ny-8jIb_v4FLrnDdu_G---ZY-20250724-184333.png)

Next, add the following line inside the `start()` function

```javascript
-	inside the start() function
return {
    error: true,
    PlaceOrderError: new Status(Status.ERROR, handlePaymentsResult.forterErrorCode ? handlePaymentsResult.forterErrorCode.code : 'confirm.error.technical')
};
```

**Ex. 2.3**

![](https://api.archbee.com/api/optimize/dYhsqkppjaUNAqFmds_Ny-biNZSG27HkPSp5OmZXUoO-20250724-184333.png)
:::

## Adjusting Cartridge Controllers for your Paypal Processor Response

The `ForterOrder.ds` file should be edited to use the response from your payment processor.

### Overview

The script is used to generate the request object for Forter validation. In the example below, we store the response from **authorize.net** on the payment instrument itself in a custom attribute to be used in this script.

If your implementation does not store the response on the payment instrument, you can pass the response object from your payment processor to the `validateOrder` function (located in the `ForterValidate.js` controller) as an input, which will be sent as a parameter to the `ForterOrder.ds` file to generate the request object.

The script examples below (**2.4** and **2.5**) has commented code as an example to illustrate the optional and required values that need to be sent.

:::ExpandableHeading
### Example 2.4

![](https://api.archbee.com/api/optimize/dYhsqkppjaUNAqFmds_Ny-XBKzF_kRUWeYs0AOZ5VDD-20250724-184331.png)

```javascript
/**
 * ForterOrder class is the DTO object for request.
 *
 * To include this script use:
 * var ForterOrder = require("int_forter/cartridge/scripts/lib/forter/dto/ForterOrder.ds");
 */
function ForterOrder(args) {

    var log          = new ForterLogger("ForterOrder.ds"),
        order        = args.Order,
        site         = dw.system.Site.getCurrent(),
        paymentInstruments = order.getPaymentInstruments(),
        payment      = null,
        authResponse = null,
        shipment     = null;
    
    for each (var paymentInstrument in paymentInstruments) {
        if (paymentInstrument.paymentMethod == 'CREDIT_CARD') {  //TODO: adjust to the existing payment instruments
            payment      = paymentInstrument;
            authResponse = new XML(paymentInstrument.custom.authorize_net_authorization);
        } else if (paymentInstrument.paymentMethod == 'PayPal' || paymentInstrument.paymentMethod == 'BML') {  //TODO: adjust to the existing payment instruments
            payment      = paymentInstrument;
            authResponse = paymentInstrument.custom.paypal_transaction_details_response;
        }
    }
```
:::

:::ExpandableHeading
### Example 2.5

```javascript
function ForterPayPal(authResponse, countryCode) {
   this.payerId = authResponse.payerId; //"FD000A45P";
   this.payerEmail = authResponse.paypalEmail;
   this.payerStatus = "VERIFIED"; //"VERIFIED";
   this.payerAddressStatus = "CONFIRMED";//"CONFIRMED";
   this.paymentMethod = "Paypal";
   this.paymentStatus = authResponse.paypalPaymentStatus.toUpperCase(); //"PENDING"
   this.payerAccountCountry = countryCode; //"US";
   this.protectionEligibility = "ELIGIBLE"; //"ELIGIBLE";
   this.correlationId = authResponse.paypalCorrelationId; //"fdshkj2390sdf";
   this.paymentId = "";
   this.authorizationId = authResponse.transactionId; //"2WC75407LV7300439";
   this.fullPaypalResponsePayload = authResponse;
   this.paymentGatewayData = {};
   this.paymentGatewayData.gatewayName = "Paypal";                  //TODO: must be adjusted according to the payment gateway used
   this.paymentGatewayData.gatewayTransactionId = authResponse.transactionId;
}
```
:::
