- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
以下代码的功能是用户可以实现业务中用户虚拟钱包的钱提现到用户银行卡,其实本质上是把商户的账户资金划转到用户银行卡,其实就是银行转账,相关代码如下:
///此方法存在部分业务代码,核心方法是doProcess方法且基本是可以复用的,其它的代码可以根据自身业务场景灵活处理;
public async Task<WithDrawResultDto> WithDrawToBank(TransferToBankDto transferToBankDto) { decimal balance = await _repository.WalletRepository.GetWalletBalance( new Contract.User.UserBasicDto() { WeChatId = transferToBankDto.WeChatId, }); if (balance < transferToBankDto.Amount) { return new WithDrawResultDto() { WithDrawResult = false , Message = " 可用余额不够,请重新输入提现金额。 " }; } long userId = await _repository.UserRepository.GetUserIdByWeChatId(transferToBankDto.WeChatId); if (userId == 0 ) { return new WithDrawResultDto() { WithDrawResult = false , Message = " 用户不存在 " }; } // bool walletToBankResult = await _walletService.WalletToBankAccount(transferToBankDto.WeChatId, userId, transferToBankDto.Amount, (int)WalletCashType.Withdrawing, yurRef); // if (walletToBankResult) // { Log.Information( " begin WithDraw call cloud direct " ); string reqId = DCHelper.GetTime() + RandomHelper.GeneratorRandomStr( 7 ); decimal amount = transferToBankDto.Amount; string bankCode = await _repository.BankRepository.QueryBankCodeByBankAccount(userId, transferToBankDto.BankAccount); string bankHolder = await _repository.BankRepository.QueryCardHolder(userId, transferToBankDto.BankAccount); Log.Information($ " bankHolder:{bankHolder} " ); // 记录业务编号 // 业务编号记录到数据库 // 组织发送报文 JObject obj = new JObject(); JObject req = new JObject(); JArray bb1paybmx1BodyArray = new JArray(); JObject bb1paybmx1Body = new JObject(); JObject bb1paybmx1Body2 = new JObject(); JArray bb1payopx1BodyArray = new JArray(); JObject bb1payopx1Body = new JObject(); JObject bb1payopx1Body2 = new JObject(); JObject head = new JObject(); head.Add( " funcode " , FunCode);// FunCode = "BB1PAYOP";功能代码 head.Add( " userid " , UID);//用户编号,与商户相关 head.Add( " reqid " , reqId); bb1paybmx1Body.Add( " busCod " , BusCod);//BusCod = "N02030";业务编码 bb1paybmx1Body.Add( " busMod " , BusMod);///业务模式 bb1paybmx1BodyArray.Add(bb1paybmx1Body); // bb1paybmx1Body2.Add("bb1paybmx1", bb1paybmx1BodyArray); JArray bb1payopx1 = new JArray(); bb1payopx1Body.Add( " dbtAcc " , CompanyCard);//公司账号 bb1payopx1Body.Add( " crtAcc " , transferToBankDto.BankAccount);//收款人账号 bb1payopx1Body.Add( " crtNam " , bankHolder);//持卡人姓名 bb1payopx1Body.Add( " ccyNbr " , CurrencyCode);//币种 CurrencyCode = "10";//10代表人民币 bb1payopx1Body.Add( " trsAmt " , amount.ToString( " #0.00 " )); // bb1payopx1Body.Add("crtBnk", "招商银行深圳分行"); bb1payopx1Body.Add( " bnkFlg " , (bankCode == CMBCode ? " Y " : " N " ));//CMBCodeCMBCode = "CMB";如果是招商银行,bnkFlg的取值是Y bb1payopx1Body.Add( " stlChn " , StlChn);//StlChn为R代表及时到账 bb1payopx1Body.Add( " nusAge " , " 钱包提现到银行卡 " ); // bb1payopx1Body.Add("yurRef", "202008260078000033"); bb1payopx1Body.Add( " yurRef " , yurRef);//业务流水号,可以使用雪花算法生成 bb1payopx1BodyArray.Add(bb1payopx1Body); JObject jobjectBodyList = new JObject(); jobjectBodyList.Add( " bb1paybmx1 " , bb1paybmx1BodyArray); jobjectBodyList.Add( " bb1payopx1 " , bb1payopx1BodyArray); JObject jobjectBody = new JObject(); jobjectBody.Add( " body " , jobjectBodyList); jobjectBody.Add( " head " , head); JObject requestBody = new JObject(); requestBody.Add( " request " , jobjectBody); // bb1payopx1Body2.Add("bb1payopx1", bb1payopx1BodyArray); // 请求发送接收 var withDrawResult = doProcess(requestBody, FunCode); if (withDrawResult.WithDrawResult == true ) { bool walletToBankResult = await _walletService.WalletToBankAccount(transferToBankDto.WeChatId, userId, transferToBankDto.Amount, ( int )WalletCashType.Withdrawing, yurRef); WithDrawToBankRecord withDrawToBankRecord = new WithDrawToBankRecord (userId: userId, funcode: FunCode, reqid: reqId, busCod: BusCod, busMod: BusMod, dbtAcc: CompanyCard, crtAcc: transferToBankDto.BankAccount, crtNam: bankHolder, ccyNbr: CurrencyCode, trsAmt: amount, bnkFlg: (bankCode == CMBCode ? " Y " : " N " ), stlChn: StlChn, nusAge: " 钱包提现到银行卡 " , yurRef: yurRef.ToString(), withdrawStatus: 0 ,openId: transferToBankDto.OpenId); await _repository.RedPackageRepository.CreateWithDrawToBankRecord(withDrawToBankRecord); await WithDrawSendMsgToClient.SendMsgToClient(openId: transferToBankDto.OpenId, templageId: SuccessTemplateId, amount: amount, withdrawDatetime: DateTime.Now.ToString( " yyyy-MM-dd HH:mm:ss " ), WithdrawToBankStatus.Success); } // 更新出金时间 await _repository.BankRepository.UpdateWithDrawDateTimeAsync(userId, transferToBankDto.BankAccount); return withDrawResult; // } // else // { // return new WithDrawResultDto() { WithDrawResult = false,Message="提现失败,请稍后重试." }; // } }
DCHelper辅助类 。
using Newtonsoft.Json.Linq; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Security; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading.Tasks; namespace Demo.Utils { public class DCHelper { public static string SerialJsonOrdered(JObject json) { List < string > keyList = new List< string > (); foreach ( var x in json) { keyList.Add(x.Key); } string [] keyArray = keyList.ToArray(); Array.Sort(keyArray, string .CompareOrdinal); StringBuilder appender = new StringBuilder(); appender.Append( " { " ); bool isFirstEle = true ; foreach ( var key in keyArray) { if (! isFirstEle) { appender.Append( " , " ); } Object val = json[key]; if (val is JObject) { appender.Append( " \" " ).Append(key).Append( " \": " ); appender.Append(SerialJsonOrdered((JObject)val)); } else if (val is JArray) { JArray jarray = (JArray)val; appender.Append( " \" " ).Append(key).Append( " \":[ " ); bool isFirstArrEle = true ; for ( int i = 0 ; i < jarray.Count; i++ ) { if (! isFirstArrEle) { appender.Append( " , " ); } Object obj = jarray[i]; if (obj is JObject) { appender.Append(SerialJsonOrdered((JObject)obj)); } else { appender.Append(obj.ToString()); } isFirstArrEle = false ; } appender.Append( " ] " ); } else if (((JToken)val).Type == JTokenType.String) { string value = val.ToString(); appender.Append( " \" " ).Append(key).Append( " \": " ).Append( " \" " ).Append(value.Replace( " \\ " , " \\\\ " )).Append( " \" " ); } else if (((JToken)val).Type == JTokenType.Boolean) { string value = val.ToString().ToLower(); appender.Append( " \" " ).Append(key).Append( " \": " ).Append(value); } else { string value = val.ToString(); appender.Append( " \" " ).Append(key).Append( " \": " ).Append(value); } isFirstEle = false ; } appender.Append( " } " ); return appender.ToString(); } public static String GetTime() { return DateTime.Now.ToString( " yyyyMMddHHmmssfff " ); } public static String GetTime2() { return DateTime.Now.ToString( " yyyyMMddHHmmss " ); } // 发送Post请求 public static String DoPostForm(String httpUrl, Hashtable param) { Encoding encoding = Encoding.GetEncoding( " utf-8 " ); HttpWebResponse response = PostHttps(httpUrl, param, encoding); Stream stream = response.GetResponseStream(); StreamReader sr = new StreamReader(stream); return sr.ReadToEnd(); } private static bool CheckValidationResult( object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) { return true ; // 信任所有https站点证书,不安全,请勿在生产环境中使用。 } private static HttpWebResponse PostHttps( string url, Hashtable param, Encoding encoding) { HttpWebRequest request = null ; // ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult); // 请勿在生产环境中使用该行程序 request = WebRequest.Create(url) as HttpWebRequest; request.ProtocolVersion = HttpVersion.Version11; request.Method = " POST " ; request.ContentType = " application/x-www-form-urlencoded " ; request.Timeout = 15000 ; request.KeepAlive = false ; request.ReadWriteTimeout = 60000 ; byte [] data = encoding.GetBytes(CreateLinkString(param)); request.ContentLength = data.Length; using (Stream stream = request.GetRequestStream()) { stream.Write(data, 0 , data.Length); } WebResponse res; try { res = request.GetResponse(); } catch (WebException e) { res = e.Response; } return (HttpWebResponse)res; } private static string CreateLinkString(Hashtable param) { IEnumerator keys = param.Keys.GetEnumerator(); StringBuilder prestr = new StringBuilder(); int i = 0 ; while (keys.MoveNext()) { i ++ ; string key = keys.Current as string ; string value = param[key] as string ; if (i == param.Count) { prestr.Append(key).Append( " = " ).Append(value); } else { prestr.Append(key).Append( " = " ).Append(value).Append( " & " ); } } return prestr.ToString(); } } }
RandomHelper辅助类 。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Demo.Utils { public static class RandomHelper { public static string GeneratorRandomStr( int len) { string chars = " 0123456789abcdefghijklmnopqrstuvwxyz " ; Random randrom = new Random(( int )DateTime.Now.Ticks); string str = "" ; for ( int i = 0 ; i < len; i++ ) { str += chars[randrom.Next(chars.Length)]; } return str; } } }
。
核心方法:
private WithDrawResultDto doProcess(JObject jObject, string FUNCODE) { JObject obj = new JObject(); // 签名 obj.Add( " sigdat " , " __signature_sigdat__ " ); obj.Add( " sigtim " , DCHelper.GetTime2()); jObject.Add( " signature " , obj); string source = DCHelper.SerialJsonOrdered(jObject); Console.WriteLine( " 签名原文: " + source); Log.Information($ " {FUNCODE} request data is {source} " ); Encoding encoding = Encoding.UTF8; byte [] signature1 = DCCryptor.CMBSM2SignWithSM3(GetID_IV(), Convert.FromBase64String(privkey), encoding.GetBytes(source));//privkey是私钥 string sigdat1 = Convert.ToBase64String(signature1); Console.WriteLine( " 签名结果: " + sigdat1); obj[ " sigdat " ] = sigdat1; // SM4-CBC加密 string plaintxt = jObject.ToString(); Console.WriteLine( " 加密前req: " + plaintxt); byte [] enInput = DCCryptor.CMBSM4EncryptWithCBC(encoding.GetBytes(sm4key), GetID_IV(), encoding.GetBytes(plaintxt));//sm4key是用户的对称密钥 string req = Convert.ToBase64String(enInput); Console.WriteLine( " 加密后req: " + req); Log.Information( " begin send request to cloud direct " ); // 发送请求 Hashtable map = new Hashtable(); map.Add( " UID " , UID); map.Add( " ALG " , ALG_SM);//ALG_SM = "SM";采用国密算法 map.Add( " DATA " , HttpUtility.UrlEncode(req, encoding)); map.Add( " FUNCODE " , FUNCODE); string res = DCHelper.DoPostForm(URL, map);//访问招商银行的api请求地址:(测试环境:http://cdctest.cmburl.cn/cdcserver/api/v2;正式环境:https://cdc.cmbchina.com/cdcserver/api/v2) Log.Information( " end request " ); Console.WriteLine( " res: " + res); Log.Information( " DoPostForm {@res} " , res); try { Convert.FromBase64String(res); } catch (Exception ex) { Console.WriteLine( " 访问返回错误. " ); Log.Information( " Convert.FromBase64String error {@ex} " , ex); return new () { WithDrawResult = false , Message = " 访问返回错误. " }; } // 解密请求 string resplain = encoding.GetString(DCCryptor.CMBSM4DecryptWithCBC(encoding.GetBytes(sm4key), GetID_IV(), Convert.FromBase64String(res))); Console.WriteLine( " res decrypt: " + resplain); Log.Information($ " {FUNCODE} response data is {resplain} " ); // 验签 JObject object2 = JObject.Parse(resplain); JObject ? object3 = object2[ " signature " ] as JObject; string ? resSign = object3?[ " sigdat " ]? .ToString(); object3[ " sigdat " ] = " __signature_sigdat__ " ; object2[ " signature " ] = object3; string resSignSource = DCHelper.SerialJsonOrdered(object2); Console.WriteLine( " 验签原文: " + resSignSource); Console.WriteLine( " 验签签名值: " + resSign); bool verify = DCCryptor.CMBSM2VerifyWithSM3(GetID_IV(), Convert.FromBase64String(bankpubkey), encoding.GetBytes(resSignSource), Convert.FromBase64String(resSign));//bankpubkey:银行公钥 Console.WriteLine( " 验签结果: " + verify); Log.Information($ " 验签结果:{verify} " ); if (verify) { // 验签成功以后正常判断 if (object2[ " response " ]?[ " head " ]?[ " resultcode " ] is not null ) { string ? resultCode = object2[ " response " ]?[ " head " ]?[ " resultcode " ]? .ToString(); if (resultCode != " SUC0000 " ) { Log.Information($ " withdraw hava error,resultmsg is {object2[ " response " ]?[ " head " ]?[ " resultmsg " ]?.ToString()}, " + $ " resultcode is {object2[ " response " ]?[ " head " ]?[ " resultcode " ]?.ToString()} " ); return new () { WithDrawResult = false , Message = object2[ " response " ]?[ " head " ]?[ " resultmsg " ]? .ToString() }; } else { string [] errors = new [] { " F " , " B " , " R " , " D " , " C " }; string ? rtnFlg = object2[ " response " ]?[ " body " ]?[ " bb1payopz1 " ][ 0 ]?[ " rtnFlg " ]? .ToString(); if (object2[ " response " ]?[ " body " ]?[ " bb1payopz1 " ][ 0 ]?[ " reqSts " ]?.ToString() == " FIN " && errors.Contains(rtnFlg)) { Log.Information($ " withdraw hava error,errTxt is {object2[ " response " ]?[ " body " ]?[ " bb1payopz1 " ][0]?[ " errTxt " ]?.ToString()}, " + $ " errCod is {object2[ " response " ]?[ " body " ]?[ " bb1payopz1 " ][0]?[ " errCod " ]?.ToString()} " ); return new () { WithDrawResult = false , Message = object2[ " response " ]?[ " body " ]?[ " bb1payopz1 " ][ 0 ]?[ " errTxt " ]? .ToString() }; } } } } else { Log.Error( " 验签失败 " ); return new () { WithDrawResult = false , Message = " 验签失败,请联系系统管理员。 " }; } return new () { WithDrawResult = true }; }
私有方法 。
private byte [] GetID_IV() { String uid = UID; // 请替换为实际的用户UID String userid = uid + " 0000000000000000 " ; return Encoding.UTF8.GetBytes(userid.Substring( 0 , 16 )); }
。
DCCryptor辅助类 。
using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.X9; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Signers; using Org.BouncyCastle.Math; using Org.BouncyCastle.Math.EC; using Org.BouncyCastle.Security; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Demo.Utils { public class DCCryptor { public static byte [] CMBSM4EncryptWithCBC( byte [] key, byte [] iv, byte [] input) { if (key == null || iv == null || input == null ) { throw new Exception( " CMBSM4EncryptWithCBC 非法输入 " ); } return CMBSM4Crypt(key, iv, input, true ); } public static byte [] CMBSM4DecryptWithCBC( byte [] key, byte [] iv, byte [] input) { if (key == null || iv == null || input == null ) { throw new Exception( " CMBSM4DecryptWithCBC 非法输入 " ); } return CMBSM4Crypt(key, iv, input, false ); } public static byte [] CMBSM2SignWithSM3( byte [] id, byte [] privkey, byte [] msg) { if (privkey == null || msg == null ) { throw new Exception( " CMBSM2SignWithSM3 input error " ); } ECPrivateKeyParameters privateKey = EncodePrivateKey(privkey); SM2Signer signer = new SM2Signer(); ParametersWithID parameters = new ParametersWithID(privateKey, id); signer.Init( true , parameters); signer.BlockUpdate(msg, 0 , msg.Length); return DecodeDERSignature(signer.GenerateSignature()); } public static bool CMBSM2VerifyWithSM3( byte [] id, byte [] pubkey, byte [] msg, byte [] signature) { if (pubkey == null || msg == null || signature == null ) { throw new Exception( " CMBSM2VerifyWithSM3 input error " ); } ECPublicKeyParameters publicKey = EncodePublicKey(pubkey); SM2Signer signer = new SM2Signer(); ParametersWithID parameters = new ParametersWithID(publicKey, id); signer.Init( false , parameters); signer.BlockUpdate(msg, 0 , msg.Length); return signer.VerifySignature(EncodeDERSignature(signature)); } private static byte [] CMBSM4Crypt( byte [] keyBytes, byte [] iv, byte [] input, bool forEncrypt) { KeyParameter key = ParameterUtilities.CreateKeyParameter( " SM4 " , keyBytes); ParametersWithIV ivParameterSpec = new ParametersWithIV(key, iv); IBufferedCipher cipher = CipherUtilities.GetCipher( " SM4/CBC/PKCS7Padding " ); cipher.Init(forEncrypt, ivParameterSpec); return cipher.DoFinal(input); } private static ECPrivateKeyParameters EncodePrivateKey( byte [] value) { BigInteger d = new BigInteger( 1 , value); X9ECParameters spec = ECNamedCurveTable.GetByName( " sm2p256v1 " ); ECDomainParameters ecParameters = new ECDomainParameters(spec.Curve, spec.G, spec.N, spec.H, spec.GetSeed()); return new ECPrivateKeyParameters(d, ecParameters); } public static ECPublicKeyParameters EncodePublicKey( byte [] value) { byte [] x = new byte [ 32 ]; byte [] y = new byte [ 32 ]; Array.Copy(value, 1 , x, 0 , 32 ); Array.Copy(value, 33 , y, 0 , 32 ); BigInteger X = new BigInteger( 1 , x); BigInteger Y = new BigInteger( 1 , y); X9ECParameters spec = ECNamedCurveTable.GetByName( " sm2p256v1 " ); ECPoint Q = spec.Curve.CreatePoint(X, Y); ECDomainParameters ecParameters = new ECDomainParameters(spec.Curve, spec.G, spec.N, spec.H, spec.GetSeed()); return new ECPublicKeyParameters(Q, ecParameters); } private static byte [] DecodeDERSignature( byte [] signature) { Asn1InputStream stream = new Asn1InputStream(signature); Asn1Sequence primitive = (Asn1Sequence)stream.ReadObject(); System.Collections.IEnumerator enumeration = primitive.GetEnumerator(); enumeration.MoveNext(); BigInteger R = ((DerInteger)enumeration.Current).Value; enumeration.MoveNext(); BigInteger S = ((DerInteger)enumeration.Current).Value; byte [] bytes = new byte [ 64 ]; byte [] r = Format(R.ToByteArray()); byte [] s = Format(S.ToByteArray()); Array.Copy(r, 0 , bytes, 0 , 32 ); Array.Copy(s, 0 , bytes, 32 , 32 ); return bytes; } private static byte [] EncodeDERSignature( byte [] signature) { byte [] r = new byte [ 32 ]; byte [] s = new byte [ 32 ]; Array.Copy(signature, 0 , r, 0 , 32 ); Array.Copy(signature, 32 , s, 0 , 32 ); Asn1EncodableVector vector = new Asn1EncodableVector(); vector.Add( new DerInteger( new BigInteger( 1 , r))); vector.Add( new DerInteger( new BigInteger( 1 , s))); return ( new DerSequence(vector)).GetEncoded(); } private static byte [] Format( byte [] value) { if (value.Length == 32 ) { return value; } else { byte [] bytes = new byte [ 32 ]; if (value.Length > 32 ) { Array.Copy(value, value.Length - 32 , bytes, 0 , 32 ); } else { Array.Copy(value, 0 , bytes, 32 - value.Length, value.Length); } return bytes; } } } }
。
最后此篇关于使用招商银行云直连服务提现(.Net6)的文章就讲到这里了,如果你想了解更多关于使用招商银行云直连服务提现(.Net6)的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在尝试使用 cordova 创建一个应用程序,我需要使用 wifi 将数据传输到另一个应用程序,我搜索了很多,我发现了许多用于扫描、连接和创建网络、设置 ssid 和其他主要内容的插件,我没有找到
我正在开发一个基于 Android 版 WiFi Direct 的简单应用程序,它必须连接两个设备。为此,我需要调用函数 onPeersAvailable(myPeerListListener),但我
如何在 unity 中使用 wifi direct 为 android 连接两个 android 设备。 最佳答案 关注this学习如何创建 Wi-Fi Direct 应用程序的教程。 为了帮助您了解
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 6 年前。 Improve this qu
我知道 Wi-Fi Direct 的工作原理以及发现阶段是什么,因为我阅读了整个 Wi-Fi Direct 规范 v1.1。 当我想连接到 Android 设备时,我必须开始发现阶段。当触发 onPe
我正在尝试让两个 Android 设备使用 WiFi Direct 相互通信。我在 ListView 中列出了可用的设备,当用户点击设备时,我通过调用 connect 来启动连接。来自 WifiP2p
我是一名优秀的程序员,十分优秀!