Account Retrieval

Trustly provides a solution that allows a user to sign into their Online Banking account and allow the selected ABA Routing and Account Number to be retrieved by the merchant. The merchant can then use this data in their own tokenization and processing platform.

Account ownership verification can be done using Trustly’s front end establish function and Get Account Balance. You can also optionally use the Get User to retrieve the user's personally identifiable information (PII) and verify account ownership against your own data.

  1. On your site, present the user to sign into Online Banking.
  2. The Trustly Lightbox opens. The user selects their bank from the list, authenticates, and selects their account.
  3. When the user has selected their account, they are returned to your returnUrl.
  4. From your back end, execute the Get Account Balance to retrieve the user's bank account and routing information.
  5. Optionally use the Get User to retrieve the user's PII (name, address, phone number, email address) to optionally compare the information provided by the user's bank account to information previously provided. You can also optionally use this data to pre-fill information required by your user.
  6. Continue processing as needed.

Integration Options and Branding Requirements

Trustly offers two types of Integration Options for its Online Banking solution: Select Bank Widget and Trustly Lightbox.

The Select Bank Widget is shown in-line on your page and shows the most popular bank accounts. Selecting one of the buttons on the Widget opens the Trustly Lightbox, where the User can sign in and authorize their account for use.

Alternatively, you can trigger the Trustly Lightbox using your own button. The Trustly Lightbox opens over your existing page.

In addition to determining if the Select Bank Widget or opening the Trustly Lightbox directly is the best option for you, Trustly has a number of Branding Requirements to consider. If you have any questions or specific requirements, please work with your Trustly team or contact [email protected].

Create a Bank Authorization using Online Banking

The Trustly Online Banking Payment service enables end users to pay by signing into their online banking interface within your website. The Trustly User interaction can be completed in 3 simple steps:

  1. The User selects Online Banking as a payment method on your website, which either displays the Trustly Widget (which then launches the Trustly Lightbox) or launches the Trustly Lightbox directly.
  2. From the Trustly Lightbox, the user authenticates with their bank and selects the account they wish to use for the transaction.
  3. The User is returned to you returnUrl, where you can continue processing.

Integrate the Trustly SDK into your flow.

Trustly offers 3 SDK's: JavaScript, iOS, and Android. The SDK has 2 main methods: selectBankWidget and establish. The methods accept 2 parameters, options and establishData. The options parameter is optional and can be used to control pieces of the Lightbox experience. The establishData parameter is used to pass transaction parameters to Trustly that are used when establishing the Bank Authorization transaction.

The following examples are using the JavaScript SDK

1. To load the SDK on the page, use the following JavaScript tag (replacing {accessId} with the Access Id provided to you by Trustly):

<script src="https://sandbox.trustly.com/start/scripts/trustly.js?accessId={accessId}"> </script>

2. To provide optional Trustly configuration options, create a TrustlyOptions object:

var TrustlyOptions = {
  closeButton: false,
  dragAndDrop: false,
  widgetContainerId: "widget-container-id" //Page element container for the widget
};

For details on the Trustly configuration options, refer to the SDK Specification.

3. To provide the transaction details to the SDK, create an establishData object:

var establishData = {
  accessId: {accessId},
  requestSignature: {requestSignature},
  merchantId: {merchantId},
  description: 'transaction description',
  merchantReference: 'merchant reference',
  paymentType: 'Retrieval',
  returnUrl: 'https://merchant.com/trustly/return',
  cancelUrl: 'https://merchant.com/trustly/cancel'      
};

🚧

Warning

Do not pass Consumer PII (name, email address, etc) in the description field. You can pass Consumer PII in the customer object.

📘

Tip

Ensure you're securing your call by including the requestSignature parameter.

4. Finally, call the Trustly SDK's establish or selectBankWidget function:

Select Bank Widget

Trustly.selectBankWidget(establishData, TrustlyOptions);

Establish

Trustly.establish(establishData, TrustlyOptions);

The following is a full HTML page using the above example.

📘

Info

Replace {accessId} and {merchantId} with the values provided to you by Trustly.

<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <script>
      var TrustlyOptions = {
        closeButton: false,
        dragAndDrop: true,
        widgetContainerId: 'widget',
      };
    </script>
    <script src="https://sandbox.trustly.com/start/scripts/trustly.js?accessId={accessId}"></script>
  </head>
  <body style="margin: 0;">
    <div id="widget"></div>
  </body>
   <script>
    var establishData = {
      accessId: {accessId},
      requestSignature: {requestSignature},
      merchantId: {merchantId},
      description: 'transaction description',
      merchantReference: 'merchant reference',
      paymentType: 'Retrieval',
      returnUrl: 'https://merchant.com/trustly/return',
      cancelUrl: 'https://merchant.com/trustly/cancel'      
    };
    Trustly.selectBankWidget(establishData, TrustlyOptions);
  </script>
