Card Issuing
Real-time Decisioning
Column allows your platform to make card authorization decisions in real-time. When Column receives authorization requests from the card networks, the Bank will send a webhook to your system and await a decision. This functionality can be used in conjunction with Column's authorization policy API to ensure only permitted transactions are approved.
Decisioning Flow
When an approval request is received by Column from the card networks, the following approval process is followed:
- Column will match the request to a Card & Card Account in the system. If Column cannot resolve the request to a card, it is automatically declined. If your platform is allocated an entire BIN, Column can send an event webhook when an authorization is declined due to an invalid account number on your behalf.
- Column will check the status of the Card & Card Account, and if the status is not active, Column will decline the transaction with the appropriate decline code and send your system an event webhook.
- Column checks the account type, address verification (AVS) results, and currency of the request, and declines the transaction if any of these checks fail.
- Column evaluates any authorization policies configured by your system using the Authorization Policy API. If a policy is triggered, Column will decline the transaction on your behalf and send an event webhook.
- Column performs fraud checks on the request.
- Column will perform a balance check to ensure sufficient funds are available, if not, the transaction will be declined, and an event webhook will be sent to your system. Note: alternate funding models such as Just-in-time or transfer upon approval can be configured, please reach out to design a flow of funds if these models are needed.
- Column will send a Real-time decision webhook to your system and will wait a total of 3 seconds for a response. If no response or an invalid response is received, Column will decline the transaction.
Note: all decisioning information is included in the decisioning_details struct in the Card Transaction Event.
Webhook Setup
To enroll an endpoint to receive real-time decisioning events the existing webhook endpoints API can be used with
the specific event type of decision.issuing.card_transaction. Real-time decisioning events will have the same
Column-Signature header that can be used to validate the request originated from Column.
It is recommended to use a different endpoint for real-time decisioning that is optimized for latency since there is a 3-second deadline for responses.
The endpoint must return the real-time decision response shape, such as a decision value of approve, decline, or
partially_approve. Responses that do not include a recognized decision value are treated as invalid and Column will
decline the authorization. If you are using the local example webhook server, register the authorization route
/webhooks/cards/authorizations for this event type. This route is distinct from the token provisioning routes, such as
/webhooks/cards/tokens.
Note: if your system fails to respond to a real-time decisioning request, Column will not retry the request and decline
the authorization. Column also has a deadline to respond to the card networks, and it does not provide sufficient time for
retries. Column will send a webhook to notify you of the decline, and the decision_reason in decisioning_details
indicates what went wrong:
realtime_authorization_endpoint_missingdecision.issuing.card_transaction.realtime_authorization_request_timeoutrealtime_authorization_connection_errorrealtime_authorization_invalid_responsedecision value or an invalid partial approval.errordecision_source is platform_owner.Real-time Decision Object
The real-time decision object contains the fields card_transaction, proposed_event, and, when Column has computed the
card account's balance, available_balance. If the decision relates to a new transaction, the transaction and proposed
event will both be created after the response is returned. If the decision relates to an existing event (for example, the
request is for an incremental auth), the card_transaction will contain the existing card transaction, and the proposed
event will be appended to the existing transaction.
3DS Authentication Decisioning
You can also make real-time decisions during 3DS authentication, before a challenge is shown. Subscribe a webhook endpoint
to decision.issuing.card_authentication. Column sends the
3DS authentication decision request to that
endpoint with the authentication attempt and available network context. Return a
3DS authentication decision response with
one of these decisions:
frictionless_approverecommends that the network's risk system authenticate without a cardholder challenge.challengeproceeds to a cardholder challenge.decline_authenticationrejects the authentication. You may returndecline_reasonassuspected_fraudortransaction_not_permitted; Column defaults tosuspected_fraudwhen the reason is omitted.
Column waits up to 1 second for a valid response. A timeout, connection error, non-success response, or invalid response
fails safe to challenge. This differs from card authorization decisioning, which waits up to 3 seconds and declines when
your endpoint does not return a valid decision. Column does not retry either decision request within the network deadline.
frictionless_approve is a recommendation to the network's risk system and might not produce a frictionless result in
every flow. A challenge decision fails authentication if the cardholder has no supported challenge method, such as an
email address on the person entity. Data-only authentications with merchant challenge indicator 06 do not invoke your
decision endpoint.
Sandbox Testing
Call POST /simulate/issuing/cards/:card_id/threeds/challenge in sandbox. Set realtime_decision to exercise a specific
decision without calling your endpoint, and optionally set decline_reason for a declined authentication. Omit
realtime_decision to invoke a sandbox endpoint subscribed to decision.issuing.card_authentication. If no subscribed
endpoint exists, the simulator preserves its default behavior and creates an OTP challenge.
Decline Reasons
If you decide to decline a transaction, you can optionally specify a decline_reason to provide more information to the
merchant who originated the request. Generally, it is best practice and more user-friendly for cardholders to include a
reason for a decline. Additionally, some card networks assess additional fees if general decline codes are used.
If a reason isn't specified in the real-time decision response, Column will return a generic "do not honor" response code.
Partial Approvals
Some card networks and merchants support partial approvals. This allows your platform to approve a subset of the requested amount. An example of this is if a debit card had a remaining balance of $10 but is used to purchase a $50 item. If you opt to partially approve $10, the merchant will apply $10 and then request an alternate form of payment for the remaining $40.
In the real-time decisioning request, the field can_support_partial_approvals field indicates whether the merchant supports
partial approvals. You can then return the decision choice of partially_approve with an amount set in partially_approve_amount.
If your system returns partially_approve when it is unsupported, without an amount, with a zero amount, or with an amount
greater than the requested amount, Column will decline the transaction with the realtime_authorization_invalid_response
reason. A partially_approve response with an amount equal to the requested amount is recorded as a partial approval of
the full amount.
Partial approvals are not supported for incremental authorizations or reauthorizations. Column declines a
partially_approve response to those requests with the realtime_authorization_invalid_response reason.
For automated fuel dispenser transactions that support partial approvals, if the card account's available balance is lower
than the requested amount, Column limits the proposed event to the available balance before sending the real-time decision
request instead of declining for insufficient funds. Respond with partially_approve (or decline) in this case; an
approve response is declined with the realtime_authorization_invalid_response reason.