Case Study: Connecting PayPal, Wise, and CurrencyCloud for Cross-Border Fintech Applications

Case Study - Design System - Blog - 14
October 11, 2025
11 min
Bohdan Hlushko
Head of Software Engineering
Vadym Shvydkyi
INSART’s tech quarterback. Oversees full-stack architecture from backend to data platforms. His team crafts fintech solutions at startup pace while keeping enterprise-grade quality and reliability front-and-center.

Table of Contents

Cross-border payments sit at the intersection of engineering complexity and financial regulation.

Every API call — whether to PayPal, Wise, or CurrencyCloud — touches real money, foreign exchange rules, and multiple jurisdictions. Each service offers world-class infrastructure for international transfers, yet none alone solves the full problem.

PayPal dominates retail and merchant payments. Wise specializes in low-cost FX transfers. CurrencyCloud provides white-labeled banking rails and institutional-grade liquidity.

When fintechs want to enable multi-currency wallets, global payouts, or cross-border remittances, they must somehow combine these into one seamless user experience.

At INSART, we build precisely that bridge — a unified orchestration layer that connects, normalizes, and secures these providers, turning fragmented APIs into a consistent, developer-friendly infrastructure for global payments.

This case study explores how we architect and implement such an integration — API by API, endpoint by endpoint — and how we handle challenges around FX, webhooks, idempotency, error handling, and compliance.


The Problem: Fragmented Cross-Border APIs

Each cross-border provider was designed for different use cases:

  • PayPal — best for consumer and merchant payments, payouts, and e-commerce flows.

  • Wise — optimized for low-cost person-to-person and B2B transfers across currencies.

  • CurrencyCloud — built for institutional fintechs needing embedded banking, collections, and FX conversions.

However, combining them introduces five major engineering challenges:

  1. Authentication fragmentation: Each provider uses different OAuth mechanisms, scopes, and lifetimes.

  2. Inconsistent data models: PayPal calls it a “payout,” Wise a “transfer,” and CurrencyCloud a “payment.”

  3. FX rate and fee handling: Conversions, spreads, and margins vary between APIs and must be unified.

  4. Webhook chaos: Three different event systems with distinct payload schemas and retry logic.

  5. Compliance alignment: Different KYC/AML, jurisdictional rules, and limits per provider.

INSART’s solution is to create an orchestration layer that hides these complexities behind a unified abstraction — a “Global Payments Gateway” that handles routing, retries, normalization, and observability.


Architectural Overview

The architecture is deliberately modular and extensible, allowing fintech clients to add or remove providers without rewriting core logic.

+------------------+       +---------------------+
|     Fintech UI   | <---> |  INSART Gateway API |
+------------------+       +---------+-----------+
                                    |
             -------------------------------------------------
             |                     |                       |
      +------v-------+      +------v-------+       +-------v-------+
      |  PayPal API  |      |   Wise API   |       | CurrencyCloud |
      |  (REST v2)   |      |   (v3 API)   |       |   (v2 API)    |
      +--------------+      +--------------+       +---------------+
             |                     |                       |
        Webhooks             Webhooks                 Webhooks
             \____________________|________________________/
                           |
                      +----v-----+
                      | Event DB |
                      +----------+

The INSART Gateway provides:

  • Unified API schema: One /payments endpoint to initiate, query, or cancel transfers.

  • Provider adapters: Dedicated modules that handle PayPal, Wise, and CurrencyCloud specifics.

  • Routing logic: Selects the optimal provider based on currency pair, country, or fees.

  • Webhooks processor: Normalizes asynchronous callbacks into a consistent event format.

  • Data persistence: Logs all interactions for reconciliation and audit.


PayPal Integration

Authentication

PayPal APIs use OAuth 2.0 client credentials for server-to-server calls. Tokens last about 9 hours and can be cached securely.

Example (Python):

import requests
from base64 import b64encode

def get_paypal_token(client_id, secret):
    auth = b64encode(f"{client_id}:{secret}".encode()).decode()
    response = requests.post(
        "https://api-m.paypal.com/v1/oauth2/token",
        headers={"Authorization": f"Basic {auth}"},
        data={"grant_type": "client_credentials"}
    )
    return response.json()["access_token"]

Tokens are stored encrypted with AWS KMS and rotated automatically by a background scheduler.


Creating and Capturing Payments

PayPal’s Orders API supports two main payment flows:

  • intent=CAPTURE for immediate payment.

  • intent=AUTHORIZE for delayed capture.

Example:

POST /v2/checkout/orders
{
  "intent": "CAPTURE",
  "purchase_units": [{
    "amount": {
      "currency_code": "USD",
      "value": "100.00"
    }
  }]
}

On approval, the user completes checkout, and the backend captures the payment:

POST /v2/checkout/orders/{id}/capture

The orchestration layer wraps this in an internal function createPayment(provider=”paypal”) and emits standardized events like:

{
  "provider": "paypal",
  "status": "captured",
  "amount": 100.00,
  "currency": "USD",
  "external_id": "9JU1234AB5678"
}

Payouts via PayPal

For mass payouts (common in marketplace or gig-fintech scenarios), PayPal’s Payouts API enables batch transfers:

POST /v1/payments/payouts
{
  "sender_batch_header": {
    "sender_batch_id": "batch_2025_001",
    "email_subject": "Your payout has arrived"
  },
  "items": [{
    "recipient_type": "EMAIL",
    "receiver": "customer@example.com",
    "amount": {"value": "250.00", "currency": "USD"},
    "note": "Weekly earnings"
  }]
}

The response includes both a batch ID and individual item IDs, which are tracked in INSART’s internal ledger.

Webhooks such as PAYMENT.PAYOUTS-ITEM.SUCCEEDED or PAYMENT.PAYOUTS-ITEM.FAILED are consumed and mapped to internal transaction states.


Wise Integration

Authentication

Wise uses OAuth 2.0 Personal Token or API Token for business accounts.

Example setup:

curl -H "Authorization: Bearer <WISE_API_TOKEN>" \
  https://api.transferwise.com/v3/profiles

The token is tied to a specific profile (personal or business) which determines limits and permissions.


Creating Transfers

Wise payments follow a strict 3-step flow:

1.Create a Quote (FX Conversion)

Defines source, target currency, and amount.

POST /v3/quotes
{
  "sourceCurrency": "USD",
  "targetCurrency": "EUR",
  "sourceAmount": "500.00"
}

Response includes an FX rate, expiry time (30s–2min), and total fee.

2. Create a Recipient Account

For repeat payees, store recipient details and re-use the account ID.

POST /v1/accounts
{
  "accountHolderName": "Maria Rossi",
  "currency": "EUR",
  "type": "iban",
  "details": {"iban": "DE89370400440532013000"}
}

3. Create a Transfer

POST /v1/transfers
{
  "targetAccount": "<recipient_id>",
  "quoteUuid": "<quote_uuid>",
  "customerTransactionId": "tx_001",
  "details": {"reference": "Invoice 123"}
}

4. Fund the Transfer

POST /v3/profiles/{profileId}/transfers/{transferId}/payments
{
  "type": "BALANCE"
}

5. Monitor the Transfer

Poll or subscribe to webhook /v3/transfers/{id} to detect completion.

INSART’s orchestration layer abstracts these into one composite transaction with clear state transitions: initiated → funded → processing → delivered.


Currency Coverage

Wise supports 50+ currencies. INSART maintains a route map: which corridors Wise handles vs PayPal vs CurrencyCloud, dynamically updated from API metadata (/v3/currency endpoint).


Error Handling

Common Wise errors:

  • 400 INVALID_CURRENCY_PAIR

  • 403 INSUFFICIENT_BALANCE

  • 429 RATE_LIMIT_EXCEEDED

Each error is mapped to an internal code to drive fallback to another provider if possible.


CurrencyCloud Integration

Authentication

CurrencyCloud uses a two-step login with API Key + Email + Password, returning a short-lived authentication token:

POST /v2/authenticate/api
{
  "login_id": "api@fintech.com",
  "api_key": "<API_KEY>"
}

Response:

{ "auth_token": "c6b25c2e7a..." }

INSART wraps this in an authentication middleware with automatic token refresh before expiry.


Account & Beneficiary Setup

1. Check existing beneficiaries

GET /v2/beneficiaries/find?bank_account_number=...&currency=EUR

2. Create a new beneficiary (if none)

POST /v2/beneficiaries
{
  "bank_account_holder_name": "Tech Ltd",
  "bank_country": "GB",
  "currency": "GBP",
  "account_number": "12345678",
  "bic_swift": "NWBKGB2L"
}

3. Retrieve balance & rates

GET /v2/balances
GET /v2/rates/detailed?buy_currency=EUR&sell_currency=USD

4. Convert currency if necessary

POST /v2/conversions/create
{
  "buy_currency": "EUR",
  "sell_currency": "USD",
  "amount": "1000"
}

5. Create payment

POST /v2/payments/create
{
  "currency": "EUR",
  "beneficiary_id": "<id>",
  "amount": "1000.00",
  "reason": "Supplier invoice"
}

Webhooks

CurrencyCloud supports webhook notifications for:

  • Payment success/failure

  • Conversion confirmation

  • Incoming funds

Webhook example:

{
  "event": "payment_released",
  "payment_id": "db8b85a9-7e97",
  "amount": "1000.00",
  "currency": "EUR",
  "status": "completed"
}

INSART’s event handler verifies signatures, logs the event, and updates the internal transaction record.


Orchestration Logic in Practice

Selecting Providers

INSART’s gateway dynamically selects a provider using configurable rules:

  • Preferred corridors: If USD→EUR under $50k → Wise; if USD→GBP → CurrencyCloud.

  • Failover: If Wise API returns 429, fallback to CurrencyCloud if corridor supported.

  • Fee optimization: Compare live quotes (Wise /quotes, CurrencyCloud /rates/detailed) and pick the cheaper provider.

This selection happens before payment creation and is logged for audit transparency.


Unified Transaction Schema

Regardless of provider, every transaction is represented as:

{
  "id": "txn_2025_001",
  "provider": "wise",
  "source_currency": "USD",
  "target_currency": "EUR",
  "source_amount": 500.00,
  "target_amount": 493.75,
  "fx_rate": 0.9875,
  "fee": 6.25,
  "status": "completed",
  "external_id": "d4f32a3e-...-12af",
  "created_at": "2025-10-10T15:00:00Z"
}

All providers’ data conform to this format in the internal ledger.


Reconciliation

Daily reconciliation verifies:

  • Provider-reported balances (GET /balances)

  • FX spreads vs quotes

  • Webhook vs transaction state parity

Discrepancies are flagged automatically to compliance or finance teams.


Observability & Support Tooling

The orchestration layer exposes a small internal dashboard:

  • Query by user, provider, or transaction ID.

  • Display provider status (/v3/healthcheck endpoints).

  • Replay failed webhook events.

  • Trigger manual payout replays or refunds.


Compliance & Security

PCI DSS & PII Handling

  • No card or bank data is stored unencrypted.

  • All access tokens (PayPal, Wise, CurrencyCloud) encrypted with KMS.

  • Sensitive responses masked in logs.

Audit & SOC 2

  • Every external call logged with timestamp, status, latency, and correlation ID.

  • Logs are immutable and retained per jurisdiction requirement.

Error Transparency

Users always see consistent messages (“Transfer failed: insufficient balance”) — mapped from raw provider error payloads.


Key Engineering Lessons

  1. Standardize early. Define your internal transaction schema before you integrate multiple APIs.

  2. Provider parity is a myth. Expect slight differences in FX timing, cut-off hours, and payout corridors.

  3. Webhooks need replay protection. PayPal retries for 72h; Wise for 24h; CurrencyCloud indefinitely until 200 OK.

  4. Compliance adds friction — automate it. Build KYC/AML checks into orchestration, not as an afterthought.

  5. Testing is critical. All three providers offer sandbox APIs — use them continuously with realistic test data.


Business Impact

By combining PayPal, Wise, and CurrencyCloud behind one orchestrated layer, INSART’s clients achieve:

  • Global reach: 60+ supported currencies and 190+ corridors.

  • Faster onboarding: One integration instead of three.

  • Redundancy: Failover between providers prevents single-vendor downtime.

  • Optimized costs: FX routing selects the cheapest conversion provider in real time.

  • Unified reporting: All payments visible in one dashboard.

  • Regulatory readiness: Integrated logging and data segregation per provider jurisdiction.

For end users, it means they can send €100 to Berlin, withdraw £50 to London, and receive $200 from New York — all through one seamless fintech experience.


Example Unified Flow (USD → EUR)

1. Client requests payout USD→EUR 500
2. Gateway fetches Wise & CurrencyCloud quotes
   - Wise: rate 0.9875, fee $6.25
   - CurrencyCloud: rate 0.9860, fee $5.50
3. Gateway picks cheaper total cost (CurrencyCloud)
4. Gateway converts 500 USD → 986.0 EUR via /conversions
5. Gateway creates payment via /payments/create
6. CurrencyCloud webhook "payment_released" → transaction status updated
7. Gateway updates user dashboard → "Delivered €986.00 to account"

This orchestration executes in seconds, logs every step, and provides reconciliation proof.


Future-Proofing: Adding New Providers

The architecture supports adding new integrations (e.g., Revolut Business, Airwallex) through simple adapter contracts:

class ProviderAdapter:
    def create_quote(self, source_currency, target_currency, amount): ...
    def create_payment(self, quote, recipient): ...
    def get_status(self, payment_id): ...
    def handle_webhook(self, event): ...

This plug-in model means fintech clients can expand corridors without rewriting orchestration logic.


Conclusion

Cross-border fintech is not about one perfect API — it’s about orchestrating many imperfect ones into a single, consistent, reliable experience.

INSART’s integration of PayPal, Wise, and CurrencyCloud proves that with the right abstraction layer, fintech companies can achieve global reach, regulatory compliance, and operational excellence simultaneously.

We build systems that don’t just move money — they move trust across borders.

SUBSCRIBE

Whether you are a founder, investor or partner – we have something for you.

Home
Get in touch
Explore on signals.MAG