</html>

Handle the redirect

If the User cancels the request, Trustly will direct the User to your provided cancelUrl. If the User successfully authorizes the request, Trustly will direct the User to your provided returnUrl.

Once you get a successful redirect to your returnUrl, check to ensure you've received the Split Token and added the account on file. If you have not, add the account on file with the provided transactionId and a blank or null splitToken.

Example Cancel URL

https://merchant.com/trustly/cancel?transactionId=1002810573&transactionType=1&merchantReference=123123123456789&status=7&payment.paymentType=6&panel=1&payment.paymentProviderTransaction.status=UC01&requestSignature=W33v56Z3csgmcKIV5cbPYOB7CSw%3D

Example Return URL

https://merchant.com/trustly/return?transactionId=1002810549&transactionType=1&merchantReference=123123123456789&status=2&payment.paymentType=6&payment.paymentProvider.type=1&payment.account.verified=true&panel=1&requestSignature=68UoOfuVyEBHQB4PPdL4vtAPDoc%3D

Redirect URL Parameters

Trustly will append the following parameters to your returnUrl or cancelUrl:

ParameterDefinition
transactionIdA unique Trustly transaction identifier. (15 characters)
transactionTypeWill always be 1 in this use case.
merchantReferenceA specific merchant reference for this cancelation. For example, this could be your order number or session id.
statusInteger value representing the Transaction Status. This will either be 2 (Authorized) or 7 (Cancelled). Refer to Transaction Status Values in the SDK Specification for a complete list of values and their definitions.
payment.paymentTypeWill always be 2 (Deferred) in this use case.
payment.paymentProvider.typeWill always be 1 (Online Banking) in this use case.
payment.account.verified...
panelInteger value representing the Trustly screen the user exited the flow on. Refer to Panel Values in the SDK Specification for a complete list of values and their definitions.
payment.paymentProviderTransaction.statusInteger value representing the Payment Provider Transaction Status of the transaction. Refer to Payment Provider Transaction Status in the SDK Specification for a complete list of values and their definitions.
requestSignatureThis is a signature that you can calculate to ensure the request you receive is coming from Trustly. See Validate the Redirect Signature for more information.

Retrieve Bank Details or User PII from Trustly

With a valid Bank Authorization, you can use the Trustly Get Transaction API to retrieve information about the Users bank account that can be displayed in their account on your system. You can also use the Trustly Get User API to retrieve personal information (name, address, email, etc) that can be used to pre-fill fields on your flow or verify the information you have already collected from the User.

Use Get Account Balance to retrieve Bank information

Calling the Get Account Balance API allows you to get the banking information selected for a given transaction. You call the Get Account Balance API by executing a GET request to the Get Transaction endpoint (/transactions/{transactionId}/payment/paymentProvider/account/balance), where {transactionId} is the Bank Account Authorization transaction id.

Example Get Account Balance API request

https://sandbox.trustly.com/api/v1/transactions/1002810549/payment/paymentProvider/account/balance

The Get Account Balance call returns a JSON response with Bank Account data that you can use in your application. Relevant fields from the response include:

  • accountBalance.account.providerId: Trustly Identifier for the Bank selected. You can use this identifier to display the Bank logo to the User.
  • accountBalance.account.nameOnAccount: Users name that is provided by the selected account.
  • accountBalance.account.name: Name (friendly identifier) of the Users Bank Account.
  • accountBalance.account.type: Type of Account selected (Checking or Savings).
  • accountBalance.account.accountNumber: Bank Account Number provided by the selected account.
  • accountBalance.account.iban: IBAN provided by the selected account.
  • accountBalance.account.routingNumber: Bank Routing Number provided by the selected account. RTN on U.S and Sort Code on Europe.

You can then use this information to display the selected Payment Method to your user and use the provided Account and Routing number in your application.

Example Get Transaction response (abbreviated)

