Skip to main content
RapidDev - Software Development Agency
bolt-ai-integrationsBolt Chat + API Route

How to Integrate Bolt.new with Payoneer

Integrate Payoneer with Bolt.new using the Payoneer REST API through an API route that keeps your API credentials server-side. Payoneer specializes in cross-border B2B payments and mass payouts to international contractors — the right choice when your platform pays workers or suppliers globally rather than collecting payments from customers. API access requires a Payoneer business account with developer access approval. All API calls use HTTPS and work from the WebContainer for outbound requests.

What you'll learn

  • How to apply for and obtain Payoneer API credentials (program ID, username, and API key)
  • How to authenticate with Payoneer's API using OAuth 2.0 client credentials and cache access tokens
  • How to create payment requests and initiate mass payouts to international contractors via API route
  • How to build a payout management dashboard in Bolt.new showing payee status and payment history
  • Why Payoneer is designed for paying people (outbound disbursements) rather than collecting payments, and how this differs from Stripe
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate14 min read30 minutesPaymentApril 2026RapidDev Engineering Team
TL;DR

Integrate Payoneer with Bolt.new using the Payoneer REST API through an API route that keeps your API credentials server-side. Payoneer specializes in cross-border B2B payments and mass payouts to international contractors — the right choice when your platform pays workers or suppliers globally rather than collecting payments from customers. API access requires a Payoneer business account with developer access approval. All API calls use HTTPS and work from the WebContainer for outbound requests.

Build Global Contractor Payout Flows in Your Bolt.new App with Payoneer

Payoneer solves a specific problem that Stripe doesn't: paying international workers, freelancers, and suppliers at scale across 200+ countries. While Stripe and Braintree are primarily designed for collecting payments from customers, Payoneer is built for disbursement — sending money out to payees globally. If you're building a freelance marketplace, staffing platform, cross-border supplier network, or any app where your business regularly pays people in different countries, Payoneer is the specialized tool for that workflow.

The Payoneer API enables your Bolt.new app to programmatically register payees (the recipients who will be paid), check their verification status, create payment requests, and trigger mass payouts. Payees register their own Payoneer accounts to receive funds — they choose how they want to be paid (bank transfer, prepaid card, digital wallet) based on what's available in their country. Your platform simply sends the payment to their Payoneer account, and Payoneer handles local disbursement. This removes the complexity of managing country-specific banking relationships, exchange rates, and compliance requirements.

Payoneer API access is not instant — it requires a business account in good standing and an application to the Payoneer developer program. This is standard for platforms handling B2B financial flows. Once approved, you receive a program ID (identifies your platform), a username, and an API key for authentication. The API uses OAuth 2.0 with client credentials, making it compatible with Bolt.new's API routes — all calls are standard HTTPS requests that work from the WebContainer during development. Plan for the application process when evaluating Payoneer for your project timeline.

Integration method

Bolt Chat + API Route

Payoneer integrates with Bolt.new through API routes that authenticate using OAuth 2.0 (client credentials flow) and call Payoneer's REST API for payee management and payout initiation. The OAuth token request and all payout API calls are outbound HTTPS requests that work from the WebContainer during development. Payoneer's webhooks for payout status updates require a deployed public URL. API access requires a Payoneer business account with approved developer access, which involves an application process.

Prerequisites

  • A Payoneer business account (payoneer.com) with verified business status
  • Approved Payoneer developer access — submit an application through developer.payoneer.com describing your use case
  • Payoneer API credentials: Program ID, username, and API key (provided after developer access approval)
  • A Bolt.new project with Next.js API routes for server-side Payoneer API calls
  • Payee Payoneer accounts — recipients must have their own Payoneer accounts to receive payments

Step-by-step guide

1

Apply for Payoneer API Access and Get Credentials

Payoneer API access requires an approved developer application — unlike Stripe which provides instant test keys, Payoneer evaluates your use case before granting API access. This is standard for financial platforms handling cross-border disbursements and is part of Payoneer's compliance requirements. Start by registering a business account at payoneer.com if you don't have one. Once your account is verified with business documents, go to developer.payoneer.com and submit a developer access application. You'll need to describe your platform (marketplace, staffing, content platform, etc.), the expected volume of payouts, the countries your payees are in, and your technical integration plan. Payoneer reviews applications and typically responds within a few business days. Upon approval, you receive three credentials: a Program ID (numeric identifier for your platform on Payoneer's system), a Username (your API authentication username), and an API Key (your API authentication password). These credentials authenticate using HTTP Basic Auth for OAuth 2.0 token requests. The Payoneer API has two environments: sandbox at `https://api.sandbox.payoneer.com` and production at `https://api.payoneer.com`. Store both your credentials and the environment base URL in your Bolt project's `.env` file. Note that Payoneer's sandbox is less fully-featured than production — some payout flows may behave differently.

.env
1# .env Payoneer API credentials
2# Received from Payoneer after developer access approval
3PAYONEER_PROGRAM_ID=your-program-id
4PAYONEER_USERNAME=your-api-username
5PAYONEER_API_KEY=your-api-key
6
7# API base URLs
8PAYONEER_API_BASE=https://api.sandbox.payoneer.com # sandbox
9# PAYONEER_API_BASE=https://api.payoneer.com # production
10
11# For Next.js server-side: process.env.PAYONEER_API_KEY
12# Never use VITE_ prefix or NEXT_PUBLIC_ these are secret server-side credentials

Pro tip: While waiting for Payoneer developer access approval, build and test your UI components with mock API responses. Payoneer's API structure is well-documented at developer.payoneer.com — you can design the full integration before receiving credentials.

Expected result: You have Payoneer API credentials stored in your .env file and access to the Payoneer sandbox environment for testing.

2

Implement OAuth 2.0 Token Authentication

Payoneer uses OAuth 2.0 client credentials flow for API authentication. Before calling any Payoneer API endpoint, you must request an access token by sending your Program ID, username, and API key to Payoneer's token endpoint. The access token is a Bearer token that you include in the Authorization header of subsequent API requests. Access tokens expire (typically after 3600 seconds — 1 hour) and must be refreshed. For a production implementation, cache the access token in memory or in your database and only request a new one when it expires. For development purposes in Bolt, requesting a fresh token on each API call is simpler to implement and debug. The token endpoint uses HTTP Basic Auth: the username is your Payoneer username and the password is your API key, encoded as a Base64 `username:password` string in the Authorization header. This is a standard HTTPS request that works perfectly from Bolt's WebContainer — no native modules required, just fetch() with the right headers. Create a server-side utility function `getPayoneerToken()` that handles token acquisition and caching, then use it from your payout API routes.

Bolt.new Prompt

Create a Payoneer authentication utility at lib/payoneer.ts. Add a getPayoneerToken() function that requests an OAuth 2.0 access token from the Payoneer token endpoint using the PAYONEER_USERNAME and PAYONEER_API_KEY environment variables. Cache the token in memory with its expiry time and return the cached token if it's still valid. Export a payoneerFetch(path, options) helper that automatically gets a token and adds the Authorization: Bearer header to requests targeting the PAYONEER_API_BASE URL.

Paste this in Bolt.new chat

lib/payoneer.ts
1// lib/payoneer.ts — server-side only
2let cachedToken: { access_token: string; expires_at: number } | null = null;
3
4export async function getPayoneerToken(): Promise<string> {
5 // Return cached token if still valid (with 60s buffer)
6 if (cachedToken && Date.now() < cachedToken.expires_at - 60_000) {
7 return cachedToken.access_token;
8 }
9
10 const username = process.env.PAYONEER_USERNAME!;
11 const apiKey = process.env.PAYONEER_API_KEY!;
12 const programId = process.env.PAYONEER_PROGRAM_ID!;
13 const apiBase = process.env.PAYONEER_API_BASE!;
14
15 const credentials = Buffer.from(`${username}:${apiKey}`).toString('base64');
16
17 const response = await fetch(`${apiBase}/v4/oauth2/token`, {
18 method: 'POST',
19 headers: {
20 'Authorization': `Basic ${credentials}`,
21 'Content-Type': 'application/x-www-form-urlencoded',
22 },
23 body: new URLSearchParams({
24 grant_type: 'client_credentials',
25 scope: `read:payments write:payments read:payees write:payees`,
26 }),
27 });
28
29 if (!response.ok) {
30 throw new Error(`Payoneer auth failed: ${response.status} ${await response.text()}`);
31 }
32
33 const data = await response.json();
34 cachedToken = {
35 access_token: data.access_token,
36 expires_at: Date.now() + (data.expires_in * 1000),
37 };
38
39 return data.access_token;
40}
41
42export async function payoneerFetch(
43 path: string,
44 options: RequestInit = {}
45): Promise<Response> {
46 const token = await getPayoneerToken();
47 const apiBase = process.env.PAYONEER_API_BASE!;
48
49 return fetch(`${apiBase}${path}`, {
50 ...options,
51 headers: {
52 'Authorization': `Bearer ${token}`,
53 'Content-Type': 'application/json',
54 ...options.headers,
55 },
56 });
57}

Pro tip: Module-level token caching (as shown) works well for serverless functions with warm instances. For cold-start-heavy deployments where each request is a fresh instance, consider caching the token in Supabase or Redis to avoid an extra round-trip on every payment request.

Expected result: Calling getPayoneerToken() returns a valid Payoneer Bearer token. Calling payoneerFetch() automatically handles authentication for any Payoneer API endpoint.

3

Create Payment Requests and Initiate Payouts

With authentication handled, build the API route that creates payment requests in Payoneer. Payoneer's payment flow distinguishes between a payment request (creating a payment record) and the actual fund transfer. For mass payouts, the payees must have existing Payoneer accounts registered with the email addresses you use. The API creates a payment transaction specifying the payee's Payoneer account identifier (typically their email address associated with their Payoneer account), the payment amount in USD or the specified currency, an internal reference ID for your records, and an optional memo or description visible to the payee. Payoneer processes the payment asynchronously — the API accepts the payment request immediately and returns a payment ID, then processes the actual fund transfer in the background. The final payment status (completed, declined, on hold) arrives via webhook or can be polled via the payments status endpoint. Build the API route to handle single payments for individual contractor payouts and optionally batch payments for mass disbursements. All Payoneer API calls use HTTPS and work from Bolt's WebContainer for the outbound requests — the payment creation happens synchronously in your API route and returns quickly with a payment ID.

Bolt.new Prompt

Create a Payoneer payment API route at app/api/payoneer/send-payment/route.ts. Accept POST requests with: payee_email (string), amount (number), currency (string, default 'USD'), description (string), and internal_reference_id (string). Use the payoneerFetch helper from lib/payoneer.ts to call the Payoneer payments endpoint and create a payment request. Return the Payoneer payment_id and status. Also update the corresponding record in Supabase with payment_id and status 'processing'.

Paste this in Bolt.new chat

app/api/payoneer/send-payment/route.ts
1// app/api/payoneer/send-payment/route.ts
2import { NextResponse } from 'next/server';
3import { payoneerFetch } from '@/lib/payoneer';
4import { createClient } from '@supabase/supabase-js';
5
6export async function POST(request: Request) {
7 const {
8 payee_email,
9 amount,
10 currency = 'USD',
11 description,
12 internal_reference_id,
13 } = await request.json();
14
15 if (!payee_email || !amount || !internal_reference_id) {
16 return NextResponse.json(
17 { error: 'payee_email, amount, and internal_reference_id are required' },
18 { status: 400 }
19 );
20 }
21
22 const paymentPayload = {
23 client_reference_id: internal_reference_id,
24 description,
25 payee: {
26 id: {
27 type: 'email',
28 value: payee_email,
29 },
30 },
31 amount: {
32 value: amount,
33 currency,
34 },
35 };
36
37 const response = await payoneerFetch('/v4/payments', {
38 method: 'POST',
39 body: JSON.stringify(paymentPayload),
40 });
41
42 if (!response.ok) {
43 const errorData = await response.json().catch(() => ({}));
44 return NextResponse.json(
45 { error: 'Payoneer payment failed', details: errorData },
46 { status: response.status }
47 );
48 }
49
50 const paymentData = await response.json();
51
52 // Update Supabase record with Payoneer payment details
53 const supabase = createClient(
54 process.env.NEXT_PUBLIC_SUPABASE_URL!,
55 process.env.SUPABASE_SERVICE_ROLE_KEY!
56 );
57
58 await supabase
59 .from('payments')
60 .update({
61 payoneer_payment_id: paymentData.id,
62 status: 'processing',
63 initiated_at: new Date().toISOString(),
64 })
65 .eq('reference_id', internal_reference_id);
66
67 return NextResponse.json({
68 success: true,
69 payment_id: paymentData.id,
70 status: paymentData.status,
71 });
72}

Pro tip: Payoneer's client_reference_id is your internal order or payment ID — it appears in reports and is used for reconciliation. Use a unique, stable identifier like your Supabase record UUID rather than a timestamp.

Expected result: Calling POST /api/payoneer/send-payment with payee details creates a Payoneer payment request and returns a payment ID. The Supabase record is updated with the Payoneer payment ID and processing status.

4

Build a Payout Dashboard and Handle Status Webhooks

A payout management dashboard gives you visibility into payment status across all your payees — which payments are processing, which completed successfully, and which encountered issues. Build a server component that fetches payment records from Supabase (which stores your payments along with Payoneer payment IDs and statuses) and displays them with filtering and search. For real-time status updates, Payoneer sends webhook notifications when payment status changes — a payment moves from 'processing' to 'completed' or 'declined'. Configure your webhook endpoint URL in the Payoneer developer portal. The webhook handler receives a JSON payload with the payment ID, new status, and event type. Your handler updates the corresponding Supabase record and can trigger downstream actions — sending confirmation emails, releasing funds in escrow, updating user dashboards. Like all webhook-based integrations, Payoneer webhooks are server-to-server HTTP calls that cannot reach Bolt's WebContainer browser-local environment. Deploy to Netlify or Bolt Cloud first, then register your webhook URL in the Payoneer partner portal. For development, you can poll the payment status endpoint (`GET /v4/payments/{paymentId}`) to check status without webhooks during testing.

Bolt.new Prompt

Create a payout dashboard page at app/admin/payouts/page.tsx. Fetch all payment records from the Supabase 'payments' table sorted by created_at descending. Display them in a table with columns: payee email, amount, currency, status (color-coded: green for completed, yellow for processing, red for failed), Payoneer payment ID, and initiated date. Add a status filter dropdown (All/Processing/Completed/Failed). Also create a webhook handler at app/api/payoneer/webhook/route.ts that updates payment status in Supabase when Payoneer sends a status change notification.

Paste this in Bolt.new chat

