FIAT to FIAT Transfers

PENDING

Overview

This guide explains how Alfred’s Penny API supports a FIAT-to-FIAT transfer flow using deposit instructions, then automatically triggering an outbound payout to the recipient once the inbound deposit is received and matched.

The flow has three required steps:

  1. Register the FIAT account (Receiver or third party beneficiary)
  2. Create a FIAT→ FIAT quote (locked FX / fees)
  3. Create a Deposit Intent with metadata (includes the fiatAccountId + quote reference) so that when the deposit arrives, Penny can auto-execute the payout to the registered FIAT account.

Important

  • This flow requires a valid FIAT Account ID (beneficiary/bank account record) before you can enable auto-offramp.
  • Funds are matched using a unique deposit reference/message that must be included by the sender (wire memo / reference field depending on rail).
  • Penny supports FIAT- native settlement for this flow (no crypto interaction and no stablecoin leg required).

Fiat-to-Fiat Transfers with Penny API (Deposit → Auto Payout)

Overview

Penny API enables fiat-to-fiat transfers by combining:

  1. Recipient account registration (create a fiatAccountId)
  2. FX quoting (lock/confirm the fiat corridor terms)
  3. Deposit order creation (generate deposit instructions for inbound funds)
  4. Automatic payout once the deposit is confirmed (Payout execution)

This flow is designed for B2B partners who need a compliant, auditable workflow where:

  • A sender deposits local currency into a Penny-provided collection account.
  • Penny matches the deposit to a specific order.
  • Penny then automatically pays out to a third-party recipient using a pre-registered FiatAccountID.

Requirements & Preconditions

Who can use this flow

  • Partners must be onboarded and approved to create fiat orders and execute fiat payouts.

  • You must have:

    • Valid API credentials
    • An approved partner profile
    • Access to the required corridor/currencies you intend to use

Key Concepts

  • Fiat Account: A stored bank account profile for a recipient/beneficiary (third party).
  • FiatAccountID: The ID returned by Penny when a fiat account is registered. Used as the canonical reference for payouts.
  • Quote: A priced corridor instruction (e.g., MXN→USD) including fees/spread and expiry.
  • Onramp (Deposit Order): An order that produces deposit instructions and awaits inbound funds.
  • Offramp (Payout): The outbound payment to the recipient’s FiatAccountID.
  • Auto Offramp: A mode where Penny triggers the payout automatically once the deposit is confirmed and matched.

Step 1 — Register a Third-Party Fiat Account (Recipient)

Before you can complete a fiat-to-fiat transfer, you must register the recipient’s fiat account. This step creates a FiatAccountID.

Why registration is required

  • Penny needs a canonical, validated reference (fiatAccountId) for:

    • routing and rail compatibility checks
    • compliance screening / audit tracing
    • consistent formatting across payout rails

What you capture during registration

At a minimum, you should be prepared to provide:

  • Recipient type: individual or business

  • Recipient identity fields (name, email, optional tax id depending on corridor)

  • Bank account details (country-specific)

    • Bank name
    • Account number / CLABE / CVU / CBU / IBAN (depending on rail)
    • Routing / bank code
    • Account type (checking/savings where applicable)
  • Recipient address (often required for international rails)

  • Optional metadata fields for your internal references

Tip: If you already have an internal beneficiary registry, store the returned fiatAccountId alongside your beneficiary record so you don’t re-register the same account.



Step 2 — Quote a Fiat Corridor (FX Quote)

Once you have a valid fiatAccountId, you must request a quote for the transfer corridor.

Why quoting is required

Quoting:

  • establishes the expected receive amount
  • defines fees and spread
  • sets expiry windows
  • provides the required reference you can attach to your deposit order

Quote behaviors

Depending on the corridor and pricing model, quotes may be:

  • indicative (preview)
  • firm/lockable (short expiry)
  • accepted (confirm intent to execute under the quote terms)

Step 3 — Create Deposit Order with Metadata (Onramp) + Auto Offramp