{
    "accountBalance": {
        "account": {
            "providerId": "200005501",
            "paymentProvider": {
                "paymentProviderId": "200005501"
            },
            "nameOnAccount": "John Smith",
            "name": "Demo Checking Account",
            "type": 1,
            "profile": 1,
            "accountNumber": "123456576",
            "routingNumber": "124003116",
            "verified": true,
            "verification": {
                "verified": true,
                "type": 2,
                "hasEnoughFunds": true,
                "verificationDate": 1561162678111
            }
        }
    }
}

Please refer to the Get Account Balance definition in the API Reference for more information.

Use Get User Information to retrieve, validate, and display User information

Calling the Get User API allows you to get the personal information (Account Owner name, address, phone, and email) of the User from their selected Bank Account. You call the Get User API by executing a GET request to the Get Transaction endpoint, where {transactionId} is the Bank Account Authorization transaction id.

Example Get User request

https://sandbox.trustly.com/api/v1/transactions/1002548448/payment/paymentProvider/user

The Get User API returns a JSON response with User data that you can use in your application. Relevant fields from the response include:

  • name: Name(s) associated with the User's Bank Account.
  • address: Address(es) associated with the User's Bank Account.
  • phone: Phone Number(s) associated with the User's Bank Account.
  • email: Email Address(es) associated with the User's Bank Account.

You can then use this information to pre-fill or display the User's information in your flow. You can also use this information to validate the personal information the User may have previously provided in your flow.

Example Get User response (abbreviated)

{
  "user": {
    "name": [
      "John Smith",
      "Mary Smith"
    ],
    "address": [
      {
      "address1": "2000 Broadway Street",
      "address2": "",
      "city": "Redwood City",
      "state": "CA",
      "zip": "94063",
      "country": "US"
      },
      {
      "address1": "105 Alternate1 Street",
      "address2": "#401",
      "city": "Redmond",
      "state": "WA",
      "zip": "98052",
      "country": "US"
      },
    ],
    "phone": [
      "2145553434"
    ],
    "email": [
      "[email protected]"
    ],
  }
}

Please refer to the Get User definition in the API Reference for more information.

Adding support for Micro Challenge Deposits (MCD)

If your account has been enabled to process Micro Challenge Deposit (MCD) verification requests, there is an additional step you must take to finish the verification process.

Create the initial bank authorization

The initial bank authorization does not change. You pass in the same establishData object as usual.

var establishData = {
  accessId: {accessId},
  requestSignature: {requestSignature},
  merchantId: {merchantId},
  transactionId: {transactionId},
  merchantReference: 'merchant reference',
  paymentType: 'Retrieval',
  returnUrl: 'https://merchant.com/trustly/return',
  cancelUrl: 'https://merchant.com/trustly/cancel'        
};

🚧

Warning

Do not pass Consumer PII (name, email address, etc) in the description field. You can pass Consumer PII in the customer object.

📘

Note

Ensure you're securing your call by including the requestSignature parameter.

Handle the redirect

Once you get a successful redirect to your returnUrl, confirm if the user needs to continue the verification process. Ensure the payment.paymentProvider.type value is 2 (Manual Entry), the status is 2 (Authorized), and the payment.account.verified is false. Because the payment.paymentProvider.type is 2 (Manual Entry) and the payment.account.verified value is false, message to the user to return to your site when they are ready to verify their account.

Retrieving the test verification code

You can use our Sandbox Merchant Portal to view the test account verification deposit code that was generated for the Bank Authorization.

1. After signing into the Sandbox Merchant Portal, find the Bank Authorization transaction you created earlier.

2. Click on the Transaction ID to bring up the details. Scroll down to the 'Account Verification Deposits' section. Copy the 'Reference Code' value.

Initiate the verification flow

The following examples are using the JavaScript SDK

1. To load the SDK on the page, use the following JavaScript tag (replacing {accessId} with the Access Id provided to you by Trustly):

<script src="https://sandbox.trustly.com/start/scripts/trustly.js?accessId={accessId}"> </script>

2. To provide optional Trustly configuration options, create a TrustlyOptions object:

var TrustlyOptions = {
  closeButton: false,
  dragAndDrop: false,
  widgetContainerId: "widget-container-id" //Page element container for the widget
};

For details on the Trustly configuration options, refer to the SDK Specification.

3. To provide the transaction details to the SDK, create an establishData object:

var establishData = {
  accessId: {accessId},
  requestSignature: {requestSignature},
  merchantId: {merchantId},
  transactionId: {transactionId},
  merchantReference: 'merchant reference',
  paymentType: 'Retrieval',
  returnUrl: 'https://merchant.com/trustly/return',
  cancelUrl: 'https://merchant.com/trustly/cancel'      
};

