Payments status updates

Webhook events triggered by a payments status update.

Platforms leveraging Zero Hash’s payments product should subscribe to webhooks to know when payments statuses have changed.

We will send you updates for every status change, including External account status updates. To tell them apart, check Webhook Security.

Note: The x-zh-hook-payload-type to subscribe for is payment_status_changed.

Once a platform is set up to receive payment status webhooks, the payload is a JSON object containing the following fields:

ParameterDescriptionType
participant_codeThe Zero Hash identifier for the customer requesting an ACH transaction.string
typeIndicates if the payment is a credit or a debit for the end customer.string
transaction_idThe unique identifier generated by Zero Hash for the transaction.string
payment_statusThe current status of the payment. See payment statuses below for more.string
reason_codeThe Nacha failure reason code, if the payment_status is returned.string
reason_descriptionThe description matching the reason_code, if the payment_status is returned.string
expected_settlement_dateFor payment type of credit, when the funds are expected to settle to the end customer bank account. This is an approximation as receiving banks are ultimately responsible for posting the update.string; YYYY-MM-DD format
reject_reasonsIf the payment_status is rejected, this object will share reasons why. Example: "error checking account rules: failed"

Payments Statuses

StatusDescription
submittedRequest received and validated
The payment passed the initial checks and was accepted
pendingBalance and authorization confirmed and transaction initialized
The payment was queued internally and will be processed
postedFor bank transfers:
Withdrawn from end customer account and successfully submitted to the network
For blockchain payments:
payment succeeded and was posted to the network, awaiting confirmation from the blockchain
settledFor bank transfers:
Hold period is over and funds have moved to the bank
For blockchain payments:
Withdrawal confirmed on-chain
cancelledTransaction was proactively cancelled
failedTransaction failed during the process
returnedTransaction was returned(reason listed in the reason_code and reason_description of webhook)
rejectedTransaction request blocked for risk mitigation or contractual reasons

Payloads

To differentiate between payloads and what they mean, you will have to mainly rely on the type field for ACH/RTP updates and the payment_type field for Blockchain payments.

ACH debit

{
	"participant_code": "ABC123",
	"type": "debit",
	"transaction_id": "e8641f4b-2098-4f86-95ba-711151cee6a5",
	"payment_status": "settled"
}

ACH credit

{
	"participant_code": "ABC123",
	"type": "credit",
	"transaction_id": "e8641f4b-2098-4f86-95ba-711151cee6a9",
	"payment_status": "posted",
	"expected_settlement_date": "2024-03-01"
}

ACH return

{
	"participant_code": "ABC123",
	"type": "debit",
	"transaction_id": "e8641f4b-2098-4f86-95ba-711151cee6a5",
	"payment_status": "returned",
	"reason_code": "R01",
	"reason_description": "Insufficient funds"
}

Blockchain Payment

{
	"payment_id": "679ee352-7705-4425-ab4a-16a3d18c1d90",
	"obo_participant": {
		"participant_code": "ABC123",
		"account_group": "PLAT01",
		"account_label": "general"
	},
	"payment_details": {
		"withdrawal_request_id": "f32a000e-fd71-42b5-ac03-5b23337aa833",
		"trade_id": "186b3b03-e625-4e3e-a5b1-80f0c43073ce",
		"on_chain_transaction_id": "",
		"network_fee_notional": "2.61",
		"network_fee_quantity": "0.0009883939413915",
		"destination_address": "0x41D9A0Ee3a917Etmn6182C030dC9f15497eCl22V"
	},
	"asset": "USDC",
	"network": "ETH",
	"payment_type": "payout",
	"external_account_id": "2d55c1dd-037d-48d2-9512-13fbea2c85d4",
	"participant_code": "ABC456",
	"quantity": "0",
	"status": "posted",
	"created_at": "2024-09-26T13:05:22.657Z",
	"updated_at": "2024-09-26T13:05:22.657Z",
	"total": "12.34"
}

Status changes

During the lifecycle of a transaction, it can change status. The payload is different as well. Use a combination of type and payment_status to tell them apart:

📘

For ACH on Demand, we'll also provide a trade_status field

Use this field to check the status of both the ACH and the Trade. Visit this page for more information

Payment status submitted

{
	"participant_code": "ABC123",
	"type": "credit",
	"transaction_id": "e8641f4b-2098-4f86-95ba-711151cee6a5",
	"payment_status": "submitted",
	"expected_settlement_date": "2024-10-06",
	"timestamp": 1633456800000,
	"trade_id": "426c739d-c40d-4d18-914b-a79e2a4ea29e",
	"trade_status": "completed"
}

Payment status failed

{
	"participant_code": "ABC123",
	"type": "credit",
	"transaction_id": "e8641f4b-2098-4f86-95ba-711151cee6a5",
	"payment_status": "returned",
	"reason_code": "R99",
	"reason_description": "failed",
	"expected_settlement_date": "2024-10-06",
	"timestamp": 1633456800000,
	"trade_id": "426c739d-c40d-4d18-914b-a79e2a4ea29e",
	"trade_status": "completed"
}

Payment status returned

{
	"participant_code": "ABC123",
	"type": "credit",
	"transaction_id": "e8641f4b-2098-4f86-95ba-711151cee6a5",
	"payment_status": "returned",
	"reason_code": "R01",
	"reason_description": "Insufficient funds",
	"expected_settlement_date": "2024-10-06",
	"timestamp": 1633456800000,
	"trade_id": "426c739d-c40d-4d18-914b-a79e2a4ea29e",
	"trade_status": "completed"
}

Payment status posted

{
	"participant_code": "ABC123",
	"type": "debit",
	"timestamp": 1633456800000,
	"transaction_id": "e8641f4b-2098-4f86-95ba-711151cee6a5",
	"payment_status": "posted"
}

Payment status settled

{
	"participant_code": "ABC123",
	"type": "debit",
	"timestamp": 1633456800000,
	"transaction_id": "e8641f4b-2098-4f86-95ba-711151cee6a5",
	"payment_status": "settled"
}

Payment status rejected

{
	"participant_code": "ABC123",
	"type": "debit",
	"timestamp": 1633456800000,
	"transaction_id": "e8641f4b-2098-4f86-95ba-711151cee6a5",
	"payment_status": "rejected",
	"rejected_reason": "rule",
	"ach_failure_reason": "insufficient funds"
}

Payment status pending_trade

{
	"participant_code": "ABC123",
	"type": "debit",
	"transaction_id": "e8641f4b-2098-4f86-95ba-711151cee6a5",
	"payment_status": "pending_trade",
	"timestamp": 1633456800000,
	"trade_id": "e8641f4b-2098-4f86-95ba-711151cee6a2",
	"trade_status": "terminated"
}

Payment status pending_settlement

{
	"participant_code": "ABC123",
	"type": "debit",
	"transaction_id": "e8641f4b-2098-4f86-95ba-711151cee6a5",
	"payment_status": "retried",
	"timestamp": 1633456800000,
	"trade_id": "e8641f4b-2098-4f86-95ba-711151cee6a2",
	"trade_status": "terminated"
}