#include "smoney.h"
#include "clog.h"
#include "cgi.h"
#include "input.h"
#include "wrenchboard_api.h"
//#include "interswitch_sendmoney.h"
#include "safestring.h"
#include "cfg.h"
#include <string>
#include "pgsql.h"
#include "pgsql_wrapper.h"
#include <curl/curl.h>
#include "email.h"
#include "payments.h"
#include "common_tool.h"

long smoney_calls(CVars in, CVars &out) {
    logfmt(logINFO, "smoney_calls()");
    out["result"] = "YES I GET TO BACK END";
    long action = REQ_LONG(in, "action", 0, -1);
    switch (action) {


        case WRENCHBOARD_SMONEY_ADDRECIPIENT:
            return member_addrecipient(in, out);
            break;

        case WRENCHBOARD_SMONEY_MEMBER:
            return member_sendmoney(in, out);
            break;

        case WRENCHBOARD_SMONEY_PROCFEE:
            return member_sendmoney_fee(in, out);
            break;

        case WRENCHBOARD_SMONEY_BKOPROC:
            REQ_LONG(in, "action_mode", 0, -1);
            return bko_process_sendmoney(in, out);
            break;

            //	case WRENCHBOARD_GROUP_CREATEGROUP:
            //		return CreateWrenchBoardGroup( in, out);		
            //	break;
    }
    logfmt(logINFO, "/smoney_calls()");
    return 0;
}

long bko_process_sendmoney(CVars in, CVars &out) {
    long ret = PHP_API_BAD_PARAM;
  const PGresult *res1;
  
    logfmt(logINFO, "long bko_process_sendmoney(CVars in, CVars out)");
    try {

        REQ_LONG(in, "sendmoney_id", 1, -1);
        long action_mode = REQ_LONG(in, "action_mode", 1, -1); // receive the amount in cents

    
                    
        REQ_STRING(in, "trans_tref", 2, 49, "(.*)");
        REQ_STRING(in, "trans_code", 2, 49, "(.*)");

        const PGresult *res = pgsql_query("SELECT * FROM money_transfer WHERE status  = 1 AND completed IS NULL AND id  = %lu", in["sendmoney_id"].Long());        
        if (res != NULL && pgsql_num_rows(res) > 0) {

            switch (action_mode) {

                case SMONEY_PROCC_MANUAL:

                    res1 = pgsql_query("SELECT * FROM money_transfer_transaction WHERE transfer_code IS NULL AND responsecode IS NULL AND detail_id  = %lu", in["sendmoney_id"].Long());
                    if (res1 != NULL && pgsql_num_rows(res1) > 0) {
                        map<const char*, const char*>f = pgsql_fetch_assoc(res1, 0);
                        logfmt(logINFO, "HERE - 1");
                        if (!f.empty()) {
                            logfmt(logINFO, "HERE - 2");
                            CVars rec;
                            map_to_cvars(f, rec);
                            out = rec;
                            logfmt(logINFO, "HERE - 3");

                            // out["status"] = "You have sent or completed a request for this task already.";		
                            pgsql_exec("UPDATE money_transfer_transaction SET transfer_code='SID:%09lu',responsecode='%s',transactionref='%s' WHERE id=%lu", in["sendmoney_id"].Long(), in["trans_code"].c_str(), in["trans_tref"].c_str(), out["id"].Long());
                            pgsql_exec("UPDATE money_transfer SET status=5,completed=now() WHERE status = 1 AND completed IS NULL AND id=%lu", in["sendmoney_id"].Long());
                            out["status"] = "Completed";
                            // send email 
                        }
                    }

                    break;

                case SMONEY_PROCC_INTERSWITCH:
                    logfmt(logINFO, "***** INTERSWITCH CALL long bko_process_sendmoney(CVars in, CVars out)");
                    //return  INTW_doCompleteSavedTransfer(in, out);
                    return -1L;
		    break;
            } 
            


            return ret;
        } else {
            out["status"] = "Invalid Status";
        }




    } catch (bad_parameter) {
        out["log_status"] = "Invalid Log Action";
    }
    logfmt(logINFO, "/long bko_process_sendmoney(CVars in, CVars out)");

    return ret;
}

long member_sendmoney_fee(CVars in, CVars &out) {
    logfmt(logINFO, "long member_sendmoney_rate(CVars in, CVars out)");
	out["processing_fee"] = "0";
    try {

        REQ_LONG(in, "member_id", 1, -1);
        REQ_LONG(in, "amount", 1, -1); // receive the amount in cents

        // this will use database and policy in full design 
        out["processing_fee"] = in["amount"].Long()*0.01 + 12000; // note we have to work in cents 
        out["total_amount"] = out["processing_fee"].Long() + in["amount"].Long();

    } catch (bad_parameter) {
        out["log_status"] = "Invalid Log Action";
    }
    logfmt(logINFO, "/long member_sendmoney_rate(CVars in, CVars out)");
	return  out["processing_fee"].Long();
}

long WRB_doServiceTransferComplete(CVars in, CVars &out);
long do_transferPayment(CVars in) ;
long INTW_configure(CVars in, CVars &out) ;

long member_sendmoney(CVars in, CVars &out) {
 long ret = PHP_API_BAD_PARAM;
    logfmt(logINFO, "************************ E****** member_sendmoney START");
    try {
        REQ_LONG(in, "member_id", 1, -1);
        REQ_LONG(in, "senderid", 1, -1);
        ret =  WRB_doServiceTransferComplete(in, out);
        logfmt(logINFO, "************************ E****** member_sendmoney(CVars in, CVars out) =%lu",ret);
        logfmt(logINFO, "************************ E****** member_sendmoney END");

    } catch (bad_parameter) {
        out["log_status"] = "Error - member_sendmoney *******";
    }
    logfmt(logINFO, "/long member_sendmoney(CVars in, CVars out)");
    return ret;
}

long member_addrecipient(CVars in, CVars &out) {

    logfmt(logINFO, "long member_addrecipient(CVars in, CVars out)");
    long ret = PHP_API_BAD_PARAM;
    const char * loc = getenv("REMOTE_ADDR");
    try {
        REQ_LONG(in, "member_id", 1, -1);

        REQ_STRING(in, "bank_code", 2, 3, "(.*)");
        REQ_STRING(in, "firstname", 2, 49, "(.*)");
        REQ_STRING(in, "lastname", 2, 49, "(.*)");
        REQ_STRING(in, "account_no", 2, 15, "(.*)");
        REQ_LONG(in, "account_type", 1, -1);


        REQ_STRING(in, "country", 2, 3, "(.*)");
        REQ_STRING(in, "state", 2, 49, "(.*)");
        REQ_STRING(in, "city", 2, 49, "(.*)");

        CVars x, xx;

        if (load_db_record(x, "SELECT count(id) AS count_duplicate FROM sendmoney_recipient WHERE member_id = %lu AND account_no='%s' AND status = 1 ", in["member_id"].Long(), in["account_no"].c_str())) {
            if (x["count_duplicate"].Long() > 0) {
                out["error"] = "Duplicate Account Detected";
                return ret;
            }
        }

        if (load_db_record(x, "SELECT count(id) AS count_duplicate FROM sendmoney_recipient WHERE  account_no='%s' AND status IN ( 1, 7 ) ", in["account_no"].c_str())) {
            if (x["count_duplicate"].Long() > 2) {
                out["error"] = "Account used too many times";
                return ret;
            }
        }




        xx["member_id"] = in["member_id"];
        xx["member_id"].set_valid(true);
        xx["bank_code"] = in["bank_code"];
        xx["bank_code"].set_valid(true);
        xx["loc"] = loc;
        xx["loc"].set_valid(true);
        xx["firstname"] = in["firstname"];
        xx["firstname"].set_valid(true);
        xx["lastname"] = in["lastname"];
        xx["lastname"].set_valid(true);
        xx["account_no"] = in["account_no"];
        xx["account_no"].set_valid(true);
        xx["account_type"] = in["account_type"];
        xx["account_type"].set_valid(true);
        xx["country"] = in["country"];
        xx["country"].set_valid(true);
        xx["state"] = in["state"];
        xx["state"].set_valid(true);

        out["recipient_id"] = insert_db_record(DBS_VALID, "sendmoney_recipient", "sendmoney_recipient_id_seq", xx);

        if (out["recipient_id"].Long() > 0) {
            load_db_record(out, "SELECT * FROM sendmoney_recipient WHERE id = %lu",out["recipient_id"].Long() );
            ret = out["recipient_id"].Long(); //PHP_API_OK;
        }

    } catch (bad_parameter) {
        out["log_status"] = "Invalid Action";
    }
    logfmt(logINFO, "/long member_addrecipient(CVars in, CVars out)");


    return ret;
}

