Monday, November 18, 2013

Token or crn xml payment using NAB

Download for payment response code

testUrl = "https://transact.nab.com.au/test/xmlapi/payment";
liveUrl = "https://transact.nab.com.au/xmlapi/payment";

NAB Transact XML API  Public Test Account Details
Merchant ID: XYZ0010
Transaction Password: abcd1234 


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package xmlparser;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 *
 * @author Pritom K Mondal
 */
public class NabTokenPayment {
    public static void main(String[] args) throws Exception {
        NabTokenPayment nabTokenPayment = new NabTokenPayment();
        nabTokenPayment.pay();
    }
    
    private void pay() throws Exception {
        String testURL = "https://transact.nab.com.au/xmlapidemo/periodic";
        String liveURL = "https://transact.nab.com.au/xmlapi/periodic";
        String xml = getTokenPaymentXml();
        URL url = new URL(testURL); 
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();           
        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.setInstanceFollowRedirects(false); 
        connection.setRequestMethod("POST"); 
        connection.setRequestProperty("Content-Type", "text/xml"); 
        connection.setRequestProperty("charset", "utf-8");
        connection.setRequestProperty("Content-Length", "" + Integer.toString(xml.getBytes().length));
        connection.setUseCaches (false);

        DataOutputStream wr = new DataOutputStream(connection.getOutputStream ());
        wr.writeBytes(xml);
        wr.flush();
        wr.close();
        
        System.out.println("Response code from nab: " + connection.getResponseCode());

        BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        String line, responseText = "";
        while ((line = br.readLine()) != null) {
            responseText += line;
        }
        br.close();
        
        System.out.println("Response: \n" + responseText);
    }
    
    private String getTokenPaymentXml() throws Exception {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssZ");
        String messageTimestamp = dateFormat.format(new Date());
        String messageID = MD5(messageTimestamp);
        String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
            "<NABTransactMessage>\n" +
                "<MessageInfo>\n" +
                    "<messageID>" + messageID + "</messageID>\n" +
                    "<messageTimestamp>" + messageTimestamp + "</messageTimestamp>\n" +
                    "<timeoutValue>60</timeoutValue>\n" +
                    "<apiVersion>spxml-4.2</apiVersion>\n" +
                "</MessageInfo>\n" +
                "<MerchantInfo>\n" +
                    "<merchantID>XYZ0010</merchantID>\n" +
                    "<password>abcd1234</password>\n" +
                "</MerchantInfo>\n" +
                "<RequestType>Periodic</RequestType>\n" +
                "<Periodic>\n" +
                    "<PeriodicList count=\"1\">\n" +
                        "<PeriodicItem ID=\"1\">\n" +
                            "<actionType>trigger</actionType>\n" +
                            "<periodicType>8</periodicType>\n" +
                            "<crn>47e8cb6ddc6ba08890d4</crn>\n" +
                            "<transactionReference>Test Trigger CC Payment</transactionReference>\n" +
                            "<amount>1200</amount>\n" +
                            "<currency>AUD</currency>\n" +
                        "</PeriodicItem>\n" +
                    "</PeriodicList>\n" +
                "</Periodic>\n" +
            "</NABTransactMessage>";
        return xml;
    }
    
    private String convertedToHex(byte[] data) {
        StringBuffer buf = new StringBuffer();       
        for (int i = 0; i < data.length; i++) {
            int halfOfByte = (data[i] >>> 4) & 0x0F;
            int twoHalfBytes = 0;
            do {
                if ((0 <= halfOfByte) && (halfOfByte <= 9)) {
                    buf.append( (char) ('0' + halfOfByte) );
                } else {
                    buf.append( (char) ('a' + (halfOfByte - 10)) );
                }
                halfOfByte = data[i] & 0x0F;
            } while(twoHalfBytes++ < 1);
        }
        return buf.toString();
    }

    public String MD5(String text) 
            throws NoSuchAlgorithmException, UnsupportedEncodingException 
    {
        MessageDigest md;
        md = MessageDigest.getInstance("MD5");
        byte[] md5 = new byte[64];
        md.update(text.getBytes("iso-8859-1"), 0, text.length());
        md5 = md.digest();
        return convertedToHex(md5);
    }
}

Successful response:


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<NABTransactMessage>
    <MessageInfo>
        <messageID>af7296fcab496a96cf54aef73ff66960</messageID>
        <messageTimestamp>20131911003610525000+660</messageTimestamp>
        <apiVersion>spxml-4.2</apiVersion>
    </MessageInfo>
    <MerchantInfo>
        <merchantID>XYZ0010</merchantID>
    </MerchantInfo>
    <Status>
        <statusCode>0</statusCode>
        <statusDescription>Normal</statusDescription>
    </Status>
    <RequestType>Periodic</RequestType>
    <Periodic>
        <PeriodicList count="1">
            <PeriodicItem ID="1">
                <actionType>trigger</actionType>
                <crn>47e8cb6ddc6ba08890d4</crn>
                <responseCode>00</responseCode>
                <responseText>Approved</responseText>
                <successful>yes</successful>
                <periodicType>8</periodicType>
                <amount>1200</amount>
                <currency>AUD</currency>
                <txnID>983211</txnID>
                <transactionReference>Test Trigger CC Payment</transactionReference>
                <settlementDate>20131119</settlementDate>
                <CreditCardInfo>
                    <pan>444433...111</pan>
                    <expiryDate>09/15</expiryDate>
                    <cardType>6</cardType>
                    <cardDescription>Visa</cardDescription>
                </CreditCardInfo>
            </PeriodicItem>
        </PeriodicList>
    </Periodic>
</NABTransactMessage>

Error response:


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<NABTransactMessage>
    <MessageInfo>
        <messageID>f8c4385e4beb4a7c177e8b8aaa124e15</messageID>
        <messageTimestamp>20131911004348303000+660</messageTimestamp>
        <apiVersion>spxml-4.2</apiVersion>
    </MessageInfo>
    <MerchantInfo>
        <merchantID>XYZ0010</merchantID>
    </MerchantInfo>
    <Status>
        <statusCode>0</statusCode>
        <statusDescription>Normal</statusDescription>
    </Status>
    <RequestType>Periodic</RequestType>
    <Periodic>
        <PeriodicList count="1">
            <PeriodicItem ID="1">
                <actionType>trigger</actionType>
                <crn>47e8cb6ddc6ba08890d4</crn>
                <responseCode>04</responseCode>
                <responseText>Pick Up Card</responseText>
                <successful>no</successful>
                <periodicType>8</periodicType>
                <amount>304</amount>
                <currency>AUD</currency>
                <txnID>983222</txnID>
                <transactionReference>Test Trigger CC Payment</transactionReference>
                <settlementDate>20131119</settlementDate>
                <CreditCardInfo>
                    <pan>444433...111</pan>
                    <expiryDate>09/15</expiryDate>
                    <cardType>6</cardType>
                    <cardDescription>Visa</cardDescription>
                </CreditCardInfo>
            </PeriodicItem>
        </PeriodicList>
    </Periodic>
</NABTransactMessage>

Wednesday, November 13, 2013

Create/edit token/crn for NAB transact

testUrl = "https://transact.nab.com.au/xmlapidemo/periodic";
liveUrl = "https://transact.nab.com.au/xmlapi/periodic";
NAB Transact XML API  Public Test Account Details
Merchant ID: XYZ0010
Transaction Password: abcd1234 


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package xmlparser;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 *
 * @author Pritom K Mondal
 */
public class NabTokenCreate {
    public static void main(String[] args) throws Exception {
        NabTokenCreate tokenCreate = new NabTokenCreate();
        tokenCreate.createToken();
    }
    
    void createToken() throws Exception {
        String testURL = "https://transact.nab.com.au/xmlapidemo/periodic";
        String liveURL = "https://transact.nab.com.au/xmlapi/periodic";
        String xml = getTokenXml();
        
        URL url = new URL(testURL); 
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();           
        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.setInstanceFollowRedirects(false); 
        connection.setRequestMethod("POST"); 
        connection.setRequestProperty("Content-Type", "text/xml"); 
        connection.setRequestProperty("charset", "utf-8");
        connection.setRequestProperty("Content-Length", "" + Integer.toString(xml.getBytes().length));
        connection.setUseCaches (false);

        DataOutputStream wr = new DataOutputStream(connection.getOutputStream ());
        wr.writeBytes(xml);
        wr.flush();
        wr.close();
        
        System.out.println("Response code from nab: " + connection.getResponseCode());

        BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        String line, responseText = "";
        while ((line = br.readLine()) != null) {
            responseText += line;
        }
        br.close();
        
        System.out.println("Response: " + responseText);
    }
    
    String getTokenXml() throws Exception {
        String xml = "";
        
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssZ");
        String messageTimestamp = dateFormat.format(new Date());
        String messageID = MD5(messageTimestamp);
        
        /**
         * crn is the key of the token system of NAB transact.
         * It must be a unique key against one account.
         * And must be less than 20 characters length.
         * Can contains a-z, A-Z, 0-9, space, underscore.
         * To edit existing customer in NAB account, please 
         * find the block '<actionType>addcrn</actionType>' in xml below
         * and replace 'addcrn' with 'editcrn' and please provide 
         * a valid crn existing against provided merchant account.
         */
        String crn = messageID;
        if(crn.length() > 20) {
            crn = crn.substring(0, 20);
        }
        
        xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
            "<NABTransactMessage>\n" +
                "<MessageInfo>\n" +
                    "<messageID>" + messageID + "</messageID>\n" +
                    "<messageTimestamp>" + messageTimestamp + "</messageTimestamp>\n" +
                    "<timeoutValue>60</timeoutValue>\n" +
                    "<apiVersion>spxml-4.2</apiVersion>\n" +
                "</MessageInfo>\n" +
                "<MerchantInfo>\n" +
                    "<merchantID>XYZ0010</merchantID>\n" +
                    "<password>changeit</password>\n" +
                "</MerchantInfo>\n" +
                "<RequestType>Periodic</RequestType>\n" +
                "<Periodic>\n" +
                    "<PeriodicList count=\"1\">\n" +
                        "<PeriodicItem ID=\"1\">\n" +
                            "<actionType>addcrn</actionType>\n" +
                            "<periodicType>5</periodicType>\n" +
                            "<crn>" + crn + "</crn>\n" +
                            "<CreditCardInfo>\n" +
                                "<cardNumber>4444333322221111</cardNumber>\n" +
                                "<expiryDate>09/15</expiryDate>\n" +
                            "</CreditCardInfo>\n" +
                        "</PeriodicItem>\n" +
                    "</PeriodicList>\n" +
                "</Periodic>\n" +
            "</NABTransactMessage>";
        
        return xml;
    }
    
    private String convertedToHex(byte[] data) {
        StringBuffer buf = new StringBuffer();       
        for (int i = 0; i < data.length; i++) {
            int halfOfByte = (data[i] >>> 4) & 0x0F;
            int twoHalfBytes = 0;
            do {
                if ((0 <= halfOfByte) && (halfOfByte <= 9)) {
                    buf.append( (char) ('0' + halfOfByte) );
                } else {
                    buf.append( (char) ('a' + (halfOfByte - 10)) );
                }
                halfOfByte = data[i] & 0x0F;
            } while(twoHalfBytes++ < 1);
        }
        return buf.toString();
    }

    public String MD5(String text) 
            throws NoSuchAlgorithmException, UnsupportedEncodingException 
    {
        MessageDigest md;
        md = MessageDigest.getInstance("MD5");
        byte[] md5 = new byte[64];
        md.update(text.getBytes("iso-8859-1"), 0, text.length());
        md5 = md.digest();
        return convertedToHex(md5);
    } 
}

