DEV Community

Cover image for One Single RESTful API, Five Payment Rails: Build Global Money Movement Without Rebuilding the Infrastructure
Eric
Eric

Posted on

One Single RESTful API, Five Payment Rails: Build Global Money Movement Without Rebuilding the Infrastructure

If you've ever tried to build a product that moves money across borders, you know how quickly things get messy.

You usually start with one use case. Maybe your users want to fund a wallet with their debit card. That sounds manageable, so you integrate with a card processor.

Then the next request comes in:

  1. Can we also support ACH? So you add an ACH provider.
  2. Then your enterprise users ask for wire transfers.
  3. Then someone wants faster domestic settlement through RTP.
  4. Then cross border payouts come up, and now stablecoins enter the conversation.

At that point, you are no longer building one payment flow. You are managing multiple rails, multiple vendors, multiple webhook formats, multiple compliance requirements, and multiple operational models.

By the time your product supports several funding and payout methods, the engineering burden starts to grow fast:

  • separate integrations
  • separate credentials
  • separate error handling logic
  • separate vendor relationships
  • separate compliance and operational workflows

And when a single user journey crosses rails such as funding via ACH, settling through USDC, and receiving through a debit card or bank payout, your team ends up writing custom glue code just to make the experience feel unified.

This is not just a payment problem. It is an infrastructure design problem.

Here is what Harbor gives you:

Rail Direction Notes
Debit Card (Visa Direct) Onramp / Offramp Card based funding and withdrawal
ACH Onramp / Offramp US bank account flows
Domestic Wire Onramp / Offramp US domestic wire transfer flow
FedWire Offramp US bank payout via FedWire
RTP (Real Time Payments) Onramp / Offramp Instant US bank transfers, 24/7
CPN (Circle Payment Network) Settlement layer USDC native settlement network

One integration. Five payment rails. One settlement layer. Backed by 40+ Money Transmitter Licenses across US states.

Full corridor and payment method reference: harbor-developers.owlpay.com/docs/fiat-payment-methods


What product teams actually need

Most product teams do not want to become payments infrastructure teams.

They do not want to stitch together card processors, ACH providers, wire support, payout networks, stablecoin infrastructure, compliance vendors, and corridor coverage one by one.

They want a single RESTful API that abstracts the complexity underneath. Supported currencies, payout corridors, compliance workflows, and rail level orchestration should not have to be rebuilt from scratch by every team trying to launch a money movement product.

That is the idea behind OwlPay Harbor.

Harbor is a compliant payment infrastructure platform backed by 40+ Money Transmitter Licenses across US states, with licensed partner coverage extending globally. It provides a single RESTful API that sits in front of multiple payment rails, while the underlying complexity is handled behind the scenes. Instead of integrating each rail separately and figuring out how to coordinate them, teams can focus on product experience, user flows, and business logic.


What integration actually looks like

The Harbor integration is organized around three objects: customers, transfers, and webhooks. Here is a walkthrough using real API calls from the sandbox.

Full API reference and sandbox credentials: harbor-developers.owlpay.com/docs/getting-started-1

On-ramp: USD to USDC

The customer wants to fund their wallet. They send USD; Harbor delivers USDC to their blockchain wallet. The response includes transfer_instructions: bank account details the customer uses to wire or ACH funds.

// On-ramp: USD -> USDC (Ethereum)
// Full reference: harbor-developers.owlpay.com/docs/initiate-a-transaction

POST /api/v1/transfer
X-API-KEY: {{API_KEY}}
X-Idempotency-Key: {{IDEMPOTENCY_KEY}}

{
  "on_behalf_of": "{{CUSTOMER_UUID}}",
  "source": {
    "asset": "USD",
    "amount": "100.00"
  },
  "destination": {
    "asset": "USDC",
    "chain": "ethereum",
    "address": "0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db",
    "transfer_purpose": "SALARY",
    "is_self_transfer": false
  }
}

// Response: transfer_instructions tells the customer where to send USD
{
  "data": {
    "uuid": "transfer_ewm6g1e0u6wRycKd7xeHqW0HaqLCV0CLj04xbn8d",
    "status": "pending_customer_transfer_start",
    "transfer_instructions": {
      "account_number": "123456789012",
      "routing_number": "987654321",
      "bank_name": "FV Bank",
      "narrative": "0297197683"
    },
    "receipt": {
      "initial_asset": "USD",  "initial_amount": "100.00",
      "final_asset": "USDC",   "final_amount": "98"
    }
  }
}
// Customer wires/ACHs USD to transfer_instructions.
// Harbor delivers USDC to the destination wallet.
Enter fullscreen mode Exit fullscreen mode

Off-ramp: USDC to bank account

The customer wants to convert USDC back to USD. The response includes a blockchain address where the customer sends USDC. Harbor receives it and delivers USD via ACH to the destination bank account.

// Off-ramp: USDC -> USD (ACH to bank account)
// Full reference: harbor-developers.owlpay.com/docs/off-ramp-stablecoin-to-fiat

