Transaction Decisioning
Since all Subnet transactions are not originated through your platform, developers like to have higher level of control on transactions settling into user accounts. Especially withdrawals.
For that reason, we enable higher level of control on Subnet withdrawals, to address three needs:
Ability to Pass/Fail a transaction based some custom criteria built on your side.
Ability to fund the transaction through one or more accounts (funding nodes) at the time of transaction decisioning, not before.
Additional ability to fund a pre-auth approved transaction to safe guard against variable final total amounts (example tip on a restaurant bill).
If the network allows, only approve a transaction partially.
We also enable decisioning for incoming card based credits, but with stricter criteria:
The transaction can not be a cash deposit.
You can only Pass/Fail the transaction. You can not pass funding nodes or partial approval amounts.
Must not be a force post transaction.
Set up
Transaction Decisioning is handled via a webhook request response flow. To enable an endpoint to receive a webhook when a Subnet withdrawal transaction is received, create a subscription with TRANS|POST|JIT
scope. So something like this:
To make the most of Transaction Decisioning (JIT), you will need to build out the appropriate logic on the platform side (e.g. restrict by transaction type, merchant profile, MCC, or other logic). Please review Meta Schema of RDFI ACH and Meta Schema of Card Transactions to find all the information we return.
Decisioning
To be able to decision a transaction, you need to respond in the following format:
Field | Type | Required | Description |
| String | Yes | Supply |
| String | No | Node ID where the supplied amount should be funded from. Not supported for credits. |
| Number | No | The amount that needs to be taken out of the supplied node id. Not supported for credits. |
| Number | No | Total amount approved for the transaction. Can be lower than the amount on transaction if partial approval is allowed. Not supported for credits |
| String | No | In a pre-auth scenario, if there is a remaining balance, the remainder will be taken from the node(s) defined here. Not supported for credits. |
Basic Transaction Decisioning
Upon receiving a supported subnet transaction, we will notify you via the TRANS|POST|JIT
webhook url. Your response will indicate to us whether to allow ({"decision": "PASS"}
) or deny ({"decision": "FAIL"}
) the transaction.
If the transaction is approved (PASS), then funds can be pulled directly from the account that the subnet sits on top of.
Example Payloads
or
Funding via Multiple Accounts (Withdrawal only)
If you wish to fund the transaction from an account other than the account the subnet sits on top of, then you can pull funds directly from one or more funding nodes (either user or platform accounts) specified in the response.
If funding for the transaction comes from multiple accounts (listed in the
funding_nodes
array supplied in the response), then you must both specify the exactamount
to be pulled from each node and ensure that the overall transaction'stotal_amount
field equals the sum of the amounts pulled from each funding node. If both of these criteria are not met, the transaction will silently fail.Please also note that providing an invalid
node_id
for any of the listed funding nodes will also cause the transaction to silently fail.
Example Payloads
Single Node Funding
Multiple Funding Nodes via JIT
Pre-Auth with Additional Funding (Withdrawal only)
The additional_funding nodes deduction only occurs if the total_amount increased and does nothing if the total_amount decreases.
Partial Approval (Withdrawal only)
If using Partial Approval, the response will need to also supply the partially approved transaction's total_amount
. If a transaction can be partially approved, you will see to.meta.partial_approval_allowed
set to True. Go to Meta Schema of Card Transactions to learn more.
Testing
To be able to test Transaction Decisioning on UAT, you will need to be able to create fake subnet transactions. For card subnets, you can do that with Virtual Terminal. While for account number subnets, you can do that with Dummy Transactions API calls.
Important Considerations
Following are some things to be mindful of while building with Transaction Decisioning:
Funding Outcome
Transaction will still settle if there are insufficient funds. However, if there are insufficient funds and another cancel reason it will fail.
Timely Response Considerations
Upon being notified of a new transaction request by the TRANS|POST|JIT
webhook you will need to perform your custom transaction logic, provide funding (if using Instant Auth), and provide a response within 1.00 seconds, or else the transaction will follow the default path of decisioning, in other words, as if JIT did not exist.
Negative Balance Considerations
Funding from other nodes does not perform balance checks on the nodes due to the timely response considerations mentioned above (i.e. response required within 1.00s), meaning that use of this feature with a funding node that has insufficient funds to cover a transaction will make that node's balance go negative.
It is your responsibility to both perform periodic balance checks and to maintain an estimate of funding node balances to avoid this (i.e. to have a reasonable expectation that a funding node can cover a transaction before allowing it).
Debit Card Cashback Considerations
Consider how to handle transactions with a debit card cashback component (e.g. from a user who took a cash disbursement along with their purchase at a retail register). This information should be provided in the webhook's transaction request notification (e.g. {"type": "PURCHASE_WITH_CASH_DISBURSEMENT"}
with sub_amounts
array containing {"amount_type": "AMOUNT_CASH"}
). You can either approve the full transaction amount, provide Partial Approval only for the purchased goods, or deny the transaction.
KYC Considerations
We will perform basic account and user KYC checks (e.g. making sure the user has SEND-AND-RECEIVE
permissions and that the user watchlists
flag is not a MATCH
) prior to ever issuing a request from the TRANS|POST|JIT
webhook. This means that you should not receive requests from users who are unable to transact.
Incoming card credits
When we receive an incoming card based credit transaction (Examples: CashApp or Venmo transfers), we will generate a webhook for these transactions. This allows you to control if and when you allow users to do things like transfer funds from a CashApp account to their Synapse account. Any transaction that involves a CASH deposit will not generate a webhook. Refund transactions and any others that might be force posts also will not generate a webhook as those can not be refused. Not responding to these webhooks at all, or not responding within the expected time frame, will allow the transaction to be deposited like normal.
Last updated