Successful response from NAB as:


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<NABTransactMessage>
    <MessageInfo>
        <messageID>5fc6a6428d5dd433c7081e97ab92697d</messageID>
        <messageTimestamp>20131411021406034000+660</messageTimestamp>
        <apiVersion>spxml-4.2</apiVersion>
    </MessageInfo>
    <MerchantInfo>
        <merchantID>XYZ0010</merchantID>
    </MerchantInfo>
    <Status>
        <statusCode>0</statusCode>
        <statusDescription>Normal</statusDescription>
    </Status>
    <RequestType>Periodic</RequestType>
    <Periodic>
        <PeriodicList count="1">
            <PeriodicItem ID="1">
                <actionType>addcrn</actionType>
                <crn>5fc6a6428d5dd433c708</crn>
                <responseCode>00</responseCode>
                <responseText>Successful</responseText>
                <successful>yes</successful>
                <DirectEntryInfo>
                    <bsbNumber/>
                    <accountNumber/>
                    <accountName/>
                    <creditFlag>no</creditFlag>
                </DirectEntryInfo>
                <CreditCardInfo>
                    <pan>444433...111</pan>
                    <expiryDate>09/15</expiryDate>
                    <recurringFlag>no</recurringFlag>
                </CreditCardInfo>
                <currency>AUD</currency>    
                <periodicType>5</periodicType>
                <paymentInterval/>
                <numberOfPayments/>
            </PeriodicItem>
        </PeriodicList>
    </Periodic>
</NABTransactMessage>

Unsuccessful response from NAB as


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<NABTransactMessage>
    <MessageInfo>
        <messageID>9efcd6fe01a0d4da7c69e16b2583ba44</messageID>
        <messageTimestamp>20131411022423765000+660</messageTimestamp>
        <apiVersion>spxml-4.2</apiVersion>
    </MessageInfo>
    <MerchantInfo>
        <merchantID>XYZ0010</merchantID>
    </MerchantInfo>
    <Status>
        <statusCode>0</statusCode>
        <statusDescription>Normal</statusDescription>
    </Status>
    <RequestType>Periodic</RequestType>
    <Periodic>
        <PeriodicList count="1">
            <PeriodicItem ID="1">
                <actionType>addcrn</actionType>
                <crn>9efcd6fe01a0d4da7c69</crn>
                <responseCode>301</responseCode>
                <responseText>Invalid Credit Card Number</responseText>
                <successful>no</successful>
                <DirectEntryInfo>
                    <bsbNumber/>
                    <accountNumber/>
                    <accountName/>
                    <creditFlag>no</creditFlag>
                </DirectEntryInfo>
                <CreditCardInfo>
                    <pan>473433...112</pan>
                    <expiryDate/>
                    <recurringFlag>no</recurringFlag>
                </CreditCardInfo>
                <currency>AUD</currency>
                <periodicType>5</periodicType>
                <paymentInterval/>
                <numberOfPayments/>
            </PeriodicItem>
        </PeriodicList>
    </Periodic>
</NABTransactMessage>

Response codes:


000 Normal Message processed correctly (check transaction response for details).

504 Invalid Merchant ID
If Merchant ID does not follow the format XXXDDDD, where X is a letter
and D is a digit, or Merchant ID is not found in NAB Transact’s database.

505 Invalid URL The URL is invalid.

510 Unable To Connect To Server
Produced by NAB Transact Client API when unable to establish connection
to NAB Transact Payment Gateway

511
Server Connection Aborted During
Transaction
Produced by NAB Transact Client API when connection to NAB Transact
Payment Gateway is lost after the payment transaction has been sent

512 Transaction timed out By Client
Produced by NAB Transact Client API when no response to payment
transaction has been received from NAB Transact Payment Gateway within
predefined time period (default 80 seconds)

513 General Database Error Unable to read information from the database.

514 Error loading properties file
Payment Gateway encountered an error while loading configuration
information for this transaction

515 Fatal Unknown Error
Transaction could not be processed by the Payment Gateway due to
unknown reasons

516 Request type unavailable NAB Transact system doesn’t support the requested transaction type

517 Message Format Error
The transaction sent to the NAB Transact Payment Gateway has not been
formatted according to the specifications.

518 Customer Not Registered The Customer cannot be found

524 Response not received The client could not receive a response from the server.

545 System maintenance in progress
The system maintenance is in progress and the system is currently unable
to process transactions

