erlang证书加密
-module(。。。).
-include("ewp.hrl").
-include("backend.hrl").
-include_lib("public_key/include/public_key.hrl").
-compile(export_all).
-define(ISSCODE,"49990014"). %% 03040000
-define(MaxMoney,"99999999").
-define(FilePath,"./config/key/enc.cer").
-spec get_mp_param(string(),string()) -> string().
'US0101'(_UserObj, _TranID, _P) ->
ClientOS = get(client_os), %%ios 01,ipad02, iwatch06,android 03,pad 04
VersionFlag = backend_util:check_new_version(ClientOS,["4.0.13","4.0.11"]), %%生产可能["4.0.13","4.0.11"]
case VersionFlag of
low ->
throw(?VERSION_LOW_ERROR); %%二维码支付功能需要更新客户端,请快快点击体验吧
high ->
go_on
end,
[].
'US0102'(UserObj, TranID, P) ->
transaction:start(TranID, UserObj),
REG_CHANNEL = user_obj:get_field('REG_CHANNEL', UserObj),
case REG_CHANNEL of
"3" ->
throw(?REG_TYPE_1_ERROR);
_ ->
ok
end,
UserCode = user_obj:get_field('USER_CODE', UserObj),
transaction:set_log_field('USER_CODE', UserCode, TranID),
NewCard = ewp_params:get("newCard",P),
NewCardType = ewp_params:get("newCardType",P),
RefreshTime = backend_params:get_value("people_valid_time"),
%%有返回卡列表,卡需要按照时间加挂最早的顺序
CardInfo = backend_db:select("select account_no,account_alias,account_type from MY_PEOPLECODE_ACCOUNTS t where t.user_code = :1 and t.delete_flag = '0' and t.ok_flag = '1' order by t.create_time",[UserCode]),
case CardInfo of
[] -> throw(?NO_PEOPLECARD_ERROR);
_ -> ok
end,
[FirstCardInfo|_] = CardInfo,
[FirstCard,_,FaccountType] = FirstCardInfo, %%第一张卡,其他卡
TheCardInfo = case NewCard of
undefined ->
[FirstCard,FaccountType];
[] ->
[FirstCard,FaccountType];
_ ->
[NewCard,NewCardType]
end,
[TheCard,TheType] = TheCardInfo,
TranNo = transaction:get_serial_no(TranID), %%流水号
QRcode = get_code(UserObj,TranNo,TheCard,TheType),%%刷新,重新请求接口,得到新的二维码编号
CardInfo1= [[{"account_no",Account_no},{"account_alias",Account_alias},{"account_type",Account_type}] || [Account_no,Account_alias,Account_type] <- CardInfo],
Now = now(),
transaction:set_log_field('TRAN_TIME',{datetime, calendar:now_to_local_time(Now)},TranID),
transaction:set_log_field('FINANCIAL_TYPE',"0",TranID),
UserName = user_obj:get_field('NAME',UserObj),
transaction:set_log_field('OUT_USER_NAME',UserName,TranID),
[{acc,TheCard},{type,TheType},{acclist,CardInfo1},{refreshTime,RefreshTime},{qrcode,QRcode}].
get_cert_serialno()->
{ok, PemServerCert} = file:read_file(?FilePath),
[{'Certificate', DerServerCert, not_encrypted}] = public_key:pem_decode(PemServerCert),
OtpServerCert = public_key:pkix_decode_cert(DerServerCert, otp),
TbsCertificate = OtpServerCert#'OTPCertificate'.tbsCertificate,
SerialNumber = TbsCertificate#'OTPTBSCertificate'.serialNumber,
integer_to_list(SerialNumber).
%%获取二维码编码
%%请求接口,根据新的卡生成新的二维码
get_code(UserObj,TranNo,CardNo,CardType)->
UserCode = user_obj:get_field('USER_CODE', UserObj),
IssCode = ?ISSCODE,
QrType = case CardType of
"0" -> "35"; %%借记卡
_ -> "51" %%贷记卡,目前状态下只有借记卡和信用卡
%% _ -> "40" %%其他
end,
UserName = user_obj:get_field('NAME',UserObj),
AcctClass = "1", %%几类账户
CardAttr = case CardType of
"0" -> "01"; %%借记卡
_ -> "02" %%贷记卡
end,
PayerInfo1 = "{accNo=" ++ CardNo ++ "&name=" ++ UserName ++ "&issCode=" ++ IssCode ++ "&acctClass=" ++ AcctClass ++ "&cardAttr=" ++ CardAttr ++"}",
PayerInfo = binary_to_list(base64:encode(public_encode(PayerInfo1))), %%public_encode(list_to_binary(PayerInfo1))
MaxAmont0 = case CardType of
"0" ->
backend_params:get_value("people_simple_cardlimit") ++ "00"; %%借记卡
_ ->
backend_params:get_value("people_simple_creditlimit") ++ "00" %%其他
end,
MaxAmont = ?MaxMoney,
AddnCondInit = "{currency=156&pinFree=0&maxAmont=" ++ MaxAmont ++"}",
AddnCond = binary_to_list(base64:encode(AddnCondInit)),
EncryptCertId = get_cert_serialno(),
ReqReserved = "01", %%请求方自定义域,若出现则后续交易中自动带回
%%先加密,再需要base64 encode
Xbody = "<version>1.0.0</version><reqType>0210000903</reqType><issCode>" ++ IssCode ++
"</issCode><qrType>" ++ QrType ++ "</qrType><payerInfo>" ++ PayerInfo ++ "</payerInfo>"
++ "<addnCond>" ++ AddnCond ++"</addnCond>" ++ "<encryptCertId>" ++ EncryptCertId ++ "</encryptCertId>"
++ "<reqReserved>" ++ ReqReserved ++ "</reqReserved>",
%% "<qrValidTime></qrValidTime><qrNo></qrNo><addnOpUrl>" ++ AddnOpUrl ++ "</addnOpUrl>" ++
%% "<backUrl></backUrl>",
Res_Cert = wailian_client_qm:peoplecode_xml_request("MBU001",TranNo,Xbody),
%%Xml_ResBody = wailian_client_qm:get_peoplecode_value(Res_Cert),
ResCode = proplists:get_value('ErrorCode', proplists:get_value('Head',proplists:get_value('Agw', Res_Cert))),
ResDetail = proplists:get_value('ErrorMsg', proplists:get_value('Head',proplists:get_value('Agw', Res_Cert))),
%%获取返回报文状态 “00”表示返回成功
case ResCode of
"00" ->
go_on;
_ ->
throw({ResCode,ResDetail})
end,
Xml_ResBody = proplists:get_value('Body', proplists:get_value('Agw', Res_Cert)),
QrNo = proplists:get_value('qrNo', Xml_ResBody),
backend_db:insert(lists:concat(["insert into MY_PEOPLECODE_STATUSLOGS (qrNo,usercode,STATUS,tran_time) values(",QrNo, ",",UserCode,",'00',to_date(sysdate))"])),
QrNo.
%%公钥加密,私钥解密,但是公钥格式不是pem而是cer
public_encode(Params)->
PlainText = list_to_binary(Params),
{ok, PemServerCert} = file:read_file(?FilePath),
[{'Certificate', DerServerCert, not_encrypted}] = public_key:pem_decode(PemServerCert),
OtpServerCert = public_key:pkix_decode_cert(DerServerCert, otp),
TbsCertificate = OtpServerCert#'OTPCertificate'.tbsCertificate,
SubjectPublicKeyInfo =TbsCertificate#'OTPTBSCertificate'.subjectPublicKeyInfo,
PublicKey = SubjectPublicKeyInfo#'OTPSubjectPublicKeyInfo'.subjectPublicKey,
CipherText = public_key:encrypt_public(PlainText, PublicKey),
CipherText.
%%银联根据时间判断
change_code(UserObj, TranID, P)->
TranNo = transaction:get_serial_no(TranID), %%流水号
CardNo = ewp_params:get("newCard",P),
CardType = ewp_params:get("newCardType",P),
QRcode = get_code(UserObj,TranNo,CardNo,CardType),
[{qrcode,QRcode}].
%%Function:get_mp_param
%%Description:从数据库中获取各种参数 unionpay_scancode:get_mp_param("people_valid_time","20")
%%Returns:string
get_mp_param(ParamName,DefaultValue)->
Data_db = backend_db:select("select param_value from MP_PARAMS t where param_code = :1",[ParamName]),
case Data_db of
[] ->
Data = DefaultValue; %%最开始时候定的生产的地址
_ ->
[[Data]] = Data_db
end,
Data.
'US0103'(_UserObj, _TranID, _P) ->
Chn_encryption_flag =backend_params:get_value("chn_encryption_flag"),
Pay_type = backend_params:get_value("people_pay_type"), %%1:卡密;0:卡密和短信验证码
[{pay_type,Pay_type},{"Chn_encryption_flag",Chn_encryption_flag}].
check_status(UserObj, _TranID, P)->
Qrcode = ewp_params:get("qrcode",P),
Acctype = ewp_params:get("acctype",P),
Data_db = backend_db:select("select STATUS,MONEY from MY_PEOPLECODE_STATUSLOGS t where QRNO = :1 AND TRAN_TIME = to_date(sysdate)",[Qrcode]),
case Data_db of %%金额从数据库得到 MY_PEOPLECODE_STATUSLOGS
[["0 ",_]] ->
[[STATUS,_MONEY]] = Data_db,
[{status,STATUS}];
[["00",_]] ->
[[STATUS,_MONEY]] = Data_db,
[{status,STATUS}];
[["0",_]] ->
[[STATUS,_MONEY]] = Data_db,
[{status,STATUS}];
[[_,_]] ->
[[STATUS,MONEY]] = Data_db,
[LimitFlag,Limit,Left] = limit_check(UserObj,MONEY,Acctype),
%% 1:超过单笔 2:超过日累计 3:超过月累计 4:正常
[{status,STATUS},{money,MONEY},{limitFlag,LimitFlag},{limit,Limit},{left,Left}]
end.
check_info(UserObj, TranID, P)->
Money = ewp_params:get("money",P),
Accno = ewp_params:get("accno",P),
QrNo = ewp_params:get("qrNo",P),
transaction:set_log_field('REMARK_ONE', QrNo, TranID), %%二维码放入tran_log表
Pay_type = ewp_params:get("pay_type",P),
Acctype = ewp_params:get("acctype",P),
case Pay_type of
"0"->
SmsID = ewp_params:get("smsid", P),
SmsCode = ewp_params:get("smscode", P),
smsic_service:identify_code(TranID, SmsID, SmsCode); %%验证动态密码
_ -> ok
end,
%点击付款的时候验证单笔限额、日累计、月累计
transaction:set_log_field('MONEY',Money,TranID),
transaction:set_log_field('ACC_OUTWARD',Accno,TranID),
Password1 = yaws_api:url_decode(ewp_params:get("password", P)), %%获取要修改的卡号
PasswordRnc =
case ewp_params:get("passwordRnc", P) of
undefined ->
undefined;
_ ->
yaws_api:url_decode(ewp_params:get("passwordRnc", P))
end,
PasswordRNS = get(passwordRNS),
case PasswordRnc of
undefined ->
Password = Password1;
_ ->
{A, B, C} = decryptKits:decode(Password1,PasswordRnc,PasswordRNS),
Password =
case {A, B, C} of
{1,Pass,_Err} ->
Pass;
{0, _Pass,_Err} ->
throw(?NOT_DECODE_PASS)
end
end,
TranNo = transaction:get_serial_no(TranID), %%流水号 algenc:encrypt()
case Acctype of %%账户类型(0借记卡、2信用卡)
"0" ->
%% 验证卡状态
transfer_api:judge_card_status(transaction:get_serial_no(TranID), Accno),
%%检测黑白名单(2为正常用户,0为黑名单,1为灰名单,0和1统一为else) check_blackorgray(Accno)
List_type = user_obj:get_field('List_type',UserObj),
case List_type of
"2" -> go_on;
_ -> throw(?UNKNOWN_CARD_STATES)
end,
%%验证卡的交易密码
transfer_api:check_acct_password(TranNo,Accno,Password);
_ -> %%"2"
Res1 = credit_api:get_Sxy001(TranNo, credit_api:get_credit_seq(), Accno, "0", ""),
case proplists:get_value(card_stat, Res1) of
"" -> go_on;
_ -> throw(?CREDIT_STATE_ERROR)
end,
Res024 = credit_api:get_Sxy024(TranNo, credit_api:get_credit_seq(), Accno, "0", ""),
case proplists:get_value(cardstat, Res024) of
"" -> go_on;
_ -> throw(?CREDIT_STATE_ERROR)
end%%, %%;
%%credit_api:get_Sxy001(TranNo, credit_api:get_credit_seq(), Accno, "2", backend_util:encrypt_cc_pin(Accno, Password))
end,
backend_db:update("update MY_PEOPLECODE_STATUSLOGS set status = : 1 where qrNo = : 2 and tran_time = to_date(sysdate) ",["02", QrNo]),
%%transfer_api:check_acct_password(TranNo, AcctNoFk,algenc:encrypt(Password),MobileNo),%%
[{result,"02"}]. %%只要不throw就是正常的,验密正确
send_addresult(_UserObj, TranID, P) ->
%%请求附加结果操作
QrNo = ewp_params:get("qrNo",P),
Data_db = backend_db:select("select VOUCHERNUM from MY_PEOPLECODE_STATUSLOGS t where QRNO = :1 AND TRAN_TIME = to_date(sysdate)",[QrNo]),
[[VOUCHERNUM]] = case Data_db of %%金额从数据库得到 MY_PEOPLECODE_STATUSLOGS
[[_Data]] ->
Data_db
end,
IssCode = ?ISSCODE,
Xbody = "<version>1.0.0</version><reqType>0240000903</reqType><issCode>" ++ IssCode ++
"</issCode><qrNo>" ++ QrNo ++ "</qrNo><respCode>00</respCode><respMsg>成功</respMsg><voucherNum>" ++
VOUCHERNUM ++ "</voucherNum>",
%%"<upReserved></upReserved>"
TranNo = transaction:get_serial_no(TranID), %%流水号
Res_Cert = wailian_client_qm:peoplecode_xml_request("MBU002",TranNo,Xbody),
Xml_ResBody = wailian_client_qm:get_peoplecode_value(Res_Cert), %%发送成功即可
RespCode = proplists:get_value('respCode', Xml_ResBody,undefined),
RespMsg = proplists:get_value('respMsg', Xml_ResBody,undefined),
case RespCode of
"00" ->
backend_db:update("update MY_PEOPLECODE_STATUSLOGS set status = : 1, OrigRespCode = : 2, OrigRespMsg = : 3 where qrNo = : 4 and tran_time = to_date(sysdate)", ["03",RespCode,RespMsg,QrNo]),
[{status,"03"}]; %%表示成功
"0000" ->
backend_db:update("update MY_PEOPLECODE_STATUSLOGS set status = : 1, OrigRespCode = : 2, OrigRespMsg = : 3 where qrNo = : 4 and tran_time = to_date(sysdate)", ["03",RespCode,RespMsg,QrNo]),
[{status,"03"}]; %%表示成功
_ ->
backend_db:update("update MY_PEOPLECODE_STATUSLOGS set status = : 1, OrigRespCode = : 2, OrigRespMsg = : 3 where qrNo = : 4 and tran_time = to_date(sysdate)", ["04",RespCode,RespMsg,QrNo]),
?ewp_err("get data error:==========================~p~n",[RespCode]),
[{status,"04"}] %%表示失败
end.
get_result(UserObj, TranID, P) ->
UserCode = user_obj:get_field('USER_CODE', UserObj),
QrNo = ewp_params:get("qrNo",P),
Acctype = ewp_params:get("acctype",P),
Money = ewp_params:get("money",P),
final_page(QrNo,Acctype,Money,UserCode,TranID).
%%查询数据库得到交易结果,根据返回成功是成功页面,否则为失败页面
final_page(QrNo,Acctype,Money,UserCode,TranID)->
Data_db = backend_db:select("select STATUS,MERNAME,VOUCHERNUM, OrigRespCode,OrigRespMsg from MY_PEOPLECODE_STATUSLOGS t where QRNO = :1 AND TRAN_TIME = to_date(sysdate)",[QrNo]),
SysDateTime = backend_date_util:get_total_time(),
case Data_db of %%金额从数据库得到 MY_PEOPLECODE_STATUSLOG
%% [["00",_,_]]-> %%判断变更为前台
%% timer:sleep(1000), %1s
%% final_page(QrNo);
%% [["01",_,_]] ->
%% timer:sleep(1000), %1s
%% final_page(QrNo);
%% [["02",MERNAME,VOUCHERNUM]] -> %%成功
%% [{status,'02'},{mername,MERNAME},{vouchernum,VOUCHERNUM},{time,SysDateTime}];
[["05",MERNAME,VOUCHERNUM,OrigRespCode,OrigRespMsg]]-> %%成功
%% case Acctype of
%% "0" ->
%% cum_transfer_sum(UserCode, Money);
%% _ ->
%% cum_transfer_sum1(UserCode, Money)
%% end,
transaction:set_log_field('INWARD_NAME',MERNAME,TranID),
transaction:finish_success(TranID),
[{status,"05"},{mername,MERNAME},{vouchernum,VOUCHERNUM},{origRespCode,OrigRespCode},{origRespMsg,OrigRespMsg},{time,SysDateTime}];
[[STATUS,MERNAME,VOUCHERNUM,OrigRespCode,OrigRespMsg]]-> %%失败
case Acctype of
"0" ->
cum_transfer_sub(UserCode, Money);
_ ->
cum_transfer_sub1(UserCode, Money)
end,
transaction:set_log_field('INWARD_NAME',MERNAME,TranID),
[{status,STATUS},{mername,MERNAME},{vouchernum,VOUCHERNUM},{origRespCode,OrigRespCode},{origRespMsg,OrigRespMsg},{time,SysDateTime}]
end.