Integrate Trustly using the JavaScript SDK
Last updated: Feb 18th, 4:05am
Use the JavaScript SDK to render payment fields and buttons, and process payments with the Orders API.
Buyer experience
Know before you code
- Request approval to enable Trustly by visiting these sandbox and live links:
- Partners: Be sure to onboard your merchants upfront, before they accept payments. Onboarding after making payments, specifically Progressive Onboarding, isn't supported for alternative payment methods.
- Complete the steps in Get started to get your sandbox account information from the Developer Dashboard:
- Client ID: Authenticates your account with PayPal and identifies an app in your sandbox.
- Client Secret: Authorizes an app in your sandbox. Keep this secret safe and don't share it.
- Business account credentials.
- Make sure the preference for receiving payments in your PayPal business account is set to accept and convert them to the default currency. To verify, in your profile select Account Settings > Payment preferences > Block payments and select Update to mark this preference.
- This client-side and server-side integration uses the following:
- Make sure you're subscribed to the following webhook events:
- Listen for the
CHECKOUT.ORDER.APPROVED
webhook in order to retrieve order details. - Listen for the
PAYMENT.CAPTURE.PENDING
,PAYMENT.CAPTURE.COMPLETED
, andPAYMENT.CAPTURE.DENIED webhooks
, which indicate payment capture status.
- Listen for the
- By adding funding sources to your checkout integration, you agree to the PayPal alternative payment methods agreement. This is in addition to the user agreement applicable to the country in which your business is physically located.
To get started
Run in Postman
Use Postman to explore and test PayPal APIs. Learn more in our Postman guide.
Get up and running in GitHub Codespaces
GitHub Codespaces are cloud-based development environments where you can code and test your PayPal integrations. Learn more.
Add PayPal JavaScript SDK
Add or update the JavaScript SDK script on your web page.
1<script src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID&components=buttons,payment-fields,marks,funding-eligibility&enable-funding=trustly¤cy=EUR"></script>
This table lists the parameters you pass to the JavaScript SDK.
Query param | Default | Description |
client-id |
none | Your PayPal REST client ID. This identifies your PayPal account and determines where transactions are paid. |
components |
buttons |
A comma-separated list of components to enable. The buttons , payment-fields , marks , and funding-eligibility components are required for payment fields components. |
enable-funding |
none | The enabled payment methods to show in buttons and marks. Note: By default, PayPal JavaScript SDK provides smart logic to display only appropriate marks and buttons for the current buyer. This optional parameter bypasses the buyer country check for desired payment methods. For example: src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID&enable-funding=venmo" |
currency |
USD |
This is the currency for the payment. This value needs to match the currency used when creating the order. |
locale |
automatic | The locale renders components. By default PayPal detects the correct locale for the buyer based on their geolocation and browser preferences. It is recommended to pass this parameter with a supported locale if you need the PayPal buttons to render in the same language as the rest of your site. |
intent |
capture |
The intent for the transaction. This determines whether the funds are captured immediately while the buyer is present on the page. |
commit |
true |
This indicates that the final amount won't change after the buyer returns to your site from PayPal. |
vault |
false |
Whether the payment information in the transaction will be saved. Save your customers' payment information for billing agreements, subscriptions, or recurring payments. Marking this parameter false shows all funding sources, including payment methods that can't be saved. |
See additional, optional parameters.
Render payment mark
You can use a mark integration for payment field components to present the buyer's payment method options as radio buttons.
1paypal.Marks({2 fundingSource: paypal.FUNDING.TRUSTLY3}).render('#trustly-mark')
Render payment fields
Integrate payment fields to collect payment information from buyers. Fields dynamically render based on the selected payment source. You can customize the fields to align with your brand.
You can choose from the following checkout flows:
Single page
The Trustly payment fields collect first name and last name.
If there are validation errors in the input fields, they'll show when the buyer selects the button.
1paypal.PaymentFields({2 fundingSource: paypal.FUNDING.TRUSTLY,3 /* style object (optional) */4 style: {5 /* customize field attributes (optional) */6 variables: {},7 /* set custom rules to apply to fields classes (optional) */8 rules: {},9 },10 fields: {11 /* fields prefill info (optional) */12 name: {13 value: "John Doe",14 },15 }16})17.render("#trustly-container")
For style
parameters, please reference this style page: Custom style for payment fields
Multi page
A multi-page checkout flow spreads the checkout steps into two or more pages. This experience is applicable when an order details page needs to be shown to the buyer before an order is placed.
First page of the checkout flow
This example renders the mark and payment fields, but not the payment button, on your checkout page.
- Payment mark
- Payment fields
1paypal.Marks({2 fundingSource: paypal.FUNDING.TRUSTLY3}).render('#trustly-mark')
Second page of the checkout flow
Based on the payment method selected on the first page, the payment button displays, along with the order details on the second page. To complete checkout, your buyer clicks the payment button, authorizes, and confirms payment. You get the code to render the payment button in step 4.
For style
parameters, please reference this style page: Custom style for payment fields
Use paypal.Buttons().isEligible()
to check if the payment source is eligible.
1var mark = paypal.Marks({2 fundingSource: paypal.FUNDING.TRUSTLY3})4var fields = paypal.PaymentFields({5 fundingSource: paypal.FUNDING.TRUSTLY,6})7var button = paypal.Buttons({8 fundingSource: paypal.FUNDING.TRUSTLY9})10if(button.isEligible()) {11 mark.render('#trustly-mark');12 fields.render("#trustly-container");13 button.render("#trustly-btn");14}
Handle webhook events
Set up a webhook handler on your server to manage and respond to any webhooks that hit your listener URL.
CHECKOUT.ORDER.APPROVED
- Listen for this webhook to retrieve order details. Order capture is performed automatically. No additional code required.PAYMENT.CAPTURE.PENDING
- Listen for this webhook to confirm that payment initialization was successful, the payment is pending, and the buyer needs to complete the transaction. Note that the funds have not yet been credited to the payee's PayPal account.PAYMENT.CAPTURE.COMPLETED
- Listen for this webhook to confirm that the money for this payment was credited to the payee's PayPal account. The buyer completed the transaction, and you can ship the order at this point.PAYMENT.CAPTURE.DENIED
- Listen for this webhook to confirm that the money couldn't be captured. The buyer didn't complete the payment before the voucher's expiration, or the bank declined the payment. You can cancel the order at this point.
See Subscribe to checkout webhooks for more information.
Here are some additional resources as you create webhook handler code:
- Webhook Management API - Manage webhooks, list event notifications, and more.
- Webhook events
- Checkout webhook events - Checkout buyer approval-related webhooks.
- Order webhook events - Other order-related webhooks.
- Show order details endpoint - Determine the status of an order.
Display the appropriate error message to the buyer
If createOrder in Step 4 is unsuccessful and returns an HTTP `422 UNPROCESSABLE_ENTITY` status code, the JSON response body should contain an error code in the `issue` parameter.
API endpoint used: Create order
- Sample request
- Sample response
1curl --location --request POST 'https://api-m.sandbox.paypal.com/v2/checkout/orders' \2--header 'Content-Type: application/json' \3--header 'Authorization: Bearer ACCESS-TOKEN' \4--header 'PayPal-Request-Id: PAYPAL-REQUESTID' \5--data-raw '{6 "intent": "CAPTURE",7 "purchase_units": [8 {9 "reference_id": "d9f80740-38f0-11e8-b467-0ed5f89f718b",10 "amount": {11 "currency_code": "SEK",12 "value": "100.00"13 }14 }15 ],16 "payment_source": {17 "trustly": {18 "country_code": "NL",19 "name": "John Doe"20 }21 },22 "processing_instruction": "ORDER_COMPLETE_ON_PAYMENT_APPROVAL",23 "application_context": {24 "locale": "en-NL",25 "return_url": "https://example.com/returnUrl",26 "cancel_url": "https://example.com/cancelUrl"27 }28}'
Step result
An unsuccessful request results in the following:
- A return status code of HTTP
422 Unprocessable Entity
. - A JSON response body that contains an error code in the
issue
parameter and the error description in thedescription
parameter.
Sample integration
See a sample Trustly integration in the PayPal GitHub repository.
Next steps
- Handle uncaptured payments - Listen for the
CHECKOUT.PAYMENT-APPROVAL.REVERSED
webhook as an indication that an approved order wasn't captured for certain reasons resulting in a cancellation of the order and a refund the buyer's account. Then notify your buyer of the problem and the reversed order. - Test in PayPal sandbox.
- Go live in PayPal's production environment.