550 Invalid password The merchant has attempted to process a request with an invalid password.

575 Not implemented This functionality has not yet been implemented

577 Too Many Records for Processing
The maximum number of allowed events in a single message has been
exceeded.

580 Process method has not been called The process() method object has not been called

595 Merchant Disabled
NAB Transact has disabled the merchant and the requests from this
merchant will not be processed.

300 Invalid Amount If payment transaction amount is non-integer, negative, or zero.

301 Invalid Credit Card Number
Credit card number is not supplied, wrong length, or does not pass Luhn
algorithm.

302 Invalid Expiry Date
Expiry date does not follow format MM/YY, where MM is the 2-digit month
(01-12) and YY is the 2-digit year.

303 Invalid CRN CRN is not provided or is longer than 20 characters.

304 Invalid Merchant ID
Merchant ID does not follow format XXXDDDD for credit card payments,
or XXXDD for direct entry, where X is a letter and D is a digit; or merchant ID
not in database.

305 Invalid BSB Number BSB does not follow format DDDDDD, or DDD-DDD, where D is a digit.

306 Invalid Account Number
Account number not provided, greater than 9 digits, or contains non-digit
characters.

307 Invalid Account Name
Account Name is mandatory for DE Credit payments, and optional for DE
Debits. Must be less than 32 characters if supplied.

308 No Matching DDA Found
A periodic DE Debit payment must match an existing DDA stored in our
database for the merchant. DDAs can be added via the Merchant Login.
DDA expiry date must be after the final periodic payment date.

309 Invalid CVV Number
CVV is optional for credit card payments, but if provided, must be either
3 or 4 digits.

313 General Database Error
A database error occurred while processing your request. Contact NAB
Transact Service Centre.

314 Unable to Read Properties File
A properties file was not found or could not be read. Contact NAB Transact
Service Centre.

316 Invalid Action Type
The server does not support the action type requested. Check user manual
for allowed values.

318 Unable to Decrypt Account Details
The card number or account details could not be decrypted. Contact NAB
Transact Service Centre.

327 Invalid Periodic Payment Type
The Periodic type requested is not supported. Check user manual for
allowed values.

328 Invalid Periodic Frequency
The Periodic frequency requested is not valid. Check user manual for
allowed values.

329 Invalid Number of Payments
Number of payments must be 1 or more for day-based and calendar-based
payments.

332 Invalid Date Format
A supplied date does not follow format YYYYMMDD, where values conform
to standard calendar rules; or the server could not correctly interpret a date.

333 Triggered Payment Not Found
Triggered payment Client ID requested does not match a stored triggered
payment for the merchant.

346 Duplicate CRN Found The CRN has already been registered for this merchant.

347 Duplicate Allocated Variable Found The Allocated Variable has already been registered for this merchant.

how to replace all characters in a java string

String line = "Pritom K Mondal";
line = line.replaceAll("(?s).", "X");

Will output:
XXXXXXXXXXXXXXX
 
The (?s) doesn't match anything but sets the DOTALL flag.

Java - Replace all non digits with an empty character in a string

String cardNumber = "4444 3333 2222 111");
cardNumber = cardNumber.trim();
cardNumber = cardNumber.replaceAll("\\D+", "");

Output:
4444333322221111

Validate credit card and get card type by java code

import org.apache.commons.validator.GenericValidator

def getCreditCardType(String cardNumber) throws AutobillException {
    cardNumber = "" + cardNumber;
    cardNumber = cardNumber.trim();
    cardNumber = cardNumber.replaceAll("\\D+", "");
    if(!GenericValidator.isCreditCard(cardNumber)) {
        throw new InvalidPropertyException("cardNumber");
    }
    if(cardNumber.matches(("^4[0-9]{12}(?:[0-9]{3})?\$"))) {
        return "VISA";
    } else if(cardNumber.matches(("^5[1-5][0-9]{14}\$"))) {
        return "MASTERCARD";
    } else if(cardNumber.matches(("^3[47][0-9]{13}\$"))) {
        return "AMEX";
    } else if(cardNumber.matches(("^3(?:0[0-5]|[68][0-9])[0-9]{11}\$"))) {
        return "DINERS";
    } else if(cardNumber.matches(("^6(?:011|5[0-9]{2})[0-9]{12}\$"))) {
        return "DISCOVER";
    } else if(cardNumber.matches(("^(?:2131|1800|35\\d{3})\\d{11}\$"))) {
        return "JCB";
    }
    return null;
}