🚧

Warning

Do not pass Consumer PII (name, email address, etc) in the description field. You can pass Consumer PII in the customer object.

📘

Tip

Secure your call by including the requestSignature parameter.

4. Finally, call the Trustly SDK's establish function:

Trustly.establish(establishData, TrustlyOptions);

The following is a full HTML page using the above example:

<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <script>
      var TrustlyOptions = {
        closeButton: false,
        dragAndDrop: true,
        widgetContainerId: 'widget',
      };
    </script>
    <script src="https://sandbox.trustly.com/start/scripts/trustly.js?accessId={accessId}"></script>
  </head>
  <body style="margin: 0;">
    <div id="widget"></div>
  </body>
   <script>
    var establishData = {
      accessId: {accessId},
      requestSignature: {requestSignature},
      merchantId: {merchantId},
      transactionId: {transactionId},
      merchantReference: 'merchant reference',
      paymentType: 'Retrieval',
      returnUrl: 'https://merchant.com/trustly/return',
      cancelUrl: 'https://merchant.com/trustly/cancel'      
    };
    Trustly.establish(establishData, TrustlyOptions);
  </script>
</html>

📘

Info

Replace {accessId} and {merchantId} with the values provided to you by Trustly.

Enter the test verification code

Using the verification HTML you created above, launch the Trustly Lightbox.

After entering the code retrieved from the Sandbox Merchant Portal and clicking Continue, the user is directed back to your site.

Handle the redirect

Once you get a successful redirect to your returnUrl, confirm if the user is indeed verified. Ensure the payment.paymentProvider.type value is 2 (Manual Entry), the status is 2 (Authorized), and the payment.account.verified is true. If payment.account.verified is true, the account is verified.

Testing

Trustly offers a Demo Bank in the Sandbox environment that can be used to trigger a number of testing scenarios. You access the Demo Bank, search for "Demo Bank" in the 'Select your bank' screen of the Trustly Lightbox. To simulate errors when using the Demo Bank, you can use the phrases below in the password field to generate errors.