POST /api/v1/transfer
X-API-KEY: {{API_KEY}}

{
  "on_behalf_of": "{{CUSTOMER_UUID}}",
  "source": {
    "chain": "ethereum",
    "asset": "USDC",
    "amount": "1000.00"
  },
  "destination": {
    "asset": "USD",
    "account_number": "123456789012",
    "routing_number": "021000021",
    "bank_name": "Test Bank USA",
    "bank_country": "US",
    "account_holder_name": "John Doe",
    "transfer_purpose": "SALARY",
    "is_self_transfer": false
  }
}

// Response: Harbor returns a USDC deposit address
{
  "data": {
    "uuid": "transfer_9r1k54ymg8xn9bleR88gWF4ItF4DGK4MR7ejuS6C",
    "status": "pending_customer_transfer_start",
    "transfer_instructions": {
      "instruction_chain": "ethereum",
      "instruction_address": "0xbf2f9dd51e8f09408dea7334953398f06fff8959"
    },
    "receipt": {
      "initial_asset": "USDC", "initial_amount": "1000.00",
      "final_asset": "USD",    "final_amount": "989.00"
    }
  }
}
// Customer sends USDC to instruction_address.
// Harbor delivers USD to the bank account via ACH.
Enter fullscreen mode Exit fullscreen mode

Cross-border payout: USDC to a bank account abroad (v2 quote flow)

For cross-border payouts, Harbor uses a quote-first flow. You lock the exchange rate upfront, fetch the corridor-specific field requirements via JSON Schema, then create the transfer. The example below sends USDC from a US wallet to a bank account in Hong Kong via WIRE. The same flow works for MXN, BRL, PHP, NGN, AED, EUR, and more.

// Cross-border payout: USDC -> USD delivered to a bank abroad (v2 quote flow)
// Full reference: harbor-developers.owlpay.com/docs/off-ramp-stablecoin-to-fiat

// Step 1: Get a locked quote
POST /api/v2/transfers/quotes
X-API-KEY: {{API_KEY}}

{
  "source": { "country": "US", "chain": "ethereum", "asset": "USDC", "type": "individual" },
  "destination": { "country": "HK", "asset": "USD", "amount": 3000, "type": "individual" }
}

// Response: locked quote with exchange rate and quote_id
{
  "data": [{
    "id": "quote_fo3AirZ3ZYtVayEot5pCoWMPLteMKBtFQfZtPDYv",
    "payment_method": "WIRE",
    "source_currency": "USDC",  "source_amount": "3419.090909",
    "destination_currency": "USD",  "destination_amount": "3000.00",
    "destination_country": "HK",
    "exchange_rate": "0.880000",
    "quote_expire_date": "2025-12-26T17:24:12+00:00"
  }]
}

// Step 2: GET /api/v2/transfers/quotes/{{quote_id}}/requirements
// Returns JSON Schema (Draft 2020-12) with corridor-specific required fields.
// e.g. for HK WIRE: beneficiary_name, SWIFT code, account_number

// Step 3: POST /api/v2/transfers
{
  "on_behalf_of": "{{CUSTOMER_UUID}}",
  "quote_id": "quote_fo3AirZ3ZYtVayEot5pCoWMPLteMKBtFQfZtPDYv",
  "source": { "payment_instrument": { "address": "0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db" } },
  "destination": {
    "beneficiary_info": { "beneficiary_name": "CHAN TAI MAN", "beneficiary_dob": "1990-01-01", ... },
    "payout_instrument": {
      "bank_name": "HSBC Hong Kong",
      "account_holder_name": "CHAN TAI MAN",
      "account_number": "123456789012",
      "swift_code": "HSBCHKHH"
    },
    "transfer_purpose": "SALARY",
    "is_self_transfer": true
  }
}

// Response: instruction_address — customer sends USDC here
{
  "data": {
    "uuid": "transfer_I3eI0LUpUZi7zkewHlWDgIHQlqS3AEBOE2iLt3Ce",
    "status": "pending_customer_transfer_start",
    "transfer_instructions": {
      "instruction_chain": "ethereum",
      "instruction_address": "0x020f4fd0e19b1db5e28e3afd9ecf09227ccf6dbf"
    },
    "receipt": {
      "initial_asset": "USDC", "initial_amount": "3028.00",
      "final_asset": "USD",    "final_amount": "3000.00"
    }
  }
}
// Customer sends USDC to instruction_address.
// Harbor converts and delivers USD to the HK bank account via WIRE.
//
// Other supported corridors:
//   MX (MXN via SPEI) |  BR (BRL via PIX)  |  PH (PHP via InstaPay)
//   NG (NGN via local) |  IN (INR via IMPS)  |  AE (AED via AANI)
//   EU (EUR via SEPA)  |  HK (USD/HKD via FPS / WIRE / CHATS)
// Full list: harbor-developers.owlpay.com/docs/fiat-payment-methods
Enter fullscreen mode Exit fullscreen mode

Staying in sync: webhook events

Harbor sends real-time status events as transfers progress. You subscribe once and receive push notifications for every state change across all rails, no polling required.

// Harbor sends real-time webhook notifications on transfer and customer events
// Full reference: harbor-developers.owlpay.com/docs/webhook

// Payload structure: no top-level event field.
// Use data.object (transfer | customer | reconciliation) + data.status to identify event type.

// Example: Transfer status update
{
  "data": {
    "uuid": "transfer_9r1k54ymg8xn9bleR88gWF4ItF4DGK4MR7ejuS6C",
    "object": "transfer",
    "status": "pending_customer_transfer_start",
    "transfer_instructions": {
      "instruction_chain": "ethereum",
      "instruction_address": "0xbf2f9dd51e8f09408dea7334953398f06fff8959"
    },
    "receipt": {
      "initial_asset": "USDC", "initial_amount": "1000.00",
      "final_asset": "USD",    "final_amount": "989.00"
    }
  }
}

// Example: Customer KYC status update
{
  "data": {
    "uuid": "{{customer_uuid}}",
    "object": "customer",
    "status": "verified"
  }
}

// No polling required. Subscribe once, receive push notifications
// for every state change across all rails and customers.
Enter fullscreen mode Exit fullscreen mode

Why USDC works as the middle layer

One of the key architectural decisions behind Harbor is using USDC as the settlement layer between fiat rails.

This does not mean every product built on top of it needs to become a crypto product.

In a well designed experience, end users may never see a wallet address or a blockchain transaction at all. The stablecoin layer works in the background as internal settlement infrastructure.

That is what allows value to move across borders more efficiently, without requiring every product team to build direct banking relationships, local payout operations, and multi corridor treasury logic on their own.

For example, a user in the US funds through ACH, value moves through USDC as the internal settlement layer, and the recipient receives funds to a bank account in another market. From the product side, that still feels like one integrated money movement flow.

Supported blockchains and stablecoins: harbor-developers.owlpay.com/docs/stablecoins-and-blockchains


What this unlocks for product teams

The value is not just that you save some integration time. The bigger advantage is that you can expand your product's payment capabilities without repeatedly rebuilding the same infrastructure stack. A few examples:

  • Wallet apps: Users fund through debit card or bank rails, hold value, and withdraw through supported payout methods without requiring the product team to independently build each connection.
  • Remittance services: US collection, stablecoin based settlement, and local currency payout can be handled in one architecture instead of across disconnected systems.
  • Payroll platforms: Employers can fund from bank rails, while recipients receive money in the form that makes sense for them, whether that is bank payout, card based withdrawal, or digital dollar settlement.
  • B2B payment products: Businesses can move money across borders without needing to manage each corridor, funding rail, and settlement path independently.
  • Embedded finance: SaaS platforms that want to add pay in, payout, vendor payment, or global settlement features do not need to become full scale payment infrastructure companies to do it.

The infrastructure layer you do not have to build

A lot of teams can build transfer logic. That is not the hard part.

The hard part is everything around the movement of money: compliance across jurisdictions, KYC and AML screening for every user, FX conversion, corridor-specific payout requirements per destination country, and exposing all of that through an API surface that product teams can actually reason about at scale.

Here is what Harbor manages underneath, so your team does not have to:

  • Compliance coverage: 40+ Money Transmitter Licenses across US states, with licensed partner support extending across 100+ countries
  • KYC, KYT, and AML screening: built in natively, no separate vendor required
  • Payout corridors: local payment rails per market out of the box (SPEI, PIX, InstaPay, SEPA, FPS, CHATS, IMPS, and more)
  • FX conversion and settlement: handled automatically per transfer, with locked rates via the Quote API
  • Rail routing: ACH, FedWire, RTP, and Debit Card — Harbor selects the right rail based on corridor and transfer type
  • Operational tooling: webhook events, transfer status tracking, and RFI handling included

For product teams, expansion does not have to start from a blank page every time a new market or payout requirement comes up. You integrate once, and the compliance layer scales with you.


The bigger point

The goal is not to make every product team become a payments infrastructure team.

The goal is to give teams one integration surface while the underlying rails, currency support, corridor coverage, and compliance complexity are handled underneath.

That way, developers can spend less time stitching together fragmented systems and more time building the product their users actually care about.


If you are building in this space

If your team is building a wallet, remittance app, payroll platform, B2B payment product, or other software involving programmable money movement, and you do not want to piece together rails, corridors, currencies, and compliance workflows one by one, OwlPay Harbor is ready for you to explore.

Ready to get started?

  • Explore the Sandbox: You can start testing immediately with our API Documentation.
  • Talk to our Team: We'd love to hear about your specific use case and help you architect your solution. You can reach us via our Contact Form (where you can also find our WhatsApp support), or simply drop an email to owlpaysupport@owlting.com.

We're happy to jump on a call to discuss how Harbor can support your global expansion and help you move money faster.

One more thing: if you use an AI coding assistant, Harbor has an MCP server that lets your assistant query the API docs directly: Harbor MCP Server



API Documentation References

Top comments (0)