Return Codes

The return-code engine (pkg/returncodes) maps a normalized ACH return code or Usio card decline code to an action plan — invalidate the bank account or card, blocklist the user, send an Iterable event — and dispatches it. ACH returns reach it asynchronously through site-payments-blocklist-handler; card declines reach it synchronously inside POST /payments. The per-code tables at the bottom of this page are generated from the Go tables by make docs.host.

Normalization

payment_method Scheme Raw code resolution

ach

ACH (NACHA Rxx codes)

Usio: return_code as stored. JPM: the leading Rxx token of return_info (statusText, e.g. R10 CUST ADVISES NOT AUTH.); when that prefix is absent, the ISO 20022 statusCode via JPM ISO code mapping.

pinless

Card (Usio decline codes)

return_code as cleaned from the Usio response message. 4-digit 5xxx gateway codes match as a family (keep card, no comms). 62 uses a Visa-specific row when the card’s issuer is VISA.

rtp

None

No instrument-level handling.

A code in neither table resolves to Known = false: no instrument action, no comms, one warning log.

Source: pkg/returncodes/engine.go, pkg/returncodes/jpm_mapping.go

Action Plan

Resolve is pure: a target (user ID, raw code and info, payment method, IsFloat, failed account or card ID, optional email) becomes an ActionPlan mirroring the matched code’s Config.

Field Meaning

InvalidateBank

Remove the bank account record and write a BLOCKED record (ACH scheme)

InvalidateCard

Mark the debit card is_valid = false (card scheme)

Suspend

Also set suspended_on on the card (21 codes); gated by payments.return_code_handling.suspend.enabled

Prohibited

ACH codes that must never be re-presented: R07, R08, R10

Comms, IterableEvent

The per-code Iterable event. Comms is forced false for non-float targets: subscription, loan, and prenote returns take the instrument action only.

Comms identify the user by email: Target.Email when the caller supplied one (the email field on a payment request), otherwise a User Service lookup made only when comms are about to send. No email resolved → comms skipped, instrument actions still run.

Source: pkg/returncodes/codes.go (Config), pkg/returncodes/engine.go

ACH Dispatch (Handle)

Called by the blocklist-handler for every SUBSCRIPTION_RETURNED / FLOAT_DEBIT_RETURNED event (Blocklist). For an invalidate-bank code:

  1. Remove the bank account record (bankaccount.Service.Remove) — Bank Accounts.

  2. Write BLOCKED keyed on the user, with the payment’s confirmation ID as trigger_id.

  3. Send the Iterable event (float payments only).

Each action is attempted independently; failures are logged and joined, and never fail the originating payment. The user’s Plaid item is not touched.

Card Dispatch (HandleCardDecline)

Called by POST /payments after a pinless decline that carries a Usio confirmation ID; a pre-network rejection or system error never reaches it — Failed payments.

  1. InvalidateCard → is_valid = false, invalid_date set, card saved.

  2. Suspend with the flag on → suspended_on set; the physical card cannot be added again — Suspended cards.

  3. Send the Iterable event (float payments only).

Metrics

Metric Fires Tags

payments.debitcard.declined

Once per handled card decline

code, action:invalidate|keep

payments.debitcard.invalidated

Card-invalidation save

code, outcome:success|failure

payments.debitcard.suspended

Card-suspension save

code, outcome:success|failure

payments.blocklist.action

Every blocklist write

action:blocked, code, outcome:success|failure

payments.comms.event

Per-code comms attempt

event, code, scheme, outcome:sent|failure|no_email

Unknown codes tag code:unknown.

Code Tables

Column Meaning

Bank action

invalidate + blocklist = remove the bank account and write BLOCKED; keep = no instrument action

Card action

invalidate = mark the card invalid; invalidate + suspend = also set suspended_on (flag-gated); keep = card stays usable

Comms

Whether the Iterable event sends for a float payment. no = never sends for any payment type

Iterable event

Event name; populated for logging even when Comms is no

Re-presentment

prohibited = never re-present (NACHA)

ACH return codes

Code Meaning Bank action Comms Iterable event Re-presentment

R01

Insufficient Funds

keep

yes

repayment_insufficient_funds

allowed

R02

Account Closed

invalidate + blocklist

yes

repayment_connect_new_bank

allowed

R03

No Account/Unable to Locate Account

invalidate + blocklist

yes

repayment_reconnect_bank

allowed

R04

Invalid Account Number Structure

invalidate + blocklist

yes

repayment_reconnect_bank

allowed

R05

Unauthorized Corporate Entry

invalidate + blocklist

yes

repayment_user_suspended

allowed

R06

Returned per ODFI Request

keep

yes

repayment_contact_bank

allowed

R07

Authorization Revoked by Customer

invalidate + blocklist

yes

repayment_user_suspended

prohibited

R08

Payment Stopped

invalidate + blocklist

yes

repayment_user_suspended

prohibited

R09

Uncollected Funds

keep

yes

repayment_contact_bank

allowed

R10

Customer Advises Not Authorized

invalidate + blocklist

yes

repayment_reconnect_bank

prohibited

R11

Entry Not In Accordance with Terms

invalidate + blocklist

yes

repayment_user_suspended

allowed

R12

Account Sold to Another DFI

invalidate + blocklist

yes

repayment_connect_new_bank

allowed

R13

Invalid ACH Routing Number

invalidate + blocklist

yes

repayment_connect_new_bank

allowed

R14

Representative Payee Deceased

invalidate + blocklist

yes

repayment_user_suspended

allowed

R15

Beneficiary or Account Holder Deceased

invalidate + blocklist

yes

repayment_user_suspended

allowed

R16

Account Frozen/Funds Returned

invalidate + blocklist

yes

repayment_connect_new_bank

allowed

R17

File Record Edit Criteria

invalidate + blocklist

yes

repayment_connect_new_bank

allowed

R18

Improper Effective Entry Date

invalidate + blocklist

yes

repayment_reconnect_bank

allowed

R19

Amount Field Error

keep

yes

repayment_contact_bank

allowed

R20

Non-Transaction Account

invalidate + blocklist

yes

repayment_connect_new_bank

allowed

R21

Invalid Company Identification

keep

yes

repayment_contact_bank

allowed

R22

Invalid Foreign Receiving DFI Identification

keep

yes

repayment_contact_bank

allowed

R23

Credit Entry Refused by Receiver

invalidate + blocklist

yes

repayment_connect_new_bank

allowed

R24

Duplicate Entry

keep

yes

repayment_contact_bank

allowed

R25

Addenda Error

keep

yes

repayment_contact_bank

allowed

R26

Mandatory Field Error

keep

yes

repayment_contact_bank

allowed

R27

Trace Number Error

keep

yes

repayment_contact_bank

allowed

R28

Routing Number Check Digit Error

invalidate + blocklist

yes

repayment_connect_new_bank

allowed

R29

Corporate Customer Advises Not Authorized

invalidate + blocklist

yes

repayment_user_suspended

allowed

R30

RDFI Not Participant in Check Truncation Program

invalidate + blocklist

yes

repayment_connect_new_bank

allowed

R31

Permissible Return Entry (CCD and CTX only)

invalidate + blocklist

yes

repayment_connect_new_bank

allowed

R32

RDFI Non-Settlement

invalidate + blocklist

yes

repayment_reconnect_bank

allowed

R33

Return of XCK Entry

invalidate + blocklist

yes

repayment_reconnect_bank

allowed

R34

Limited Participation DFI

invalidate + blocklist

yes

repayment_connect_new_bank

allowed

R35

Improper Debit

invalidate + blocklist

yes

repayment_connect_new_bank

allowed

R36

Improper Credit

invalidate + blocklist

yes

repayment_connect_new_bank

allowed

R37

Source Document Presented for Payment

keep

yes

repayment_contact_bank

allowed

R38

Stop Payment on Source Document

invalidate + blocklist

yes

repayment_user_suspended

allowed

R39

Improper Source Document

invalidate + blocklist

yes

repayment_connect_new_bank

allowed

R40

Return of ENR

invalidate + blocklist

yes

