Transactions

Overview

A "transaction" in the Synctera platform represents any movement of funds between accounts.

Transactions comes in 2 flavours:

  • Pending transactions
  • Posted transactions

A pending transaction represents a "hold" or "authorization" for the movement of funds in an account. Pending transactions are used whenever we need to
guarantee the availability of funds for any multi-step payment flow. See The Transaction Life-cycle below for an example.

A pending transaction is mutable, meaning that up to the point that the pending transaction is posted or expired, the amount of the hold may be increased, decreased, canceled, or declined. Note that this functionality is not typically exposed directly to integrator, but instead depends on the business logic of the specific payment rail.

Once a transaction is "posted", it is then considered immutable and cannot be changed. Any adjustments (such as a reversal, for example) requires the creation of a new transaction.

Creating Transactions

Transactions can be initiated in a few different ways:

Directly, via the Synctera payment APIs:

Indirectly, via an external payment network:

  • A card transaction at an ATM or point-of-sale.
  • An incoming ACH debit or credit from another bank (such as a direct deposit).

An integrator can subscribe various TRANSACTION webhook events to be notified when a transaction is created or updated, even when the transactions aren't directly initiated by your application.

Anatomy of a Transaction

The full spec for pending and posted transactions is documented in the API reference for Pending Transactions and Posted Transactions respectively, there are several fields worth describing in more detail:

id

The id of a transaction is a unique identifier for a particular payment. This identifier is preserved through the entire life-cycle of a transaction. This means that a pending transaction and its final posted transaction will share the same id.

type

The type of a transaction generally represents the "payment rail" that is being used. For ACH payments this will be ach, which debit card transactions will use card.

subtype

The subtype field represents the specific operation that initiated the transaction. For example, for card transactions, the subtype might be could be atm_withdrawal for taking money out of an ATM, or pos_purchase for any purchase made at a Point-of-Sale system.

effective_date

The effective_date of a transaction represents the time that the transaction should be considered effective for the purposes of interest calculation.

posted_date

📘

This value is specific to posted transactions.

This value represents the current banking day the transaction was initiated on, from the perspective of the sponsor bank. This doesn't always match up with the chronological time. Notably, "banking days" do not include weekends or bank holidays.

As an example, of a payment is made on Friday at 9PM, the effective_date would have the current date/time the transaction was created, while the posted_date would actually be the following Monday.

user_data

The user_data field represents key-value meta-data specific to a given payment rail. For example, transactions with type ach will have a user_data field containing ACH-specific meta-data (ACH return codes, trace numbers, or file names), which card transactions will have card-specific meta-data (merchant codes, etc...). This is not used for arbitrary metadata supplied by a Fintech, see external_data below.

This field is only populated by internal Synctera payment services.

Below is an example of a user_data from an ACH debit transaction that has been sent out to the ACH network (indicated by the file_name field being populated):

{
  "id": 1234,
  "idemkey": "87a964a7-9191-488d-bbb8-b4f9a39578f6",
  "exported": "2022-03-22T16:55:01.60644546Z",
  "file_name": "20220322T165501.596_OUTBOUND.ach",
  "account_id": "7b0ccc9f-957a-4e0b-bc4b-9a3d59c2eef6",
  "account_no": "1234567890",
  "customer_id": "226de0b5-e9b9-48f3-b562-c9bc3b35cd5b",
  "description": "KandaBank",
  "is_same_day": false,
  "trace_number": "601282010001234",
  "reference_info": "This is some reference info",
  "source_account_id": "d23b541b-1fda-4c3f-b44e-3605f2095618",
  "source_account_name": "Alberta Charleson"
}

external_data

The external_data field will include any arbitrary key-value meta-data that you as a Fintech would like to associate with the payment. This is only available for payments initiated directly via one of the Synctera payment APIs (for example, an outgoing ACH payment, or an internal transfer).

risk_info

The risk_info field is used to hold risk analysis details from Synctera's Risk/Fraud service.

This is an example of a risk_info payload where the fraud service has determined that the transaction is not fraudulent:

{
  "accept": true,
  "reasons": ["TRANSACTION_ACCEPTED"],
  "provider": "FEEDZAI",
  "provider_info": {
    "alert": false,
    "score": 0,
    "status": "ok",
    "decision": "approve",
    "action_codes": ["[Transfers-DR6]"],
    "lifecycle_id": "c67c7799-f273-4318-8649-1378e42d64af",
    "sca_required": false,
    "sender_segment": "27",
    "event_external_id": "c67c7799-f273-4318-8649-1378e42d64af",
    "sender_bank_branch_id": "4",
    "secondary_action_codes": []
  },
  "provider_reasons": ["Transfers-DR6"]
}

lines

📘

The lines field is specific to Posted Transactions.

The Synctera Ledger uses a concept called Double-Entry Accounting to help ensure the integrity of all financial operation. This means that every debit or credit to an account must be offset by a corresponding credit or debit to another account. This is represented in the Posted Transaction resource by the data.lines field. This field is an array of (primarily) two accounting entries: A debit from one account, and a credit from another account.

In many cases, only one side of a transaction will represent a real Synctera (customer) account. For example, consider an ACH payment to an external bank, or an ATM withdrawal.

In this case, Synctera uses an internal account, called a settlement account as a proxy to offset the transaction.

Transaction Types and Subtypes

Transactions (both pending and posted) are categorized using a combination of type and subtype fields, as mentioned above.

The set of types and subtypes currently supported by the Synctera ledger are documented below:

TypeSubtypeD/C to originating party
achincoming_creditCredit
achincoming_credit_contested_returnCredit
achincoming_credit_dishonored_returnCredit
achincoming_credit_returnCredit
achincoming_credit_reversalDebit
achincoming_debitDebit
achincoming_debit_contested_returnDebit
achincoming_debit_dishonored_returnDebit
achincoming_debit_returnDebit
achincoming_debit_reversalCredit
achoutgoing_creditDebit
achoutgoing_credit_contested_returnDebit
achoutgoing_credit_dishonored_returnDebit
achoutgoing_credit_returnDebit
achoutgoing_credit_reversalCredit
achoutgoing_debitCredit
achoutgoing_debit_contested_returnCredit
achoutgoing_debit_dishonored_returnCredit
achoutgoing_debit_returnCredit
achoutgoing_debit_reversalDebit
achtemp_holdDebit
cardauthDebit
cardauth_atm_withdrawalDebit
cardauth_quasi_cashDebit
cardpindebit_authDebit
cardauth_cashbackCredit
cardauth_incrementalCredit
cardauth_clearingDebit
cardauth_clearing_atm_withdrawalDebit
cardauth_clearing_quasi_cashDebit
cardpindebit_auth_clearingDebit
cardauth_adviceDebit
cardauth_reversalCredit
cardpindebit_auth_reversalCredit
cardoc_auth_reversalCredit
cardrefund_auth_reversalCredit
cardrefundCredit
cardpindebit_refundCredit
cardrefund_auth_clearingCredit
cardpindebit_reversalCredit
cardbalance_inquiryDebit
cardpindebit_balance_inquiryDebit
cardpindebitDebit
cardpindebit_atm_withdrawalDebit
cardpindebit_cashbackCredit
cardpindebit_quasi_cashDebit
cardoc_authDebit
cardoc_auth_clearingDebit
cardoc_auth_captureDebit
cardpindebit_refund_reversalDebit
cardrefund_authCredit
cardcard_transactionDebit
cardpos_purchaseDebit
cardatm_withdrawalDebit
cardpos_cashbackCredit
cardcreditCredit
cardpos_refundCredit
cardpos_purchase_refundCredit
cardprovisional_creditCredit
cardcard_network_first_chargebackCredit
cardcard_network_final_chargebackCredit
cardprovisional_credit_reversalDebit
checkmobile_depositCredit
checkmobile_deposit_reversalDebit
checkmobile_deposit_returnDebit
checkmobile_deposit_return_reversalCredit
external_cardcard_fundingCredit
external_cardcard_funding_reversalDebit
external_cardcard_sendDebit
external_cardcard_send_reversalCredit
internal_transferaccount_decrease_limitDebit
internal_transferaccount_decrease_limit_reversalCredit
internal_transferaccount_increase_limitCredit
internal_transferaccount_increase_limit_reversalDebit
internal_transferaccount_to_accountDebit
internal_transferaccount_to_account_reversalCredit
internal_transferach_credit_sweepDebit
internal_transferach_credit_sweep_reversalCredit
internal_transferach_debit_sweepCredit
internal_transferach_debit_sweep_reversalDebit
internal_transfercashbackDebit
internal_transfercashback_reversalCredit
internal_transferfeeDebit
internal_transferfee_reversalCredit
internal_transferincoming_wireCredit
internal_transferincoming_wire_reversalDebit
internal_transferinterest_payoutCredit
internal_transferinterest_payout_reversalDebit
internal_transferjit_fundDebit
internal_transferjit_fund_reversalCredit
internal_transferloc_usageDebit
internal_transferloc_usage_reversalCredit
internal_transfermanual_adjustmentDebit
internal_transfermanual_adjustment_reversalCredit
internal_transfermastercard_gross_sweepDebit
internal_transfermastercard_gross_sweep_reversalCredit
internal_transfermastercard_interchange_sweepCredit
internal_transfermastercard_interchange_sweep_reversalDebit
internal_transfermastercard_net_sweepDebit
internal_transfermastercard_net_sweep_reversalCredit
internal_transferoutgoing_international_remittanceDebit
internal_transferoutgoing_international_remittance_reversalCredit
internal_transferprogram_decrease
internal_transferprogram_decrease_reversal
internal_transferprogram_expansion
internal_transferprogram_expansion_reversal
internal_transferpromotional_creditCredit
internal_transferpromotional_credit_reversalDebit
internal_transferpulse_gross_sweepDebit
internal_transferpulse_gross_sweep_reversalCredit
internal_transferpulse_interchange_sweepCredit
internal_transferpulse_interchange_sweep_reversalDebit
internal_transferrepaymentCredit
internal_transferrepayment_reversalDebit
internal_transfersign_up_bonusCredit
internal_transfersign_up_bonus_reversalDebit
internal_transfersubscription_feeDebit
internal_transfersubscription_fee_reversalCredit
internal_transfertransfer_feeDebit
internal_transfertransfer_fee_reversalCredit
wireoriginatedDebit
wireoriginated_reversalCredit
wireoriginated_returnCredit
wireoriginated_return_reversalDebit
wirereceivedCredit
wirereceived_reversalDebit

