/// <summary> /// 生成一个新的钱包 /// </summary> /// <returns></returns> DBModels.Wallet CreateWallet() { string account = null; using (var db = new MainDB()) { //generate account number while (account == null) { account = new Random().Next(10000000, 99999999).ToString(); if (db.Wallet.Any(m => m.Account == account)) { //account exists,generate account number again account = null; } } db.BeginTransaction(); try { var wallet = new DBModels.Wallet() { Account = account, Secret = Guid.NewGuid().ToString("N") }; db.Insert(wallet); #region 创建BTC平台密钥 BTC_Client btc_client = new BTC_Client(); byte[] key1, key2; btc_client.CreatePlatformKey(out key1, out key2); var walletInfo = new DBModels.WalletCyptoCoinInfo() { Key1 = key1, Key2 = key2, WalletId = wallet.id, Currency = "BTC", }; db.Insert(walletInfo); #endregion db.CommitTransaction(); return(wallet); } catch { db.RollbackTransaction(); throw; } } }
/// <summary> /// 发起btc支付交易 /// </summary> /// <returns></returns> public object Pay([FromBody] NullableSortedDict <string, object> postData) { using (var db = new MainDB()) using (Way.Lib.CLog log = new Way.Lib.CLog("Pay")) { try { double?amount = postData.GetValue <double?>("amount"); string account = postData.GetValue <string>("account"); string sign = postData.GetValue <string>("sign"); string outTradeNo = postData.GetValue <string>("outTradeNo"); string notifyUrl = postData.GetValue <string>("notifyUrl"); string currency = postData.GetValue <string>("currency"); if (amount <= 0) { throw new Exception("金额无效"); } var wallet = db.Wallet.FirstOrDefault(m => m.Account == account); if (wallet == null) { throw new Exception($"账户“{account}”不存在"); } log.LogJson(postData); currency = currency.ToUpper(); var signResult = Helper.Sign(postData, wallet.Secret); if (signResult != sign) { throw new Exception("签名校验失败"); } var newTran = new DBModels.Transaction { Amount = amount, NotifyUrl = notifyUrl, OutTradeNo = outTradeNo }; //根据币种创建ICyptoCoinClient var client = Activator.CreateInstance(typeof(ApiController).Assembly.GetType($"Cailutong.CyptoCoinGateway.CyptoCoinPlatform.Impls.{currency}.{currency}_Client")) as CyptoCoinPlatform.ICyptoCoinClient; if (client == null) { throw new Exception("不支持" + currency); } //填充交易里面的付款地址 transactionGetCyptoCoinAddress(db, account, currency, client, newTran); newTran.WalletId = wallet.id; db.Insert(newTran); return(Helper.SignResult(new { status = "success", outTradeNo = outTradeNo, targetAddress = newTran.CyptoCoinAddress }, wallet.Secret)); } catch (Exception ex) { log.Log(ex.ToString()); return(new { status = "error", errMsg = ex.Message }); } } }
static void checkTransaction(MainDB db, NBitcoin.Transaction cyptoCoinTransaction, int confirmations, Way.Lib.CLog log) { var payedTranid = cyptoCoinTransaction.GetHash().ToString(); log.Log($"transactionid:{payedTranid}"); foreach (var txOut in cyptoCoinTransaction.Outputs) { var addr = txOut.ScriptPubKey.GetDestinationAddress(NBitcoin.Network.Main).ToString(); log.Log($"txOut:{addr} value:{txOut.Value}"); //如果支付地址和钱包交易里的地址一致,那么,进行处理 var transaction = db.Transaction.FirstOrDefault(m => m.Status != DBModels.Transaction_StatusEnum.Invalided && m.CyptoCoinAddress == addr); if (transaction != null) { var cyptoCoinTranItem = db.CyptoCoinTran.FirstOrDefault(m => m.TransactionId == transaction.id && m.CyptoCoinTransId == payedTranid); if (cyptoCoinTranItem == null) { log.Log($"belong to Transaction {transaction.id},increase Transaction's PayedAmount"); var amount = Convert.ToDouble(txOut.Value.ToDecimal(NBitcoin.MoneyUnit.BTC)); transaction.PayedAmount += amount; if (transaction.PayedAmount >= transaction.Amount) { transaction.Status = DBModels.Transaction_StatusEnum.AllPayed; } else { transaction.Status = DBModels.Transaction_StatusEnum.PartialPayed; } db.Update(transaction); var secret = db.Wallet.Where(m => m.id == transaction.WalletId).Select(m => m.Secret).FirstOrDefault(); //发送通知 if (!string.IsNullOrEmpty(transaction.NotifyUrl)) { Task.Run(() => NotifyTask.SentNotify(transaction, secret)); } cyptoCoinTranItem = new DBModels.CyptoCoinTran() { CyptoCoinTransId = payedTranid, TransactionId = transaction.id, PayedAmount = amount, PayTime = DateTime.Now }; db.Insert(cyptoCoinTranItem); } else { cyptoCoinTranItem.Confirmations = confirmations; db.Update(cyptoCoinTranItem); //发送通知 if (!string.IsNullOrEmpty(transaction.NotifyUrl) && confirmations <= 6) { var secret = db.Wallet.Where(m => m.id == transaction.WalletId).Select(m => m.Secret).FirstOrDefault(); Task.Run(() => NotifyTask.SentNotify(transaction, secret)); } } } } }