Accept payments with Trustly Pay
Trustly Pay provides a deferred payment flow that separates the user bank authorization from the movement of funds. Unlike a standard checkout, Trustly Pay establishes a persistent authorization for the user bank account. This tokenization generates a secure transactionId once, which serves as a reference for multiple operations later without requiring the user to re-authenticate.
Use Trustly Pay for all new integrations, including one-time payments. It offers better risk optimization and a better user experience.
- Code Parameter: Even when the user pays immediately, the
paymentTypefor Trustly Pay is technically'Deferred'. - Legacy Requirements: Only use
paymentType: 'Instant'if your backend specifically requires the legacy, single-phase capture rail.
When to use Trustly Pay
-
One-click deposits: Tokenize the bank account so returning users can fund their account instantly without logging into the bank again.
-
Wallets and trading platforms: Use a single authorization to handle the full lifecycle of a user account for both funding (Pay-ins) and cashing out (Payouts).
-
Session-based charges: Authorize a user account at the start of a session (such as gameplay or service usage) and 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 bank account to your platform.
-
Payouts (Deposit): Push winnings or withdrawals back to the user 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. The process begins with the initial user authorization, which Trustly recommends initiating through the Select Bank Widget to reduce checkout abandonment. The server-side funds capture follows the user authorization.
sequenceDiagram participant User participant Client as Merchant Frontend participant Server as Merchant Backend participant Trustly as Trustly UI / API User->>Client: A (Select Bank Widget) Client->>Trustly: B (Establish Call) Trustly-->>User: C (Lightbox UI) User->>Trustly: D (Authentication) Trustly-->>Client: E (Browser Redirect) Trustly-)Server: F (Split Token Webhook) Note over User, Trustly: Phase 2: Capture Funds Server->>Trustly: G (Capture Request) Trustly-->>Server: H (Immediate Response) Trustly-)Server: I (Settlement Webhook)
The following table describes each step in the workflow, corresponding to the lettered annotations in the diagram.
| Workflow Step | Action | Description |
|---|---|---|
| A | User initiates | The user interacts with the Select Bank Widget on the frontend. |
| B | Client calls SDK | The frontend calls Trustly.selectBankWidget with paymentType="Deferred". |
| C | Trustly launches UI | The Lightbox opens for the user to authenticate with the bank. |
| D | User authorizes | The user logs in and confirms the bank connection. |
| E | Redirect | Trustly sends the user back to the returnUrl with a transactionId. |
| F | Webhook | Trustly sends a notification containing the splitToken to the backend. |
| G | Server captures | The backend calls the Capture API through a server-to-server request. |
| H | API Response | Trustly returns an immediate PENDING status for the capture. |
| I | Final Webhook | Trustly sends a final webhook once the funds clear the network. |
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: Sign the non-disclosure agreement (NDA) and commercial agreements.
Create a bank authorization
The Establish call is the foundation of Trustly Pay. 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 you know it. 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',
splitToken: 'YOUR_STORED_SPLIT_TOKEN', // Required for returning users (Trustly Remember Me)
requestSignature: 'GENERATED_SIGNATURE',
// verifyCustomer: true, // Required for Gaming/Sportsbook
customer: {
externalId: 'merchant_user_123', // Required to identify the returning user
name: 'Jane Doe',
email: '[email protected]',
phone: '+15555555555',
address: {
country: 'US'
}
},
returnUrl: 'https://merchant.com/return',
cancelUrl: '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
While a standard button can call Trustly.establish(), Trustly recommends the Select Bank Widget as the primary integration method. The widget displays bank logos directly on the checkout page, which helps more users complete the bank authorization process. This visual familiarity often leads to a higher rate of successful transactions.
To initialize the widget, pass the transaction data and options to the selectBankWidget function:
// Launches the inline bank selection widget
Trustly.selectBankWidget(establishData, TrustlyOptions);To configure the widget container and other UI settings, 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
Trustly Remember Me significantly reduces friction for returning users and increases conversion rates by enabling a seamless, one-click payment experience.
You’ll receive the splitToken through a backend webhook once the user finishes the authorization. You must store this token securely in your database; don’t rely on the frontend redirect to pass this sensitive data. Use this token in future establish calls to let users pay with a single click.
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 processes requests synchronously, while Trustly processes subsequent transaction statuses asynchronously. 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 Refresh bank authorization. |
| Failed | SW051 / 380 | Invalid / corrupt token | See Refresh bank authorization. |
| Failed | SW056 / 330 | Invalid account | Remove the bank account from the user 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 the response includes a thirdPartyDeclineCode, direct the user to the supplier. |
| Failed | SW055 / 390 | Fraud analysis (Negative Data) | Remove the bank account from the user 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.
- Schedule Certification: Complete a formal integration certification with the Trustly team before moving to production. Contact your integration manager to schedule your review.
Updated about 1 month ago