Webhook Events
Each object in the platform has its own lifecycle and its status changes as it transitions between states.
Whenever one such transition occurs, a webhook event is fired.
Setup
You can configure your webhook destinations from the CFX Platform dashboard:
| Environment | URL |
|---|---|
| Development | app.dev.cfx.to/settings/webhooks |
| Production | app.cfx.to/settings/webhooks |
From the settings page you can add a destination URL, manage your signing secret, and choose which event topics to subscribe to.
Authentication
All webhook requests are signed using the Standard Webhooks specification. Every request includes the following headers:
| Header | Description |
|---|---|
webhook-id | A unique identifier for the webhook message. This ID is stable across retries and can be used for idempotency. |
webhook-timestamp | The Unix timestamp (in seconds) when the message was sent. |
webhook-signature | A base64-encoded HMAC-SHA256 signature in the format v1,<base64>. |
The signature is computed over the message ID, timestamp, and request body:
signed_content = "${webhook-id}.${webhook-timestamp}.${body}"
signature = base64(HMAC-SHA256(secret, signed_content))
Signing Secret
Your signing secret is available on the webhook settings page and follows the format whsec_<base64>. Keep this value secure — it is used to verify that incoming requests genuinely originated from the CFX Platform.
Secret Rotation
You can rotate your signing secret from the settings page. During the rotation window (24 hours by default), both the old and new secrets are valid for signature verification, so you can update your consumer without downtime.
Verifying Webhook Signatures
We strongly recommend verifying signatures on every incoming webhook to ensure authenticity and protect against replay attacks.
Using the Standard Webhooks SDK (recommended)
The easiest approach is to use the official standardwebhooks library, available for JavaScript/TypeScript, Python, Go, Ruby, Java/Kotlin, PHP, C#, Rust, and Elixir.
JavaScript / TypeScript:
npm install standardwebhooks
# or
yarn add standardwebhooksimport { Webhook } from "standardwebhooks";
const secret = "whsec_YOUR_SIGNING_SECRET";
const wh = new Webhook(secret);
// headers from the incoming request
const headers = {
"webhook-id": req.headers["webhook-id"],
"webhook-timestamp": req.headers["webhook-timestamp"],
"webhook-signature": req.headers["webhook-signature"],
};
// IMPORTANT: use the raw request body string, not a parsed/re-serialized object
const payload = req.body;
try {
wh.verify(payload, headers);
// Signature is valid — process the event
} catch (err) {
// Signature verification failed — reject the request
res.status(401).send("Invalid signature");
}Python:
pip install standardwebhooksfrom standardwebhooks import Webhook
secret = "whsec_YOUR_SIGNING_SECRET"
wh = Webhook(secret)
headers = {
"webhook-id": request.headers["webhook-id"],
"webhook-timestamp": request.headers["webhook-timestamp"],
"webhook-signature": request.headers["webhook-signature"],
}
# Use the raw request body bytes
payload = request.body
try:
wh.verify(payload, headers)
# Valid — process the event
except Exception:
# Invalid — reject
passImportant: Always use the raw request body when verifying signatures. Parsing the body as JSON and re-serializing it can alter the content (e.g. whitespace, number formatting), which will cause verification to fail.
Manual Verification
If you prefer not to use the SDK, you can verify signatures manually:
- Extract the
webhook-id,webhook-timestamp, andwebhook-signatureheaders from the request. - Build the signed content string:
${webhook-id}.${webhook-timestamp}.${body}(wherebodyis the raw request body). - Decode the base64 portion of your signing secret (the part after
whsec_). - Compute the HMAC-SHA256 of the signed content using the decoded secret.
- Base64-encode the result and compare it to the signature value (the part after
v1,in the header) using a constant-time comparison. - Optionally, reject requests where the
webhook-timestampis more than 5 minutes from the current time to prevent replay attacks.
Delivery & Retries
The CFX Platform operates on an at-least-once delivery guarantee — events are guaranteed to be delivered but may occasionally be sent more than once. Use the webhook-id header to deduplicate events you have already processed.
Automatic Retries
If your endpoint is unavailable, returns a non-2xx HTTP status code, or fails to respond within the timeout window, delivery will be retried automatically using exponential backoff (base 2) for up to 10 attempts.
As a best practice, accept the webhook quickly (return a 200 response), then process the event asynchronously. This avoids timeouts and reduces the chance of unnecessary retries.
Disabled Destinations
If your endpoint consistently fails to accept events (20 consecutive failures), the destination will be automatically disabled and further events will be discarded. You can re-enable the destination from the webhook settings page once the issue is resolved.
Payload
All webhook events have a consistent JSON payload.
{
"event": "<event code>",
"createdAt": "<ISO timestamp of when the event was generated>",
"data": {
"id": "<ID of the object that has been updated>",
"status": "<The new status of the object>"
}
}If the event is relevant to an Identity or Organization, additional fields are available at the root of the structure: identityId and identityReferenceId (or organizationId and organizationReferenceId).
The data field varies per event and is documented for each one below.
That said, most events carry only id and status. The expected integration pattern is to perform a GET operation on the given resource to get the latest data for that resource, when a new event arrives. This is to protect consumers from out-of-order delivery issues and ensure they are always working with the latest information about an object.
Events
The CFX Platform publishes the following 41 events.
Entity scopes records which entity reference pair an event may carry at the root of the envelope. An event scoped to identity may arrive with identityId and identityReferenceId; one scoped to organization with organizationId and organizationReferenceId. At most one pair is ever present, and an event may arrive with neither.
event | Description | Entity scopes | Read the current state |
|---|---|---|---|
account.depositMemo.created | A deposit memo has been created against a ledger account. | identity, organization | Get an identity deposit memo, Get an organization deposit memo |
account.depositMemo.deleted | A deposit memo has been deleted. | identity, organization | Get an identity deposit memo, Get an organization deposit memo |
account.ledgerAccount.balanceUpdated | A ledger account's balance has changed. | identity, organization | Get a ledger account |
account.ledgerAccount.created | A ledger account has been opened. | identity, organization | Get a ledger account |
account.ledgerAccount.statusUpdated | A ledger account has changed status. | identity, organization | Get a ledger account |
account.virtualAccount.created | A virtual account has been requested. | identity, organization | Get a virtual account |
account.virtualAccount.statusUpdated | A virtual account has changed status. | identity, organization | Get a virtual account |
card.cardTransaction.statusUpdated | A card transaction has changed status. | None | N/A |
deposit.cashRequest.statusUpdated | A cash deposit request has changed status. | identity, organization | Get a cash deposit request |
deposit.deposit.created | A deposit has been created. | identity, organization | Get a deposit |
deposit.deposit.statusUpdated | A deposit has changed status. | identity, organization | Get a deposit |
deposit.manualMint.created | A manual mint has been created. | None | N/A |
deposit.manualMint.statusUpdated | A manual mint has changed status. | None | N/A |
entity.document.deleted | A document belonging to an identity or organization has been deleted. | identity, organization | Get an identity document, Get an organization document |
entity.document.uploaded | A document has been uploaded for an identity or organization. | identity, organization | Get an identity document, Get an organization document |
escrow.escrowTransfer.statusUpdated | An escrow transfer has changed status. | identity | Get an escrow transfer |
identity.identity.statusUpdated | An identity has changed status. | identity, organization | Get an identity |
identity.verification.statusUpdated | One of an identity's verification checks has been resolved. | identity, organization | Get an identity |
ledger.account.transfer.statusUpdated | A transfer between ledger accounts has changed status. | identity, organization | Get a transfer |
organization.organization.created | An organization has been created. | None | Get an organization |
organization.organization.statusUpdated | An organization has changed status. | None | Get an organization |
organization.relatedPerson.created | A related person has been added to an organization. | identity, organization | Get a related person |
organization.relatedPerson.deleted | A related person has been removed from an organization. | identity, organization | Get a related person |
organization.relatedPerson.statusUpdated | A related person has changed verification status. | identity, organization | Get a related person |
organization.relatedPerson.updated | A related person's details have changed. | identity, organization | Get a related person |
paymentInstrument.afBank.statusUpdated | An African bank account payment instrument has changed status. | identity, organization | Get an identity payment instrument, Get an organization payment instrument |
paymentInstrument.afMomo.statusUpdated | An African mobile money payment instrument has changed status. | identity, organization | Get an identity payment instrument, Get an organization payment instrument |
paymentInstrument.externalUsAch.statusUpdated | An external US ACH payment instrument has changed status. | identity, organization | Get an identity payment instrument, Get an organization payment instrument |
paymentInstrument.mxClabe.statusUpdated | A Mexican CLABE payment instrument has changed status. | identity, organization | Get an identity payment instrument, Get an organization payment instrument |
paymentInstrument.networkWallet.statusUpdated | A network wallet payment instrument has changed status. | identity, organization | Get an identity payment instrument, Get an organization payment instrument |
paymentInstrument.swiftWire.statusUpdated | A SWIFT wire payment instrument has changed status. | identity, organization | Get an identity payment instrument, Get an organization payment instrument |
paymentInstrument.usAch.statusUpdated | A US ACH payment instrument has changed status. | identity, organization | Get an identity payment instrument, Get an organization payment instrument |
paymentInstrument.usInstant.statusUpdated | A US instant payment instrument has changed status. | identity, organization | Get an identity payment instrument, Get an organization payment instrument |
paymentInstrument.usWire.statusUpdated | A US wire payment instrument has changed status. | identity, organization | Get an identity payment instrument, Get an organization payment instrument |
paymentInstrument.wallet.statusUpdated | A wallet payment instrument has changed status. | identity, organization | Get an identity payment instrument, Get an organization payment instrument |
reward.reward.claimed | A reward has been claimed. | identity, organization | Get a reward |
reward.reward.created | A reward has been issued. | None | Get a reward |
swap.swap.statusUpdated | A swap has changed status. | identity, organization | Get a swap |
withdrawal.positivePayDecision.created | An inbound ACH debit on one of your accounts is waiting for a positive pay decision. | identity, organization | Get a positive pay decision |
withdrawal.positivePayDecision.statusUpdated | A positive pay decision was confirmed, or sent to the bank. | identity, organization | Get a positive pay decision |
withdrawal.withdrawal.statusUpdated | A withdrawal has changed status. | identity, organization | Get a withdrawal |
Event payloads
The data field of each event, given as a TypeScript type. A ? marks a field that is present only in some cases.
account.depositMemo.created
account.depositMemo.createdA deposit memo has been created against a ledger account.
data.id is the memo itself, not a prefixed identifier.
data: {
id: string;
}account.depositMemo.deleted
account.depositMemo.deletedA deposit memo has been deleted.
data.id is the memo itself. The memo is retired and will no longer be matched against incoming funds.
data: {
id: string;
}account.ledgerAccount.balanceUpdated
account.ledgerAccount.balanceUpdatedA ledger account's balance has changed.
data.balance is a decimal string, not a number — parse it with an arbitrary-precision library rather than a float.
data: {
id: string;
balance: string;
}account.ledgerAccount.created
account.ledgerAccount.createdA ledger account has been opened.
data: {
id: string;
}account.ledgerAccount.statusUpdated
account.ledgerAccount.statusUpdatedA ledger account has changed status.
data: {
id: string;
}account.virtualAccount.created
account.virtualAccount.createdA virtual account has been requested.
PENDING at creation — provisioning with the partner bank completes asynchronously, and the outcome arrives as account.virtualAccount.statusUpdated.
data: {
id: string;
status: "PENDING" | "ACTIVE" | "FAILED" | "INACTIVE";
}account.virtualAccount.statusUpdated
account.virtualAccount.statusUpdatedA virtual account has changed status.
data.reason is present only on a failure.
data: {
id: string;
status: "PENDING" | "ACTIVE" | "FAILED" | "INACTIVE";
reason?: string;
}card.cardTransaction.statusUpdated
card.cardTransaction.statusUpdatedA card transaction has changed status.
data: {
id: string;
status:
| "PENDING"
| "AUTHORIZED"
| "COMPLETED"
| "CLEARED"
| "REVERSED"
| "DECLINED"
| "FAILED"
| "CANCELLED";
}deposit.cashRequest.statusUpdated
deposit.cashRequest.statusUpdatedA cash deposit request has changed status.
data.amount.amount is a number here, unlike the decimal strings used elsewhere.
data: {
status:
| "CREATED"
| "PENDING"
| "CONSUMED"
| "CANCELLED"
| "DECLINED"
| "EXPIRED"
| "VOIDED";
cashDepositRequestId: string;
cashDepositRequestReference: string;
cashDepositTransactionReference?: string;
amount?: {
currency: string;
amount: number;
};
}deposit.deposit.created
deposit.deposit.createdA deposit has been created.
data.addenda, data.companyEntryDescription and data.companyDiscretionaryData are ACH_CREDIT-only — they are lifted off the inbound NACHA entry, and each appears only when the bank reported it.
data: {
depositId: string;
depositReference: string;
type: "US_WIRE" | "US_BANK_ACH" | "CASH" | "SWIFT_WIRE" | "RTP" | "ACH_CREDIT";
status: "PENDING" | "CANCELLED" | "PROCESSING" | "DEPOSITED";
addenda?: string;
companyEntryDescription?: string;
companyDiscretionaryData?: string;
ffcMemo?: string;
sendingFI?: {
code: string;
name: string;
};
originatorInfo?: string;
originatorAddressLine1?: string;
originatorAddressLine2?: string;
originatorAddressLine3?: string;
originatingFI?: string;
}deposit.deposit.statusUpdated
deposit.deposit.statusUpdatedA deposit has changed status.
data.addenda, data.companyEntryDescription and data.companyDiscretionaryData are ACH_CREDIT-only — they are lifted off the inbound NACHA entry, and each appears only when the bank reported it. For a US_BANK_ACH deposit, PROCESSING means the funds were received. An ACH return during the hold window that follows moves it to CANCELLED.
data: {
depositId: string;
depositReference: string;
type: "US_WIRE" | "US_BANK_ACH" | "CASH" | "SWIFT_WIRE" | "RTP" | "ACH_CREDIT";
status: "PENDING" | "CANCELLED" | "PROCESSING" | "DEPOSITED";
addenda?: string;
companyEntryDescription?: string;
companyDiscretionaryData?: string;
ffcMemo?: string;
sendingFI?: {
code: string;
name: string;
};
originatorInfo?: string;
originatorAddressLine1?: string;
originatorAddressLine2?: string;
originatorAddressLine3?: string;
originatingFI?: string;
}deposit.manualMint.created
deposit.manualMint.createdA manual mint has been created.
data: {
id: string;
}deposit.manualMint.statusUpdated
deposit.manualMint.statusUpdatedA manual mint has changed status.
data: {
id: string;
status: "CREATED" | "PROCESSING" | "COMPLETED" | "FAILED";
}entity.document.deleted
entity.document.deletedA document belonging to an identity or organization has been deleted.
data: {
id: string;
type:
| "BANK_STATEMENT_DOCUMENT"
| "OPERATING_LICENSE_DOCUMENT"
| "SOURCE_OF_FUNDS_DOCUMENT"
| "BUSINESS_REGISTRATION_DOCUMENT"
| "ADDRESS_PROOF_DOCUMENT"
| "FRAUD_CHECK_DOCUMENT"
| "BANK_ACCOUNT_DETAILS"
| "OTHER"
| "PASSPORT"
| "DRIVER_LICENSE"
| "NATIONAL_ID"
| "ID_CARD"
| "VOTER_ID_CARD"
| "RESIDENT_CARD"
| "VISA_DOCUMENT"
| "USER_SELFIE"
| "USER_SELFIE_VIDEO"
| "TAX_CERTIFICATE"
| "CHAMBER_OF_COMMERCE_CERTIFICATE"
| "CAC_CERTIFICATE"
| "ARTICLES_OF_INCORPORATION"
| "AML_POLICY"
| "FINANCIAL_CONDUCT_AUTHORITY_AUTHORIZATION"
| "DIRECTORS_REGISTRY"
| "CORPORATE_CHART"
| "SHAREHOLDERS_REGISTRY"
| "BALANCE_SHEET"
| "REPORTING_ENTITY_REGISTRATION_DOCUMENT"
| "COMPANY_CONSTITUTION"
| "MEMORANDUM_OF_ASSOCIATION"
| "PARTNERSHIP_DEED"
| "CERTIFIED_ANNUAL_RETURNS_STATEMENT"
| "COMPANY_PROFILE"
| "AUDITED_ACCOUNTS"
| "ANTI_BRIBERY_POLICY"
| "DATA_PROTECTION_POLICY"
| "INVOICE"
| "PEP_FORM";
}entity.document.uploaded
entity.document.uploadedA document has been uploaded for an identity or organization.
data: {
id: string;
type:
| "BANK_STATEMENT_DOCUMENT"
| "OPERATING_LICENSE_DOCUMENT"
| "SOURCE_OF_FUNDS_DOCUMENT"
| "BUSINESS_REGISTRATION_DOCUMENT"
| "ADDRESS_PROOF_DOCUMENT"
| "FRAUD_CHECK_DOCUMENT"
| "BANK_ACCOUNT_DETAILS"
| "OTHER"
| "PASSPORT"
| "DRIVER_LICENSE"
| "NATIONAL_ID"
| "ID_CARD"
| "VOTER_ID_CARD"
| "RESIDENT_CARD"
| "VISA_DOCUMENT"
| "USER_SELFIE"
| "USER_SELFIE_VIDEO"
| "TAX_CERTIFICATE"
| "CHAMBER_OF_COMMERCE_CERTIFICATE"
| "CAC_CERTIFICATE"
| "ARTICLES_OF_INCORPORATION"
| "AML_POLICY"
| "FINANCIAL_CONDUCT_AUTHORITY_AUTHORIZATION"
| "DIRECTORS_REGISTRY"
| "CORPORATE_CHART"
| "SHAREHOLDERS_REGISTRY"
| "BALANCE_SHEET"
| "REPORTING_ENTITY_REGISTRATION_DOCUMENT"
| "COMPANY_CONSTITUTION"
| "MEMORANDUM_OF_ASSOCIATION"
| "PARTNERSHIP_DEED"
| "CERTIFIED_ANNUAL_RETURNS_STATEMENT"
| "COMPANY_PROFILE"
| "AUDITED_ACCOUNTS"
| "ANTI_BRIBERY_POLICY"
| "DATA_PROTECTION_POLICY"
| "INVOICE"
| "PEP_FORM";
}escrow.escrowTransfer.statusUpdated
escrow.escrowTransfer.statusUpdatedAn escrow transfer has changed status.
CREATED means the sender's funds are held in escrow. CLAIMED is the only status that releases them to the recipient; CANCELLED, REJECTED and EXPIRED return them to the sender. FAILED means funding failed and no funds were held. The intermediate step that attaches the recipient is not published.
data: {
id: string;
status: "CREATED" | "CLAIMED" | "CANCELLED" | "REJECTED" | "EXPIRED" | "FAILED";
}identity.identity.statusUpdated
identity.identity.statusUpdatedAn identity has changed status.
data: {
id: string;
status:
| "PENDING_VERIFICATION"
| "ACTIVE"
| "REVIEW"
| "DISABLED"
| "BLOCKED"
| "DELETED";
}identity.verification.statusUpdated
identity.verification.statusUpdatedOne of an identity's verification checks has been resolved.
The two type values are independent checks and each reports its own status; an identity is not fully verified until both are APPROVED.
data: {
type: "AML" | "IDENTITY_DOCUMENT";
status: "PENDING" | "APPROVED" | "REVIEW" | "DECLINED";
}ledger.account.transfer.statusUpdated
ledger.account.transfer.statusUpdatedA transfer between ledger accounts has changed status.
data: {
id: string;
status: "PENDING" | "SUCCEEDED" | "FAILED" | "CANCELLED";
}organization.organization.created
organization.organization.createdAn organization has been created.
data: {
id: string;
status: "PENDING_VERIFICATION" | "ACTIVE" | "DISABLED";
}organization.organization.statusUpdated
organization.organization.statusUpdatedAn organization has changed status.
data: {
id: string;
status: "PENDING_VERIFICATION" | "ACTIVE" | "DISABLED" | "DELETED";
}organization.relatedPerson.created
organization.relatedPerson.createdA related person has been added to an organization.
data: {
id: string;
type: "CONTROL" | "BENEFICIAL_OWNER";
}organization.relatedPerson.deleted
organization.relatedPerson.deletedA related person has been removed from an organization.
data: {
id: string;
}organization.relatedPerson.statusUpdated
organization.relatedPerson.statusUpdatedA related person has changed verification status.
data: {
id: string;
type: "CONTROL" | "BENEFICIAL_OWNER";
status: "PENDING_VERIFICATION" | "ACTIVE" | "REVIEW" | "BLOCKED";
}organization.relatedPerson.updated
organization.relatedPerson.updatedA related person's details have changed.
data: {
id: string;
type: "CONTROL" | "BENEFICIAL_OWNER";
}paymentInstrument.afBank.statusUpdated
paymentInstrument.afBank.statusUpdatedAn African bank account payment instrument has changed status.
data: {
id: string;
status: "PENDING_VERIFICATION" | "ACTIVE" | "BLOCKED" | "DELETED";
}paymentInstrument.afMomo.statusUpdated
paymentInstrument.afMomo.statusUpdatedAn African mobile money payment instrument has changed status.
data: {
id: string;
status: "PENDING_VERIFICATION" | "ACTIVE" | "BLOCKED" | "DELETED";
}paymentInstrument.externalUsAch.statusUpdated
paymentInstrument.externalUsAch.statusUpdatedAn external US ACH payment instrument has changed status.
data: {
id: string;
status: "PENDING_VERIFICATION" | "ACTIVE" | "BLOCKED" | "DELETED";
}paymentInstrument.mxClabe.statusUpdated
paymentInstrument.mxClabe.statusUpdatedA Mexican CLABE payment instrument has changed status.
data: {
id: string;
status: "PENDING_VERIFICATION" | "ACTIVE" | "BLOCKED" | "DELETED";
}paymentInstrument.networkWallet.statusUpdated
paymentInstrument.networkWallet.statusUpdatedA network wallet payment instrument has changed status.
data: {
id: string;
status: "PENDING_VERIFICATION" | "ACTIVE" | "BLOCKED" | "DELETED";
}paymentInstrument.swiftWire.statusUpdated
paymentInstrument.swiftWire.statusUpdatedA SWIFT wire payment instrument has changed status.
data: {
id: string;
status: "PENDING_VERIFICATION" | "ACTIVE" | "BLOCKED" | "DELETED";
}paymentInstrument.usAch.statusUpdated
paymentInstrument.usAch.statusUpdatedA US ACH payment instrument has changed status.
data: {
id: string;
status: "PENDING_VERIFICATION" | "ACTIVE" | "BLOCKED" | "DELETED";
}paymentInstrument.usInstant.statusUpdated
paymentInstrument.usInstant.statusUpdatedA US instant payment instrument has changed status.
data: {
id: string;
status: "PENDING_VERIFICATION" | "ACTIVE" | "BLOCKED" | "DELETED";
}paymentInstrument.usWire.statusUpdated
paymentInstrument.usWire.statusUpdatedA US wire payment instrument has changed status.
data: {
id: string;
status: "PENDING_VERIFICATION" | "ACTIVE" | "BLOCKED" | "DELETED";
}paymentInstrument.wallet.statusUpdated
paymentInstrument.wallet.statusUpdatedA wallet payment instrument has changed status.
data: {
id: string;
status: "PENDING_VERIFICATION" | "ACTIVE" | "BLOCKED" | "DELETED";
}reward.reward.claimed
reward.reward.claimedA reward has been claimed.
data: {
id: string;
status: "PENDING" | "CLAIMED" | "RETURNED";
reward: {
amount: {
amount: string;
currency: "MOVEUSD";
};
};
}reward.reward.created
reward.reward.createdA reward has been issued.
data.idempotencyKey is the key supplied when the reward was created, so a consumer can correlate the event with its own request.
data: {
id: string;
transactionType: "DEBIT" | "CREDIT";
amount: {
amount: string;
currency: "MOVEUSD";
};
phone: string;
idempotencyKey: string;
category?: string;
note?: string;
createdAt: string;
}swap.swap.statusUpdated
swap.swap.statusUpdatedA swap has changed status.
data.quote is present once a quote has been attached to the swap.
data: {
id: string;
status: "CREATED" | "PENDING" | "COMPLETED" | "FAILED";
quote?: {
id: string;
status: "ACTIVE" | "ACCEPTED" | "REJECTED" | "EXPIRED";
source: {
amount: string;
amountAfterFees: string;
currency: "MOVEUSD" | "USDC" | "SOL" | "WETH" | "WBTC";
wallet: {
chain: "SOLANA";
address: string;
};
};
target: {
amount: string;
amountAfterFees: string;
currency: "MOVEUSD" | "USDC" | "SOL" | "WETH" | "WBTC";
wallet: {
chain: "SOLANA";
address: string;
};
};
fees: {
cfxFixedFee: {
amount: string;
currency: "MOVEUSD" | "USDC" | "SOL" | "WETH" | "WBTC";
};
cfxVariableFee: {
amount: string;
currency: "MOVEUSD" | "USDC" | "SOL" | "WETH" | "WBTC";
};
providerFixedFee: {
amount: string;
currency: "MOVEUSD" | "USDC" | "SOL" | "WETH" | "WBTC";
};
providerVariableFee: {
amount: string;
currency: "MOVEUSD" | "USDC" | "SOL" | "WETH" | "WBTC";
};
customerFixedFee: {
amount: string;
currency: "MOVEUSD" | "USDC" | "SOL" | "WETH" | "WBTC";
};
customerVariableFee: {
amount: string;
currency: "MOVEUSD" | "USDC" | "SOL" | "WETH" | "WBTC";
};
};
productQuoteId: string;
expiresAt: string;
createdAt: string;
updatedAt: string;
};
}withdrawal.positivePayDecision.created
withdrawal.positivePayDecision.createdAn inbound ACH debit on one of your accounts is waiting for a positive pay decision.
Approve or deny it before data.decisionDeadline. An undecided debit is returned to its originator.
data: {
positivePayDecisionId: string;
amount: string;
presentedOn: string;
decisionDeadline: string;
}withdrawal.positivePayDecision.statusUpdated
withdrawal.positivePayDecision.statusUpdatedA positive pay decision was confirmed, or sent to the bank.
data.submitted is true once the decision is in the file sent to the bank.
data: {
positivePayDecisionId: string;
status: "PENDING" | "APPROVED" | "DENIED";
submitted: boolean;
}withdrawal.withdrawal.statusUpdated
withdrawal.withdrawal.statusUpdatedA withdrawal has changed status.
data: {
withdrawalId: string;
status: "CREATED" | "PENDING" | "COMPLETED" | "FAILED" | "RETURNED";
type:
| "MX_SPEI"
| "US_WIRE_DRAWDOWN"
| "US_ACH"
| "US_INSTANT"
| "SWIFT_WIRE"
| "US_WIRE"
| "AF_WITHDRAWAL"
| "ACH_PULL"
| "BLOCKCHAIN";
}Updated 6 days ago