/*
  Column    |            Type             |                            Modifiers                             
--------------+-----------------------------+------------------------------------------------------------------
 id           | integer                     | not null default nextval('sendmoney_recipient_id_seq'::regclass)
 member_id    | integer                     | 
 bank_code    | character varying(3)        | 
 firstname    | character varying(50)       | not null
 lastname     | character varying(50)       | not null
 account_no   | character varying(20)       | not null
 added        | timestamp without time zone | default now()
 updated      | timestamp without time zone | default now()
 status       | integer                     | default 1
 account_type | integer                     | default 20
Indexes:
    "sendmoney_recipient_id_key" UNIQUE CONSTRAINT, btree (id)
Foreign-key constraints:
    "sendmoney_recipient_member_id_fkey" FOREIGN KEY (member_id) REFERENCES members(id)
Referenced by:
    TABLE "money_transfer" CONSTRAINT "money_transfer_recipientid_fkey" FOREIGN KEY (recipientid) REFERENCES sendmoney_recipient(id)

 */



long INTW_configure(CVars in, CVars &out) {
    logfmt(logINFO, "long INTW_configure(CVars in, CVars &out)");
    long ret = PHP_API_BAD_PARAM;
    try {
        // Configure Interswitch SSL


        out["interswitch_ver"] = CfgReadLong("interswitch.version");
        out["interswitch_sep"] = CfgReadChar("interswitch.soap_endpoint");
        out["interswitch_tid"] = CfgReadChar("interswitch.terminal_id");
        out["interswitch_code"] = CfgReadChar("interswitch.entity_code");
        out["interswitch_mkey"] = CfgReadChar("interswitch.master_key");
        out["interswitch_pin"] = CfgReadChar("interswitch.pin");
        out["interswitch_pfix"] = CfgReadChar("interswitch.prefix");
        out["interswitch_keyf"] = CfgReadChar("interswitch.keyfile");
        out["interswitch_pass"] = CfgReadChar("interswitch.password");
        out["interswitch_cert"] = CfgReadChar("interswitch.cacert");

        ret = PHP_API_OK;

    } catch (bad_parameter) {

        out["status"] = "Bad parameter";

    } catch (...) {

        out["status"] = "Unhandled exception in INTW_configure";

    }
    logfmt(logINFO, "/long INTW_configure(CVars in, CVars &out)");
    return ret;
}