This section is the Penny equivalent of “deposit intent” in the Bitso example.

You will create an onramp deposit order that:

  • generates deposit instructions (where the sender will deposit funds)

  • ties the deposit to:

    • a quoteId
    • a fiatAccountId (recipient)
  • With a valid QuoteID from Step 2, Penny API knows this is a FIAT → FIAT flow and uses the quote as the locked source of truth (currencies, rate/fees, execution path). That lets Penny auto-execute the FX/liquidation and then initiate the off-ramp payout to the provided FiatAccountID with the required information.


What happens after deposit is received (Auto Payout)

Once the deposit is detected and matched, Penny will:

  1. Mark the onramp as FIAT_DEPOSIT_RECEIVED
  2. Execute the FX conversion (as specified by quoteId) you receive the
  3. Automatically trigger the offramp payout to the registered destinationFiatAccountId
  4. Transition the transfer to a completed terminal status

This “deposit + auto payout” sequence is the canonical fiat-to-fiat behavior.


Webhooks (recommended)

To operate reliably, partners should subscribe to webhooks that reflect the lifecycle.

Suggested webhook events

  • FIAT_DEPOSIT_RECEIVED

    • includes: sender name, sender bank name (where available), amount, currency, timestamp, onrampId, reference
  • OFFRAMP_INITIATED

    • includes: payoutId, destinationFiatAccountId, amount, currency
  • OFFRAMP_SETTLED

    • includes: payoutId, confirmation/reference from payout rail
  • TRANSFER_COMPLETED (optional umbrella event)

Example: FIAT_DEPOSIT_RECEIVED

{
  "eventType": "FIAT_DEPOSIT_RECEIVED",
  "timestamp": "2026-01-15T19:02:11Z",
  "data": {
    "onrampId": "or_01HZX33B2A3G7Z0KXKQ9Y7D5V1",
    "sourceAmount": "50000.00",
    "sourceCurrency": "MXN",
    "senderName": "Empresa ABC SA de CV",
    "senderBankName": "BBVA México",
    "reference": "ALF-OR-01HZX33B2A3G7Z0KXKQ9Y7D5V1"
  }
}

Status model (simplified)

A deposit order can move through states like:

  • AWAITING_DEPOSIT → (waiting for inbound funds)
  • FUNDS_RECEIVED → (deposit matched)
  • OFFRAMP_IN_PROGRESS → (payout initiated)
  • COMPLETED → (payout settled)
  • FAILED → (deposit never arrived, mismatch, compliance rejection, payout failure, etc.)

Common failure scenarios & handling

1) Deposit mismatch (amount/reference)

Cause: Sender sends wrong amount or omits reference. Outcome: Deposit cannot be auto-matched. Resolution: Manual investigation; partner may need to provide proof of payment.

2) Recipient FiatAccountID invalid or not active

Cause: Fiat account not ACTIVE or fails corridor validations. Outcome: Auto offramp cannot proceed. Resolution: Register a valid FiatAccountID and update the order (if allowed) or re-create.

3) Quote expired

Cause: Deposit arrives after quote expiry window. Outcome: FX execution blocked until re-quote. Resolution: Create a new quote; depending on policy, order may need re-creation.

4) Compliance hold

Cause: corridor limits, sanctions screening, high-risk activity triggers review. Outcome: Transfer paused. Resolution: Provide requested information; once cleared, processing resumes.


Summary of the 3 required sections

  1. Fiat Account Registration (3rd party) Create a recipient fiatAccountId that represents the beneficiary bank account to be paid out.

  2. Deposit (Onramp) with metadata Create an onramp deposit order that generates deposit instructions and includes:

  • quoteId
  • recipientFiatAccountId in metadata
  • autoOfframp.enabled=true
  1. Automatic Offramp after deposit When deposit is received and matched, Penny triggers the offramp automatically using the fiatAccountId, completing the fiat-to-fiat transfer end-to-end.