Wednesday, November 6, 2013

Merge two hashmap by multiple keys using java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package xmlparser;

import java.util.HashMap;

/**
 *
 * @author Pritom K Mondal
 */
public class HashMapMerge {
    public static void main(String[] args) {
        HashMap a = new HashMap();
        
        /**
         * First row
         */
        HashMap b = new HashMap();
        b.put("name", "name-1");
        b.put("roll_0", "roll-11");
        b.put("roll_1", "roll-12");
        HashMap b10 = new HashMap();
        b10.put("item_0", 0);
        b10.put("item_1", 1);
        b.put("item_0", b10);
        
        HashMap c = new HashMap();
        c.put("name", "name-2");
        c.put("roll", "roll-2");
        
        HashMap d = new HashMap();
        d.put("student_0", b);
        d.put("student_1", c);  
        d.put("student_2", "TATA");
        
        /**
         * Second row
         */
        HashMap b1 = new HashMap();
        b1.put("grade", "grade-1");
        HashMap c10 = new HashMap();
        c10.put("item_2", 33);
        c10.put("item_3", 44);
        b1.put("item_0", c10);
        
        HashMap c1 = new HashMap();
        c1.put("grade", "grade-2");
        
        HashMap d1 = new HashMap();
        d1.put("student_0", b1);
        d1.put("student_1", c1); 
        d1.put("student_2", b1);
        
        System.out.println(d);
        System.out.println(d1);
        
        HashMapMerge hashMapMerge = new HashMapMerge();
        a = hashMapMerge.merge(d, d1);
        System.out.println(a);
    }
    
    public HashMap merge(HashMap a, HashMap b) {
        HashMap c = new HashMap();
        
        for(Object key : a.keySet()) {
            String key2 = (String) key;
            Object dup = a.get(key2);
            c.put(key2, dup);
        }
        for(Object key : b.keySet()) {
            String key2 = (String) key;
            Object dup = b.get(key2);
            if(dup instanceof HashMap && c.containsKey(key2) 
                    && c.get(key2) instanceof HashMap) {
                HashMap kk = (HashMap) c.get(key2);
                HashMap p = merge(kk, (HashMap) dup);
                c.put(key2, p);
            } else if(dup instanceof HashMap && c.containsKey(key2) 
                    && !(c.get(key2) instanceof HashMap)) {
                HashMap kk = new HashMap();
                kk.put(key2, c.get(key2));
                HashMap p = merge(kk, (HashMap) dup);
                c.put(key2, p);
            } else {
                c.put(key2, dup);
            } 
        }
        return c;
    }
}

Input map 1:


{
    student_1={
        roll=roll-2, 
        name=name-2
    }, 
    student_0={
        item_0={
            item_1=1, 
            item_0=0
        }, 
        roll_0=roll-11, 
        roll_1=roll-12, 
        name=name-1
    }, 
    student_2=TATA
}

Input map 2:

{
    student_1={
        grade=grade-2
    }, 
    student_0={
        item_0={
            item_3=44, 
            item_2=33
        }, 
        grade=grade-1
    }, 
    student_2={
        item_0={
            item_3=44, 
            item_2=33
        }, 
        grade=grade-1
    }
}

And result map after merge:

{
    student_1={
        roll=roll-2, 
        name=name-2, 
        grade=grade-2
    }, 
    student_0={
        item_0={
            item_1=1, 
            item_0=0, 
            item_3=44, 
            item_2=33
        }, 
        roll_0=roll-11, 
        name=name-1, 
        roll_1=roll-12, 
        grade=grade-1
    }, 
    student_2={
        student_2=TATA, 
        item_0={
            item_3=44, 
            item_2=33
        }, 
        grade=grade-1
    }
}