app/api/payoneer/webhook/route.ts
1// app/api/payoneer/webhook/route.ts
2import { NextRequest, NextResponse } from 'next/server';
3import { createClient } from '@supabase/supabase-js';
4
5export async function POST(request: NextRequest) {
6 // Payoneer webhook payload
7 const body = await request.json();
8
9 const { event_type, payment } = body;
10
11 if (!payment?.id) {
12 return NextResponse.json({ received: true });
13 }
14
15 const supabase = createClient(
16 process.env.NEXT_PUBLIC_SUPABASE_URL!,
17 process.env.SUPABASE_SERVICE_ROLE_KEY!
18 );
19
20 let status: string;
21 switch (event_type) {
22 case 'PAYMENT_COMPLETED':
23 status = 'completed';
24 break;
25 case 'PAYMENT_DECLINED':
26 status = 'failed';
27 break;
28 case 'PAYMENT_ON_HOLD':
29 status = 'on_hold';
30 break;
31 default:
32 status = 'processing';
33 }
34
35 await supabase
36 .from('payments')
37 .update({
38 status,
39 payoneer_status: payment.status,
40 completed_at: status === 'completed' ? new Date().toISOString() : null,
41 updated_at: new Date().toISOString(),
42 })
43 .eq('payoneer_payment_id', payment.id);
44
45 return NextResponse.json({ received: true });
46}

Pro tip: Configure the webhook URL in the Payoneer partner portal after deploying. During development, use the Payoneer API to poll GET /v4/payments/{id} to check payment status manually — this works from the WebContainer without needing a public URL.

Expected result: The admin payout dashboard shows all payment records with color-coded statuses. After deploying and configuring the webhook URL, Payoneer sends status updates that automatically update payment records in Supabase.

Common use cases

Freelance Marketplace Contractor Payouts

Build a platform where clients post projects, freelancers complete work, and your app automatically releases payment to the freelancer's Payoneer account upon client approval. The payout dashboard shows pending payments, processing status, and completion confirmations.

Bolt.new Prompt

Build a payout management system for my freelance marketplace. Create an API route that initiates a Payoneer payment to a contractor's email address (their Payoneer account) when a project is marked as completed. Accept: contractor_email, amount, currency, and project_id. Store payment records in Supabase with status tracking. Show a /admin/payouts dashboard with pending, processing, and completed payments sorted by date.

Copy this prompt to try it in Bolt.new

Mass Payout to Survey or Content Respondents

Send small payments (micro-payments) to hundreds of users who completed surveys, content tasks, or market research. Payoneer's mass payout API batches multiple payment requests in a single API call, making bulk disbursements efficient.

Bolt.new Prompt

Create a bulk payout feature that sends Payoneer payments to all survey respondents who haven't been paid yet. Fetch unpaid respondents from Supabase where paid_at is null, group them into batches of 50, and call the Payoneer mass payout API for each batch. Update Supabase with the Payoneer payment ID and set paid_at timestamp. Show progress in a /admin/mass-payout page with success/failure counts.

Copy this prompt to try it in Bolt.new

Supplier Payment Automation

Automate monthly payments to international suppliers based on invoice data stored in your system. The payment runs automatically on a schedule, reads approved invoices from Supabase, and triggers Payoneer payouts for each supplier.

Bolt.new Prompt

Build an automated supplier payment system. Create an API route at /api/payoneer/process-invoices that fetches all approved invoices from Supabase where status is 'approved' and payment_method is 'payoneer'. For each invoice, call the Payoneer payment API to send the invoice amount to the supplier's Payoneer account stored in their profile. Update invoice status to 'payment_initiated' with the Payoneer payment ID. Log all payment attempts.

Copy this prompt to try it in Bolt.new

Troubleshooting

Payoneer token request returns 401 Unauthorized

Cause: The Basic Auth credentials are incorrect — the username or API key doesn't match the Payoneer developer portal, or the credentials are for a different environment (sandbox vs production).

Solution: Verify your PAYONEER_USERNAME and PAYONEER_API_KEY in .env match exactly what's shown in the Payoneer developer portal. Confirm PAYONEER_API_BASE points to the correct environment URL (sandbox.payoneer.com for sandbox, api.payoneer.com for production). Check that the Base64 encoding is correct — use Buffer.from('username:apikey').toString('base64') in Node.js.

typescript
1// Debug authentication encoding
2const credentials = Buffer.from(`${process.env.PAYONEER_USERNAME}:${process.env.PAYONEER_API_KEY}`).toString('base64');
3console.log('Auth header:', `Basic ${credentials}`);

