Commit 7f2d56e3 by NitefullWind

1. SPCC版本可唤起非码支付、退款功能。

parent e81624bf
...@@ -17,6 +17,8 @@ EXTERN_C IMAGE_DOS_HEADER __ImageBase; ...@@ -17,6 +17,8 @@ EXTERN_C IMAGE_DOS_HEADER __ImageBase;
typedef int (__stdcall *GetValue) (char *, char *); typedef int (__stdcall *GetValue) (char *, char *);
typedef int (__stdcall *GetRSACret)(int ,const char *,const char *); typedef int (__stdcall *GetRSACret)(int ,const char *,const char *);
typedef int (__stdcall *SKBAPISend)(const char *indata, const char *guid, char *outdata, char *errMsg, const char *mode);
typedef int (__stdcall *AddSign)(char *, char *);
void Control::GetProcPath(char * pathBuf) void Control::GetProcPath(char * pathBuf)
{ {
...@@ -48,7 +50,29 @@ void Control::Start(const char *indata, char *outdata) ...@@ -48,7 +50,29 @@ void Control::Start(const char *indata, char *outdata)
if(_widget == NULL) if(_widget == NULL)
_widget = new HostWidget(); _widget = new HostWidget();
memcpy(&_request, indata, sizeof(struct AlipayRequest)); QJsonParseError parseError;
QJsonDocument inDataDoc = QJsonDocument::fromJson(QString::fromLocal8Bit(indata).toUtf8(), &parseError);
if(parseError.error == QJsonParseError::NoError) {
_posReqJsonObj = inDataDoc.object();
int type = FMTool::GetJsonValue(_posReqJsonObj, JSON_KEY_REQTYPE).toInt();
switch (type) {
case SPCC_pay:
_posReqJsonObj[JSON_KEY_REQTYPE] = 72;
break;
case SPCC_refund:
_posReqJsonObj[JSON_KEY_REQTYPE] = 62;
break;
default:
break;
}
} else {
qDebug() << "Json parse error: " << parseError.errorString();
memcpy(&_request, indata, sizeof(struct AlipayRequest));
ReqType type = (ReqType)(FMTool::GetString(_request.TransType, 2).toInt());
JsonFactory::GetJsonWithType(type, _posReqJsonObj, _request);
qDebug() << _posReqJsonObj;
}
connect(_widget, &HostWidget::RequestWithType, this, &Control::RequestWithType); connect(_widget, &HostWidget::RequestWithType, this, &Control::RequestWithType);
...@@ -64,7 +88,8 @@ void Control::Start(const char *indata, char *outdata) ...@@ -64,7 +88,8 @@ void Control::Start(const char *indata, char *outdata)
loop.exit(); loop.exit();
}); });
_widget->ShowWithRequest(_request); // _widget->ShowWithRequest(_request);
_widget->ShowWithRequest(_posReqJsonObj);
loop.exec(); loop.exec();
...@@ -147,6 +172,110 @@ bool Control::SendMessageToPayMent(const QJsonObject &json, QByteArray &outdata, ...@@ -147,6 +172,110 @@ bool Control::SendMessageToPayMent(const QJsonObject &json, QByteArray &outdata,
return false; return false;
} }
bool Control::SendMessageToSBKAPI(const QJsonObject &json, QByteArray &outdata, QString &error)
{
char mod[MAX_PATH] = { 0 };
GetProcPath(mod);
QLibrary lib(QString(mod) + "\\" + "SBKAPIWrapper.dll");
QLOG_INFO() << QString(mod) + "\\" + "SBKAPIWrapper.dll";
if(lib.load())
{
SKBAPISend skbSend = (SKBAPISend)lib.resolve("Send");
if(skbSend != NULL)
{
QEventLoop loop;
QFuture<QByteArray> future = QtConcurrent::run( [ this, &loop, json, &error, skbSend]() ->QByteArray
{
QString reqXmlStr = QString::fromLocal8Bit("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<ns0:OLTP xmlns:ns0=\"http://spcc.com.cn/online\">"
"<ns0:HEADER>"
"<ns0:VER>01.01</ns0:VER>"
"<ns0:FROM>CS00000001</ns0:FROM>"
"<ns0:TERMINO>%1</ns0:TERMINO>"
"<ns0:TO>%2</ns0:TO>"
"<ns0:BUSINESS>0000000</ns0:BUSINESS>"
"<ns0:DATE>%3</ns0:DATE>"
"<ns0:TIME>%4</ns0:TIME>"
"<ns0:STATCODE>0000</ns0:STATCODE>"
"<ns0:STATDESC/>"
"</ns0:HEADER>"
"<ns0:AP>"
"%5"
"</ns0:AP>"
"</ns0:OLTP>");
QString nsTo = "CS00400004";
int type = FMTool::GetJsonValue(_posReqJsonObj, JSON_KEY_REQTYPE).toInt();
if(type==SPCC_sign) {
nsTo = "CS00400003";
}
QString date = QDate::currentDate().toString("yyMMdd");
QString time = QTime::currentTime().toString("hhmmss");
QString storeId = FMTool::GetJsonValue(_posReqJsonObj, JSON_KEY_STOREID).toString();
QString posId = FMTool::GetJsonValue(_posReqJsonObj, JSON_KEY_STATIONID).toString();
qsrand(QDateTime::currentMSecsSinceEpoch());
QString termino = QString::fromUtf8("%1%2%3%4%5").arg(date).arg(storeId).arg(posId).arg(qrand()%90+10).arg(time);
QByteArray jsonArray = QJsonDocument(json).toJson(QJsonDocument::Compact);
char signStr[MAX_BUF_LEN] = {0};
GetSPCCSign(jsonArray.data(), signStr);
QLOG_INFO() << "Sign str: " << signStr;
reqXmlStr = reqXmlStr.arg(termino).arg(nsTo).arg(date).arg(time).arg(QString::fromUtf8(jsonArray));
char in[MAX_BUF_LEN] = {0};
char out[MAX_BUF_LEN] = {0};
char *guid = "";
char errMsg[MAX_BUF_LEN] = {0};
char *mode = "ONLINE";
strcpy(in, reqXmlStr.toUtf8().data());
QLOG_INFO() << "Request StarbucksAPI XML data: " << in;
int result = skbSend(in, guid, out, errMsg, mode);
if(result!=0) {
error = QString(errMsg);
QLOG_ERROR() << "SKBSend return: " << result << " errMsg: " << errMsg << " data: " << out;
return QByteArray();
}
QLOG_INFO() << "SKBSend return: " << result << " data: " << out;
return QByteArray(out);
});
QFutureWatcher<QByteArray> watcher;
watcher.setFuture(future);
connect(&watcher, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();
outdata = watcher.result();
bool isEmpty = outdata.isNull() && outdata.isEmpty();
return !isEmpty;
}
else
{
QLOG_ERROR() << "get function (Send) failed";
error = QString::fromLocal8Bit("加载基础组件(fun)失败");
}
}
else
{
QLOG_ERROR() << "load dll failed";
error = QString::fromLocal8Bit("加载基础组件(dll)失败");
}
return false;
}
bool Control::GetRSA(QString &error) bool Control::GetRSA(QString &error)
{ {
char mod[MAX_PATH] = { 0 }; char mod[MAX_PATH] = { 0 };
...@@ -239,15 +368,21 @@ void Control::Request(ReqType type, QStringList list) ...@@ -239,15 +368,21 @@ void Control::Request(ReqType type, QStringList list)
QString error; QString error;
QByteArray outdata; QByteArray outdata;
JsonFactory::GetJsonWithType(type, json, _request, list); // JsonFactory::GetJsonWithType(type, json, _request, list);
bool rlt = SendMessageToPayMent(json, outdata, error); // bool rlt = SendMessageToPayMent(json, outdata, error);
JsonFactory::GetJsonWithType(type, json, _posReqJsonObj, list);
bool rlt = SendMessageToSBKAPI(json, outdata, error);
if(rlt) if(rlt)
rlt = Control::GetJson(type, rtjson, outdata, error); rlt = Control::GetJson(type, rtjson, outdata, error);
else else
SetResPonseWithMessage("23", error); SetResPonseWithMessage("23", error);
_lock.lock(); _lock.lock();
if(_widget != NULL) if(_widget != NULL)
_widget->ShowWiteMGS(type, rlt, error); _widget->ShowWiteMGS(type, rlt, error);
...@@ -263,3 +398,28 @@ void Control::RequestWithType(ReqType type, QStringList list) ...@@ -263,3 +398,28 @@ void Control::RequestWithType(ReqType type, QStringList list)
} }
Request(type, list); Request(type, list);
} }
void Control::GetSPCCSign(char *in, char *out)
{
char mod[MAX_PATH] = { 0 };
GetProcPath(mod);
QLibrary lib(QString(mod) + "\\" + "FreemudWrapper.dll");
if(lib.load())
{
AddSign addsign = (AddSign)lib.resolve("AddSign");
if(addsign != NULL) {
QLOG_INFO() << "Sign return: " << addsign(in, out);
} else {
QLOG_ERROR() << "get function (AddSign) failed";
// error = QString::fromLocal8Bit("加载基础组件(fun)失败");
}
}
else
{
QLOG_ERROR() << "load dll failed";
// error = QString::fromLocal8Bit("加载基础组件(dll)失败");
}
}
...@@ -32,6 +32,8 @@ private: ...@@ -32,6 +32,8 @@ private:
bool SendMessageToPayMent(const QJsonObject &json, QByteArray &outdata, QString &error); bool SendMessageToPayMent(const QJsonObject &json, QByteArray &outdata, QString &error);
bool SendMessageToSBKAPI(const QJsonObject &json, QByteArray &outdata, QString &error);
void SetResPonseWithMessage(QString code, const QString &message); void SetResPonseWithMessage(QString code, const QString &message);
void RequestSign(); void RequestSign();
...@@ -44,6 +46,8 @@ private: ...@@ -44,6 +46,8 @@ private:
bool GetJson(ReqType type, QJsonObject &json, const QByteArray array, QString &error); bool GetJson(ReqType type, QJsonObject &json, const QByteArray array, QString &error);
void GetSPCCSign(char *in, char *out);
public slots: public slots:
void RequestWithType(ReqType type, QStringList list); void RequestWithType(ReqType type, QStringList list);
...@@ -53,6 +57,9 @@ public slots: ...@@ -53,6 +57,9 @@ public slots:
private: private:
struct AlipayRequest _request; struct AlipayRequest _request;
struct AlipayResponse _response; struct AlipayResponse _response;
QJsonObject _posReqJsonObj;
QJsonObject _responseJsonObj;
HostWidget *_widget; HostWidget *_widget;
//确保exe结束后不会重新弹窗 //确保exe结束后不会重新弹窗
QMutex _lock; QMutex _lock;
......
...@@ -146,6 +146,23 @@ public: ...@@ -146,6 +146,23 @@ public:
} }
static QJsonValue GetJsonValue(const QJsonObject &jsonObj, const QString &key)
{
if(jsonObj.contains(key)) {
return jsonObj[key];
} else {
foreach(QString k, jsonObj.keys()) {
if(jsonObj[k].isObject()) {
QJsonObject ob = jsonObj[k].toObject();
QJsonValue value = GetJsonValue(ob, key);
if(!value.isNull()){
return value;
}
}
}
}
return QJsonValue();
}
}; };
......
...@@ -153,6 +153,73 @@ void HostWidget::ShowWithRequest(AlipayRequest request) ...@@ -153,6 +153,73 @@ void HostWidget::ShowWithRequest(AlipayRequest request)
} }
} }
void HostWidget::ShowWithRequest(QJsonObject requestObj)
{
int reqtype = FMTool::GetJsonValue(requestObj, JSON_KEY_REQTYPE).toInt();
switch (reqtype) {
case manage:
{
ShowWidget(ui->Manager);
_curr_show_widget = ui->Manager;
}
case pay:
{
_type = pay;
ShowWidget(ui->pay);
_curr_show_widget = ui->pay;
double Amount = FMTool::GetString(_data.Amount, 12).toInt()/100.0;
ui->label_pay_title->setText(QString::fromLocal8Bit("请扫描输入支付宝二维码"));
ui->btn_pay_exit->setText(QString::fromLocal8Bit("取消支付"));
ui->label_pay_money->setText(QString::fromLocal8Bit("需收取 ¥ %1").arg(Amount));
break;
}
case refund:
{
_type = refund;
ShowWidget(ui->pay);
_curr_show_widget = ui->pay;
double Amount = FMTool::GetString(_data.Amount, 12).toInt()/100.0;
ui->label_pay_title->setText(QString::fromLocal8Bit("请扫描退款凭证号"));
ui->btn_pay_exit->setText(QString::fromLocal8Bit("取消退款"));
ui->label_pay_money->setText(QString::fromLocal8Bit("退款 ¥ %1").arg(Amount));
break;
}
case SPCC_sign: {
ShowWidget(ui->Manager);
_curr_show_widget = ui->Manager;
break;
}
case SPCC_manage: {
ShowWidget(ui->Manager);
_curr_show_widget = ui->Manager;
break;
}
case 72: {
_type = pay;
ShowWidget(ui->pay);
_curr_show_widget = ui->pay;
double Amount = FMTool::GetJsonValue(requestObj, JSON_KEY_TRANSAMOUNT).toInt()/100.0;
ui->label_pay_title->setText(QString::fromLocal8Bit("请扫描输入支付宝二维码"));
ui->btn_pay_exit->setText(QString::fromLocal8Bit("取消支付"));
ui->label_pay_money->setText(QString::fromLocal8Bit("需收取 ¥ %1").arg(Amount));
break;
}
case 62: {
_type = refund;
ShowWidget(ui->pay);
_curr_show_widget = ui->pay;
double Amount = FMTool::GetJsonValue(requestObj, JSON_KEY_TRANSAMOUNT).toInt()/100.0;
ui->label_pay_title->setText(QString::fromLocal8Bit("请扫描退款凭证号"));
ui->btn_pay_exit->setText(QString::fromLocal8Bit("取消退款"));
ui->label_pay_money->setText(QString::fromLocal8Bit("退款 ¥ %1").arg(Amount));
break;
}
default:
break;
}
}
void HostWidget::ShowWiteMGS(ReqType type, bool flag, QString message) void HostWidget::ShowWiteMGS(ReqType type, bool flag, QString message)
{ {
if(type == sign) if(type == sign)
......
...@@ -25,6 +25,7 @@ public: ...@@ -25,6 +25,7 @@ public:
~HostWidget(); ~HostWidget();
void ShowWithRequest(AlipayRequest request); void ShowWithRequest(AlipayRequest request);
void ShowWithRequest(QJsonObject requestObj);
void ShowWiteMGS(ReqType type, bool flag, QString message = QString()); void ShowWiteMGS(ReqType type, bool flag, QString message = QString());
......
...@@ -29,6 +29,18 @@ public: ...@@ -29,6 +29,18 @@ public:
return false; return false;
} }
static bool GetJsonWithType(ReqType type, QJsonObject &json, const QJsonObject &reqJson, QStringList list)
{
switch (type) {
case pay:
return GetPayJson(json, reqJson, list);
case refund:
return GetRefundJosn(json, reqJson, list);
default:
break;
}
}
static bool GetResponseWithType(ReqType type, const QByteArray &rspJsonData, AlipayResponse &response) static bool GetResponseWithType(ReqType type, const QByteArray &rspJsonData, AlipayResponse &response)
{ {
QJsonParseError parseError; QJsonParseError parseError;
...@@ -104,6 +116,15 @@ private: ...@@ -104,6 +116,15 @@ private:
return true; return true;
} }
static bool GetPayJson(QJsonObject &json, const QJsonObject &reqJson, QStringList list)
{
if(list.size() != 1 || list[0].isEmpty())
return false;
json = reqJson;
json[JSON_KEY_CODE] = list[0];
return true;
}
//退款 //退款
static bool GetRefundJosn(QJsonObject &json, const AlipayRequest &request, QStringList list) static bool GetRefundJosn(QJsonObject &json, const AlipayRequest &request, QStringList list)
{ {
...@@ -125,6 +146,15 @@ private: ...@@ -125,6 +146,15 @@ private:
return true; return true;
} }
static bool GetRefundJosn(QJsonObject &json, const QJsonObject &reqJson, QStringList list)
{
if(list.size() != 1 || list[0].isEmpty())
return false;
json = reqJson;
json.insert(JSON_KEY_FMID, list[0]);
return true;
}
//日结 //日结
static bool GetDayEndJson(QJsonObject &json, const AlipayRequest &request, QStringList list) static bool GetDayEndJson(QJsonObject &json, const AlipayRequest &request, QStringList list)
{ {
......
...@@ -283,10 +283,13 @@ int main(int argc, char *argv[]) ...@@ -283,10 +283,13 @@ int main(int argc, char *argv[])
//char as[] = "ak10dh171300000000000 *#dhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"; //char as[] = "ak30dh171300000000000 *#dhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh";
char b[MAX_BUF_LEN] = {0}; char b[MAX_BUF_LEN] = {0};
control.Start(as, b); // control.Start(as, b);
char spccIn[MAX_BUF_LEN] = "{\"reqType\":353,\"storeId\":\"1713\",\"stationId\":\"1\",\"partnerId\":1443,\"operatorId\":\"sssaw\",\"transId\":\"52342342323806\",\"transAmount\":8000,\"partnerOrderId\":\"909911039993720192019\",\"businessDate\":\"20170508\",\"products\":[{\"pid\":\"123\",\"name\":\"中杯拿铁\",\"price\":321,\"salesType\":\"NORMAL\"}]}";
control.Start(spccIn, b);
return a.exec(); return a.exec();
} }
......
#ifndef REQFACTORY_H
#define REQFACTORY_H
#include "requestmodel.h"
#include "global.h"
#include "fmtool.h"
#include "jsonfactory.h"
#include <QFile>
#include <QJsonDocument>
#include <QJsonParseError>
#include <QJsonObject>
#include <QApplication>
class ReqFactory
{
public:
static bool GetReqJsonObj(const char* indata, QJsonObject &reqJsonObj)
{
QJsonParseError parseError;
QJsonDocument inDataDoc = QJsonDocument::fromJson(QString(indata).toUtf8(), &parseError);
if(parseError.error == QJsonParseError::NoError) {
reqJsonObj = inDataDoc.object();
} else {
AlipayRequest request;
memcpy(&request, indata, sizeof(struct AlipayRequest));
ReqType type = (ReqType)(FMTool::GetString(request.TransType, 2).toInt());
JsonFactory::GetJsonWithType(type, reqJsonObj, _request);
}
}
//private:
// static void GetSPCCJson()
};
#endif // REQFACTORY_H
...@@ -3,12 +3,18 @@ ...@@ -3,12 +3,18 @@
typedef enum typedef enum
{ {
pay = 0, manage = 10,
refund, pay = 30,
refund = 40,
endday, endday,
againprint, againprint,
find, find = 80,
sign sign = 90,
SPCC_sign= 350,
SPCC_manage,
SPCC_pay,
SPCC_refund,
SPCC_find
} ReqType; } ReqType;
struct EFTItem struct EFTItem
......
...@@ -13,7 +13,7 @@ TARGET = sbkpay ...@@ -13,7 +13,7 @@ TARGET = sbkpay
include("./QsLog/QsLog.pri") include("./QsLog/QsLog.pri")
CONFIG += C++11 CONFIG += C++11 SBKDLL
include($$PWD/qtwinmigrate/src/qtwinmigrate.pri) include($$PWD/qtwinmigrate/src/qtwinmigrate.pri)
...@@ -47,7 +47,8 @@ HEADERS += hostwidget.h \ ...@@ -47,7 +47,8 @@ HEADERS += hostwidget.h \
fmtool.h \ fmtool.h \
jsonfactory.h \ jsonfactory.h \
labelstimer.h \ labelstimer.h \
rspfactory.h rspfactory.h \
reqfactory.h
FORMS += hostwidget.ui FORMS += hostwidget.ui
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment