diff --git a/lib/command-handler/adddownline.js b/lib/command-handler/adddownline.js
index fca2ded..b9008dc 100644
--- a/lib/command-handler/adddownline.js
+++ b/lib/command-handler/adddownline.js
@@ -1,16 +1,24 @@
 "use strict";
 
+const common = require('../common');
 const commandError = require('./error');
 const coreapi = require('../coreapi');
 
 const coreEndpoint = '/stores/create';
 
 function help(keyword) {
-    return `Untuk membuat downline baru, ketik perintah dengan format: ${ keyword.toUpperCase() }.<NAMADOWNLINE>.<PIN>`;
+    return `
+        Untuk membuat downline baru, ketik dgn format:
+        ${ keyword.toUpperCase() }.<NAMADOWNLINE>.<PIN>
+        atau
+        ${ keyword.toUpperCase() }.<NAMADOWNLINE>.<TERMINAL>.<PIN>
+        atau
+        ${ keyword.toUpperCase() }.<NAMADOWNLINE>.<TERMINAL>.<MARKUP>.<PIN>
+    `.replace(/^\s+/mg, '').replace(/\s+$/mg, '').trim();
 }
 
 function execute(tokens, params, cb) {
-    
+
     if (!tokens || tokens.length < 3) {
         const responseParams = {
             body: `${ commandError.ERR_INVALID_FORMAT }. ${ help(tokens[0]) }`
@@ -22,10 +30,39 @@ function execute(tokens, params, cb) {
 
     const coreParams = {
         asker_terminal_name: params.from,
+        asker_terminal_password: null,
         new_store_name: tokens[1],
-        asker_terminal_password: tokens[2],
+        new_terminal_name: null,
+        markup: null,
     };
 
+    if (tokens.length === 3) {
+        coreParams.asker_terminal_password = tokens[2];
+    } else if (tokens.length === 4) {
+        coreParams.new_terminal_name = tokens[2];
+        coreParams.asker_terminal_password = tokens[3];
+        coreParams.generate_password = 1;
+    } else if (tokens.length === 5) {
+        coreParams.new_terminal_name = tokens[2];
+        coreParams.markup = tokens[3];
+        coreParams.asker_terminal_password = tokens[4];
+        coreParams.generate_password = 1;
+    }
+
+    if (typeof coreParams.new_terminal_name === 'string' && coreParams.new_terminal_name.indexOf('@') < 0) {
+        let suffix = '';
+        if (common.isPhoneNumber(coreParams.new_terminal_name)) {
+            coreParams.new_terminal_name = common.indonesiaIntlNumberToZeroPrefix(coreParams.new_terminal_name);
+            suffix = '@phonenumber';
+        } else {
+            suffix = common.guessSuffix(coreParams.asker_terminal_name);
+        }
+    
+        if (suffix) {
+            coreParams.new_terminal_name += suffix;
+        }
+    }
+
     coreapi(coreEndpoint, coreParams, 'GET', cb);
 }
 
diff --git a/lib/command-handler/error.js b/lib/command-handler/error.js
index d3a9e3d..eb6c231 100644
--- a/lib/command-handler/error.js
+++ b/lib/command-handler/error.js
@@ -2,7 +2,7 @@
 
 exports.ERR_EMPTY_MESSAGE = 'Tidak dapat memproses pesan kosong';
 exports.ERR_UNKNOWN_COMMAND_GROUP = 'Perintah tidak dikenal';
-exports.ERR_INVALID_FORMAT = 'Format perintah salah';
+exports.ERR_INVALID_FORMAT = 'Perintah salah';
 exports.ERR_INVALID_CREDENTIAL = 'Kesalahan kredensial. User atau PIN tidak sesuai';
 exports.ERR_INVALID_CORE_RESPONSE = 'Respon CORE tidak valid';
 exports.ERR_INVALID_CORE_HTTP_STATUS_RESPONSE = 'CORE tidak merespon dengan HTTP status 200';
diff --git a/lib/common.js b/lib/common.js
new file mode 100644
index 0000000..a15ff27
--- /dev/null
+++ b/lib/common.js
@@ -0,0 +1,32 @@
+function guessSuffix(terminalName) {
+    if (typeof terminalName !== 'string') {
+        return;
+    }
+
+    const items = terminalName.split('@');
+    if (!items || (items.length < 2)) return;
+
+    return `@${items[items.length - 1]}`;
+}
+
+function isPhoneNumber(terminalName) {
+    if (typeof terminalName !== 'string') {
+        return false;
+    }
+
+    if (!terminalName) return false;
+
+    return Boolean(terminalName.replace(/^\+/, '').match(/^\d+$/));
+}
+
+function indonesiaIntlNumberToZeroPrefix(phoneNumber) {
+    if (!isPhoneNumber(phoneNumber)) {
+        return phoneNumber;
+    }
+
+    return phoneNumber.replace(/^\+62/, '0');
+}
+
+exports.guessSuffix = guessSuffix;
+exports.isPhoneNumber = isPhoneNumber;
+exports.indonesiaIntlNumberToZeroPrefix = indonesiaIntlNumberToZeroPrefix;
diff --git a/test/common.js b/test/common.js
new file mode 100644
index 0000000..ba97a7f
--- /dev/null
+++ b/test/common.js
@@ -0,0 +1,34 @@
+/* global describe it */
+
+const should = require('should');
+const common = require('../lib/common');
+
+describe('#common', () => {
+    describe('#guessSuffix', () => {
+        it('should handle missing suffix', () => {
+            should.not.exist(common.guessSuffix('xxx'));
+        });
+
+        it('should return correct suffix', () => {
+            common.guessSuffix('xxx@yyy').should.equal('@yyy');
+            common.guessSuffix('xxx@yyy@zzz').should.equal('@zzz');
+        })
+    });
+
+    describe('#isPhoneNumber', () => {
+        it('should detect correctly', () => {
+            common.isPhoneNumber('0818').should.be.ok();
+            common.isPhoneNumber('62818').should.be.ok();
+            common.isPhoneNumber('+62818').should.be.ok();
+            common.isPhoneNumber('ada').should.not.be.ok();
+        });
+    });
+
+    describe('#indonesiaIntlNumberToZeroPrefix', () => {
+        it('should transform correctly', () => {
+            common.indonesiaIntlNumberToZeroPrefix('+62818').should.equal('0818');
+            common.indonesiaIntlNumberToZeroPrefix('0818').should.equal('0818');
+            common.indonesiaIntlNumberToZeroPrefix('ada').should.equal('ada');
+        });
+    })
+});
\ No newline at end of file