Change Log

August 11th 2025 (In Beta for certain teams)

Summary: The main objective of this release is to allow developers to select a specific rail for a payment. Previously, only LOCAL, CRYPTO, and WIRE were allowed. The dashboard has NOT yet been updated to use these new endpoints.

Corridors

The first step was creating a new GET /payments/corridors endpoint that allows you to see which corridors/rails are available. A few notes:

  • "rails" now contains all supported blockchains and all supported fiat rails. "chain" has been deprecated
  • "currencyCodes" and "rails" are now arrays, allowing us to greatly reduce the number of objects returned by the response. Instead of having an object for every permutation of blockchain and stablecoin (e.g., POLYGON/USDC, ETHEREUM/USDC, BASE/USDC), these are all concatenated into one object
  • Instead of having fees for LOCAL, CRYPTO, and WIRE, fees are now specific to the source and destination rail combination.

Breaking Change: GET configurations/corridors will be deprecated September 20th.

Before (GET configurations/corridors):

"data": [
        {
            "source": {
                "currencyCode": "USDC",
                "chain": "POLYGON"
            },
            "destination": {
                "currencyCode": "BRL",
                "chain": null,
                "countryCode": "BR"
            },
            "fees": {
                "LOCAL": {
                    "fixedFeeInUSD": 1,
                    "variableFeeInSourceCurrency": 0.005
                },
                "CRYPTO": {
                    "fixedFeeInUSD": 1,
                    "variableFeeInSourceCurrency": 0.005
                },
                "WIRE": {
                    "fixedFeeInUSD": null,
                    "variableFeeInSourceCurrency": null
                }
            }
        }
]

After (GET payments/corridors):

"data": [
        {
            "source": {
                "currencyCodes": [
                    "USDC",
                    "USDT",
                    "EURC"
                ],
                "rails": [
                    "POLYGON",
                    "ETHEREUM",
                    "BASE",
                    "SOLANA",
                    "TRON"
                ]
            },
            "destination": {
                "currencyCodes": [
                    "BRL"
                ],
                "rails": [
                    "TED"
                ],
                "countryCode": "BR"
            },
            "fees": {
                "fixed": 1,
                "variable": 0.005
            }
        }
]

Customers

Previously, if your team had USD corridors enabled, all onboarded customers would require passing through compliance checks mandated by US banks (which tend to be slower). Since it's possible not all your customers need access to USD corridors, you can now specify which capabilities you would like to enable for the onboarded customer: USD and NON_USD (putting both or not including the capabilities parameter in the request will give the customer access to all corridors).

Important note: USD capability also covers EUR onramps.

Example

{
    "type": "INDIVIDUAL",
    "capabilities": ["NON_USD"], // Optional
    "firstName": "Jason",
    "lastName": "Smith",
    ....
}

Accounts

GET /requirements

With the ability to choose which rail to send the payment, it is also important to know which parameters are required for each rail when creating an account. We have therefore created a new GET /accounts/requirements endpoint to replace the existing GET /accounts/requirements/external-bank-accounts endpoint. A few notes:

  • Objects are not grouped by INDIVIDUAL and BUSINESS anymore. Instead, each variable will have an accountHolderTypes array to designate to whom it applies
  • The regex provided for IBANs is now specific to the country

Breaking Change: GET /accounts/requirements/external-bank-accounts will be deprecated September 20th.

Before (GET /accounts/requirements/external-bank-accounts):

{
    "INDIVIDUAL": [
        {
            "variableName": "bank.accountNumber",
            "regex": "^[0-9]{2,15}$",
            "example": "001000456789",
            "enum": []
        },
        ....
    ],
    "BUSINESS": [
        {
            "variableName": "bank.accountNumber",
            "regex": "^[0-9]{2,15}$",
            "example": "001000456789",
            "enum": []
        },
        ...
    ]
}

After (GET /accounts/requirements):

[
    {
        "variableName": "bank.accountNumber",
        "rails": [
            "TED"
        ],
        "accountHolderTypes": [
            "INDIVIDUAL",
            "BUSINESS"
        ],
        "regex": "^[0-9]{2,15}$",
        "example": "001000456789",
        "enum": []
    },
    ...
    {
        "variableName": "bank.pixCode",
        "rails": [
            "PIX"
        ],
        "accountHolderTypes": [
            "INDIVIDUAL",
            "BUSINESS"
        ],
        "regex": "^.{1,100}$",
        "example": "01.234.456/5432-10 (cnpj) | 123.456.789-87 (cpf) | +5511912345678",
        "enum": []
    }
]

POST /accounts

In addition to the revamped requirements endpoint, you can now specify the rails you want to unlock for the account you create. Currently, this can be done for two different countries:

  • US: ACH, ACH_SAME_DAY, and DOMESTIC WIRE. Some US banks don't have all three rails for their accounts, so it's important to designate which rails can be used to send funds. If you do not include the "rails" field in the request, the account will get access to all 3 by default
  • BR: TED and PIX. These rails have different field requirements. By selecting which rail you want to enable for the account, you can make sure to only ask your customer for the actual fields required for the rail you want to use. If you do not include the "rails" field in the request, the account will get access to TED by default

Example

{
    "type": "EXTERNAL_BANK_ACCOUNT",
    "currencyCode": "BRL",
    "isThirdParty": true,
    "rails": ["TED", "PIX"],
    "bank": {
        "name": "BANCO DO BRASIL S.A",
    ....
}

Payments

GET /rate

With the introduction of specific rails, the GET /payments/rate/walapay has also been replaced with GET /payments/rate to provide the details of the specific rail chosen. A few notes:

  • Instead of query parameters sourceChain and destinationChain, it is sourceRail and destinationRail
  • You can still use LOCAL as the value for "rail". Behind the scenes, we map this value to the appropriate country-specific rail
  • The current /payments/rate/walapay will append the results of the new endpoint automatically so that you can transition from one to the other smoothly

Breaking Change: GET /payments/rate/walapay will be deprecated September 20th.

Before (GET /payments/rate/walapay):

{
    "midMarketRate": 5.4952529294,
    "invertedMidMarketRate": 0.1819755763,
    "walapayFees": {
        "description": "The Walapay fees for the payment based on the destination rail",
        "LOCAL": {
            "fixed": 1,
            "variable": 0.001
        },
        "WIRE": {
            "fixed": 45,
            "variable": 0.0065
        },
        "CRYPTO": {
            "fixed": null,
            "variable": null
        }
    },
    "walapayRates": {
        "description": "[Deprecated] The mid market rate minus the Walapay variable fee: mid market rate * (1 - Walapay variable fee)",
        "LOCAL": 5.4897576764706,
        "WIRE": 5.459533785358901,
        "CRYPTO": null
    },
    "developerFees": {
        "description": "The developer fees for the payment. Added on top of the walapay fees.",
        "fixed": null,
        "variable": null
    },
    "calculatedAmounts": {
        "LOCAL": {
            "sourceAmount": 679.27,
            "destinationAmount": 3723.52,
            "totalFeeInSourceCurrency": 1.68
        },
        "WIRE": {
            "sourceAmount": 727.03,
            "destinationAmount": 3723.52,
            "totalFeeInSourceCurrency": 49.44
        },
        "CRYPTO": {
            "sourceAmount": null,
            "destinationAmount": null,
            "totalFeeInSourceCurrency": null
        }
    },
    "quoteId": "cmdxts4kx0000dunid010mqd7"
}

After (GET /payments/rate):

{
    "midMarketRate": 5.495449870300001,
    "invertedMidMarketRate": 0.18196857419999998,
    "walapayFee": {
        "fixed": 1,
        "variable": 0.007
    },
    "developerFee": {
        "fixed": 1,
        "variable": 0.01
    },
    "calculatedAmount": {
        "description": "The calculated amounts for the payment, along with total fee (both walapay and developer).destinationAmount = (((sourceAmount - walapayFixedFee) * (1 - walapayVariableFee)) - developerFixedFee) * midMarketRate * (1 - developerVariableFee). sourceAmount = (destinationAmount / (midMarketRate * (1 - developerVariableFee)) + developerFixedFee) / (1 - walapayVariableFee) + walapayFixedFee.",
        "sourceAmount": 691.24,
        "destinationAmount": 3723.52,
        "totalFeeInSourceCurrency": 13.68
    },
    "quoteId": "cmdxtdy6e000010y04ovhu28i"
}

POST /payments

In addition to the new rate endpoint, the POST /payments endpoint has been updated to allow you to choose a country-specific rail if desired. A few notes:

  • To start, the currencies that will have multiple options:
    • USD: ACH, ACH_SAME_DAY, DOMESTIC_WIRE
    • BRL: TED, PIX
    • INR: IMPS, IMPS_WITH_FIRC
  • You can still use LOCAL if you want Walapay to choose the default option on your behalf
  • For SWIFT payments, you should use the rail type "SWIFT" (WIRE is deprecated)

Before:

{
    "source": {
        "currencyCode": "USDC",
        "amount": 10,
        "rail": "CRYPTO",
        "chain": "POLYGON",
        "fromAddress": "0x9dE08B842B9f9E27c478fF816330118939a7BF90"
    },
    "destination": {
        "currencyCode": "USD",
        "rail": "LOCAL",
        "accountId": "cmca02pfl000cfc5qjs3emffc"
    },
    "comment": "Test Transaction",
    "memo": "Test",
    "paymentReason": "CONSULTING_FEES",
    "documentReference": "Test"
}

After (with "source.rail" as "POLYGON" and "destination.rail" as "ACH_SAME_DAY"):

{
    "source": {
        "currencyCode": "USDC",
        "amount": 10,
        "rail": "POLYGON",
        "fromAddress": "0x9dE08B842B9f9E27c478fF816330118939a7BF90"
    },
    "destination": {
        "currencyCode": "USD",
        "rail": "ACH_SAME_DAY",
        "accountId": "cmca02pfl000cfc5qjs3emffc"
    },
    "comment": "Test Transaction",
    "memo": "Test",
    "paymentReason": "CONSULTING_FEES",
    "documentReference": "Test"
}