// Account management toosl #include "clog.h" #include "cgi.h" #include "input.h" #include "wrenchboard_api.h" #include "payments.h" #include "common_tool.h" #include "email.h" #include "safestring.h" #include #include "pgsql.h" #include "pgsql_wrapper.h" #include "cfg.h" #include #include "stripe_charge.h" /* CREATE TABLE payment_types ( id SERIAL, type_code varchar(25) UNIQUE NOT NULL, code varchar(5) UNIQUE NOT NULL, dir INT DEFAULT 0 ) ALTER TABLE ONLY payment_types ADD CONSTRAINT payment_types_id_key UNIQUE (id); INSERT INTO payment_types(type_code,code,dir) VALUES('OFFER_PYM_DEPOSIT','OFDPS',0); INSERT INTO payment_types(type_code,code,dir) VALUES('OFFER_PYM_REFUND','OFRFD',1); -- // refund if offer was rejected or not accepted */ long WrenchCanceContractPayment( CVars in, CVars &out ) { /* y["member_id"] = in["member_id"]; // note we are actually paying the client_id y["contract_id"] = in["job_id"]; y["code"] = "COPAY"; y["dir"] = DIR_TARGET; */ long ret = PHP_API_BAD_PARAM; //ULONG payment_id = 0; const char * loc = getenv("REMOTE_ADDR"); in["loc"] = loc; in["loc"].set_valid(true); long member_id = REQ_LONG( in, "member_id", 1, -1 ); long contract_id = REQ_LONG( in, "contract_id", 1, -1 ); REQ_LONG( in, "dir", 1, -1 ); REQ_STRING (in, "code", 4, 5, "(.*)"); //long offer_id = REQ_LONG( in, "offer_id", 1, -1 ); long payment_id = 0; // //long client_id = 0; long offer_id = 0; long amount = 0; //IS THIS JOB COMPLETED AND ACCEPTED YET if ( load_db_record( out, "SELECT * FROM members_jobs_contract WHERE status =%lu AND id=%lu AND member_id =%lu",in["job_status"].Long(),contract_id,in["member_id"].Long() ) ) { member_id = out["member_id"].Long(); // NOTE THAT WE ARE REFUNDING SO CLIENT IS SAME AS MEMBER FOR THIS REFUND } else{ out["status_message"] = "Task is not in complete mode"; return PHP_API_BAD_PARAM; } CVars y; if ( load_db_record( y, "SELECT * FROM members_payments WHERE code ='OFDPS' AND confirmation IS NOT NULL AND status=1 AND flags=4 AND what_contract= %lu AND member_id =%lu",contract_id,in["member_id"].Long() ) ) { payment_id = y["id"].Long(); offer_id = y["what_offer"].Long(); amount = y["amount"].Long(); } else{ out["status_message"] = "Task payment not found"; return PHP_API_BAD_PARAM; } if (member_id <=0 || payment_id<=0) { out["status_message"] = "Client or Payment not properly determined"; return PHP_API_BAD_PARAM; } // TEST FOR DUPLICATE long retDb = load_db_record( out, "SELECT balance AS curr_balance FROM members WHERE id = %lu", member_id); if (retDb) { in["curr_balance"] =out["curr_balance"]; in["curr_balance"].set_valid( true ); // get this one LIVE } else { out["status"] = "Unable to get client balance"; out["status_message"] = out["status"]; return PHP_API_BAD_PARAM; } /* // TEST FOR DUPLICATE long retDb = load_db_record( out, "SELECT balance AS curr_balance FROM members WHERE id = %lu", in["member_id"].Long()); if (retDb) { in["curr_balance"] =out["curr_balance"]; in["curr_balance"].set_valid( true ); // get this one LIVE } else { out["status"] = "Duplicate payment detetected"; return PHP_API_BAD_PARAM; } */ long retDb2 = load_db_record( out, "SELECT * FROM members_payments WHERE id =%lu AND what_offer = %lu AND member_id=%lu AND code = 'OFDPS' AND status = 1 AND flags = 4 AND confirmation IS NOT NULL",payment_id,offer_id,member_id); if (retDb2) { CVars x; x["member_id"] = member_id; x["member_id"].set_valid( true ); x["code"] = in["code"]; x["code"].set_valid( true ); x["dir"] = in["dir"]; x["dir"].set_valid( true ); x["loc"] = in["loc"]; x["loc"].set_valid( true ); x["curr_balance"] = in["curr_balance"]; x["curr_balance"].set_valid( true ); x["amount"] = amount; x["amount"].set_valid( true ); x["fee"] = "0"; x["fee"].set_valid( true ); x["what_offer"] = offer_id; x["what_offer"].set_valid( true ); x["what_contract"] = contract_id; x["what_contract"].set_valid( true ); x["flags"] = FLAG_INIT; x["flags"].set_valid( true ); // starting the pprocess payment_id = insert_db_record( DBS_VALID, "members_payments", "members_payments_id_seq", x ); if (payment_id) { ret = PHP_CREATED_OK; x["flags"] = FLAG_START; x["flags"].set_valid( true ); // done not completed yet // now generate the confirmation pgsql_exec("UPDATE members SET balance=balance + %lu WHERE id = %lu",x["amount"].Long(),x["member_id"].Long() ); // pay attention to who you pay here char confirmation[15] = ""; Confirmation(payment_id, confirmation, sizeof (confirmation)); // this stamp the offer code directly in that call x["flags"] = FLAG_OK; x["flags"].set_valid( true ); x["payment_id"] = payment_id; x["payment_id"].set_valid( true ); pgsql_exec("UPDATE members_payments SET flags = %lu WHERE id = %lu",x["flags"].Long(),payment_id ); //pgsql_exec("UPDATE members_jobs_offer SET payment_id = %lu WHERE id = %lu",x["payment_id"].Long(),x["what_offer"].Long() ); load_db_record( out, "SELECT * FROM members_payments WHERE id = %lu ", payment_id ); } else { out["status"] = "Unable to create payment"; } } return ret; } long WrenchOfferPayment( CVars in, CVars &out ) { /* wrenchboard=> \d members_payments; Table "public.members_payments" Column | Type | Modifiers ----------------+-----------------------------+--------------------------------------------------------------- id | integer | not null default nextval('members_payments_id_seq'::regclass) member_id | integer | code | character varying(5) | dir | integer | not null curr_balance | integer | default 0 amount | integer | default 0 fee | integer | default 0 confirmation | character varying(15) | status | integer | default 1 flags | integer | default 1 added | timestamp without time zone | default now() updated | timestamp without time zone | default now() loc | inet | what_offer | integer | what_contract | integer | what_sendmoney | integer | Indexes: "members_payments_confirmation_key" UNIQUE CONSTRAINT, btree (confirmation) "members_payments_id_key" UNIQUE CONSTRAINT, btree (id) Foreign-key constraints: "members_payments_code_fkey" FOREIGN KEY (code) REFERENCES payment_types(code) "members_payments_member_id_fkey" FOREIGN KEY (member_id) REFERENCES members(id) "members_payments_what_contract_fkey" FOREIGN KEY (what_contract) REFERENCES members_jobs_contract(id) "members_payments_what_offer_fkey" FOREIGN KEY (what_offer) REFERENCES members_jobs_offer(id) "members_payments_what_sendmoney_fkey" FOREIGN KEY (what_sendmoney) REFERENCES money_transfer(id) */ long ret = PHP_API_BAD_PARAM; logfmt( logINFO, "WrenchOfferPayment()" ); ULONG payment_id = 0; const char * loc = getenv("REMOTE_ADDR"); in["loc"] = loc; in["loc"].set_valid(true); REQ_LONG( in, "member_id", 1, -1 ); REQ_STRING (in, "code", 4, 5, "(.*)"); REQ_LONG( in, "dir", 1, -1 ); REQ_LONG( in, "offer_id", 1, -1 ); long retDb = load_db_record( out, "SELECT balance AS curr_balance FROM members WHERE id = %lu", in["member_id"].Long()); if (retDb) { in["curr_balance"] =out["curr_balance"]; in["curr_balance"].set_valid( true ); // get this one LIVE } else { out["status"] = "Invalid user"; return PHP_API_BAD_PARAM; } long retDb2 = load_db_record( out, "SELECT jj.price,0 as fee FROM members_jobs_offer j LEFT JOIN members_jobs jj ON jj.id=j.job_id WHERE j.id =%lu ",in["offer_id"].Long()); if (retDb2) { in["amount"] =out["price"]; in["amount"].set_valid( true ); // get this one LIVE in["fee"] =out["fee"]; in["fee"].set_valid( true ); // get this one LIVE } else { out["status"] = "Invalid offer"; return PHP_API_BAD_PARAM; } long totalAmount = in["amount"].Long() + in["fee"].Long(); if ( in["curr_balance"] < in["amount"].Long() + in["fee"].Long()) { out["status"] = "Insufficient balance for this offer"; return PHP_API_BAD_PARAM; } // if you have enough money for this offer // flags // CVars x; x["member_id"] = in["member_id"]; x["member_id"].set_valid( true ); x["code"] = in["code"]; x["code"].set_valid( true ); x["dir"] = in["dir"]; x["dir"].set_valid( true ); x["loc"] = in["loc"]; x["loc"].set_valid( true ); x["curr_balance"] = in["curr_balance"]; x["curr_balance"].set_valid( true ); x["amount"] = in["amount"]; x["amount"].set_valid( true ); x["fee"] = in["fee"]; x["fee"].set_valid( true ); x["what_offer"] = in["offer_id"]; x["what_offer"].set_valid( true ); x["flags"] = FLAG_INIT; x["flags"].set_valid( true ); // starting the pprocess payment_id = insert_db_record( DBS_VALID, "members_payments", "members_payments_id_seq", x ); out["payment_id"] = payment_id; out["payment_id"].set_valid( true ); if (payment_id) { ret = PHP_CREATED_OK; x["flags"] = FLAG_START; x["flags"].set_valid( true ); // done not completed yet // now generate the confirmation pgsql_exec("UPDATE members SET balance=balance - %lu WHERE id = %lu",in["amount"].Long() + in["fee"].Long(),in["member_id"].Long() ); char confirmation[15] = ""; Confirmation(payment_id, confirmation, sizeof (confirmation)); // this stamp the offer code directly in that call x["flags"] = FLAG_OK; x["flags"].set_valid( true ); x["payment_id"] = payment_id; x["payment_id"].set_valid( true ); pgsql_exec("UPDATE members_payments SET flags = %lu WHERE id = %lu",x["flags"].Long(),payment_id ); pgsql_exec("UPDATE members_jobs_offer SET payment_id = %lu WHERE id = %lu",x["payment_id"].Long(),x["what_offer"].Long() ); load_db_record( out, "SELECT * FROM members_payments WHERE id = %lu ", payment_id ); } else { out["status"] = "Uanble to create payment"; } logfmt( logINFO, "/WrenchOfferPayment()" ); return ret; } long WrenchRefundoffer( CVars in, CVars &out ) { long ret = PHP_API_BAD_PARAM; //ULONG payment_id = 0; const char * loc = getenv("REMOTE_ADDR"); in["loc"] = loc; in["loc"].set_valid(true); long member_id = REQ_LONG( in, "member_id", 1, -1 ); REQ_STRING (in, "code", 4, 5, "(.*)"); REQ_LONG( in, "dir", 1, -1 ); long offer_id = REQ_LONG( in, "offer_id", 1, -1 ); long payment_id = REQ_LONG( in, "payment_id", 1, -1 ); long retDb = load_db_record( out, "SELECT balance AS curr_balance FROM members WHERE id = %lu", in["member_id"].Long()); if (retDb) { in["curr_balance"] =out["curr_balance"]; in["curr_balance"].set_valid( true ); // get this one LIVE } else { out["status"] = "Invalid user"; return PHP_API_BAD_PARAM; } long retDb2 = load_db_record( out, "SELECT * FROM members_payments WHERE id =%lu AND what_offer = %lu AND member_id=%lu AND code = 'OFDPS' AND status = 1 AND flags = 4 AND confirmation IS NOT NULL",payment_id,offer_id,member_id); if (retDb2) { CVars x; x["member_id"] = in["member_id"]; x["member_id"].set_valid( true ); x["code"] = in["code"]; x["code"].set_valid( true ); x["dir"] = in["dir"]; x["dir"].set_valid( true ); x["loc"] = in["loc"]; x["loc"].set_valid( true ); x["curr_balance"] = in["curr_balance"]; x["curr_balance"].set_valid( true ); x["amount"] = out["amount"]; x["amount"].set_valid( true ); x["fee"] = out["fee"]; x["fee"].set_valid( true ); x["what_offer"] = out["what_offer"]; x["what_offer"].set_valid( true ); x["flags"] = FLAG_INIT; x["flags"].set_valid( true ); // starting the pprocess payment_id = insert_db_record( DBS_VALID, "members_payments", "members_payments_id_seq", x ); if (payment_id) { ret = PHP_CREATED_OK; x["flags"] = FLAG_START; x["flags"].set_valid( true ); // done not completed yet // now generate the confirmation pgsql_exec("UPDATE members SET balance=balance + %lu WHERE id = %lu",x["amount"].Long() + x["fee"].Long(),in["member_id"].Long() ); char confirmation[15] = ""; Confirmation(payment_id, confirmation, sizeof (confirmation)); // this stamp the offer code directly in that call x["flags"] = FLAG_OK; x["flags"].set_valid( true ); x["payment_id"] = payment_id; x["payment_id"].set_valid( true ); pgsql_exec("UPDATE members_payments SET flags = %lu WHERE id = %lu",x["flags"].Long(),payment_id ); //pgsql_exec("UPDATE members_jobs_offer SET payment_id = %lu WHERE id = %lu",x["payment_id"].Long(),x["what_offer"].Long() ); load_db_record( out, "SELECT * FROM members_payments WHERE id = %lu ", payment_id ); } else { out["status"] = "Unable to create payment"; } } return ret; } long WrenchContractPayment( CVars in, CVars &out ) { /* y["member_id"] = in["member_id"]; // note we are actually paying the client_id y["contract_id"] = in["job_id"]; y["code"] = "COPAY"; y["dir"] = DIR_TARGET; */ long ret = PHP_API_BAD_PARAM; //ULONG payment_id = 0; const char * loc = getenv("REMOTE_ADDR"); in["loc"] = loc; in["loc"].set_valid(true); long member_id = REQ_LONG( in, "member_id", 1, -1 ); long contract_id = REQ_LONG( in, "contract_id", 1, -1 ); REQ_LONG( in, "dir", 1, -1 ); REQ_STRING (in, "code", 4, 5, "(.*)"); //long offer_id = REQ_LONG( in, "offer_id", 1, -1 ); long payment_id = 0; // long client_id = 0; long offer_id = 0; long amount = 0; //IS THIS JOB COMPLETED AND ACCEPTED YET if ( load_db_record( out, "SELECT * FROM members_jobs_contract WHERE status = %lu AND id=%lu AND member_id =%lu",CONTRACT_ACCEPT_COMPLETE,contract_id,in["member_id"].Long() ) ) { client_id = out["client_id"].Long(); } else{ out["status_message"] = "Task is not in complete mode"; return PHP_API_BAD_PARAM; } CVars y; if ( load_db_record( y, "SELECT * FROM members_payments WHERE code ='OFDPS' AND confirmation IS NOT NULL AND status=1 AND flags=4 AND what_contract= %lu AND member_id =%lu",contract_id,in["member_id"].Long() ) ) { payment_id = y["id"].Long(); offer_id = y["what_offer"].Long(); amount = y["amount"].Long(); } else{ out["status_message"] = "Task is not in complete mode"; return PHP_API_BAD_PARAM; } if (client_id <=0 || payment_id<=0) { out["status_message"] = "Client or Payment not properly determined"; return PHP_API_BAD_PARAM; } // TEST FOR DUPLICATE long retDb = load_db_record( out, "SELECT balance AS curr_balance FROM members WHERE id = %lu", client_id); if (retDb) { in["curr_balance"] =out["curr_balance"]; in["curr_balance"].set_valid( true ); // get this one LIVE } else { out["status"] = "Unable to get client balance"; return PHP_API_BAD_PARAM; } /* // TEST FOR DUPLICATE long retDb = load_db_record( out, "SELECT balance AS curr_balance FROM members WHERE id = %lu", in["member_id"].Long()); if (retDb) { in["curr_balance"] =out["curr_balance"]; in["curr_balance"].set_valid( true ); // get this one LIVE } else { out["status"] = "Duplicate payment detetected"; return PHP_API_BAD_PARAM; } */ long retDb2 = load_db_record( out, "SELECT * FROM members_payments WHERE id =%lu AND what_offer = %lu AND member_id=%lu AND code = 'OFDPS' AND status = 1 AND flags = 4 AND confirmation IS NOT NULL",payment_id,offer_id,member_id); if (retDb2) { CVars x; x["member_id"] = client_id; x["member_id"].set_valid( true ); x["code"] = in["code"]; x["code"].set_valid( true ); x["dir"] = in["dir"]; x["dir"].set_valid( true ); x["loc"] = in["loc"]; x["loc"].set_valid( true ); x["curr_balance"] = in["curr_balance"]; x["curr_balance"].set_valid( true ); x["amount"] = amount; x["amount"].set_valid( true ); x["fee"] = "0"; x["fee"].set_valid( true ); x["what_offer"] = offer_id; x["what_offer"].set_valid( true ); x["what_contract"] = contract_id; x["what_contract"].set_valid( true ); x["flags"] = FLAG_INIT; x["flags"].set_valid( true ); // starting the pprocess payment_id = insert_db_record( DBS_VALID, "members_payments", "members_payments_id_seq", x ); if (payment_id) { ret = PHP_CREATED_OK; x["flags"] = FLAG_START; x["flags"].set_valid( true ); // done not completed yet // now generate the confirmation pgsql_exec("UPDATE members SET balance=balance + %lu WHERE id = %lu",x["amount"].Long(),x["member_id"].Long() ); // pay attention to who you pay here char confirmation[15] = ""; Confirmation(payment_id, confirmation, sizeof (confirmation)); // this stamp the offer code directly in that call x["flags"] = FLAG_OK; x["flags"].set_valid( true ); x["payment_id"] = payment_id; x["payment_id"].set_valid( true ); pgsql_exec("UPDATE members_payments SET flags = %lu WHERE id = %lu",x["flags"].Long(),payment_id ); //pgsql_exec("UPDATE members_jobs_offer SET payment_id = %lu WHERE id = %lu",x["payment_id"].Long(),x["what_offer"].Long() ); load_db_record( out, "SELECT * FROM members_payments WHERE id = %lu ", payment_id ); } else { out["status"] = "Unable to create payment"; } } return ret; } long WrenchSendMoneyPayment( CVars in, CVars &out ) { /* wrenchboard=> \d members_payments; Table "public.members_payments" Column | Type | Modifiers ----------------+-----------------------------+--------------------------------------------------------------- id | integer | not null default nextval('members_payments_id_seq'::regclass) member_id | integer | code | character varying(5) | dir | integer | not null curr_balance | integer | default 0 amount | integer | default 0 fee | integer | default 0 confirmation | character varying(15) | status | integer | default 1 flags | integer | default 1 added | timestamp without time zone | default now() updated | timestamp without time zone | default now() loc | inet | what_offer | integer | what_contract | integer | what_sendmoney | integer | Indexes: "members_payments_confirmation_key" UNIQUE CONSTRAINT, btree (confirmation) "members_payments_id_key" UNIQUE CONSTRAINT, btree (id) Foreign-key constraints: "members_payments_code_fkey" FOREIGN KEY (code) REFERENCES payment_types(code) "members_payments_member_id_fkey" FOREIGN KEY (member_id) REFERENCES members(id) "members_payments_what_contract_fkey" FOREIGN KEY (what_contract) REFERENCES members_jobs_contract(id) "members_payments_what_offer_fkey" FOREIGN KEY (what_offer) REFERENCES members_jobs_offer(id) "members_payments_what_sendmoney_fkey" FOREIGN KEY (what_sendmoney) REFERENCES money_transfer(id) */ long ret = PHP_API_BAD_PARAM; logfmt( logINFO, "WrenchSendMoneyPayment()" ); ULONG payment_id = 0; const char * loc = getenv("REMOTE_ADDR"); in["loc"] = loc; in["loc"].set_valid(true); REQ_LONG( in, "member_id", 1, -1 ); REQ_STRING (in, "code", 4, 5, "(.*)"); REQ_LONG( in, "dir", 1, -1 ); REQ_LONG( in, "sendmoney_id", 1, -1 ); long retDb = load_db_record( out, "SELECT balance AS curr_balance FROM members WHERE id = %lu", in["member_id"].Long()); if (retDb) { in["curr_balance"] =out["curr_balance"]; in["curr_balance"].set_valid( true ); // get this one LIVE } else { out["status"] = "Invalid user"; return PHP_API_BAD_PARAM; } long retDb2 = load_db_record( out, "SELECT id,initiatingamount AS amount,fee from money_transfer WHERE member_id= %lu AND id = %lu",in["member_id"].Long(), in["sendmoney_id"].Long()); if (retDb2) { in["amount"] =out["amount"]; in["amount"].set_valid( true ); // get this one LIVE in["fee"] =out["fee"]; in["fee"].set_valid( true ); // get this one LIVE } else { out["status"] = "Invalid offer"; return PHP_API_BAD_PARAM; } long totalAmount = in["amount"].Long() + in["fee"].Long(); if ( in["curr_balance"] < in["amount"].Long() + in["fee"].Long()) { out["status"] = "Insufficient balance for this offer"; return PHP_API_BAD_PARAM; } // if you have enough money for this offer // flags // CVars x; x["member_id"] = in["member_id"]; x["member_id"].set_valid( true ); x["code"] = in["code"]; x["code"].set_valid( true ); x["dir"] = in["dir"]; x["dir"].set_valid( true ); x["loc"] = in["loc"]; x["loc"].set_valid( true ); x["curr_balance"] = in["curr_balance"]; x["curr_balance"].set_valid( true ); x["amount"] = in["amount"]; x["amount"].set_valid( true ); x["fee"] = in["fee"]; x["fee"].set_valid( true ); x["what_sendmoney"] = in["sendmoney_id"]; x["what_sendmoney"].set_valid( true ); x["flags"] = FLAG_INIT; x["flags"].set_valid( true ); // starting the pprocess payment_id = insert_db_record( DBS_VALID, "members_payments", "members_payments_id_seq", x ); // return if not good const PGresult *res = pgsql_query("SELECT * FROM members_payments WHERE id=%lu AND member_id = %lu",payment_id, x["member_id"].Long() ); if (res!=NULL && pgsql_num_rows(res)>0) { } else { out["status"] = "Failure to create"; return PHP_API_BAD_PARAM; } out["payment_id"] = payment_id; out["payment_id"].set_valid( true ); if (payment_id) { ret = PHP_CREATED_OK; x["flags"] = FLAG_START; x["flags"].set_valid( true ); // done not completed yet // now generate the confirmation pgsql_exec("UPDATE members SET balance=balance - %lu WHERE id = %lu",in["amount"].Long() + in["fee"].Long(),in["member_id"].Long() ); char confirmation[15] = ""; Confirmation(payment_id, confirmation, sizeof (confirmation)); // this stamp the offer code directly in that call x["flags"] = FLAG_OK; x["flags"].set_valid( true ); x["payment_id"] = payment_id; x["payment_id"].set_valid( true ); pgsql_exec("UPDATE members_payments SET flags = %lu WHERE id = %lu",x["flags"].Long(),payment_id ); load_db_record( out, "SELECT * FROM members_payments WHERE id = %lu ", payment_id ); } else { out["status"] = "Uanble to create payment"; } logfmt( logINFO, "/WrenchSendMoneyPayment()" ); return ret; } //******************************************************************************