Payment creation returns 'Payee not found' or 404 for the payee

Cause: The payee's email address is not associated with an active Payoneer account, or the payee hasn't completed Payoneer registration and identity verification.

Solution: The payee must have an active, verified Payoneer account registered with the email address you're sending the payment to. Send the payee a Payoneer registration invitation through your platform before attempting to pay them. Check the payee's registration status via the Payoneer API GET /v4/payees endpoint before initiating payments.

Payoneer webhooks are not arriving at the deployed endpoint

Cause: The webhook URL is misconfigured in the Payoneer partner portal, or webhooks are configured for the wrong environment (sandbox vs production). The WebContainer preview URL cannot receive Payoneer webhooks.

Solution: Verify the webhook URL in the Payoneer partner portal points to your deployed endpoint (not the WebContainer preview URL). Ensure the deployed app is accessible at the configured URL. Use Payoneer's webhook test tool in the portal to send a test notification and verify receipt. Webhooks require a publicly accessible HTTPS URL — deploy to Netlify or Bolt Cloud first.

Best practices

  • Never expose Payoneer API credentials (username, API key, program ID) in client-side code — all Payoneer API calls must go through server-side API routes
  • Cache OAuth access tokens with their expiry times to avoid requesting a new token on every API call — tokens typically last 3600 seconds
  • Store the Payoneer payment ID returned on creation and use it for status polling and reconciliation — it's your primary reference for the payment lifecycle
  • Verify payee registration status before initiating payouts to avoid failed payment requests for unregistered email addresses
  • Use idempotent client_reference_ids tied to your database record IDs to safely retry failed payment requests without creating duplicate payments
  • Deploy before testing webhooks — Payoneer sends server-to-server notifications that cannot reach the WebContainer's browser-local environment
  • Build a retry mechanism for failed payouts with exponential backoff — network issues and temporary Payoneer service interruptions are handled gracefully with retries

Alternatives

Frequently asked questions

How do I get Payoneer API access for my Bolt.new app?

Register a business account at payoneer.com with verified business documents, then apply for developer access at developer.payoneer.com describing your platform and use case. Payoneer reviews applications and typically responds within several business days. API access is not instant like Stripe — factor this approval timeline into your development schedule. Once approved, you receive a Program ID, username, and API key.

Can I test Payoneer API calls from Bolt's WebContainer preview?

Yes, for outbound API calls — creating payment requests, fetching payment status, and listing payees are all standard HTTPS requests that work from the WebContainer. The limitation is for webhooks: Payoneer sends status change notifications (payment completed, declined) as server-to-server HTTP calls that cannot reach the WebContainer's browser-local environment. Deploy to Netlify or Bolt Cloud to receive webhook notifications, or poll the status API during development.

How is Payoneer different from Stripe for a Bolt.new app?

Stripe is primarily for collecting payments from customers (inbound money flow). Payoneer is for paying people — contractors, suppliers, sellers, survey respondents (outbound money flow). Stripe has native Bolt.new integration with instant API access; Payoneer requires an application process and manual API route setup. Choose Stripe for collecting payments, Payoneer for paying international workers and suppliers at scale.

Do payees need a Payoneer account to receive payments through my Bolt app?

Yes. Payees must have an active, verified Payoneer account registered with the email address you send payments to. Your platform should include a payee onboarding flow that prompts contractors or suppliers to create a Payoneer account before they can receive payments. You can check payee registration status via the Payoneer API before initiating a payment.

Does the Payoneer npm package work in Bolt's WebContainer?

There is no official Payoneer Node.js SDK as a widely-used npm package — the integration uses direct HTTP calls to the REST API using fetch(). This is actually simpler: the payoneerFetch() helper function covers all API calls without any npm dependency. Your only dependency is the built-in fetch API and the Buffer class, both available in Node.js without any installation.

RapidDev

Talk to an Expert

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

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

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.