需求:自助機調用接口生成二維碼,用戶掃描二維碼付款后,回調方法里寫入到數據庫,自助機輪詢查數據庫判斷用戶是否付款。
1 using bk.Services.Log; 2 using bk.web.Common.Alipay; 3 using bk.web.Common.Weixin; 4 using System.Collections.Generic; 5 using System.Collections.Specialized; 6 using System.Text; 7 using System.Web; 8 using System.Web.Mvc; 9 using Com.Alipay; 10 using Com.Alipay.Business; 11 using Com.Alipay.Domain; 12 using Com.Alipay.Model; 13 using System; 14 using bk.web.Models; 15 using bk.Core.Domain; 16 using System.IO; 17 using bk.Core; 18 using bk.Services.Admin; 19 using System.Threading.Tasks; 20 using bk.Core.Infrastructure; 21 using System.Linq; 22 using System.Configuration; 23 24 namespace bk.web.Controllers 25 { 26 public class PayNotifyController : Controller 27 { 28 private readonly IAgent_User_ImgService _userService; 29 private readonly IAgentOperationPayService _payService; 30 private readonly IAgentOperationService _operateService; 31 private readonly IAgentDevice_PayService _amountService; 32 public PayNotifyController( 33 IAgent_User_ImgService userService, 34 IAgentOperationPayService payService, 35 IAgentOperationService operateService, 36 IAgentDevice_PayService amountService) 37 { 38 this._userService = userService; 39 _payService = payService; 40 _operateService = operateService; 41 _amountService = amountService; 42 } 43 44 // GET: PayNotify 45 public ActionResult Index() 46 { 47 return View(); 48 } 49 50 #region 微信支付回調 51 /// <summary> 52 /// 支付結果通知回調處理類 53 /// 負責接收微信支付后台發送的支付結果並對訂單有效性進行驗證,將驗證結果反饋給微信支付后台 54 /// </summary> 55 public void wxNotify() 56 { 57 Log.Info(this.GetType().ToString(), "微信支付回調開始"); 58 59 WxPayData notifyData = GetNotifyData(); 60 //檢查支付結果中transaction_id是否存在 61 if (!notifyData.IsSet("transaction_id")) 62 { 63 //若transaction_id不存在,則立即返回結果給微信支付后台 64 WxPayData res = new WxPayData(); 65 res.SetValue("return_code", "FAIL"); 66 res.SetValue("return_msg", "支付結果中微信訂單號不存在"); 67 Log.Error(this.GetType().ToString(), "The Pay result is error : " + res.ToXml()); 68 Response.Write(res.ToXml()); 69 Response.End(); 70 } 71 72 string transaction_id = notifyData.GetValue("transaction_id").ToString(); 73 74 //查詢訂單,判斷訂單真實性 75 if (!QueryOrder(transaction_id)) 76 { 77 //若訂單查詢失敗,則立即返回結果給微信支付后台 78 WxPayData res = new WxPayData(); 79 res.SetValue("return_code", "FAIL"); 80 res.SetValue("return_msg", "訂單查詢失敗"); 81 Log.Error(this.GetType().ToString(), "Order query failure : " + res.ToXml()); 82 Response.Write(res.ToXml()); 83 Response.End(); 84 } 85 //查詢訂單成功 86 else 87 { 88 //更新數據庫 89 //WriteLog.Debug("notifyData begin:"); 90 //var dicValue = notifyData.GetValues(); 91 //foreach (var item in dicValue) 92 //{ 93 // WriteLog.Debug(item.Key + " : " + item.Value); 94 //} 95 //WriteLog.Debug("notifyData end;"); 96 string out_trade_no = notifyData.GetValue("out_trade_no").ToString(); 97 UpdatePayData(1, out_trade_no, transaction_id); 98 99 WxPayData res = new WxPayData(); 100 res.SetValue("return_code", "SUCCESS"); 101 res.SetValue("return_msg", "OK"); 102 Log.Info(this.GetType().ToString(), "order query success : " + res.ToXml()); 103 104 Response.Write(res.ToXml()); 105 Response.End(); 106 } 107 108 } 109 110 private void UpdatePayData(int payType, string out_trade_no, string transaction_id) 111 { 112 //更新AgentOperationPay 113 M_AgentOperationPay m = _payService.GetByOrderNo(out_trade_no); 114 if (m == null) 115 { 116 117 } 118 else 119 { 120 m.SerialNo = transaction_id; 121 m.Payment = payType; 122 m.PayStatus = 1; 123 _payService.Update(m); 124 125 //更新AgentOperation 126 M_AgentOperation om = _operateService.GetByOperationNo(m.OperationNo); 127 om.Status = 1; 128 _operateService.Update(om); 129 } 130 } 131 132 /// <summary> 133 /// 接收從微信支付后台發送過來的數據並驗證簽名 134 /// </summary> 135 /// <returns>微信支付后台返回的數據</returns> 136 public WxPayData GetNotifyData() 137 { 138 //接收從微信后台POST過來的數據 139 System.IO.Stream s = Request.InputStream; 140 int count = 0; 141 byte[] buffer = new byte[1024]; 142 StringBuilder builder = new StringBuilder(); 143 while ((count = s.Read(buffer, 0, 1024)) > 0) 144 { 145 builder.Append(Encoding.UTF8.GetString(buffer, 0, count)); 146 } 147 s.Flush(); 148 s.Close(); 149 s.Dispose(); 150 151 WriteLog.Debug("Receive data from WeChat : " + builder.ToString()); 152 153 //轉換數據格式並驗證簽名 154 WxPayData data = new WxPayData(); 155 try 156 { 157 data.FromXml(builder.ToString()); 158 } 159 catch (WxPayException ex) 160 { 161 //若簽名錯誤,則立即返回結果給微信支付后台 162 WxPayData res = new WxPayData(); 163 res.SetValue("return_code", "FAIL"); 164 res.SetValue("return_msg", ex.Message); 165 WriteLog.Debug("Sign check error : " + res.ToXml()); 166 Response.Write(res.ToXml()); 167 Response.End(); 168 } 169 170 WriteLog.Debug("Check sign success"); 171 return data; 172 } 173 //查詢訂單 174 private bool QueryOrder(string transaction_id) 175 { 176 WxPayData req = new WxPayData(); 177 req.SetValue("transaction_id", transaction_id); 178 WxPayData res = WxPayApi.OrderQuery(req); 179 if (res.GetValue("return_code").ToString() == "SUCCESS" && 180 res.GetValue("result_code").ToString() == "SUCCESS") 181 { 182 return true; 183 } 184 else 185 { 186 return false; 187 } 188 } 189 #endregion 190 191 #region 支付寶回調 192 public void aliNotify() 193 { 194 WriteLog.Debug("支付寶回調開始"); 195 WriteLog.Debug("aliNotify : begin"); 196 SortedDictionary<string, string> sPara = GetRequestPost(); 197 198 if (sPara.Count > 0)//判斷是否有帶返回參數 199 { 200 //Notify aliNotify = new Notify(); 201 Com.Alipay.Notify aliNotify = new Com.Alipay.Notify(Config.charset, Config.sign_type, Config.pid, Config.mapiUrl, Config.alipay_public_key); 202 203 //對異步通知進行驗簽 204 bool verifyResult = aliNotify.Verify(sPara, Request.Form["notify_id"], Request.Form["sign"]); 205 //對驗簽結果 206 //bool isSign = Aop.Api.Util.AlipaySignature.RSACheckV2(sPara, Config.alipay_public_key ,Config.charset,Config.sign_type,false ); 207 208 if (verifyResult && CheckParams()) //驗簽成功 && 關鍵業務參數校驗成功 209 { 210 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 211 //請在這里加上商戶的業務邏輯程序代碼 212 213 214 //——請根據您的業務邏輯來編寫程序(以下代碼僅作參考)—— 215 //獲取支付寶的通知返回參數,可參考技術文檔中服務器異步通知參數列表 216 217 //商戶訂單號 218 string out_trade_no = Request.Form["out_trade_no"]; 219 220 221 //支付寶交易號 222 string trade_no = Request.Form["trade_no"]; 223 224 //交易狀態 225 //在支付寶的業務通知中,只有交易通知狀態為TRADE_SUCCESS或TRADE_FINISHED時,才是買家付款成功。 226 string trade_status = Request.Form["trade_status"]; 227 228 //更新數據庫 229 if (trade_status == "TRADE_SUCCESS" || trade_status == "TRADE_FINISHED") 230 { 231 UpdatePayData(2, out_trade_no, trade_no); 232 } 233 234 //判斷是否在商戶網站中已經做過了這次通知返回的處理 235 //如果沒有做過處理,那么執行商戶的業務程序 236 //如果有做過處理,那么不執行商戶的業務程序 237 238 WriteLog.Debug("aliNotify : success"); 239 Response.Write("success"); //請不要修改或刪除 240 241 //——請根據您的業務邏輯來編寫程序(以上代碼僅作參考)—— 242 243 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 244 } 245 else//驗證失敗 246 { 247 WriteLog.Debug("aliNotify : fail"); 248 Response.Write("fail"); 249 } 250 } 251 else 252 { 253 WriteLog.Debug("aliNotify : 無通知參數"); 254 Response.Write("無通知參數"); 255 } 256 } 257 /// <summary> 258 /// 獲取支付寶POST過來通知消息,並以“參數名=參數值”的形式組成數組 259 /// </summary> 260 /// <returns>request回來的信息組成的數組</returns> 261 public SortedDictionary<string, string> GetRequestPost() 262 { 263 int i = 0; 264 SortedDictionary<string, string> sArray = new SortedDictionary<string, string>(); 265 NameValueCollection coll; 266 //Load Form variables into NameValueCollection variable. 267 coll = Request.Form; 268 269 // Get names of all forms into a string array. 270 string[] requestItem = coll.AllKeys; 271 272 for (i = 0; i < requestItem.Length; i++) 273 { 274 sArray.Add(requestItem[i], Request.Form[requestItem[i]]); 275 WriteLog.Debug("aliNotify : GetRequestPost, key="+ requestItem[i] + ",value="+ Request.Form[requestItem[i]]); 276 } 277 278 return sArray; 279 } 280 281 282 /// <summary> 283 /// 對支付寶異步通知的關鍵參數進行校驗 284 /// </summary> 285 /// <returns></returns> 286 private bool CheckParams() 287 { 288 bool ret = true; 289 290 //獲得商戶訂單號out_trade_no 291 string out_trade_no = Request.Form["out_trade_no"]; 292 //TODO 商戶需要驗證該通知數據中的out_trade_no是否為商戶系統中創建的訂單號, 293 294 //獲得支付總金額total_amount 295 string total_amount = Request.Form["total_amount"]; 296 //TODO 判斷total_amount是否確實為該訂單的實際金額(即商戶訂單創建時的金額), 297 298 //獲得賣家賬號seller_email 299 string seller_email = Request.Form["seller_email"]; 300 //TODO 校驗通知中的seller_email(或者seller_id) 是否為out_trade_no這筆單據的對應的操作方(有的時候,一個商戶可能有多個seller_id / seller_email) 301 302 //獲得調用方的appid; 303 //如果是非授權模式,appid是商戶的appid;如果是授權模式(token調用),appid是系統商的appid 304 string app_id = Request.Form["app_id"]; 305 //TODO 驗證app_id是否是調用方的appid;。 306 307 //驗證上述四個參數,完全吻合則返回參數校驗成功 308 return ret; 309 310 } 311 312 #endregion 313 314 #region 微信、支付寶生成二維碼url 315 public JsonResult GetWxAliCodeUrl(WxAliPayRequestOnlyUrl req) 316 { 317 WriteLog.Debug("計時:開始時間=" + DateTime.Now.ToString()); 318 WxAliPayResponse result = new WxAliPayResponse(); 319 320 #region 業務參數判斷 和 簽名判斷--占不加業務 321 322 //bool have_err = false; 323 //string err_msg = "缺少參數:"; 324 //if (req == null) 325 //{ 326 // result.Code = "1000"; 327 // result.Msg = "傳入參數為空"; 328 // return Json(result); 329 //} 330 331 //if (string.IsNullOrEmpty(req.file_name)) 332 //{ 333 // have_err = true; 334 // err_msg += "文件名稱不能為空"; 335 //} 336 //if (string.IsNullOrEmpty(req.sign)) 337 //{ 338 // have_err = true; 339 // err_msg += "、簽名不能為空"; 340 //} 341 //if (string.IsNullOrEmpty(req.avatar)) 342 //{ 343 // have_err = true; 344 // err_msg += "、照片不能為空"; 345 //} 346 //if (req.time_stamp <= 0) 347 //{ 348 // have_err = true; 349 // err_msg += "、請傳入正確的時間戳格式"; 350 //} 351 //if (string.IsNullOrEmpty(req.SFZMHM)) 352 //{ 353 // have_err = true; 354 // err_msg += "身份證明號碼不能為空"; 355 //} 356 //if (string.IsNullOrEmpty(req.SFZMMC)) 357 //{ 358 // have_err = true; 359 // err_msg += "身份證明名稱不能為空"; 360 //} 361 //if (string.IsNullOrEmpty(req.SFZMLX)) 362 //{ 363 // have_err = true; 364 // err_msg += "身份證明類型不能為空"; 365 //} 366 //if (req.Img_Type != 1 && req.Img_Type != 2 && req.Img_Type != 3) 367 //{ 368 // have_err = true; 369 // err_msg += "照片類型格式不正確"; 370 //} 371 //if (string.IsNullOrEmpty(req.OperationNo)) 372 //{ 373 // have_err = true; 374 // err_msg += "操作編號不能為空"; 375 //} 376 //if (have_err) 377 //{ 378 // //commonHelper.write_log("1001圖片接口上傳失敗", err_msg); 379 // result.Code = "1001"; 380 // result.Msg = err_msg; 381 // return Json(result); 382 //} 383 //string strtime_stamp = ConfigurationManager.AppSettings["time_stamp"]; 384 //int intTimeStampCfg = 600; 385 //int.TryParse(strtime_stamp, out intTimeStampCfg); 386 //if (Math.Abs(CommonHelper.GetCurrentTimeStamp() - req.time_stamp) > intTimeStampCfg) 387 //{ 388 // //commonHelper.write_log("1002圖片接口上傳失敗", "請求過期----當前時間:" + commonHelper.GetCurrentTimeStamp() + "------傳入時間:" + model.time_stamp); 389 // result.Code = "1002"; 390 // result.Msg = "請求過期"; 391 // return Json(result); 392 //} 393 //string api_user_key = ConfigurationManager.AppSettings["upload_img_key"]; 394 //string mysign = string.Format("apikey={0}&time_stamp={1}&file_name={2}&operationNo={3}", api_user_key, req.time_stamp, req.file_name, req.OperationNo); 395 //mysign = CommonHelper.MD5Encrypt(mysign, 32); 396 //mysign = mysign.ToLower(); 397 //WriteLog.Debug("GetWxAliCodeUrl: mysign="+ mysign + ", 簽名參數sign="+ req.sign.ToLower()); 398 //if (req.sign.ToLower() != mysign) 399 //{ 400 // //commonHelper.write_log("1003圖片接口上傳失敗", "簽名不匹配----傳入的簽名:" + model.sign.ToLower() + "------正確的簽名:" + mysign); 401 // result.Code = "1003"; 402 // result.Msg = "簽名不匹配"; 403 // return Json(result); 404 //} 405 //WriteLog.Debug("業務參數判斷 和 簽名判斷 成功"); 406 407 #endregion 408 409 #region 判斷參數 410 if (req == null) 411 { 412 result.Code = "1000"; 413 result.Msg = "傳入參數為空"; 414 return Json(result); 415 } 416 if (string.IsNullOrEmpty(req.deviceNo)) 417 { 418 result.Code = "1001"; 419 result.Msg = "設備號不能為空"; 420 return Json(result); 421 } 422 if (string.IsNullOrEmpty(req.busyCode)) 423 { 424 result.Code = "1002"; 425 result.Msg = "業務編號不能為空"; 426 return Json(result); 427 } 428 if (string.IsNullOrEmpty(req.OperationNo)) 429 { 430 result.Code = "1003"; 431 result.Msg = "操作編號不能為空"; 432 return Json(result); 433 } 434 if (string.IsNullOrEmpty(req.sign)) 435 { 436 result.Code = "1004"; 437 result.Msg = "簽名不能為空"; 438 return Json(result); 439 } 440 if (req.time_stamp <= 0) 441 { 442 result.Code = "1005"; 443 result.Msg = "請傳入正確的時間戳格式"; 444 return Json(result); 445 } 446 string strtime_stamp = ConfigurationManager.AppSettings["time_stamp"]; 447 int intTimeStampCfg = 600; 448 int.TryParse(strtime_stamp, out intTimeStampCfg); 449 if (Math.Abs(CommonHelper.GetCurrentTimeStamp() - req.time_stamp) > intTimeStampCfg) 450 { 451 //commonHelper.write_log("1002圖片接口上傳失敗", "請求過期----當前時間:" + commonHelper.GetCurrentTimeStamp() + "------傳入時間:" + model.time_stamp); 452 result.Code = "1006"; 453 result.Msg = "請求過期"; 454 return Json(result); 455 } 456 string api_user_key = ConfigurationManager.AppSettings["upload_img_key"]; 457 string mysign = string.Format("apikey={0}&deviceNo={1}&busyCode={2}&OperationNo={3}&time_stamp={4}", api_user_key, req.deviceNo, req.busyCode, req.OperationNo, req.time_stamp); 458 mysign = CommonHelper.MD5Encrypt(mysign, 32); 459 mysign = mysign.ToLower(); 460 if (!req.sign.ToLower().Equals(mysign)) 461 { 462 //commonHelper.write_log("1003圖片接口上傳失敗", "簽名不匹配----傳入的簽名:" + model.sign.ToLower() + "------正確的簽名:" + mysign); 463 result.Code = "1007"; 464 result.Msg = "簽名不匹配"; 465 return Json(result); 466 } 467 #endregion 468 469 string WxCode = "", WxCodeUrl = "", AliCodeUrl = "", AliCode = "", Str_Out_trade_no = ""; 470 //訂單號 471 Str_Out_trade_no = GetOut_trade_no(); 472 //商品ID 473 string Str_productId = GetRandom(9); 474 //金額 475 string strAmount = GetAmount(req.deviceNo, req.busyCode, req.isTest); 476 string Str_total_amount = strAmount;// "0.01";//支付寶支付金額,以 元 為單位 477 int Int_total_amount = ParIntForWeixin(strAmount);// 1;//微信支付金額,以 分 為單位 478 479 #region weixin 480 NativePay nativePay = new NativePay(); 481 482 //生成掃碼支付模式二url 483 string url2 = nativePay.GetPayUrl(Str_Out_trade_no, Str_productId, Int_total_amount); 484 485 Log.Info(this.GetType().ToString(), "WeiXinNativePay url2 : " + url2); 486 487 WxCode = "SUCCESS"; 488 WxCodeUrl = HttpUtility.UrlEncode(url2); 489 490 #endregion 491 492 #region ali 493 AlipayTradePrecreateContentBuilder builder = BuildPrecreateContent(Str_Out_trade_no, Str_productId, Str_total_amount); 494 //string out_trade_no = builder.out_trade_no; 495 496 //推薦使用輪詢撤銷機制,不推薦使用異步通知,避免單邊賬問題發生。 497 IAlipayTradeService serviceClient = F2FBiz.CreateClientInstance(Config.serverUrl, Config.appId, Config.merchant_private_key, Config.version, 498 Config.sign_type, Config.alipay_public_key, Config.charset); 499 500 string notify_url = Config.NotifyUrl; //商戶接收異步通知的地址 501 AlipayF2FPrecreateResult precreateResult = serviceClient.tradePrecreate(builder, notify_url); 502 503 //以下返回結果的處理供參考。 504 //payResponse.QrCode即二維碼對於的鏈接 505 //將鏈接用二維碼工具生成二維碼,顧客可以用支付寶錢包掃碼支付。 506 switch (precreateResult.Status) 507 { 508 case ResultEnum.SUCCESS: 509 AliCode = "SUCCESS"; 510 AliCodeUrl = HttpUtility.UrlEncode(precreateResult.response.QrCode); 511 break; 512 case ResultEnum.FAILED: 513 AliCode = "FAILED"; 514 AliCodeUrl = precreateResult.response.Body; 515 break; 516 case ResultEnum.UNKNOWN: 517 AliCode = "UNKNOWN"; 518 if (precreateResult.response == null) 519 { 520 AliCodeUrl = "配置或網絡異常,請檢查后重試"; 521 } 522 else 523 { 524 AliCodeUrl = "系統異常,請更新外部訂單后重新發起請求"; 525 } 526 break; 527 } 528 529 #endregion 530 531 //處理業務數據,存圖片、寫數據庫 532 Task.Run(()=> WritePayDataNew(req, Str_Out_trade_no)); 533 534 WriteLog.Debug("計時:結束時間=" + DateTime.Now.ToString()); 535 result.Code = "200"; 536 result.Msg = "成功"; 537 result.WxCode = WxCode; 538 result.WxCodeUrl = WxCodeUrl; 539 result.AliCode = AliCode; 540 result.AliCodeUrl = AliCodeUrl; 541 result.Out_trade_no = Str_Out_trade_no; 542 return Json(result); 543 } 544 545 private int ParIntForWeixin(string strAmount) 546 { 547 double p = 0; 548 double.TryParse(strAmount, out p); 549 int intp = (int)(p * 100); 550 if (intp == 0) 551 return 20 * 100; 552 else 553 return intp; 554 } 555 556 private string GetAmount(string deviceNo, string busyCode, string isTest) 557 { 558 var strTest = string.IsNullOrEmpty(isTest) ? "" : isTest; 559 if (strTest.Equals("1")) 560 { 561 //測試用,金額為配置的0.01 562 string TestamountPrice = ConfigurationManager.AppSettings["TestamountPrice"]; 563 if (string.IsNullOrEmpty(TestamountPrice)) 564 return "0.01"; 565 else 566 return TestamountPrice; 567 } 568 else 569 { 570 IQueryable<M_AgentDevice_Pay> q = _amountService.GetByNoCode(deviceNo, busyCode); 571 var ls = q.ToList(); 572 if (ls == null || ls.Count < 1) 573 { 574 string amountPrice = ConfigurationManager.AppSettings["amountPrice"]; 575 if (string.IsNullOrEmpty(amountPrice)) 576 return "20"; 577 else 578 return amountPrice; 579 } 580 else 581 { 582 return ls[0].PayAmount; 583 } 584 } 585 } 586 587 /// <summary> 588 /// 支付寶 構造支付請求數據 589 /// </summary> 590 /// <returns>請求數據集</returns> 591 private AlipayTradePrecreateContentBuilder BuildPrecreateContent(string Str_Out_trade_no, string Str_productId, string Str_total_amount) 592 { 593 //bkin 三個參數:out_trade_no total_amount subject 594 595 //線上聯調時,請輸入真實的外部訂單號。 596 string out_trade_no = Str_Out_trade_no; 597 598 AlipayTradePrecreateContentBuilder builder = new AlipayTradePrecreateContentBuilder(); 599 //收款賬號 600 builder.seller_id = Config.pid; 601 //訂單編號 602 builder.out_trade_no = out_trade_no; 603 //訂單總金額 604 builder.total_amount = Str_total_amount; 605 //參與優惠計算的金額 606 //builder.discountable_amount = ""; 607 //不參與優惠計算的金額 608 //builder.undiscountable_amount = ""; 609 //訂單名稱 610 builder.subject = "證件照"; 611 //自定義超時時間 612 builder.timeout_express = "5m"; 613 //訂單描述 614 builder.body = ""; 615 //門店編號,很重要的參數,可以用作之后的營銷 616 builder.store_id = "test store id"; 617 //操作員編號,很重要的參數,可以用作之后的營銷 618 builder.operator_id = "證件照"; 619 620 //傳入商品信息詳情 621 List<GoodsInfo> gList = new List<GoodsInfo>(); 622 GoodsInfo goods = new GoodsInfo(); 623 goods.goods_id = Str_productId; 624 goods.goods_name = "證件照"; 625 goods.price = Str_total_amount; 626 goods.quantity = "1"; 627 gList.Add(goods); 628 builder.goods_detail = gList; 629 630 //系統商接入可以填此參數用作返佣 631 //ExtendParams exParam = new ExtendParams(); 632 //exParam.sysServiceProviderId = "20880000000000"; 633 //builder.extendParams = exParam; 634 635 return builder; 636 } 637 638 private void WritePayData(WxAliPayRequest req, string Str_Out_trade_no) 639 { 640 WriteLog.Debug("WritePayData begin"); 641 if (req == null) 642 return; 643 var filePath = Base64_to_File(req.avatar); 644 645 // 646 var _payService1 = EngineContext.Current.Resolve<IAgent_User_ImgService>(); 647 var _payService2 = EngineContext.Current.Resolve<IAgentOperationPayService>(); 648 var _payService3 = EngineContext.Current.Resolve<IAgentOperationService>(); 649 650 //插入 Agent_User_Img 表 651 var m = new M_Agent_User_Img() 652 { 653 SFZMHM = req.SFZMHM, 654 SFZMMC = req.SFZMMC, 655 SFZMLX = req.SFZMLX, 656 Img_Type = req.Img_Type, 657 Img_Url = filePath, 658 OperationNo = req.OperationNo, 659 Img_Spec = req.Img_Spec, 660 Create_Time = DateTime.Now, 661 IsDeleted = false 662 }; 663 _payService1.Insert(m); 664 665 //插入 AgentOperationPay 表 666 var m2 = new M_AgentOperationPay() 667 { 668 Payment = 0,//支付成功回調更新為 (1, "微信支付");(2, "支付寶支付");(3, "銀聯支付");(4, "現金支付"); 669 Amount = (decimal)0.01, 670 Quantity = 1, 671 PayStatus = 0,//支付成功回調更新為1 672 AddTime = DateTime.Now, 673 IsDeleted = false, 674 OrderNo = Str_Out_trade_no, 675 SerialNo = Str_Out_trade_no, 676 OperationNo = req.OperationNo 677 }; 678 _payService2.Insert(m2); 679 680 //插入 AgentOperation 表 681 var m3 = new M_AgentOperation() 682 { 683 AgentNo = "bsr_zxj", 684 OperationNo = req.OperationNo, 685 AgentDeviceNo = req.deviceNo, 686 BusinessNo = "dgnzxj", 687 OperationStatus = true, 688 AddTime = DateTime.Now, 689 IsDeleted = false, 690 ValidateCode = "1111", 691 Status = 0 //支付成功回調更新為1 692 }; 693 _payService3.Insert(m3); 694 695 696 } 697 private void WritePayDataNew(WxAliPayRequestOnlyUrl req, string Str_Out_trade_no) 698 { 699 WriteLog.Debug("WritePayData begin"); 700 if (req == null) 701 return; 702 // 703 var _payService2 = EngineContext.Current.Resolve<IAgentOperationPayService>(); 704 var _payService3 = EngineContext.Current.Resolve<IAgentOperationService>(); 705 706 //插入 AgentOperationPay 表 707 var m2 = new M_AgentOperationPay() 708 { 709 Payment = 0,//支付成功回調更新為 (1, "微信支付");(2, "支付寶支付");(3, "銀聯支付");(4, "現金支付"); 710 Amount = (decimal)0.01, 711 Quantity = 1, 712 PayStatus = 0,//支付成功回調更新為1 713 AddTime = DateTime.Now, 714 IsDeleted = false, 715 OrderNo = Str_Out_trade_no, 716 SerialNo = Str_Out_trade_no, 717 OperationNo = req.OperationNo 718 }; 719 _payService2.Insert(m2); 720 721 //插入 AgentOperation 表 722 var m3 = new M_AgentOperation() 723 { 724 AgentNo = "bsr_zxj", 725 OperationNo = req.OperationNo, 726 AgentDeviceNo = req.deviceNo, 727 BusinessNo = "dgnzxj", 728 OperationStatus = true, 729 AddTime = DateTime.Now, 730 IsDeleted = false, 731 ValidateCode = "1111", 732 Status = 0 //支付成功回調更新為1 733 }; 734 _payService3.Insert(m3); 735 736 737 } 738 private void WritePayData2(WxAliPayRequest req, string Str_Out_trade_no) 739 { 740 WriteLog.Debug("WritePayData begin"); 741 if (req == null) 742 return; 743 var filePath = Base64_to_File(req.avatar); 744 745 //插入 Agent_User_Img 表 746 var m = new M_Agent_User_Img() 747 { 748 SFZMHM = req.SFZMHM, 749 SFZMMC = req.SFZMMC, 750 SFZMLX = req.SFZMLX, 751 Img_Type = req.Img_Type, 752 Img_Url = filePath, 753 OperationNo = req.OperationNo, 754 Img_Spec = req.Img_Spec, 755 Create_Time = DateTime.Now, 756 IsDeleted = false 757 }; 758 _userService.Insert(m); 759 760 //插入 AgentOperationPay 表 761 var m2 = new M_AgentOperationPay() 762 { 763 Payment = 1, 764 Amount = (decimal)0.01, 765 Quantity = 1, 766 PayStatus = 0, 767 AddTime = DateTime.Now, 768 IsDeleted = false, 769 OrderNo = Str_Out_trade_no, 770 SerialNo = Str_Out_trade_no, 771 OperationNo = req.OperationNo 772 }; 773 _payService.Insert(m2); 774 775 //插入 AgentOperation 表 776 var m3 = new M_AgentOperation() 777 { 778 AgentNo = "bsr_zxj", 779 OperationNo = req.OperationNo, 780 AgentDeviceNo = req.deviceNo, 781 BusinessNo = "dgnzxj", 782 OperationStatus = true, 783 AddTime = DateTime.Now, 784 IsDeleted = false, 785 ValidateCode = "1111", 786 Status = 1 787 }; 788 _operateService.Insert(m3); 789 790 791 } 792 793 private string GetOut_trade_no() 794 { 795 return System.DateTime.Now.ToString("yyyyMMddHHmmss") + GetRandom(10); 796 } 797 798 private string Base64_to_File(string imageCode) 799 { 800 if (string.IsNullOrEmpty(imageCode)) 801 return ""; 802 803 byte[] arr2 = Convert.FromBase64String(imageCode); 804 using (MemoryStream ms2 = new MemoryStream(arr2)) 805 { 806 string dir = "/user_img/" + DateTime.Now.ToString("yyyyMMdd") + "/"; 807 if (!Directory.Exists(Server.MapPath(dir))) 808 { 809 Directory.CreateDirectory(Server.MapPath(dir)); 810 } 811 string fileName = Guid.NewGuid() + ".jpg"; 812 string dirFile = Server.MapPath(dir) + fileName; 813 814 System.Drawing.Bitmap bmp2 = new System.Drawing.Bitmap(ms2); 815 bmp2.Save(dirFile, System.Drawing.Imaging.ImageFormat.Jpeg); 816 //bmp2.Save(filePath + ".bmp", System.Drawing.Imaging.ImageFormat.Bmp); 817 //bmp2.Save(filePath + ".gif", System.Drawing.Imaging.ImageFormat.Gif); 818 //bmp2.Save(filePath + ".png", System.Drawing.Imaging.ImageFormat.Png); 819 return dir + fileName; 820 } 821 } 822 823 //生成N位的隨機數 全數字 824 private string GetRandom(int len) 825 { 826 string k = ""; 827 Random rand = new Random(GetRandomSeed()); 828 for (int i = 0; i < len; i++) 829 { 830 k += rand.Next(0, 10).ToString(); 831 } 832 return k; 833 } 834 //取隨機數種子 835 private int GetRandomSeed() 836 { 837 byte[] bytes = new byte[4]; 838 System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider(); 839 rng.GetBytes(bytes); 840 return BitConverter.ToInt32(bytes, 0); 841 } 842 #endregion 843 844 #region 客戶端輪詢此接口,查是否已經付款 845 //根據訂單號來查詢 846 [HttpPost] 847 public JsonResult CheckIsPay(string out_trade_no) 848 { 849 var m = _payService.GetByOrderNo(out_trade_no); 850 if (m == null) 851 { 852 return Json(new { code = "0", msg = "未支付" }); 853 } 854 else if (m.PayStatus == 1) 855 { 856 return Json(new { code = "1", msg = "已支付" }); 857 } 858 else 859 { 860 return Json(new { code = "0", msg = "未支付" }); 861 } 862 863 } 864 #endregion 865 } 866 }
支付寶調用需要引用官網的一些dll, 微信的需要添加一些文件: