Skip to main content
RapidDev - Software Development Agency
retool-integrationsREST API Resource

How to Integrate Retool with 2Checkout (Verifone)

Connect Retool to 2Checkout (now Verifone) using a REST API Resource with HMAC-authenticated requests. Configure the base URL and merchant credentials in the Resources tab, then build queries to manage orders, view subscriptions, and process refunds. The setup takes about 20 minutes and gives your ops team a faster alternative to 2Checkout's native admin interface.

What you'll learn

  • How to add a 2Checkout REST API Resource in the Retool Resources tab
  • How to generate HMAC authentication headers for 2Checkout API requests using JavaScript transformers
  • How to query orders, subscriptions, and refund data from 2Checkout's API
  • How to build an order management panel with filters, search, and refund actions
  • How to set up a Retool Workflow to monitor subscription churn and send alerts
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate17 min read20 minutesPaymentLast updated April 2026RapidDev Engineering Team
TL;DR

Connect Retool to 2Checkout (now Verifone) using a REST API Resource with HMAC-authenticated requests. Configure the base URL and merchant credentials in the Resources tab, then build queries to manage orders, view subscriptions, and process refunds. The setup takes about 20 minutes and gives your ops team a faster alternative to 2Checkout's native admin interface.

Quick facts about this guide
FactValue
Tool2Checkout (Verifone)
CategoryPayment
MethodREST API Resource
DifficultyIntermediate
Time required20 minutes
Last updatedApril 2026

Why Connect Retool to 2Checkout?

2Checkout's native admin interface is functional but slow for high-volume payment operations. Support and finance teams frequently need to look up orders, verify subscription statuses, issue refunds, and investigate payment failures — tasks that take multiple clicks and page loads in the 2Checkout dashboard. Building a Retool app over the 2Checkout API gives your team a single, fast interface that combines payment data with your internal database records, CRM data, and customer support tickets in one view.

2Checkout's API is particularly valuable for SaaS businesses because it exposes subscription lifecycle data — trial conversions, renewal status, upgrade/downgrade history, and cancellation reasons — that is difficult to extract from the native dashboard in bulk. A Retool app can surface all of this in a Table component with real-time filters, letting your sales ops or customer success team take action without waiting for monthly reports.

The integration also supports refund workflows that require approval chains: a support agent can flag an order for refund in Retool, a manager can approve it in the same app, and the refund query executes against the 2Checkout API automatically. This keeps the entire process auditable inside your Retool app rather than spread across emails and the 2Checkout dashboard.

Integration method

REST API Resource

Retool connects to 2Checkout's REST API through a REST API Resource configured in the Resources tab. You set the base URL and authentication credentials once, then build queries visually using the endpoint path, HTTP method, and request body fields. All requests are proxied server-side through Retool's backend, keeping your merchant credentials off the browser. HMAC signature generation for authenticated endpoints is handled in JavaScript transformer functions attached to each query.