The Transaction Life-cycle

While specific details may differ slightly across different payment networks, most payments follow the same basic flow:

  1. A hold is placed on an account for the requested amount. This is represented in the system as a pending transaction.
  2. Synctera performs various account status, KYC, and fraud checks. If any of these checks fail, the pending transaction is declined.
  3. The amount of the hold may be increased or decreased. This is mainly seen in the context of a card transaction. For example if you are at a gas station authorize $100 at the pump, but only end up filling up $50 worth.
  4. At some point later the pending transaction either expires, is cancelled, or settles. When settled, this is represented as a new posted transaction.

Depending on the type of payment, the time between steps (1) and (3) may be anywhere from a few seconds, to several days (in the case of ACH payments).

Each time a transaction changes state, a webhook will be triggered. The exact events are described below:

ScenarioWebhook event(s)Notes
A hold is placed on an accountTRANSACTION.PENDING.CREATED
Hold amount is increased or decreasedTRANSACTION.PENDING.UPDATEDFinal amount is reflected in total_amount.
Fraud service declines transactionTRANSACTION.PENDING.UPDATEDstatus field changes from PENDING to DECLINED to DECLINED. Additional risk data may be placed in user_data.
Fraud service accepts transactionTRANSACTION.PENDING.UPDATEDAdditional risk data may be placed in user_data.
Transaction expiresTRANSACTION.PENDING.UPDATEDstatus field changes from PENDING to EXPIRED.
Transaction is posted to accountTRANSACTION.PENDING.UPDATED, TRANSACTION.POSTED.CREATEDPending transaction status changes from PENDING to POSTED. A new "posted" transaction is created.

Transaction History

Synctera provides 2 endpoints for viewing transactions:

  1. List pending transactions retrieves all "pending" or
    "unsettled" transaction within a given time period
  2. List posted transactions returns all "posted" or "settled"
    transactions within a given time period

You can also take advantage of the TRANSACTION Webhook) events to build your own transaction feed tailored to your specific use case.