long do_transferPayment(CVars in) {
    logfmt(logINFO, "START ***** long do_transferPayment(CVars in, CVars &out)");
    long ret = PHP_API_BAD_PARAM;
    CVars out;



	try {
        long member_id = REQ_LONG(in, "member_id", 1, -1);
        long customer_id = REQ_LONG(in, "customer_id", 1, -1);
        long transfer_id = REQ_LONG(in, "transfer_id", 1, -1);
        long payMode = REQ_LONG(in, "mode", 1, -1);
        long payment_id = 0;
        long amount = 0;
        long fee = 0;
        long total = 0;
        long wallet_id = 0;

        REQ_STRING(in, "wallet_uid", 3, 150, "(.*)");
        REQ_STRING(in, "terminating_country_code", 2, 2, "(.*)");

         ret = load_db_record(out, "SELECT balance FROM members WHERE id = %lu AND status = 1", member_id);
            if (ret < 1L) {
                throw new bad_parameter(out, "senderid");
            }

            if (payMode == PAYMENT_MODE) {
                amount = REQ_LONG(in, "amount", 1, -1);
                fee = REQ_LONG(in, "fee", 1, -1);
                total = amount + fee; // make sure you are cent here

                CVars wl;
                if ( load_db_record(wl, "SELECT w.*,c.country,w.amount,w.id AS wallet_id from members_wallet w LEFT join currency c ON c.code=w.currency"
                " WHERE c.country='%s' AND w.member_id=%lu AND w.uid='%s' ",in["terminating_country_code"].c_str(), in["member_id"].Long(),in["wallet_uid"].c_str())> 0){
                    if ( total > wl["amount"].Long() )
                    {
                        out["status_message"] = "insufficient_balance_error";
                        out["status_text"] = "insufficient balance for transaction";
                        return ret;
                    }
                    wallet_id  = wl["wallet_id"].Long();
                }
                else
                {
                     out["status_message"] = "wallet_not_found_error";
                      throw new bad_parameter(out, "senderid");
                    // return ret;
                }



                if (wl["amount"].Long() >= total && wallet_id > 0) // do you have this money
                {
                    CVars x;
                    x["transfer_mode"] = PAYMENT_MODE;
                    x["transfer_mode"].set_valid(true);
                    x["member_id"] = customer_id;
                    x["member_id"].set_valid(true);
                    x["transfer_id"] = transfer_id;
                    x["transfer_id"].set_valid(true);
                    x["amount"] = amount;
                    x["amount"].set_valid(true);
                    x["fee"] = fee;
                    x["fee"].set_valid(true);
                    x["total"] = total;
                    x["total"].set_valid(true);
                    x["current_balance"] = wl["amount"];
                    x["current_balance"].set_valid(true);
                    payment_id = 0;

                    out["sendmoney_payment_id"] = insert_db_record(DBS_VALID, "sendmoney_payment", "sendmoney_payment_id_seq", x);
                    char confirmation[20] = "";
                   // payment_id = out["payment_id"].Long();

                   //  Confirmation(payment_id, confirmation, sizeof (confirmation));
                    ret = PHP_API_BAD_PARAM; // it is still a failure if we get here and did not take the money out of the balance

                    CVars y;
                    y["member_id"] = x["member_id"];
                    y["member_id"].set_valid(true);
                    y["sendmoney_id"] = x["transfer_id"];
                    y["sendmoney_id"].set_valid(true);
                    y["code"] = "SMPAY";
                    y["code"].set_valid(true);
                    y["dir"] = DIR_TARGET;
                    y["dir"].set_valid(true);
                    y["wallet_id"] = wallet_id;
                    y["wallet_id"].set_valid(true);

                    //y["payment_id"] = out["payment_id"];  y["payment_id"].set_valid( true );

                    ret = WrenchSendMoneyPayment(y, out);

                    if (ret == PHP_CREATED_OK) {
                        load_db_record(out, "SELECT amount AS new_balance FROM members_wallet WHERE id = %lu", wallet_id);
                        pgsql_exec("UPDATE sendmoney_payment SET new_balance=%lu WHERE id=%lu", out["new_balance"].Long(), out["sendmoney_payment_id"].Long());
                        ret = PHP_API_OK;
                    }
                }
            }

            if (payMode == REFUND_MODE) {
                if (load_db_record(out, "SELECT * FROM sendmoney_payment WHERE transfer_id = %lu AND member_id = %lu", transfer_id, customer_id)) {
                    logfmt(logINFO, "*****WE RE DO VERIFICATION and NO DUPLICATES)");
                    logfmt(logINFO, "**)");
                    logfmt(logINFO, "**)");
                    logfmt(logINFO, "**)");
                    logfmt(logINFO, "**)");
                    logfmt(logINFO, "**)");
                    logfmt(logINFO, "**)");
                    logfmt(logINFO, "**)");
                    logfmt(logINFO, "**)");
                    CVars out;
                    /*REQ_STRING( in, "TransferCode",         3,  30, "(.*)" );
                    REQ_STRING( in, "requestReference",         3,  30, "(.*)" );*/

                    //int vRet = INTW_querySendMoneyTransaction(in, out);
                    ret = PHP_API_OK;
                }


            }

	} catch (bad_parameter) {
		logfmt(logINFO, "ERROR CALL long do_transferPayment(CVars in, CVars &out***");
	}
    //PAYMENT_MODE
    //REFUND_MODE
    logfmt(logINFO, "END ***** long do_transferPayment(CVars in, CVars &out)");

    return ret;
}
//*****************************************************************************/

