Trustly Risk Decline Override

Trustly Risk Decline Override allows you to manage, override, and approve declined Trustly transactions.

When you approve a declined transaction, it becomes a non-guaranteed capture. This means you combine the benefits of guaranteed and non-guaranteed payments, and this gives you full control to manage risk according to your own criteria.

The following are a few of the key features of Trustly Risk Decline Override:

  • Trustly Integration: Direct integration with the Trustly payment system.
  • Risk Data Access: Retrieve detailed risk data for transactions.
  • Custom Risk Management: Make decisions based on your own risk appetite and policies.
  • Override Capability: Approve transactions that Trustly has flagged for potential override, making them non-guaranteed.

Workflow

The following is the Trustly Risk Decline Override workflow:

  • Receive the Trustly declined or failed transaction notification. This notification includes extended reason codes and a flag that indicates if you can override the transaction.
  • When an override is possible, call the Get Risk Data API to override and convert the Trustly decline. Use this data to decide whether to approve the transaction.
  • When your risk assessment approves the transaction, call the Approve Transaction API. This action overrides Trustly risk decline and converts the transaction into a non-guaranteed transaction.
  • Process returned transactions for the non-guaranteed transactions. Trustly offers Representment as a Service that you can enable for these returns to help reduce your losses.

API reference

Use the information provided here to retrieve risk data and execute a risk decline override.

Declined transaction notification parameters

The following table lists the parameters provided by Trustly when a transaction is denied:

ParameterTypeDescription
merchantIdstringUnique identifier for the merchant.
merchantReferencestringUnique transaction identifier.
paymentTypestringType of payment.
transactionTypestringType of transaction.
eventIdstringUnique identifier for the event.
eventTypestringType of event (e.g., "Deny").
objectIdstringUnique identifier for the object.
objectTypestringType of object (e.g., "Transaction").
messagestringMessage describing the reason for denial.
timeZonestringTime zone of the event.
createdAtstringTimestamp of the event.
errorCodestringError code for the denial.
isOverridePossiblebooleanIndicates if a transaction override is possible.
shouldOverrideBeAvoidedbooleanIndicates if a transaction override should be avoided (due to the extended reasons provided).
paymentProviderTransaction.reasonCodestringReason code from the payment provider.
paymentProviderTransaction.reasonCodeMessagestringMessage corresponding to the reason code.
paymentProviderTransaction.statusstringStatus of the transaction from the payment provider.
paymentProviderTransaction.statusMessagestringStatus message from the payment provider.
paymentProviderTransaction.extendedReason.coderepeated stringExtended reason codes.
statusstringStatus of the transaction.
statusMessagestringMessage corresponding to the transaction status.

Sample notification request

The following is an example of the notification you'll receive from Trustly when a transaction is declined.

POST /{notification path}
Authorization: Basic TThSYUhnRWpCRTU0enVGWU1SUXE6RVlOM0dYYXNyVlUxdlExdXlZejIyTk5RZHk0PQ==
merchantId=00123&merchantReference=my+reference&paymentType=2&transactionType=3&eventId=1030845856&eventType=Deny&objectId=1025228290&objectType=Transaction&message=Not+enough+balance&createdAt=1714503865362&errorCode=331&isOverridePossible=true&shouldOverrideBeAvoided=true&paymentProviderTransaction.reasonCode=12&paymentProviderTransaction.reasonCodeMessage=Not+enough+balance&paymentProviderTransaction.status=SW021&paymentProviderTransaction.statusMessage=Not+enough+balance&paymentProviderTransaction.extendedReason.code=10000&paymentProviderTransaction.extendedReason.code=11000&status=8&statusMessage=Denied

See Payment Decline Codes and Reason Codes for more information about the decline reason codes shared by Trustly.

Get risk data

To request risk data from Trustly, you must define the following parameters in your API request definition:

  • Endpoint: /api/v1/transactions/{transactionId}/risk
  • Method: GET
  • Description: Retrieves risk data for the specified declined capture transaction.
  • transactionId (string): A unique identifier for the transaction.

Sample request

The following is an example of the API request definition you'll send to Trustly.

GET /api/v1/transactions/1006755981/risk
Host: trustly.one
Authorization: Basic TThSYUhnRWpCRTU0enVGWU1SUXE6RVlOM0dYYXNyVlUxdlExdXlZejIyTk5RZHk0PQ==

Response

The following table lists the response you will receive from Trustly when you request risk data.

FieldTypeDescription
responseCodestringResponse code for the risk data request.
reasonCodeintegerReason code for the transaction denial.
isOverridePossiblebooleanIndicates if you can override the denial.
shouldOverrideBeAvoidedbooleanIndicates if you should avoid the override.
extendedReasonsarrayDetailed reasons for the transaction denial.
codeintegerExtended reason code.
descriptionstringDescription of the extended reason.
hasEnoughBalanceoptional booleanIndicates if the bank account has enough balance to cover the capture transaction on the settlement date. Considers all pending Automated Clearing House (ACH) transactions and predicted future deposits (like W2 income).
suggestedRetryAmountoptional stringSuggested retry amount for the transaction.
velocityoptional arrayArray of velocity objects detailing transaction activity.
periodintegerPeriod in days.
customer.capturesintegerNumber of captures for the customer.
customer.depositsintegerNumber of deposits for the customer.
device.capturesintegerNumber of captures for the device.
device.depositsintegerNumber of deposits for the device.
account.capturesintegerNumber of captures for the account.
account.depositsintegerNumber of deposits for the account.
overall.capturesintegerOverall number of captures.
overall.depositsintegerOverall number of deposits.
predictedReturnRiskoptional objectPredicted return risk data.
customerInitiatedobjectRisk of returns initiated by customers. For example, unauthorized ACH returns, stop payment ACH returns).
  minRateintegerMinimum return rate (in basis points).
  maxRateintegerMaximum return rate (in basis points).
bankInitiatedobjectRisk of returns initiated by financial institutions. For example, NSFs and administrative returns.
  minRateintegerMinimum return rate (in basis points).
  maxRateintegerMaximum return rate (in basis points).
combinedReturnRiskobjectOverall return risk assessment combining customer-initiated and bank-initiated risks.
  minRateintegerCombined minimum return rate (in basis points).
  maxRateintegerCombined maximum return rate (in basis points).

Sample response

The following is an example of the response you'll receive from Trustly when you request risk data.

{
  "responseCode": "SW021",
  "reasonCode": 1,
  "isOverridePossible": true,
  "shouldOverrideBeAvoided": false,
  "extendedReasons": [
    {
      "code": 10000,
      "description": "Exceeded thresholds"
    },
    {
      "code": 11072,
      "description": "Exceeded 72 hours consumer amount velocity limit"
    }
  ],
  "hasEnoughBalance": true,
  "suggestedRetryAmount": "230.00",
  "velocity": [
    {
      "period": 30,
      "customer": {
        "captures": 2,
        "deposits": 3
      },
      "device": {
        "captures": 3,
        "deposits": 4
      },
      "account": {
        "captures": 4,
        "deposits": 5
      },
      "overall": {
        "captures": 4,
        "deposits": 5
      }
    },
    {
      "period": 90,
      "customer": {
        "captures": 3,
        "deposits": 3
      },
        "device": {
        "captures": 3,
        "deposits": 4
      },
      "account": {
        "captures": 4,
        "deposits": 5
      },
      "overall": {
        "captures": 4,
        "deposits": 5
      }
    }
  ],
  "predictedReturnRisk": {
    "customerInitiated": {
      "minRate": 0,
      "maxRate": 50
    },
    "bankInitiated": {
      "minRate": 100,
      "maxRate": 300
    },
    "minRate": 100,
    "maxRate": 350
  }
}

See Payment Decline Codes and Reason Codes for more information about the decline reason codes shared by Trustly.

Approve transaction

To approve a declined Trustly transaction, the following parameters must be defined in your API request definition:

  • Endpoint: /api/v1/transactions/{transactionId}/approve
  • Method: POST
  • Description: Approves the specified transaction, overriding the Trustly risk engine and converting it to a non-guaranteed transaction. If a return happens for this non-guaranteed transaction, its status changes to Reversed, and the payment provider transaction status shows the return code. For example, R03.
  • transactionId (string): Unique identifier for the transaction.

Sample request

The following is an example of the API request definition you'll send to Trustly.

POST /api/v1/transactions/1006755981/approve
Host: trustly.one
Authorization: Basic TThSYUhnRWpCRTU0enVGWU1SUXE6RVlOM0dYYXNyVlUxdlExdXlZejIyTk5RZHk0PQ==

Sample response

The following is an example of the response you'll receive when you approve a transaction. The transaction (object) is returned with its including status.

{
    "transaction": {
        "transactionId": "1025319672",
        "transactionType": 3,
        "originalTransactionId": "1025319406",
        "payment": {
            "paymentId": "1024188827",
            "paymentType": 2,
            "system": 1,
            "country": "US",
            "merchant": {
                "merchantId": "1076"
            },
            "merchantReference": "A8791F6165148D27",
            "merchantId": "1076",
            "customer": {
                "customerId": "1024101150"
            },
            "fingerprint": "ICaCEX7AjYCt14TvsQp6DBwi8T8=",
            "verification": {
                "status": 3,
                "mode": 3,
                "verifyCustomer": false
            },
            "account": {
                "name": "Demo Checking Account",
                "type": 1,
                "profile": 1,
                "country": "US",
                "accountNumber": "6576",
                "routingNumber": "124003116",
                "verified": true,
                "verification": {
                    "verified": true,
                    "type": 2,
                    "hasEnoughFunds": false
                },
                "source": 1,
                "virtualAccountRoutingPair": false
            },
            "description": "Globex Demo",
            "currency": "USD",
            "amount": "0.00",
            "paymentProvider": {
                "paymentProviderId": "200005501",
                "type": 1,
                "subtype": 1000,
                "name": "Demo Bank",
                "country": "US"
            },
            "paymentProviderSubtype": 1000,
            "auth": {
                "token": "1B8F4NF3O086",
                "status": 2,
                "message": "Authorized"
            },
            "authorization": "1B8F4NF3O086",
            "authorizationStatus": 2,
            "authorizationStatusMessage": "Authorized",
            "pending": "0.00",
            "paid": "2.00",
            "refunded": "0.00",
            "reversed": "0.00",
            "balance": "2.00",
            "createdAt": 1719836931223,
            "updatedAt": 1719851444167,
            "recordVersion": 10,
            "paymentFlow": 79,
            "allowedPaymentProviderSubType": [
                1000,
                2000
            ]
        },
        "currency": "USD",
        "amount": "1.00",
        "pending": "0.00",
        "paid": "1.00",
        "refunded": "0.00",
        "reversed": "0.00",
        "balance": "1.00",
        "paymentProviderTransaction": {
            "paymentProviderTransactionId": "ptx-fBQgeemdGzcWSE0QxqA60G8M-sbx",
            "signature": "46401",
            "status": 118,
            "statusMessage": "Settled",
            "paymentProcessor": {
                "paymentProcessorId": "100000016"
            },
            "instantSettle": false,
            "statementId": "1K8T",
            "reasonCode": -1
        },
        "status": 4,
        "statusMessage": "Completed",
        "ip": "177.53.170.106",
        "createdAt": 1719851400859,
        "processedAt": 1719851443780,
        "completedAt": 1719851444167,
        "updatedAt": 1719851444172,
        "ppTrxId": "ptx-fBQgeemdGzcWSE0QxqA60G8M-sbx",
        "merchantReference": "A8791F6165148D27",
        "automaticRepresentment": false,
        "paymentProcessorType": "ACH",
        "statusCode": "AC118",
        "forgiven": "0.00",
        "kycType": -1,
        "recordVersion": 7
    }
}

Receive ACH return notifications from Trustly

When an ACH return occurs on a transaction whose risk decline you overrode, the resulting non-guaranteed transaction's status changes to Reversed. The payment provider transaction status shows the specific ACH return code. For example, R01.

Additionally, Trustly places a hold on the consumer, automatically declining all their subsequent transactions. To enable the consumer to authorize new transactions, you must call the Remove Debt Block API.

Trustly sends webhook notifications to make you aware of ACH returns. The following table lists the parameters that are included in a an ACH return notification.

FieldTypeDescription
merchantIdstringUnique identifier for the merchant.
merchantReferencestringUnique transaction identifier.
paymentTypestringType of payment.
transactionTypestringType of transaction.
eventIdstringUnique identifier for the event.
eventTypestringType of event. For example, Reverse.
objectIdstringUnique identifier for the object.
objectTypestringType of object. For example, Transaction.
messagestringMessage describing the reason for reversal.
timeZonestringTime zone of the event.
createdAtstringTimestamp of the event.
paymentProviderTransaction.statusstringStatus of the transaction from the payment provider.
paymentProviderTransaction.statusMessagestringStatus message from the payment provider.
reversedAmountstringThe reversed amount.
statusstringStatus of the transaction.
statusMessagestringMessage corresponding to the transaction status.

Sample notification request

The following is an example of the ACH notification request you'll send to Trustly.

POST /{notification path}
Authorization: Basic TThSYUhnRWpCRTU0enVGWU1SUXE6RVlOM0dYYXNyVlUxdlExdXlZejIyTk5RZHk0PQ==
merchantId=00123&merchantReference=my+reference&paymentType=2&transactionType=3&eventId=1030845856&eventType=Reverse&objectId=1025228290&objectType=Transaction&message=US_ACH_CROSSRIVER+returned+transaction+with+message%3A+R01&createdAt=1714503865362&paymentProviderTransaction.status=R01&paymentProviderTransaction.statusMessage=Insufficient+Funds&reversedAmount=37.99&status=10&statusMessage=Reversed

Remove debt block

To remove a debt block, the following parameters must be defined in your API request definition:

  • Endpoint: /api/v1/transactions/{transactionId}/removeDebtBlock
  • Method: POST
  • Description: Removes any holds that may have been placed by Trustly on the consumer due to an ACH return on an overridden transaction. If there are no other transactions with debt blocks, the consumer can successfully authorize new transactions.
  • transactionId (string): Unique identifier for the transaction that has received an ACH return.

Sample request

The following is an example of the remove debt block request you'll send to Trustly.

POST /api/v1/transactions/1006755981/removeDebtBlock
Host: trustly.one
Authorization: Basic TThSYUhnRWpCRTU0enVGWU1SUXE6RVlOM0dYYXNyVlUxdlExdXlZejIyTk5RZHk0PQ==

Sample response

The following is an example of the response you'll receive after submitting a request to remove a remove debt block.

{}