Prerequisites

  • A Retool account (Cloud or self-hosted) with permission to add Resources
  • A 2Checkout / Verifone merchant account with API access enabled
  • Your 2Checkout merchant code and secret key (found in Account → Integrations → API → Secret Word in the 2Checkout control panel)
  • Basic familiarity with the Retool query editor and JavaScript transformer functions
  • Understanding of HMAC-SHA256 signing (Retool's built-in CryptoJS library handles the computation)

Step-by-step guide

1

Add a 2Checkout REST API Resource

Navigate to the Resources tab in Retool (accessible from the left sidebar on the home page, or via the top navigation bar). Click the blue Add Resource button in the upper right corner. In the resource type selector, scroll to the API section or type 'REST' in the search field. Click REST API to open the configuration form. In the resource configuration form, fill in the following fields: - Name: Give the resource a clear name such as '2Checkout API' or '2Checkout Production' to distinguish it from test and live configurations. - Base URL: Enter the 2Checkout API base URL. For the Inline Checkout and Order API, this is https://api.2checkout.com/rest/6.0 for v6 of their REST API. - Authentication: Set authentication to None — 2Checkout uses HMAC signatures in individual request headers rather than a global bearer token. You will generate these per-query in a JavaScript transformer. Under the Headers section, add a default header: - Key: Content-Type - Value: application/json Click Save to create the resource. It appears in your Resources list without a connection status badge since REST API resources do not test connectivity on save. To store your merchant code and secret key securely, navigate to Settings → Configuration Variables, click Add Variable, name it TWOCHECKOUT_MERCHANT_CODE and TWOCHECKOUT_SECRET_KEY, mark them as secrets, and save. These will be referenced in query headers using {{ retoolContext.configVars.TWOCHECKOUT_MERCHANT_CODE }} syntax.

Pro tip: Create two separate resources — '2Checkout Sandbox' pointing to the sandbox API and '2Checkout Production' pointing to the live API. Use Retool resource environments to switch between them without changing your queries.

Expected result: A 2Checkout REST API resource appears in your Resources list. Configuration variables for your merchant code and secret key are saved as secrets in Settings.

2

Generate HMAC authentication headers in a JavaScript query

2Checkout's API uses HMAC-SHA256 signatures to authenticate requests. The signature is computed from your merchant code, a date string, and your secret key, then sent as an Authorization header in the format: 'code='MERCHANT_CODE' date='DATE' hash='HASH''. In your Retool app, create a JavaScript query (click + New in the query panel, select Run JavaScript Script as the query type rather than selecting the 2Checkout resource). This query will compute the auth header and make the signed API request. In the JavaScript editor, write the signing logic: The date is a Unix timestamp in seconds as a string. The HMAC is computed as HMAC-SHA256(merchantCode + date, secretKey) and then hex-encoded. Retool provides the CryptoJS library, so you can use CryptoJS.HmacSHA256() directly without any imports. The resulting hash is converted to a hex string with .toString(CryptoJS.enc.Hex). Once the header is computed, use the built-in fetch() equivalent or trigger another query that uses this header. A cleaner pattern is to use a JavaScript query that calls Retool's query system: use the 2Checkout resource with the Authorization header set to a dynamic expression that references a global variable or another query's result. Set a Retool state variable (click + State in the left panel) named authHeader, and have the JavaScript query write the computed header to that state variable using state.setValue('authHeader', headerValue). Then reference {{ authHeader.value }} in your 2Checkout resource queries' Authorization header field.

generateAuthHeader.js
1// JavaScript query: compute 2Checkout HMAC Authorization header
2// Run this query on page load, store result in a state variable
3const merchantCode = retoolContext.configVars.TWOCHECKOUT_MERCHANT_CODE;
4const secretKey = retoolContext.configVars.TWOCHECKOUT_SECRET_KEY;
5
6const date = Math.floor(Date.now() / 1000).toString();
7const hmacInput = merchantCode + date;
8const hash = CryptoJS.HmacSHA256(hmacInput, secretKey).toString(CryptoJS.enc.Hex);
9
10const authHeader = `code="${merchantCode}" date="${date}" hash="${hash}"`;
11
12// Store in a state variable named 'authHeader'
13await authHeader_state.setValue(authHeader);
14
15return { authHeader, date, hash };

Pro tip: The 2Checkout HMAC date must match the date used in the Authorization header exactly. Recompute it for each request rather than caching it — the timestamp must be within a few minutes of the server's current time or the request will be rejected with a 401.

Expected result: The JavaScript query runs successfully and the state variable contains a valid Authorization header string in the 2Checkout format. You can verify by logging the output and checking that the hash matches a manually computed value.

3

Query 2Checkout orders and display in a Table

With the resource and authentication set up, create your first data query. In the query panel, click + New and select your 2Checkout API resource. Set the HTTP method to GET and the path to /orders. This endpoint returns a paginated list of orders. In the Headers section of the query, add the Authorization header: - Key: Authorization - Value: {{ authHeader_state.value }} In the URL Parameters section, add pagination and filter parameters: - Limit: {{ pagination.pageSize || 50 }} - Offset: {{ pagination.pageOffset || 0 }} - To filter by date, add StartDate and EndDate parameters referencing a DateRange picker component in your app: {{ dateRange.start }} and {{ dateRange.end }} - To search by order status, add Status: {{ statusSelect.value || '' }} Enable the query to Run this query automatically when inputs change and set it to trigger On page load so the table loads data immediately. Drag a Table component from the component panel onto the canvas. In the Table's Inspector, set the Data source to {{ ordersQuery.data.Items || [] }}. Map columns to the relevant fields in the 2Checkout response: OrderNo, ExternalRef, Email, Total, Currency, Status, OrderDate. Add a column override for Total to format it as a currency using the column type 'Number' with a currency prefix. Add a DateRange Picker and a Select component for status filter above the Table. Set the Select component's options to the 2Checkout order statuses: COMPLETE, AUTHRECEIVED, PENDING, REFUND, INVALID. When users change these filters, the query re-runs automatically and the Table updates.

ordersTransformer.js
1// JavaScript transformer to reshape 2Checkout orders response
2// Add as a query transformer on the orders GET query
3const items = data.Items || [];
4return items.map(order => ({
5 order_no: order.OrderNo,
6 external_ref: order.ExternalRef || '',
7 customer_email: order.BillingDetails?.Email || '',
8 customer_name: `${order.BillingDetails?.FirstName || ''} ${order.BillingDetails?.LastName || ''}`.trim(),
9 total: parseFloat(order.GrossPrice || 0).toFixed(2),
10 currency: order.Currency,
11 status: order.Status,
12 order_date: new Date(order.OrderDate * 1000).toLocaleDateString(),
13 country: order.BillingDetails?.CountryCode || ''
14}));

Pro tip: 2Checkout returns timestamps as Unix epoch integers. Use new Date(timestamp * 1000).toLocaleDateString() in a transformer to convert them to readable date strings before displaying in the Table.

Expected result: The Table displays a paginated list of 2Checkout orders with formatted dates, currency amounts, and status labels. Changing the date range or status filter re-runs the query and updates the Table automatically.

4

Build a refund action with confirmation modal

Add a refund capability to your order management panel. When a support agent selects an order in the Table and needs to issue a refund, they should be able to do so directly from Retool without navigating to the 2Checkout admin interface. Drag a Button component onto the canvas and label it 'Issue Refund'. In the Button's Inspector, open the Interaction section and enable Confirm before running. Set the confirmation title to 'Confirm Refund' and the message to 'Issue a full refund for Order #{{ ordersTable.selectedRow.order_no }} ({{ ordersTable.selectedRow.currency }} {{ ordersTable.selectedRow.total }})? This action cannot be undone.' This gives agents a clear preview of what they are about to do. Create a new query using your 2Checkout API resource. Set the method to POST and the path to /orders/{{ ordersTable.selectedRow.order_no }}/refund. In the Body section, select JSON and enter the refund request payload: include the reason field (reference a TextInput component where the agent enters the refund reason) and the amount (for full refunds, pass the total from the selected row). Remember to include the Authorization header in this query as well, pointing to {{ authHeader_state.value }}. Since HMAC timestamps can expire, add an event handler on the Refund button click that first runs the generateAuthHeader query (to refresh the HMAC), then on success runs the refund query. In the refund query's On success handler, add a 'Show notification' action with message 'Refund issued successfully for Order #{{ ordersTable.selectedRow.order_no }}' and trigger the orders list query to refresh the table data. For error handling, in the query's On failure handler, add a 'Show notification' action with type 'error' and the message '{{ refundQuery.error.message }}' so agents see actionable feedback when a refund fails (for example, if the order is already refunded or the refund window has closed).

refundPayload.json
1{
2 "amount": "{{ ordersTable.selectedRow.total }}",
3 "currency": "{{ ordersTable.selectedRow.currency }}",
4 "comment": "{{ refundReasonInput.value || 'Customer request' }}",
5 "reason": "OTHER"
6}

Pro tip: 2Checkout supports partial refunds by setting the amount to less than the order total. Add a Number Input component that defaults to the full order amount, letting support agents override it for partial refunds before clicking the Refund button.

Expected result: Clicking the Refund button shows a confirmation modal with the order details. After confirming, the refund query executes and the Table refreshes showing the updated REFUND status. A success notification appears in the top-right corner of the app.

5

Add a subscription management view

2Checkout's subscription API lets you view and manage recurring billing for your SaaS products. Create a second query in your app targeting the subscriptions endpoint to give your team visibility into subscription health alongside order data. Create a new query using your 2Checkout API resource. Set the method to GET and the path to /subscriptions. Add URL parameters for filtering: CustomerEmail (reference a search TextInput component), Status (ACTIVE, EXPIRED, CANCELED, TRIAL), and pagination parameters Limit and Offset. Add a second Tab component to your Retool app — one tab for Orders, one for Subscriptions. Inside the Subscriptions tab, drag a Table component and bind its data to {{ subscriptionsQuery.data.Items || [] }}. Add a JavaScript transformer on the query to reshape the data: Map the subscription fields to human-readable column names: subscription reference, customer email, plan name, billing cycle, next renewal date (formatted from Unix timestamp), payment status, and number of renewal attempts. Add a calculated field that flags subscriptions with failed renewal attempts (NextRenewalAttempts > 0) so agents can prioritize outreach. Add event handlers so that clicking a subscription row loads the related orders for that customer by triggering the orders query with a filter on the customer's email address. This creates a drill-down experience: the agent can see all orders associated with a subscription in the adjacent Table, providing full billing history context. For complex subscription management workflows involving multiple APIs and approval chains, RapidDev's team can help design and build the Retool solution to fit your specific billing operations requirements.

subscriptionsTransformer.js
1// JavaScript transformer to reshape 2Checkout subscriptions response
2const items = data.Items || [];
3return items.map(sub => ({
4 reference: sub.SubscriptionReference,
5 customer_email: sub.CustomerEmail || '',
6 plan_name: sub.ExternalProductCode || sub.ProductId,
7 billing_cycle: `${sub.BillingCycles} ${sub.BillingCycleUnit}`,
8 next_renewal: sub.NextRenewalDate
9 ? new Date(sub.NextRenewalDate * 1000).toLocaleDateString()
10 : 'N/A',
11 status: sub.Status,
12 failed_attempts: sub.NextRenewalAttempts || 0,
13 at_risk: (sub.NextRenewalAttempts || 0) > 0
14}));

Pro tip: Use a Tag or Badge component override in the subscriptions Table to color-code the 'at_risk' column — red for subscriptions with failed renewal attempts, green for healthy ones — so agents can instantly spot problem accounts without reading each row.

Expected result: The Subscriptions tab shows a Table of active subscriptions with renewal dates, billing status, and at-risk flags. Clicking a subscription row loads that customer's full order history in the adjacent table.

Common use cases

Build a global payment operations dashboard

Create a Retool panel that lists all 2Checkout orders with filters for date range, payment status, country, and product. Support agents can search by order number or customer email, view full order details in a side panel, and initiate refunds with a confirmation modal. The dashboard shows key metrics — total revenue, refund rate, and failed payments — in Summary components at the top.

Retool Prompt

Build an order management panel that queries 2Checkout orders with filters for date range, status (completed, refunded, pending), and country. Show order ID, customer email, product name, amount, currency, and status in a Table. Add a Refund button that calls the refund endpoint for the selected row after confirming with a modal.

Copy this prompt to try it in Retool

Monitor subscription renewals and churn risk

Build a Retool app that pulls subscription data from 2Checkout and surfaces renewals due in the next 30 days alongside subscriptions that have recently failed renewal attempts. Customer success managers can see which accounts are at risk, view their order history, and take action — sending a manual outreach note or escalating to a Slack alert — all from the same interface.

Retool Prompt

Create a subscription health dashboard showing all active subscriptions with next renewal date, billing status, and number of failed payment attempts. Filter for renewals due within 30 days and subscriptions with at least one failed attempt. Add a 'Send Alert' button that posts a Slack message with subscription details.

Copy this prompt to try it in Retool

Reconcile 2Checkout settlements with internal records

Build a reconciliation tool that fetches 2Checkout settlement reports and compares them against your internal database orders table. Display side-by-side results in a Retool Table with color-coded rows for matched, unmatched, and discrepancy records. Finance teams can export the mismatched records or trigger a webhook to notify the accounting system.

Retool Prompt

Build a reconciliation panel that fetches the latest 2Checkout settlement report and joins it with the internal PostgreSQL orders table on order ID. Show a Table with matched/unmatched status, highlighting rows where amounts differ by more than $0.01. Add an Export button and a 'Flag for Review' button that updates the internal orders table.

Copy this prompt to try it in Retool

Troubleshooting

API returns 401 Unauthorized with 'Invalid authorization header' even though credentials are correct

Cause: The HMAC signature is time-sensitive — if the timestamp used in the signature differs from the server's current time by more than a few minutes, 2Checkout rejects the request. This commonly happens when the authHeader state variable was computed earlier in the session and has expired, or when the client machine's clock is significantly off.

Solution: Re-run the generateAuthHeader JavaScript query immediately before each API call by chaining it as the first step in your button event handlers. In query event handlers, set the trigger order: first run generateAuthHeader, then on success run the API query. This ensures the HMAC timestamp is always fresh. Also verify your local machine clock is synchronized correctly.

Orders query returns an empty Items array despite orders existing in the 2Checkout dashboard

Cause: The date range filter parameters may not be formatted correctly. 2Checkout's API expects dates in a specific format (YYYY-MM-DD or Unix timestamp depending on the endpoint version), and passing an ISO string with timezone information can cause the filter to return zero results.

Solution: In the URL Parameters section of the orders query, format the date parameters explicitly: use a JavaScript expression to format the DateRange picker values as YYYY-MM-DD strings. For example: {{ dateRange.start ? new Date(dateRange.start).toISOString().split('T')[0] : '' }}. If still returning empty, try removing the date filters entirely to confirm the endpoint is working, then add filters back one at a time.

typescript
1// Format date for 2Checkout API URL parameter
2new Date(dateRange.start).toISOString().split('T')[0]

Refund query fails with 'Order cannot be refunded' error even for recent orders

Cause: 2Checkout has a refund eligibility window based on the payment method and jurisdiction. Some payment methods (bank transfers, certain regional methods) have shorter refund windows or require manual processing. Additionally, orders in AUTHRECEIVED status (authorized but not fully captured) may require cancellation rather than refund.

Solution: Check the order's payment method and status in the order detail view before attempting a refund. For AUTHRECEIVED orders, use the cancel endpoint (/orders/{OrderNo}/cancel) instead of refund. For orders outside the refund window, inform the agent that manual processing through the 2Checkout merchant control panel is required. Add a validation check in the Retool app that disables the Refund button for orders older than 180 days or in non-refundable statuses.

Subscription endpoint returns 404 Not Found

Cause: The subscription API endpoint path varies between 2Checkout API versions. v6 and v4 have different endpoint structures, and the base URL configured in the resource may not match the subscription endpoint path being requested.

Solution: Verify your base URL is set correctly for the API version you are targeting. For 2Checkout API v6, the subscriptions endpoint is /subscriptions under https://api.2checkout.com/rest/6.0. For older API versions, check the 2Checkout/Verifone developer documentation for the correct base URL and endpoint path. Test the endpoint directly using Retool's Debug panel (click the Debug tab in the query editor to see the full request URL being sent).

Best practices

  • Store your 2Checkout merchant code and secret key as secret configuration variables in Retool Settings — never hardcode them in query headers or JavaScript code.
  • Regenerate the HMAC Authorization header immediately before each API call to ensure the timestamp is fresh and within 2Checkout's acceptance window.
  • Create separate Retool resources for sandbox and production 2Checkout environments and use Retool resource environments to switch between them without changing app queries.
  • Use Retool's confirmation modals for all refund and cancellation actions — these are irreversible operations that should require explicit agent confirmation with the order details displayed.
  • Add error handling on all write queries (refund, cancel, update) with 'Show notification' on failure event handlers so agents see specific error messages rather than silent failures.
  • Restrict the Retool app's refund capabilities to users with a specific Retool group (e.g., 'Support Lead') using Retool's permission groups feature to prevent unauthorized refunds.
  • Use JavaScript transformers to format currency amounts consistently — 2Checkout returns amounts as strings in some endpoints and floats in others, so normalize to a fixed-decimal string before displaying in the Table.
  • Log all refund and cancellation actions to an internal PostgreSQL audit table alongside the Retool user who initiated the action, creating a compliance trail outside of the 2Checkout dashboard.

Alternatives

Frequently asked questions

Does 2Checkout have a native Retool connector or does it require a REST API Resource?

2Checkout does not have a native Retool connector with pre-built action dropdowns. You connect via a generic REST API Resource configured with the 2Checkout base URL and authentication credentials. This requires manually configuring HMAC-signed Authorization headers for each request, which you handle in JavaScript transformer queries within Retool.

How do I handle 2Checkout's HMAC authentication in Retool without exposing my secret key?

Store your 2Checkout secret key as a secret configuration variable in Retool Settings → Configuration Variables. Reference it in JavaScript queries as retoolContext.configVars.TWOCHECKOUT_SECRET_KEY. The HMAC computation happens server-side in Retool's JavaScript execution environment, and the secret key is never sent to the browser or exposed in query responses. Secret configuration variables are also excluded from Retool's frontend bundle.

Can I use Retool to automate subscription renewal failure alerts for 2Checkout?

Yes. Create a Retool Workflow with a Schedule trigger (for example, daily at 8 AM) that queries the 2Checkout subscriptions endpoint for accounts with failed renewal attempts. Add a Slack or SendGrid block after the query to notify your customer success team with the list of at-risk subscriptions. This runs server-side without requiring anyone to open the Retool app.

What is the difference between 2Checkout's v4 and v6 APIs when building Retool integrations?

2Checkout API v6 is the current version and uses a REST architecture with JSON responses at the base URL https://api.2checkout.com/rest/6.0. The v4 API has different endpoint structures and some deprecated fields. When building your Retool REST API Resource, use the v6 base URL for new integrations. If you are integrating with an existing 2Checkout implementation that uses v4, check the Verifone developer portal for the v4 base URL and endpoint paths, as some response field names differ between versions.

Can Retool receive 2Checkout webhook notifications for real-time payment events?

Retool apps cannot directly receive incoming webhooks since they run in the browser. However, you can create a Retool Workflow with a Webhook trigger, which exposes a public HTTPS endpoint URL. Configure that URL in 2Checkout's IPN (Instant Payment Notification) settings under your merchant control panel. When 2Checkout sends a payment event, the Workflow receives the payload, validates it, and can update your internal database or trigger downstream actions like Slack notifications.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Integrations are where projects stall

We wire Retool integrations like this one every week — auth, webhooks, edge cases included. Fixed-price builds from $13K, delivered in 6–10 weeks.

Talk to an integration engineer

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.