Accept payments with Trustly Pay
Trustly Pay is a deferred payment flow that allows you to separate the user's bank authorization from the movement of funds.
Unlike a standard one-time checkout, Trustly Pay establishes a persistent connection with the user's bank account. This allows you to generate a secure token (transactionId) once and use it for multiple operations.
While the API technically separates Authorization (establishing the connection) and Capture (moving the money) into two steps, most integrations execute them in immediate succession.
When to use Trustly Pay
-
One-click deposits: You want to tokenize the bank account so returning users can fund their account instantly without logging into their bank again.
-
Wallets and trading platforms: You need a single authorization to handle the full lifecycle of a user account—both funding (Pay-ins) and cashing out (Payouts).
-
Session-based charges: You need to authorize a user's account at the start of a session (for example, gameplay or service usage) but determine the final capture amount at the end.
Core capabilities
The Trustly Pay workflow supports the following API operations:
-
Pay-ins (Capture): Pull funds from the user's bank account to your platform.
-
Payouts (Deposit): Push winnings or withdrawals back to the user's bank account.
-
Refunds: Return funds to the user from a previous Pay-in.
Payment workflow
The following diagram illustrates the two-phase lifecycle of a Trustly Pay transaction, starting with the initial user authorization and followed by the server-side funds capture.
sequenceDiagram participant User participant Client as Merchant Frontend participant Server as Merchant Backend participant Trustly Note over User, Trustly: Phase 1: Bank Authorization User->>Client: A Client->>Trustly: B Trustly-->>User: C User->>Trustly: D Trustly-->>Client: E Client->>Server: F Note over User, Trustly: Phase 2: Capture Funds Server->>Trustly: G Trustly-->>Server: H Trustly-)Server: I
The following table describes each step in the workflow, corresponding to the lettered annotations in the diagram.
| Workflow Step | Action | Description |
|---|---|---|
| A | User initiates payment | The user clicks a button, such as Deposit, on your frontend application. |
| B | Client calls establish | Your frontend calls Trustly.establish with paymentType="Deferred". |
| C | Trustly launches UI | Trustly presents the Trustly Lightbox to the user. |
| D | User authorizes | The user logs into their bank through the Trustly Lightbox and confirms the authorization. |
| E | Redirect to returnUrl | Trustly redirects the user back to the returnUrl specified in your establish data. |
| F | Client sends ID to server | Your frontend extracts the transactionId from the redirect URL and securely passes it to your backend server. |
| G | Server requests capture | Your backend makes a server-to-server API call (POST /transactions/{id}/capture) using the stored transactionId. Trustly recommends triggering this immediately after receiving the transactionId to minimize risk and ensure funding. |
| H | Trustly acknowledges | Trustly returns an HTTP 200 OK response with a status of PENDING. The transaction is accepted and processing. |
| I | Final confirmation webhook | Trustly sends an asynchronous webhook notification to your backend confirming the final status (usually CAPTURED or SETTLED). |
Prerequisites
- Client-side SDK: You must integrate the JavaScript SDK (Web) or Mobile SDK to launch the Trustly UI. See Integrate the Client-Side SDK.
- Sandbox credentials: You need your
accessIdandaccessKey. Contact Trustly Support if you do not have them. - Legal agreement: Ensure your non-disclosure agreement (NDA) and commercial agreements are signed.
Create a bank authorization
The foundation of Trustly Pay is the Establish call. This launches the Lightbox and generates a transactionId that represents the authorized user.
Configure the transaction
Create an establishData object to define the transaction parameters. To create a deferred authorization, you must set the paymentType to Deferred.
While you can set the amount to '0.00' for open-ended authorizations, Trustly recommends passing the full purchase value if it is known. This ensures Trustly validates that the user has sufficient funds during the initial authorization step.
var establishData = {
accessId: 'YOUR_ACCESS_ID',
merchantId: 'YOUR_MERCHANT_ID',
merchantReference: 'user_session_8829',
description: 'Wallet funding', // Do not put PII here
currency: 'USD',
amount: '100.00', // Set to 0.00 or the specific deposit amount
paymentType: 'Deferred',
requestSignature: 'GENERATED_SIGNATURE',
// verifyCustomer: true, // Required for Gaming/Sportsbook
customer: {
name: 'Jane Doe',
address: {
country: 'US'
}
},
returnUrl: '[https://merchant.com/return](https://merchant.com/return)',
cancelUrl: '[https://merchant.com/cancel](https://merchant.com/cancel)'
};Implementation details
- requestSignature (Required): You must generate an HMAC-SHA256 signature to prevent tampering. See Generate request signatures.
- verifyCustomer (gaming only): Electronic Gaming clients must set
verifyCustomer: trueand pass all PII (Name, Email, and so on) inside thecustomerobject. Do not pass PII in thedescriptionfield.
Launch the Lightbox
Call Trustly.establish() passing both your transaction data and your options object (if configured). For example:
Trustly.establish(establishData, TrustlyOptions);To configure TrustlyOptions, see Integrate the Client-Side SDK.
Handle the redirect
Once the user successfully authorizes the request, Trustly redirects them to your returnUrl. If the user cancels, Trustly redirects them to your cancelUrl.
Example Return URL: https://merchant.com/return?transactionId=1002633191&status=2
You must capture and store the transactionId from the URL parameters. This ID is the unique key you'll use to execute all subsequent API requests. You should also confirm that the status parameter is 2 (Authorized). For a complete list of transaction statuses, see Status codes.
Enable Trustly Remember Me (optional)
Trustly Remember Me significantly reduces friction for returning users and increases conversion rates by enabling a seamless, one-click payment experience.
When the user completes the authorization, Trustly generates a secure splitToken. You can use this token to recognize the returning user and allow them to pay in the future with a single click, bypassing the bank login process entirely.
To enable this functionality, ensure you provide the user's email, phone, and externalId in the customer object of your establishData.
For implementation details, see Enable Trustly Remember Me.
Capture funds
Once you have a valid bank authorization (transactionId), you can pull funds from the user's account into your merchant account using the Capture API.
Endpoint: POST /transactions/{transactionId}/capture
Replace {transactionId} with the ID from the original bank authorization.
Request parameters
| Parameter | Description |
|---|---|
amount | The amount to debit from the user. |
merchantReference | Your unique identifier for this order. For example, the order ID. |
Example request
curl -X POST https://sandbox.trustly.one/api/v1/transactions/{transactionId}/capture \
-u "YOUR_ACCESS_ID:YOUR_ACCESS_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": "10.00",
"merchantReference": "order_12345"
}'Response handling
The Capture API is synchronous, but all of the subsequent transaction statuses are asynchronous. The immediate response is typically Pending. You must wait for a webhook to confirm the final status.
| Status | Description | Action |
|---|---|---|
PENDING | Transaction accepted and processing. | Record the transaction. Wait for the final confirmation webhook. For example, CAPTURED or SETTLED. |
DECLINED | Transaction rejected. For example, non-sufficient funds or risk. | Ask the user for a different payment method. |
Send funds (payouts)
To send winnings or withdrawals back to the user's bank account, use the Deposit API. See Send payouts.
Event notifications
Trustly Pay relies on the ACH network, so transaction statuses are asynchronous. You must configure a webhook listener to track when funds actually settle.
Key events for the Trustly Pay workflow include:
debit: Confirms a successful Pay-in (Capture).credit: Confirms a successful Payout (Deposit).
See Handle webhooks.
Refresh bank authorization
Bank authorizations may expire or require refreshing. For example, if a user changes their bank password. See Refresh bank authorization
Error codes
The following table lists the error codes you may encounter during pay-in or payout requests.
For detailed user messaging recommendations for each error code, see Status codes and type definitions.
| Transaction Status | Error Code | Description | Action |
|---|---|---|---|
| Failed | SW057 / 326 | Expired token | See Maintain authorizations. |
| Failed | SW051 / 380 | Invalid / corrupt token | See Maintain authorizations. |
| Failed | SW056 / 330 | Invalid account | Remove the bank account from the user's profile. Prompt the user to add a new payment method. |
| Failed | SW054 / 390 | Fraud analysis | Prompt the user to use a different payment method. If a thirdPartyDeclineCode is provided, direct the user to the supplier. |
| Failed | SW055 / 390 | Fraud analysis (Negative Data) | Remove the bank account from the user's profile. Prompt the user to add a new payment method. |
| Failed | SW052 / 378 | Internal error or bank request error | Show a generic error message and allow the user to try again. |
| Denied | SW021 / 331 | Not enough balance | Prompt the user to check their balance or use another payment method. |
Next steps
- Display confirmation: Retrieve account details to show a confirmation screen or pre-fill checkout forms. See Retrieve bank and user information.
- Test: Verify that your application handles success and error states correctly. See Test your integration.
Updated 4 days ago