long WRB_doServiceTransferComplete(CVars in, CVars &out) {
    logfmt(logINFO, "long WRB_doServiceTransferComplete(CVars in, CVars &out)");
    long ret = PHP_API_BAD_PARAM;
    try {

        out = in;
        // Initiate interswitch session
        CVars setup;
        INTW_configure(in, setup);


        in["action"].set_valid(false);
        REQ_STRING(in, "wallet_uid", 3, 150, "(.*)");
        REQ_STRING(in, "InitiatingEntityCode", 3, 3, "(.*)");
        REQ_LONG(in, "InitiatingAmount", 1, -1);
        REQ_LONG(in, "Fee", 1, -1);
        REQ_LONG(in, "InitiatingChannel", 1, -1);
        REQ_STRING(in, "InitiatingPaymentMethodCode", 2, 2, "(.*)");
        REQ_STRING(in, "InitiatingCurrencyCode", 3, 3, "(.*)");
        REQ_STRING(in, "TerminatingPaymentMethodCode", 2, 2, "(.*)");
        REQ_LONG(in, "TerminatingAmount", 1, -1);
        REQ_STRING(in, "TerminatingCurrencyCode", 3, 3, "(.*)");
        REQ_STRING(in, "TerminatingCountryCode", 2, 2, "(.*)");

        //REQ_STRING( in, "TerminatingEntityCode",        1,  5, "(.*)" );
        //REQ_STRING( in, "TerminatingAccountNumber",     1, 50, "(.*)" );
        //REQ_STRING( in, "TerminatingAccountType",       2,  2, "(.*)" );

        long senderid = REQ_LONG(in, "senderid", 1, -1);
        long recipientid = REQ_LONG(in, "recipientid", 1, -1);

        in["InitiatingEntityCode"] = "MBA";
        in["InitiatingEntityCode"].set_valid(true);


        CVars sender; // Load sender
        ret = load_db_record(sender, "SELECT firstname,lastname FROM members WHERE id = %lu AND status = 1", senderid);
        if (ret < 1L) {
            throw new bad_parameter(out, "senderid");
        }

        long LongTotalCost = in["Fee"].Long() + in["TerminatingAmount"].Long() + 0;

        // LETS DEAL WITH AMONT BALANCE HERE
        // LET CHECK IF YOU HAVE THE WALLET
        CVars wl;
        if ( load_db_record(wl, "SELECT w.*,c.country,w.amount from members_wallet w LEFT join currency c ON c.code=w.currency"
        " WHERE c.country='%s' AND w.member_id=%lu AND w.uid='%s' ",in["TerminatingCountryCode"].c_str(), in["member_id"].Long(),in["wallet_uid"].c_str())> 0){
            if ( LongTotalCost > wl["amount"].Long() )
            {
                out["status_message"] = "insufficient_balance_error";
                out["status_text"] = "insufficient balance for transaction";
                return ret;
            }
        }
        else
        {
             out["status_message"] = "wallet_not_found_error";
             return ret;
        }


        CVars recipient; // Load recipient
        /*recipient["firstname"]  = in["firstname"]; recipient["firstname"].set_valid( true );
        recipient["lastname"]  = in["lastname"]; recipient["lastname"].set_valid( true );
        recipient["account_no"]  = in["account_no"]; recipient["account_no"].set_valid( true );
        recipient["bank_code"]  = in["bank_code"]; recipient["bank_code"].set_valid( true );
        recipient["account_type"]  = in["account_type"]; recipient["account_type"].set_valid( true );*/
        ret = load_db_record(recipient, "SELECT firstname,lastname,account_no,bank_code,account_type FROM sendmoney_recipient WHERE id = %lu AND member_id = %lu AND status = 1", recipientid, senderid);
        if (ret < 1L) {
            throw new bad_parameter(out, "recipientid");
        }

        in["TerminatingEntityCode"] = recipient["bank_code"];
        in["TerminatingEntityCode"].set_valid(true);
        in["TerminatingAccountNumber"] = recipient["account_no"];
        in["TerminatingAccountNumber"].set_valid(true);
        in["transactionID"] = in["transaction_id"];
        in["transactionID"].set_valid(true);

        CVars inx;
        inx["Fee"] = in["Fee"];
        inx["Fee"].set_valid(true);
        inx["InitiatingAmount"] = in["InitiatingAmount"];
        inx["InitiatingAmount"].set_valid(true);

        inx["InitiatingChannel"] = in["InitiatingChannel"];
        inx["InitiatingChannel"].set_valid(true);
        inx["InitiatingCurrencyCode"] = in["InitiatingCurrencyCode"];
        inx["InitiatingCurrencyCode"].set_valid(true);

        inx["InitiatingEntityCode"] = in["InitiatingEntityCode"];
        inx["InitiatingEntityCode"].set_valid(true);
        inx["InitiatingPaymentMethodCode"] = in["InitiatingPaymentMethodCode"];
        inx["InitiatingPaymentMethodCode"].set_valid(true);

        inx["TerminatingAccountNumber"] = in["TerminatingAccountNumber"];
        inx["TerminatingAccountNumber"].set_valid(true);
        inx["TerminatingAmount"] = in["TerminatingAmount"];
        inx["TerminatingAmount"].set_valid(true);

        inx["TerminatingCountryCode"] = in["TerminatingCountryCode"];
        inx["TerminatingCountryCode"].set_valid(true);
        inx["TerminatingCurrencyCode"] = in["TerminatingCurrencyCode"];
        inx["TerminatingCurrencyCode"].set_valid(true);

        inx["TerminatingEntityCode"] = in["TerminatingEntityCode"];
        inx["TerminatingEntityCode"].set_valid(true);
        inx["TerminatingPaymentMethodCode"] = in["TerminatingPaymentMethodCode"];
        inx["TerminatingPaymentMethodCode"].set_valid(true);

        inx["recipientid"] = in["recipientid"];
        inx["recipientid"].set_valid(true);
        inx["member_id"] = in["senderid"];
        inx["member_id"].set_valid(true);
        inx["transactionID"] = in["transactionID"];
        inx["transactionID"].set_valid(true);

        inx["transfer_code"] = "";
        inx["transfer_code"].set_valid(true);


        out["money_transfer_id"] = insert_db_record(DBS_VALID, "money_transfer", " money_transfer_id_seq", inx);
        if (out["money_transfer_id"].Long() < 1L) {
            throw new runtime_error("Failed to create money transfer record");
        }

        const PGresult *res = pgsql_query("SELECT * FROM money_transfer WHERE id=%lu AND member_id = %lu", out["money_transfer_id"].Long(), in["member_id"].Long());
        if (res != NULL && pgsql_num_rows(res) > 0) {

        } else {
            throw new runtime_error("Failed to create money_transfer record");
        }

        CVars transaction;
        transaction["detail_id"] = out["money_transfer_id"];
        transaction["detail_id"].set_valid(true);
        transaction["type"] = 2L;
        /* DoTransfer */ transaction["type"].set_valid(true);
        out["transaction_id"] = insert_db_record(DBS_VALID, "money_transfer_transaction", "money_transfer_transaction_id_seq", transaction);
        if (out["transaction_id"].Long() < 1L) {
            throw new runtime_error("Failed to create money_transfer_transaction  record");
        }
        CVars transaction_final;

        char xtid[12], uniqueRef[20];
        memset(uniqueRef, 0, 20);
        // TransferCode - RequestReference - UniqueRef => request prefix for terminal owner + ID
        sprintf(uniqueRef, "%s%s000000", setup["interswitch_pfix"].c_str(), out["transaction_id"].c_str());
        //sprintf( uniqueRef, "%s%-09lu", setup["interswitch_pfix"].c_str(), out["transaction_id"].Long() );

        transaction["transfer_code"] = uniqueRef;
        transaction["transfer_code"].set_valid(true);
        transaction_final["transfer_code"] = transaction["transfer_code"];
        transaction_final["transfer_code"].set_valid(true);

        pgsql_exec("UPDATE money_transfer SET transfer_code='%s' WHERE id=%lu", transaction_final["transfer_code"].c_str(), out["money_transfer_id"].Long());

        //sprintf( xtid, "%s", setup["interswitch_tid"].c_str() );
        sprintf(xtid, "%s", setup["interswitch_tid"].c_str());


        //in["SenderEmail"] = sender["email"]; in["SenderEmail"].set_valid(true);
        //in["BeneficiaryEmail"] = recipient["email"]; in["BeneficiaryEmail"].set_valid(true);

        //*TAKE THE MONEY NOW
        CVars pm;
        pm["customer_id"] = senderid;
        pm["customer_id"].set_valid(true);
        pm["member_id"] =  in["member_id"];
        pm["member_id"].set_valid(true);
        pm["transfer_id"] = out["money_transfer_id"];
        pm["transfer_id"].set_valid(true);
        pm["amount"] = in["InitiatingAmount"];
        pm["amount"].set_valid(true);
        pm["fee"] = in["Fee"];
        pm["fee"].set_valid(true);
        pm["mode"] = PAYMENT_MODE;
        pm["mode"].set_valid(true);
        pm["wallet_uid"] = in["wallet_uid"];
        pm["wallet_uid"].set_valid(true);
        pm["terminating_country_code"] = in["TerminatingCountryCode"];
        pm["terminating_country_code"].set_valid(true);
        /*
        #define SM_PENDING 1
        #define SM_CANCEL  3
        #define SM_FAILED  4
        #define SM_COMPLETED 5
         */
         // REQ_STRING(in, "wallet_uid", 3, 150, "(.*)"); make sure we align the wallet
        if (do_transferPayment(pm) == PHP_API_OK) {
            out["sendmoney_status"] = SM_PENDING;
            in["sendmoney_id"] = out["money_transfer_id"];
			ret = PHP_API_OK;
            sendmoney_email(SM_PENDING, in, out);
            // all is good on money side
            logfmt(logINFO, "*** ALL Good ------ ****** ");
        } else {
            out["sendmoney_status"] = SM_FAILED;
            throw new runtime_error("Failed to create payment record");
        }

        load_db_record(out, "SELECT r.firstname, r.lastname, m.*,mp.confirmation,r.firstname||' '||r.lastname  AS Recitient,"
                            " r.account_no,b.name AS bank_name  FROM money_transfer m "
                            " LEFT JOIN members_payments mp ON mp.what_sendmoney = m.id "
                            " LEFT JOIN sendmoney_recipient r ON r.id = m.recipientid "
                            " LEFT JOIN bank_entity_codes b ON b.code = r.bank_code WHERE m.id=%lu", out["money_transfer_id"].Long());

    } catch (runtime_error& ex) {

        out["status"] = ex.what();
        ret = PHP_API_BAD_PARAM;

    } catch (bad_parameter) {

        out["status"] = "Invalid input";
        ret = PHP_API_BAD_PARAM;

    } catch (...) {

        out["status"] = "Unhandled exception in INTW_doTransfer";
        ret = PHP_API_BAD_PARAM;

    }

    //out["wallet"].set_valid( false );

    logfmt(logINFO, "/long WRB_doServiceTransferComplete(CVars in, CVars &out)");
    return ret;

}