PasswordUse Case
NoEligibleAccountsNo eligible accounts found
LoginErrorWrong username or password
NotRecognizedMain Error that users see when using an ACA
NoSuchFieldThis error ultimately ends up as a PageNotRec error. It happens when an item cannot be found on the page. ACA will try to execute another page. If there is not another page, “page not recognized” error will be returned. Customers shouldn’t see this error.
PostErrorHTTP connection error using GET. The customer shouldn’t see this error. In real ACA, this will result in a Site not available” error.
GetErrorHTTP connection error using POST. The customer shouldn’t see this error. In real ACA, this will result in a Site not available” error.
PromptTypeErrorWhen an ACA fails to create a prompt, this error is returned. If this error appears, it means the ACA has a bug.
JsErrorWhen ACA tries to run javascript code and there are any errors during running, this error will be thrown.
UnavailableBank Site cannot be reached.
AccountLockedUser’s account is locked.
UnclassifiedThere are some run time exceptions that are not captured by ACA, like NPE(null pointer exception), array out of bounds exception, and so on.
BankActionThe bank requires the user to login and perform some action on their site.
ConnectErrorThere was a connection problem when accessing the bank site
ConnectionErrorThere was a connection problem when accessing the bank site
BlockedIpErrorThe bank indicates the caller IP was blocked
ChallengeErrorSimulates retry scenario, where the user provides a wrong challenge (or anything that isn't userid or password) and is allowed to retry
ValidRouteCodeExtraConnector returns 2 accounts whose route codes are larger than 9 digits: one of them has a valid route code as a substring, so both accounts use the same valid code
InvalidRouteCodeExtraConnector returns a single account whose route code is larger than 9 digits, but no valid route code is found as a substring. Hence, the account is ignored
TimeoutErrorIn order to simulate a timeout, the connector sleeps for at least a minute before actually doing anything.
TestPromptsThis is not an error. This is to test the prompts on the next page, including (Checkbox, radio, text, password, date, description, and so on)
NotEnoughFundsConnector returns a single account with zero balance. This is similar to having no eligible accounts, but for different reasons.
NotEnoughFundsExtraConnector returns two accounts. One with zero balance, the other with a valid balance.
InvalidAccountNumberSizeConnector returns a single account, but with an account number shorter than the required. This is to test how the screen filters invalid accounts
InvalidAccountNumberSizeExtraConnector returns two accounts. One with account number shorter (3 characters) than the required, the other with the valid account number.
PartialAccountNumbersConnector returns two accounts, however only with partial numbers. Simulating when for example the account is new and we still don't have statements to get the full account number.
OnlyPartialsPartialAccountNumbers + NoRouteCode
NoCustomerSimulates as if FIC was not able to retrieve customer information
NoRouteCodeRegular flow with 2 accounts, but none with route code. This prompts a question for account location, where the user must select where the account was open (from the given options)
InvalidRouteCodeRegular flow but simulates an invalid routing code (will simulate if ProfitStars returns invalid routing code)
2FASimulates as the bank requested a challenge question to the user. The question should be answered with the word 'error' if it's necessary to simulate a wrong credential. Otherwise, it should be anything to have successful access.
WrongCredentialsSimulates retry scenario, where the user provides a wrong challenge (or anything that isn't userid or password) and is allowed to retry
SiteRequestErrorSimulates as if the bank couldn't process a particular request, allowing the user to retry it
SessionTimeoutSimulates as if the user took too long to provide the requested information, since the bank session is already expired
PreLoginErrorSimulates an error before the user gets authenticated
NotSupportedSimulates a user with no supported accounts
AccountsWithNameAndAddressSimulates a User with 2 accounts and each one with different names and addresses.
ManyInformationSimulates a User with 10 accounts.
AccountNotSupportedSimulates a User with an account not supported by our service (Chase Liquid, etc)
AmountNullSimulates the Demo Checking Account returning an amount with a null value.
AccNumberNullSimulates the Demo Checking Account returning the null value in the account number and routing number
AccFromUsernameReturns the account number from the pattern {prefix}_{accountnumber} on the username. Ex: To return an account with number 1234445 you can enter the username user1_1234445 or anotheruser_1234445.
RandomBalanceReturns account with a random balance
RandomAccountsReturns an account with a random account number
LargeCustomerInfoReturns account with very large customer information
FICWarningIt simply adds to log engine fic-warning one example message to simulate the FIC Warning flow
EmailMFASimulates as the bank requested the user to select an email address to send him an MFA token.
MixedMFASimulates as the bank requested the user to select an email address or a phone number to send him an MFA token.
CreditCardsOnlyReturns an account only with a credit card
TCKAccountsReturns an account that is valid on the TeleCheck test environment
AccountProfileReturns accounts with Business, Personal, Other, Unknown and Null profiles.
Balance{xxx}Configures the account to have a balance of {xxx}. For example, Balance1000 will set the account balance to $1000. This is useful when testing transactions of larger dollar amounts.
RandomAccWithSleepReturns random accounts with random account numbers and sleeps (in seconds) during the number passed in the password field
ExpiredSplitTokenAllows the transaction to be authorized but every refresh API call fails because of an expired split token.
NotEnoughFundsOnRefreshAllows the transaction to be authorized but every refresh API call returns 0.00 as a balance for all accounts.

To simulate a delay, just enter Sleep as username and the number of seconds as the password, The connector will wait for at least the given number of seconds before presenting any results.

Error Handling

Trustly uses conventional HTTP response codes to indicate the success or failure of an API request.

HTTP Status CodeDescription
200 OKEverything worked as expected.
400 Bad RequestOften due to a missing, required parameter.
401 UnauthorizedInvalid accessId or accessKey.
500 Server errorSomething went wrong on Trustly's end.
503 Service UnavailableThe server is currently unable to handle the request due to temporary overloading or server maintenance.

Not all errors map cleanly onto HTTP response codes, however. In addition to the HTTP response code, Trustly returns an array of error objects that describes the errors as a JSON string such as the example below.

{
  "errors": [
    {
      "domain" : "com.trustly.merchantgateway.v1.exception.InvalidParameterException",
      "code" : 200,
      "message" : "Could not find a transaction using Id 10000021"
    }
  ]
}
Error CodeDescription
100Internal error. An internal error (an internal database exception for example) occurred when trying to process the request.
150Remote error. A remote error (the consumer's bank interface is down) occurred when trying to process the request. This is an internal error.
200Invalid parameter error. One of the request parameters is invalid (sending an invalid amount format string for example).
300Security error. These are generic security errors that can happen when trying to process the request.
326Expired split token.
330Invalid account.
331Not enough balance.
375Access control error. This occurs when some security parameter (accessId, accessKey or requestSignature) is invalid and the request cannot be processed.
390Fraud analysis. Suspicious transaction or negative data.

Further Reading


Did this page help you?