Skip to content

Instantly share code, notes, and snippets.

@sadiqumar18
Created February 16, 2025 13:51
Show Gist options
  • Save sadiqumar18/3cc37dfd36ec81a1be391a1d474bf1f8 to your computer and use it in GitHub Desktop.
Save sadiqumar18/3cc37dfd36ec81a1be391a1d474bf1f8 to your computer and use it in GitHub Desktop.
Transaction Schema With ISO mapping
export enum ISO8583Fields {
MTI = '0',
PAN = '2',
PROCESSING_CODE = '3',
AMOUNT = '4',
AMOUNT_RECONCILIATION = '5',
AMOUNT_CARDHOLDER_BILLING = '6',
TRANSMISSION_DATE_TIME = '7',
AMOUNT_CARDHOLDER_FEE = '8',
STAN = '11',
LOCAL_TIME = '12',
EFFECTIVE_DATE = '13',
EXPIRATION_DATE = '14',
SETTLEMENT_DATE = '15',
CAPTURE_DATE = '17',
MESSAGE_ERROR = '18',
ACQUIRING_COUNTRY_CODE = '19',
LIFECYCLE_DATA = '21',
POS_DATA = '22',
CARD_SEQUENCE = '23',
FUNCTION_CODE = '24',
REASON_CODE = '25',
MERCHANT_CATEGORY = '26',
POS_CAPABILITIES = '27',
AMOUNTS_ORIGINAL = '30',
ACQUIRER_ID = '32',
FORWARDING_ID = '33',
TRACK2 = '35',
RRN = '37',
APPROVAL_CODE = '38',
RESPONSE_CODE = '39',
TERMINAL_ID = '41',
MERCHANT_ID = '42',
CARD_ACCEPTOR = '43',
TRACK1 = '45',
FEES = '46',
VERIFICATION_DATA = '49',
PIN_BLOCK = '52',
SECURITY_INFO = '53',
ADDITIONAL_AMOUNTS = '54',
ICC_DATA = '55',
ORIGINAL_DATA = '56',
TRANSPORT_DATA = '59',
DISPLAY_MESSAGE = '63',
BATCH_NUMBER = '68',
BATCH_DATA = '69',
DATA_RECORD = '72',
RECONCILIATION_DATA = '74',
DESTINATION_INSTITUTION = '93',
ORIGINATOR_INSTITUTION = '94',
REPLACEMENT_AMOUNTS = '95',
NET_RECONCILIATION = '97',
SETTLEMENT_INSTITUTION = '99',
RECEIVING_INSTITUTION = '100',
FILE_NAME = '101',
ACCOUNT_1 = '102',
ACCOUNT_2 = '103',
HANDBACK_DATA = '111',
TRANSPORT_DATA_ADDITIONAL = '112',
TPP_DATA = '113'
}
// iso8583.schema.ts
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import mongoose, { Document } from 'mongoose';
@Schema({
timestamps: true,
collection: 'transactions',
strict: false // Allow additional fields
})
export class Transaction extends Document {
@Prop({required: true, ref: 'Card'})
card: mongoose.Types.ObjectId
@Prop({required: true, ref: 'Institution'})
institution: mongoose.Types.ObjectId
@Prop({ required: true, index: true })
mti: string;
@Prop({ required: true, index: true })
stan: string;
@Prop({ required: true, index: true })
rrn: string;
@Prop({ required: true })
processingCode: string;
@Prop({ required: true })
terminalId: string;
@Prop({ required: true })
merchantId: string;
// Amount Fields
@Prop({
type: {
amount: String,
currency: String,
originalAmount: String,
reconciliationAmount: String,
billingAmount: String,
feeAmount: String
},
required: true
})
amounts: {
amount: string;
currency: string;
originalAmount?: string;
reconciliationAmount?: string;
billingAmount?: string;
feeAmount?: string;
};
// Date/Time Fields
@Prop({
type: {
transmission: Date,
local: Date,
settlement: Date,
capture: Date
},
required: true
})
dates: {
transmission: Date;
local: Date;
settlement?: Date;
capture?: Date;
};
@Prop({
type: {
pan: String,
track1: String,
track2: String,
sequence: String,
expiry: String
}
})
cardData: {
pan?: string;
track1?: string;
track2?: string;
sequence?: string;
expiry?: string;
};
@Prop({
type: {
protocolVersion: String,
firstName: String,
middleName: String,
lastName: String,
secondaryLastName: String,
email: String,
statusFlags: String,
honorific: String,
gender: String,
address1: String,
address2: String,
city: String,
stateCode: String,
zipCode: String,
countryCode: String,
phone: String,
notes: String,
dates: String,
alternateId: String,
cardProductId: String,
uuid: String,
ssn: String,
installmentsInfo: String,
networkName: String,
deviceId: String,
geolocation: String,
cardholderIdData: String,
invoice: String,
presentmentData: {
sequenceCount: String,
sequenceNumber: String
},
transactionIds: {
origin: String,
related: String
}
}
})
tppData: {
protocolVersion?: string;
firstName?: string;
middleName?: string;
lastName?: string;
secondaryLastName?: string;
email?: string;
statusFlags?: string;
honorific?: string;
gender?: string;
address1?: string;
address2?: string;
city?: string;
stateCode?: string;
zipCode?: string;
countryCode?: string;
phone?: string;
notes?: string;
dates?: string;
alternateId?: string;
cardProductId?: string;
uuid?: string;
ssn?: string;
installmentsInfo?: string;
networkName?: string;
deviceId?: string;
geolocation?: string;
cardholderIdData?: string;
invoice?: string;
presentmentData?: {
sequenceCount: string;
sequenceNumber: string;
};
transactionIds?: {
origin: string;
related: string;
};
};
@Prop()
responseCode?: string;
@Prop()
approvalCode?: string;
@Prop()
displayMessage?: string;
@Prop({ type: Map, of: String })
hexFields: Map<string, string>;
@Prop({ type: Map, of: Map, of: String })
nestedFields: Map<string, Map<string, string>>;
@Prop({ required: true, enum: ['request', 'response'] })
messageType: string;
@Prop({ index: true })
correlationId: string;
@Prop({ default: false })
reversed: boolean;
@Prop()
reversalId?: string;
@Prop({ type: Map, of: String })
metadata: Map<string, string>;
@Prop()
originalMessage: string;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment