portal.ramps.noah. Each method sends a message to the embedded Portal iframe, which calls Portal’s Noah integration on the Client API using your client credentials. You do not call Noah’s servers directly from the browser.
For dashboard setup, signing keys, and supported CAIP-2 networks, see Noah integration overview. For HTTP shapes and webhooks, see the Noah workflow guides and Noah Business API / EMM documentation.
Prerequisites
- An initialized Portal client with the iframe ready (
onReadyor equivalent). - Noah enabled for your Portal environment and configured in the dashboard.
- For payins and payouts, the end user must complete Noah KYC with approved status before those flows succeed.
Architecture
| Layer | Role |
|---|---|
| Your app | Calls portal.ramps.noah.* |
| Portal Web SDK | postMessage bridge to the Portal iframe (do not call Mpc directly) |
| Portal iframe | Forwards to POST/GET …/api/v3/clients/me/integrations/noah/... with the Portal session |
| Noah (via Portal) | Hosted KYC, banking rails, settlement |
portal.ramps.noah over lower-level APIs. The SDK types for requests and responses live in @portal-hq/web (see the Web SDK reference section portal.ramps.noah (Noah)).
Types and responses
Successful Client API responses use an envelope{ data: T, metadata?: Record<string, unknown> }. Methods on portal.ramps.noah return Promise of that envelope (for example NoahInitiateKycResponse is { data: { hostedUrl: string } }).
Throwing or rejected promises usually indicate network errors, iframe timeouts, or API error payloads surfaced by the SDK—handle them with try/catch like other async Portal calls.
initiateKyc
Starts hosted Noah onboarding. Opendata.hostedUrl in a new browser context (for example window.open with noopener,noreferrer). Validate HTTPS and the hostname against the checkout domains Noah documents for your environment (extend the example allowlist accordingly).
| Parameter | Type | Required | Description |
|---|---|---|---|
data.returnUrl | string | Yes | HTTPS URL where Noah returns the user after onboarding. |
data.fiatOptions | { fiatCurrencyCode: string }[] | No | Fiat currencies to present in onboarding. |
data.customerType | 'Individual' | 'Business' | No | Onboarding flow variant. |
data.metadata | Record<string, unknown> | No | Opaque metadata forwarded per API rules. |
data.form | Record<string, unknown> | No | Optional prefill payload for hosted forms. |
NoahInitiateKycResponse: { data: { hostedUrl: string } }.
This call only starts onboarding; KYC outcome and status changes arrive asynchronously via Noah
Customer webhooks. See Noah webhooks.initiatePayin
Creates a fiat-to-stablecoin payin and returns bank instructions and apayinId. Use a supported CAIP-2 network and the user’s wallet address as destinationAddress.
| Parameter | Type | Required | Description |
|---|---|---|---|
data.fiatCurrency | string | Yes | Fiat currency code (for example USD). |
data.cryptoCurrency | string | Yes | Noah crypto asset code (for example stablecoin test symbols in sandbox). |
data.network | string | Yes | CAIP-2 chain identifier. |
data.destinationAddress | string | Yes | Address that receives crypto after settlement. |
data.businessFees | Record<string, NoahBusinessFee> | No | Optional business-level fee overrides keyed by fee type. |
NoahInitiatePayinResponse: { data: { payinId: string; cryptoCurrency: string; fee: NoahFeeDetails; bankDetails: BankDetails } }.
NoahFeeDetails shape: { fiatCurrencyCode: string; totalFeePct: string; totalFeeBase: string; totalFeeMin: string }.
BankDetails includes:
paymentMethodId— payment method identifierpaymentMethodType— payment rail typeaccountNumber— bank account numbercryptoCurrency— crypto currency for this payinnetwork— network identifierfee— fee breakdown (NoahFeeDetails)accountHolderName?— optional account holder namebankCode?— optional bank routing/sort codebankName?— optional bank namebankAddress?— optional bank address withstreet,street2?,city,postCode,state,countryreference?— optional payment referencerelatedPaymentMethods?— optional array of related payment methods
Payin lifecycle updates are asynchronous; track them with Noah
FiatDeposit and Transaction webhooks, not by polling this SDK response. See Noah webhooks.simulatePayin
Sandbox-oriented call to estimate fees or eligibility for a payin without creating a live payin. Typical body includes a NoahpaymentMethodId and fiat amount.
| Parameter | Type | Required | Description |
|---|---|---|---|
data.paymentMethodId | string | Yes | Payment method identifier from Noah. |
data.fiatAmount | string | Yes | Fiat amount as a string (decimal). |
data.fiatCurrency | string | Yes | Fiat currency code. |
NoahSimulatePayinResponse: { data: { fiatDepositId: string; reference?: string } }.
getPayoutCountries
Lists countries available for fiat payouts.NoahGetPayoutCountriesResponse: { data: { countries: Record<string, string[]> } }.
getPayoutChannels
Returns payout rails available for a crypto currency.country and fiatCurrency narrow results but are optional; fiatAmount can further refine channel availability.
| Parameter | Type | Required | Description |
|---|---|---|---|
data.cryptoCurrency | string | Yes | Crypto asset code for the payout leg. |
data.country | string | No | ISO country code (for example US). Narrows results when provided. |
data.fiatCurrency | string | No | Fiat currency for the payout. Narrows results when provided. |
data.fiatAmount | string | No | Amount string used for filtering or quotes. |
data.paymentMethodId | string | No | Filters channels compatible with a specific payment method. |
data.pageSize | number | No | Maximum number of payout channels to return. |
data.pageToken | string | No | Pagination token returned from a previous response. |
NoahGetPayoutChannelsResponse: { data: { items: Channel[]; pageToken?: string } }.
Each Channel includes:
id— channel identifierpaymentMethodCategory—'Bank' | 'Card' | 'Identifier'paymentMethodType— payment rail type (NoahPaymentMethodType)fiatCurrency— fiat currency codecountry— ISO country codelimits—{ minLimit: string; maxLimit?: string }rate— exchange rate as a stringprocessingSeconds— estimated settlement timecalculated?— optional{ totalFee: string }processingTier?—'Standard' | 'Priority'issuer?— optional issuer identifierpaymentMethods?—PaymentMethodDisplay[]
getPayoutChannelForm
Loads the dynamic form schema for a channel so you can collect recipient fields before requesting a quote.| Parameter | Type | Required | Description |
|---|---|---|---|
channelId | string | Yes | Channel identifier from getPayoutChannels. |
NoahGetPayoutChannelFormResponse: { data: { formSchema?: Record<string, unknown>; formMetadata?: { contentHash: string } } }.
getPayoutQuote
Requests fees and crypto amount estimates for a payout. Includeform when the channel requires recipient data.
| Parameter | Type | Required | Description |
|---|---|---|---|
data.channelId | string | Yes | Payout channel id. |
data.cryptoCurrency | string | Yes | Crypto asset for the quote. |
data.fiatAmount | string | No | Fiat amount as a string. Mutually exclusive with cryptoAmount; provide one. |
data.cryptoAmount | string | No | Crypto amount as a string. Mutually exclusive with fiatAmount; provide one. |
data.quoted | boolean | No | When true, requests a firm signed quote alongside the estimate. |
data.form | Record<string, unknown> | No | Recipient fields from the channel form. |
data.fiatCurrency | string | No | Fiat currency override when needed. |
data.paymentMethodId | string | No | Payment method hint when applicable. |
data.businessFee | NoahBusinessFee | No | Optional business-level fee override ({ feeBase?, feePct?, fiatCurrency? }). |
NoahGetPayoutQuoteResponse: { data: { payoutId: string; totalFee: string; cryptoAmountEstimate: string; cryptoAuthorizedAmount: string; formSessionId: string; rate?: string; breakdown?: TransactionBreakdownItem[]; quote?: NoahSellQuote; cryptoCurrency?: string; fiatCurrency?: string; fiatAmount?: string; nextStep?: FormNextStep } }.
cryptoAuthorizedAmount— authorized crypto amount for the payoutrate?— effective exchange rate for this quotebreakdown?— fee breakdown array ({ type: 'ChannelFee' | 'BusinessFee' | 'Remaining'; amount: string }[])quote?— firm signed quote whenquoted: truewas requested ({ signedQuote: string; expiry: string })cryptoCurrency?,fiatCurrency?,fiatAmount?— disclosure fields echoing back the quote parameters
nextStep includes:
stepId—'Vop' | 'Cob' | 'PaymentDetails'stepType—'Ack'or'DataEntry'schema— form schema for the next step
initiatePayout
Executes a payout after quoting. For crypto-sourced payouts you may need to pass depositconditions from the quote response via a trigger payload; align with Payouts and Noah’s on-chain deposit triggers.
| Parameter | Type | Required | Description |
|---|---|---|---|
data.payoutId | string | Yes | Identifier from getPayoutQuote. |
data.sourceAddress | string | Yes | Address funding the crypto leg when applicable. |
data.expiry | string | Yes | ISO-8601 expiry for the deposit authorization. |
data.nonce | string | Yes | Stable nonce for this payout attempt; reuse on retry so repeated calls stay idempotent. Must be ≤ 36 characters per Noah API constraints. |
data.network | string | Yes | CAIP-2 network for the deposit leg. |
data.trigger | NoahOnchainDepositSourceTriggerInput | No | Explicit on-chain deposit trigger. Supports Single, Permanent, and Quoted variants (discriminated on Type). |
data.fiatAmount | string | No | Fiat amount for the payout. Only applicable when trigger.Type is 'SingleOnchainDepositSourceTriggerInput'. |
data.businessFee | NoahBusinessFee | No | Optional business-level fee override ({ feeBase?, feePct?, fiatCurrency? }). |
NoahInitiatePayoutResponse: { data: { destinationAddress: string | null; conditions: DepositSourceTriggerCondition[]; ruleId?: string } }.
Each DepositSourceTriggerCondition includes:
amountConditions— array of{ comparisonOperator: 'EQ' | 'LTEQ' | 'GTEQ'; value: string }cryptoCurrency— crypto asset codenetwork— CAIP-2 network identifierdestinationAddress— destination address for the deposit
After this call returns
destinationAddress and conditions, submit the onchain transfer to satisfy them. You can do this with any wallet — including Portal’s own send method (portal.sendAsset(...)) on the same Portal instance, which builds, signs, and broadcasts in one call.This call initiates the payout flow; completion and failures are reported asynchronously via Noah
Transaction webhooks. See Noah webhooks.getPaymentMethods
Returns payment methods available to the customer (for example cards or bank rails), including pagination tokens when present.| Parameter | Type | Required | Description |
|---|---|---|---|
data.pageSize | number | No | Maximum number of payment methods to return. |
data.pageToken | string | No | Pagination token returned from a previous response. |
data.capability | 'PayoutFrom' | 'PayinTo' | 'PayoutTo' | No | Filters payment methods by supported Noah capability. |
NoahGetPaymentMethodsResponse: { data: { paymentMethods: PaymentMethod[]; pageToken?: string } }.
Each PaymentMethod includes:
id— payment method identifierpaymentMethodCategory—'Bank' | 'Card' | 'Identifier'paymentMethodType— payment rail typedetails— payment method details withtype, optionalaccountNumber,bankCode,last4,scheme,identifierType,identifier,routingNumber,swiftCode,bankingSystems,bankName,bankAddressaccountHolderDetails?— optional holder info withname?: { firstName: string; lastName: string; middleName?: string }issuerDetails?— optional issuer info withname?: string
Error handling
Wrap calls intry/catch. Log or surface errors without printing full API responses in production if they might contain sensitive identifiers. Retry only for idempotent reads unless your product team confirms otherwise.
Related documentation
- Web SDK reference — Noah (section portal.ramps.noah (Noah))
- Noah integration overview
- KYC, Payins, Payouts, Webhooks
- Noah docs — API concepts
- Noah docs — authentication & signing