repayment_reconnect_bank

allowed

R41

Invalid Transaction Code

invalidate + blocklist

yes

repayment_reconnect_bank

allowed

R42

Routing Number Check Digit Error (ENR)

invalidate + blocklist

yes

repayment_connect_new_bank

allowed

R43

Invalid DFI Account Number

invalidate + blocklist

yes

repayment_connect_new_bank

allowed

R44

Invalid Individual ID Number (ENR)

invalidate + blocklist

yes

repayment_connect_new_bank

allowed

R45

Invalid Individual / Company Name

invalidate + blocklist

yes

repayment_connect_new_bank

allowed

R46

Invalid Representative Payee Indicator

invalidate + blocklist

yes

repayment_connect_new_bank

allowed

R47

Duplicate Enrollment

keep

yes

repayment_contact_bank

allowed

R50

State Law Affecting RCK Acceptance

invalidate + blocklist

yes

repayment_connect_new_bank

allowed

R51

Ineligible / Improper Item Related to RCK

invalidate + blocklist

yes

repayment_connect_new_bank

allowed

R52

Stop Payment on Item Related to RCK

invalidate + blocklist

yes

repayment_user_suspended

allowed

R53

Item and RCK Entry Presented for Payment

keep

yes

repayment_contact_bank

allowed

R61

Misrouted Return

invalidate + blocklist

yes

repayment_connect_new_bank

allowed

R62

Erroneous / Reversing Debit

keep

yes

repayment_contact_bank

allowed

R67

Duplicate Return

keep

yes

repayment_contact_bank

allowed

R68

Untimely Return

keep

yes

repayment_contact_bank

allowed

R69

Field Error

invalidate + blocklist

yes

repayment_reconnect_bank

allowed

R70

Permissible Return Not Accepted / Not Requested by ODFI

invalidate + blocklist

yes

repayment_reconnect_bank

allowed

R71

Misrouted Dishonored Return

invalidate + blocklist

yes

repayment_reconnect_bank

allowed

R72

Untimely Dishonored Return

invalidate + blocklist

yes

repayment_reconnect_bank

allowed

R73

Timely Original Return

keep

yes

repayment_contact_bank

allowed

R74

Corrected Return

keep

yes

repayment_contact_bank

allowed

R75

Return Not Duplicate

keep

yes

repayment_contact_bank

allowed

R76

No Errors Found

keep

yes

repayment_contact_bank

allowed

R77

Non-Acceptance of R62 Dishonored Return

invalidate + blocklist

yes

repayment_reconnect_bank

allowed

R80

IAT Coding Error

invalidate + blocklist

yes

repayment_reconnect_bank

allowed

R81

Non-Participant in IAT Program

invalidate + blocklist

yes

repayment_connect_new_bank

allowed

R82

Invalid Foreign RDFI Identification

invalidate + blocklist

yes

repayment_connect_new_bank

allowed

R83

Foreign RDFI Unable to Settle

invalidate + blocklist

yes

repayment_connect_new_bank

allowed

R84

Not Processed by Gateway

invalidate + blocklist

yes

repayment_reconnect_bank

allowed

R85

Incorrectly Coded Outbound International Payment

invalidate + blocklist

yes

repayment_reconnect_bank

allowed

Card decline codes

Network override rows (Visa 62) follow the main table.

Code Meaning Card action Comms Iterable event

00

Approved / Completed Successfully

keep

no

—

01

Refer to Card Issuer

keep

yes

repayment_contact_card

02

Refer to Card Issuer (Special Conditions)

keep

yes

repayment_contact_card

03

Invalid Merchant

keep

yes

repayment_contact_card

04

Pick-Up (No Fraud Indicated)

invalidate + suspend

yes

repayment_connect_new_card

05

Do Not Honor

keep

yes

repayment_contact_card

06

General Error / 6P

keep

yes

repayment_contact_card

07

Pick-Up Card (Fraud / Special Conditions)

invalidate + suspend

yes

repayment_connect_new_card

08

Honor with Identification (Approval Variant)

invalidate

no

repayment_contact_card

09

Request in Progress

keep

yes

repayment_contact_card

10

Approved for Partial Amount

keep

no

repayment_insufficient_funds

11

Approved (VIP)

keep

no

—

12

Invalid Transaction

invalidate

yes

repayment_reconnect_card

13

Invalid Amount

keep

yes

repayment_contact_card

14

Invalid Card Number (No Such Number)

invalidate + suspend

yes

repayment_connect_new_card

15

No Such Issuer

invalidate + suspend

yes

repayment_connect_new_card

17

Manual PAN Tries Exceeded

invalidate

yes

repayment_reconnect_card

19

Re-Enter Transaction

keep

yes

repayment_contact_card

20

Invalid Response

keep

yes

repayment_contact_card

21

Reversal Unsuccessful

keep

yes

repayment_contact_card

28

File Temporarily Unavailable

keep

yes

repayment_contact_card

30

Message Format Error

keep

yes

repayment_contact_card

31

Bank Not Supported by Switch

invalidate

yes

repayment_connect_new_card

33

Pick Up Card — Expired

invalidate + suspend

yes

repayment_connect_new_card

34

Suspected Fraud, Pick Up

invalidate + suspend

yes

repayment_connect_new_card

38

Allowable PIN Tries Exceeded

invalidate

yes

repayment_reconnect_card

39

No Credit Account

invalidate + suspend

yes

repayment_connect_new_card

40

Requested Function Not Supported

invalidate

yes

repayment_connect_new_card

41

Lost Card, Pick Up

invalidate + suspend

yes

repayment_connect_new_card

43

Stolen Card, Pick Up

invalidate + suspend

yes

repayment_connect_new_card

44

No Investment Account

keep

yes

repayment_contact_card

46

Account Closed

invalidate + suspend

yes

repayment_connect_new_card

47

Remote Function Unknown

keep

yes

repayment_contact_card

51

Insufficient Funds

keep

yes

repayment_insufficient_funds

52

No Checking Account

invalidate + suspend

yes

repayment_connect_new_card

53

No Savings Account

invalidate

yes

repayment_connect_new_card

54

Expired Card

invalidate

yes

repayment_connect_new_card

55

Incorrect PIN

invalidate

yes

repayment_connect_new_card

56

Cannot Process / No Card Record

keep

yes

repayment_contact_card

57

Transaction Not Permitted to Cardholder

invalidate + suspend

yes

repayment_connect_new_card

58

Transaction Not Permitted to Terminal (May Also Be Chargeback)

invalidate

yes

repayment_connect_new_card

59

Suspected Fraud

invalidate

yes

repayment_reconnect_card

61

Exceeds Withdrawal Amount Limit

keep

yes

repayment_contact_card

62

Restricted Card

invalidate

yes

repayment_reconnect_card

63

Security Violation

invalidate + suspend

yes

repayment_connect_new_card

65

Exceeds Withdrawal Frequency Limit

keep

yes

repayment_contact_card

67

Hard Capture, Pick-Up

invalidate + suspend

yes

repayment_connect_new_card

75

Allowable PIN Tries Exceeded

keep

yes

repayment_contact_card

76

Unable to Locate / Late Reversal

keep

yes

repayment_contact_card

77

Inconsistent Data / Reversal or Repeat

keep

yes

repayment_contact_card

78

Customer Not Eligible for POS (Star SM)

keep

yes

repayment_contact_card

79

Already Reversed at Switch / No 'From' Account

invalidate

yes

repayment_reconnect_card

80

Invalid Date

invalidate

yes

repayment_connect_new_card

81

Cryptographic Error

invalidate

yes

repayment_reconnect_card

82

Cashback Limit Exceeded / Invalid CVV

invalidate

yes

repayment_reconnect_card

83

Fraud, Card-Absent Environment

invalidate + suspend

yes

repayment_connect_new_card

86

Cannot Verify PIN

invalidate

yes

repayment_connect_new_card

88

Card Record Not Available

keep

yes

repayment_contact_card

89

CVV Verification Failed (No Pickup)

keep

yes

repayment_contact_card

91

Issuer or Switch is Inoperative

invalidate

yes

repayment_connect_new_card

92

Financial Institution Cannot Be Found for Routing

invalidate

yes

repayment_reconnect_card

93

Violation / Cannot Complete / Illegal Transaction

invalidate

yes

repayment_connect_new_card

96

System Malfunction

keep

yes

repayment_contact_card

98

Duplicate Transaction

keep

yes

repayment_contact_card

99

Preferred Debit Routing Denial

invalidate

yes

repayment_reconnect_card

100

Do Not Honor (Extended)

keep

yes

repayment_contact_card

101

Expired Card (Extended)

invalidate

yes

repayment_connect_new_card

107

Refer to Card Issuer (Extended)

keep

yes

repayment_contact_card

108

Refer to Card Issuer’s Special Condition (Extended)

keep

yes

repayment_contact_card

114

No Account of Type Requested

invalidate

yes

repayment_reconnect_card

116

Insufficient Funds (Extended)

keep

yes

repayment_insufficient_funds

119

Transaction Not Permitted to Cardholder (Extended)

invalidate + suspend

yes

repayment_connect_new_card

123

Exceeds Withdrawal Frequency Limit (Extended)

keep

yes

repayment_contact_card

209

Stolen Card

invalidate + suspend

yes

repayment_connect_new_card

908

Transaction Destination Cannot Be Found for Routing

keep

yes

repayment_contact_card

9G

Blocked (9G)

invalidate

yes

repayment_contact_card

E9

P2PE Encryption Required

invalidate

yes

repayment_reconnect_card

EA

Verification Error

keep

yes

repayment_contact_card

EC

Verification Error (Alternate)

keep

yes

repayment_contact_card

EQ

No Available Gateway Nodes

keep

yes

repayment_contact_card

EU

Unknown / Not Documented

keep

yes

repayment_contact_card

N3

Cashback Service Not Available

keep

yes

repayment_contact_card

N4

Exceeds Issuer Withdrawal Limit

keep

yes

repayment_contact_card

N7

Error in Addition / CVV Mismatch

invalidate

yes

repayment_reconnect_card

P55

Invalid Credit Card Number (USIO-Specific)

invalidate + suspend

yes

repayment_connect_new_card

R0

Stop Payment Order

invalidate + suspend

yes

repayment_connect_new_card

R1

Credit Not Received (Recurring Charge Stopped)

invalidate + suspend

yes

repayment_connect_new_card

R3

Revocation of All Authorizations

invalidate + suspend

yes

repayment_connect_new_card

RR

Unknown Backend Processing Error

keep

yes

repayment_contact_card

S9

Expiration Date Mismatch

invalidate

yes

repayment_connect_new_card

SA

Inactive Card

invalidate

yes

repayment_connect_new_card

ZN

MasterCard MoneySend Decline — Card Declined

invalidate

yes

repayment_connect_new_card

ZR

MasterCard MoneySend Decline — Unsupported Card

invalidate

yes

repayment_connect_new_card

ZU

MasterCard MoneySend Error — Unknown Reason

invalidate

yes

repayment_connect_new_card

Table 1. Visa overrides — these replace the default row above when the declined card’s issuer is Visa
Code Meaning Card action Comms Iterable event

62

Restricted Card

keep

yes

repayment_contact_card

JPM ISO code mapping

Fallback used only when return_info carries no Rxx prefix. The map holds ISO codes that resolve to a single R-code; AG01 and NARR are not mapped.

JPM ISO code Usio code Meaning

AC01

R04

Invalid Account Number Structure

AC04

R02

Account Closed

AC06

R16

Account Frozen/Funds Returned

AG07

R07

Authorization Revoked by Customer

AM04

R01

Insufficient Funds

AM05

R24

Duplicate Entry

AM07

R09

Uncollected Funds

BE01

R03

No Account/Unable to Locate Account

DS02

R08

Payment Stopped

FF02

R17

File Record Edit Criteria

MD07

R15

Beneficiary or Account Holder Deceased

Source: pkg/returncodes/codes.go, pkg/returncodes/jpm_mapping.go — regenerate with make docs.host