int AuthorizeDotNetProcessor::doCharge(const int pccardid, const int pcvv, const double pamount, const double ptax, const bool ptaxexempt, const double pfreight, const double pduty, const int pcurrid, QString& pneworder, QString& preforder, int &pccpayid, ParameterList &pparams) { if (DEBUG) qDebug("AN:doCharge(%d, %d, %f, %f, %d, %f, %f, %d, %s, %s, %d)", pccardid, pcvv, pamount, ptax, ptaxexempt, pfreight, pduty, pcurrid, pneworder.toAscii().data(), preforder.toAscii().data(), pccpayid); int returnValue = 0; double amount = pamount; double tax = ptax; double freight = pfreight; double duty = pduty; int currid = pcurrid; if (_metrics->value("CCANCurrency") != "TRANS") { currid = _metrics->value("CCANCurrency").toInt(); amount = currToCurr(pcurrid, currid, pamount, &returnValue); if (returnValue < 0) return returnValue; tax = currToCurr(pcurrid, currid, ptax, &returnValue); if (returnValue < 0) return returnValue; freight = currToCurr(pcurrid, currid, pfreight, &returnValue); if (returnValue < 0) return returnValue; duty = currToCurr(pcurrid, currid, pduty, &returnValue); if (returnValue < 0) return returnValue; } QString request; returnValue = buildCommon(pccardid, pcvv, amount, currid, request, "AUTH_CAPTURE"); if (returnValue != 0) return returnValue; APPENDFIELD(request, "x_tax", QString::number(tax)); APPENDFIELD(request, "x_tax_exempt", ptaxexempt ? "TRUE" : "FALSE"); APPENDFIELD(request, "x_freight", QString::number(freight)); APPENDFIELD(request, "x_duty", QString::number(duty)); if (! preforder.isEmpty()) APPENDFIELD(request, "x_po_num", preforder); QString response; returnValue = sendViaHTTP(request, response); if (returnValue < 0) return returnValue; returnValue = handleResponse(response, pccardid, "C", amount, currid, pneworder, preforder, pccpayid, pparams); return returnValue; }
int AuthorizeDotNetProcessor::doVoidPrevious(const int pccardid, const int pcvv, const double pamount, const int pcurrid, QString &pneworder, QString &preforder, QString &papproval, int &pccpayid, ParameterList &pparams) { if (DEBUG) qDebug("AN:doVoidPrevious(%d, %d, %f, %d, %s, %s, %s, %d)", pccardid, pcvv, pamount, pcurrid, pneworder.toAscii().data(), preforder.toAscii().data(), papproval.toAscii().data(), pccpayid); QString tmpErrorMsg = _errorMsg; int returnValue = 0; double amount = pamount; int currid = pcurrid; if (_metrics->value("CCANCurrency") != "TRANS") { currid = _metrics->value("CCANCurrency").toInt(); amount = currToCurr(pcurrid, currid, pamount, &returnValue); if (returnValue < 0) { _errorMsg = tmpErrorMsg; return returnValue; } } QString request; returnValue = buildCommon(pccardid, pcvv, amount, currid, request, "VOID"); if (returnValue != 0) return returnValue; APPENDFIELD(request, "x_trans_id", preforder); QString response; returnValue = sendViaHTTP(request, response); _errorMsg = tmpErrorMsg; if (returnValue < 0) return returnValue; returnValue = handleResponse(response, pccardid, "V", amount, currid, pneworder, preforder, pccpayid, pparams); if (! tmpErrorMsg.isEmpty()) _errorMsg = tmpErrorMsg; return returnValue; }
int AuthorizeDotNetProcessor::doChargePreauthorized(const int pccardid, const int pcvv, const double pamount, const int pcurrid, QString &pneworder, QString &preforder, int &pccpayid, ParameterList &pparams) { if (DEBUG) qDebug("AN:doChargePreauthorized(%d, %d, %f, %d, %s, %s, %d)", pccardid, pcvv, pamount, pcurrid, pneworder.toAscii().data(), preforder.toAscii().data(), pccpayid); int returnValue = 0; double amount = pamount; int currid = pcurrid; if (_metrics->value("CCANCurrency") != "TRANS") { currid = _metrics->value("CCANCurrency").toInt(); amount = currToCurr(pcurrid, currid, pamount, &returnValue); if (returnValue < 0) return returnValue; } QString request; returnValue = buildCommon(pccardid, pcvv, amount, currid, request, "PRIOR_AUTH_CAPTURE"); if (returnValue != 0) return returnValue; APPENDFIELD(request, "x_trans_id", preforder); QString response; returnValue = sendViaHTTP(request, response); if (returnValue < 0) return returnValue; returnValue = handleResponse(response, pccardid, "CP", amount, currid, pneworder, preforder, pccpayid, pparams); return returnValue; }
int AuthorizeDotNetProcessor::buildCommon(const int pccardid, const int pcvv, const double pamount, const int pcurrid, QString &prequest, QString pordertype) { // TODO: if check and not credit card transaction do something else XSqlQuery anq; anq.prepare( "SELECT ccard_active," " formatbytea(decrypt(setbytea(ccard_number), setbytea(:key),'bf')) AS ccard_number," " formatccnumber(decrypt(setbytea(ccard_number),setbytea(:key),'bf')) AS ccard_number_x," " formatbytea(decrypt(setbytea(ccard_name), setbytea(:key),'bf')) AS ccard_name," " formatbytea(decrypt(setbytea(ccard_address1), setbytea(:key),'bf')) AS ccard_address1," " formatbytea(decrypt(setbytea(ccard_address2), setbytea(:key),'bf')) AS ccard_address2," " formatbytea(decrypt(setbytea(ccard_city), setbytea(:key),'bf')) AS ccard_city," " formatbytea(decrypt(setbytea(ccard_state), setbytea(:key),'bf')) AS ccard_state," " formatbytea(decrypt(setbytea(ccard_zip), setbytea(:key),'bf')) AS ccard_zip," " formatbytea(decrypt(setbytea(ccard_country), setbytea(:key),'bf')) AS ccard_country," " formatbytea(decrypt(setbytea(ccard_month_expired),setbytea(:key),'bf')) AS ccard_month_expired," " formatbytea(decrypt(setbytea(ccard_year_expired),setbytea(:key), 'bf')) AS ccard_year_expired," " cust.* " " FROM ccard, cust " "WHERE ((ccard_id=:ccardid)" " AND (ccard_cust_id=cust_id));"); // note use of the cust view instead of the custinfo table anq.bindValue(":ccardid", pccardid); anq.bindValue(":key", omfgThis->_key); anq.exec(); if (anq.first()) { if (!anq.value("ccard_active").toBool()) { _errorMsg = errorMsg(-10); return -10; } } else if (anq.lastError().type() != QSqlError::NoError) { _errorMsg = anq.lastError().databaseText(); return -1; } else { _errorMsg = errorMsg(-17).arg(pccardid); return -17; } if (! _metrics->value("CCANDelim").isEmpty()) APPENDFIELD(prequest, "x_delim_char", _metrics->value("CCANDelim")); APPENDFIELD(prequest, "x_version", _metrics->value("CCANVer")); APPENDFIELD(prequest, "x_delim_data", "TRUE"); if (! _metrics->value("CCANEncap").isEmpty()) APPENDFIELD(prequest, "x_encap_char", _metrics->value("CCANEncap")); APPENDFIELD(prequest, "x_login", _metricsenc->value("CCLogin")); APPENDFIELD(prequest, "x_tran_key", _metricsenc->value("CCPassword")); APPENDFIELD(prequest, "x_amount", QString::number(pamount)); // TODO: if check and not credit card transaction do something else APPENDFIELD(prequest, "x_card_num", anq.value("ccard_number").toString()); APPENDFIELD(prequest, "x_test_request", isLive() ? "FALSE" : "TRUE"); // TODO: if check and not credit card transaction do something else QString work_month; work_month.setNum(anq.value("ccard_month_expired").toDouble()); if (work_month.length() == 1) work_month = "0" + work_month; APPENDFIELD(prequest, "x_exp_date", work_month + anq.value("ccard_year_expired").toString().right(2)); APPENDFIELD(prequest, "x_relay_response", "FALSE"); APPENDFIELD(prequest, "x_duplicate_window", _metrics->value("CCANDuplicateWindow")); QStringList name = anq.value("ccard_name").toString().split(QRegExp("\\s+")); APPENDFIELD(prequest, "x_first_name", name.at(0)); APPENDFIELD(prequest, "x_last_name", name.at(name.size() - 1)); APPENDFIELD(prequest, "x_company", anq.value("cust_name").toString()); APPENDFIELD(prequest, "x_address", anq.value("ccard_address1").toString()); APPENDFIELD(prequest, "x_city", anq.value("ccard_city").toString()); APPENDFIELD(prequest, "x_state", anq.value("ccard_state").toString()); APPENDFIELD(prequest, "x_zip", anq.value("ccard_zip").toString()); APPENDFIELD(prequest, "x_country", anq.value("ccard_country").toString()); if (_metrics->boolean("CCANWellsFargoSecureSource")) { APPENDFIELD(prequest, "x_phone", anq.value("cust_phone").toString()); APPENDFIELD(prequest, "x_email", anq.value("cust_email").toString()); } anq.prepare("SELECT curr_abbr FROM curr_symbol WHERE (curr_id=:currid);"); anq.bindValue(":currid", pcurrid); anq.exec(); if (anq.first()) { APPENDFIELD(prequest, "x_currency_code", anq.value("curr_abbr").toString()); } else if (anq.lastError().type() != QSqlError::NoError) { _errorMsg = anq.lastError().databaseText(); return -1; } else { _errorMsg = errorMsg(-17).arg(pccardid); return -17; } // TODO: if check and not credit card transaction do something else APPENDFIELD(prequest, "x_method", "CC"); APPENDFIELD(prequest, "x_type", pordertype); if (pcvv > 0) APPENDFIELD(prequest, "x_card_code", pcvv); if (DEBUG) qDebug("AN:buildCommon built %s\n", prequest.toAscii().data()); return 0; }
int AuthorizeDotNetProcessor::doCredit(const int pccardid, const QString &pcvv, const double pamount, const double ptax, const bool ptaxexempt, const double pfreight, const double pduty, const int pcurrid, QString &pneworder, QString &preforder, int &pccpayid, ParameterList &pparams) { Q_UNUSED(pcvv); if (DEBUG) qDebug("AN:doCredit(%d, pcvv, %f, %f, %d, %f, %f, %d, %s, %s, %d)", pccardid, pamount, ptax, ptaxexempt, pfreight, pduty, pcurrid, pneworder.toLatin1().data(), preforder.toLatin1().data(), pccpayid); int returnValue = 0; double amount = pamount; int currid = pcurrid; bool tryVoid = false; QString approvalCode; QString request; returnValue = buildFollowup(pccpayid, preforder, amount, currid, request, "CREDIT"); if (returnValue != 0) return returnValue; XSqlQuery anq; anq.prepare("SELECT ccpay_card_pan_trunc," " (ccpay_transaction_datetime > CURRENT_DATE" " AND ccpay_amount = :amount) AS tryVoid," " ccpay_r_code," " formatbytea(decrypt(setbytea(ccard_number)," " setbytea(:key),'bf')) AS ccard_number" " FROM ccpay LEFT OUTER JOIN ccard ON (ccpay_ccard_id=ccard_id)" " WHERE (ccpay_id=:ccpayid);"); anq.bindValue(":ccpayid", pccpayid); anq.bindValue(":key", omfgThis->_key); anq.bindValue(":now", QDateTime::currentDateTime()); anq.bindValue(":amount", amount); anq.exec(); if (anq.first()) { QString cardnum = anq.value("ccpay_card_pan_trunc").toString(); if (cardnum.isEmpty()) cardnum = anq.value("ccard_number").toString(); APPENDFIELD(request, "x_card_num", cardnum.right(4)); tryVoid = anq.value("tryVoid").toBool(); approvalCode = anq.value("ccpay_r_code").toString(); } else if (anq.lastError().type() != QSqlError::NoError) { _errorMsg = anq.lastError().databaseText(); return -1; } QString response; returnValue = sendViaHTTP(request, response); if (returnValue < 0) return returnValue; returnValue = handleResponse(response, pccardid, "R", amount, currid, pneworder, preforder, pccpayid, pparams); // TODO: make more precise - look for return code 54 if (returnValue < 0 && tryVoid) { int voidResult = 0; QString tmpErrorMsg = _errorMsg; ParameterList voidParams; _errorMsg.clear(); voidResult = doVoidPrevious(pccardid, pcvv, amount, currid, pneworder, preforder, approvalCode, pccpayid, voidParams); if (voidResult >= 0) { returnValue = voidResult; pparams.clear(); while (! voidParams.isEmpty()) pparams.append(voidParams.takeFirst()); } else _errorMsg = tmpErrorMsg; } return returnValue; }
/** @brief Build an outgoing request for a follow-on transaction - that is, one that requires a previous transaction to be meaningful. Some Authorize.Net transactions can only occur after being set up by a prior transaction. For example, @em capturing a pre-authorization requires an existing valid pre-authorization. These follow-on transactions pass less data and are somewhat more secure than full messages. @param pccpayid the internal id of the @c ccpay record @param ptransid the transaction id, typically the order number @param pamount in: the amount in the ERP transaction currency, out: the amount in the Authorize.Net transaction @param[in,out] pcurrid in: the currency of the ERP transaction, out: the currency of the Authorize.Net transaction @param[in,out] prequest The message to send to Authorize.Net @param pordertype The type of Authorize.Net transaction @see buildCommon */ int AuthorizeDotNetProcessor::buildFollowup(const int pccpayid, const QString &ptransid, double &pamount, int &pcurrid, QString &prequest, QString pordertype) { Q_UNUSED(pccpayid); int returnValue = 0; int currid = pcurrid; if (_metrics->value("CCANCurrency") != "TRANS") { currid = _metrics->value("CCANCurrency").toInt(); pamount = currToCurr(pcurrid, currid, pamount, &returnValue); pcurrid = currid; if (returnValue < 0) return returnValue; } if (! _metrics->value("CCANDelim").isEmpty()) APPENDFIELD(prequest, "x_delim_char", _metrics->value("CCANDelim")); if (! _metrics->value("CCANEncap").isEmpty()) APPENDFIELD(prequest, "x_encap_char", _metrics->value("CCANEncap")); APPENDFIELD(prequest, "x_version", _metrics->value("CCANVer")); APPENDFIELD(prequest, "x_delim_data", "true"); APPENDFIELD(prequest, "x_login", _metricsenc->value("CCLogin")); APPENDFIELD(prequest, "x_tran_key", _metricsenc->value("CCPassword")); APPENDFIELD(prequest, "x_trans_id", ptransid); APPENDFIELD(prequest, "x_amount", QString::number(pamount, 'f', 2)); APPENDFIELD(prequest, "x_method", "CC"); if (_metrics->value("CCServer").contains("test.authorize.net")) { APPENDFIELD(prequest, "x_test_request", "false"); } else { APPENDFIELD(prequest, "x_test_request", isLive() ? "false" : "true"); } APPENDFIELD(prequest, "x_relay_response", "false"); APPENDFIELD(prequest, "x_duplicate_window", _metrics->value("CCANDuplicateWindow")); XSqlQuery anq; anq.prepare("SELECT curr_abbr FROM curr_symbol WHERE (curr_id=:currid);"); anq.bindValue(":currid", pcurrid); anq.exec(); if (anq.first()) { APPENDFIELD(prequest, "x_currency_code", anq.value("curr_abbr").toString()); } else if (anq.lastError().type() != QSqlError::NoError) { _errorMsg = anq.lastError().databaseText(); return -1; } // TODO: if check and not credit card transaction do something else APPENDFIELD(prequest, "x_method", "CC"); APPENDFIELD(prequest, "x_type", pordertype); if (DEBUG) qDebug("AN:buildFollowup built %s\n", prequest.toLatin1().data()); return 0; }