using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using Aop.Api.Request; using Aop.Api.Response; using BaseModel.Models; using WayneCloud.PaymentProcessors.Alipay.FromSDK; namespace Aop.Api.Business { public class CodePay { private static volatile IAopClient client; private static volatile Dictionary clients = new Dictionary(); public static IAopClient Clients(AliPayConfig config) { //if (config != null) //{ //if (client == null) //{ // client = new DefaultAopClient(config.serverUrl, // config.appId, // config.merchant_private_key, // "json", // config.version, // config.sign_type, // config.alipay_public_key, // config.charset); //} //return client; if (!clients.ContainsKey(config)) { var newClient = new DefaultAopClient(config.serverUrl, config.appId, config.merchant_private_key, "json", config.version, config.sign_type, config.alipay_public_key, config.charset); clients.Add(config, newClient); return newClient; } else { return clients[config]; } } public static async Task Run(ElectronicOrderModel order) { //set the default trade_status to PAYERROR order.TradeStatus = TradeStatus.PAYERROR; //线上联调时,请输入真实的外部订单号。 string out_trade_no = order.BillNumber; //线上联调时,请输入真实的条码。 string auth_code = order.AuthCode; //扫码枪扫描到的用户手机钱包中的付款条码 string total_amount = order.NetAmount.ToString(); StringBuilder sb = new StringBuilder(); sb.Append("{\"out_trade_no\":\"" + out_trade_no + "\","); sb.Append("\"scene\":\"bar_code\","); sb.Append("\"auth_code\":\"" + auth_code + "\","); sb.Append("\"total_amount\":\"" + total_amount + "\",\"discountable_amount\":\"0.00\","); sb.Append("\"subject\":\"" + order.Title + "\",\"body\":\"empty_body\","); sb.Append("\"goods_detail\":["); var goodsString = (order.FuelOrderDetails.Count == 0) ? "" : (order.FuelOrderDetails.Select(s => "{\"goods_id\":\"" + s.FuelProductId + "\",\"goods_name\":\"" + s.FuelProductName + "\",\"goods_category\":\"" + s.Category + "\",\"price\":\"" + s.Price + "\",\"quantity\":\"" + s.Qualtity + "\"}").Aggregate((acc, n) => acc + "," + n)); sb.Append(goodsString); sb.Append("],"); sb.Append("\"operator_id\":\"" + (order.OperatorId ?? "") + "\",\"store_id\":\"" + order.SiteId + "\",\"terminal_id\":\"" + (order.TerminalId ?? "") + "\","); string expire_time = System.DateTime.Now.AddHours(1).ToString("yyyy-MM-dd HH:mm:ss"); sb.Append("\"time_expire\":\"" + expire_time + "\"}"); var payResponse = await Pay(sb.ToString(), (AliPayConfig)order.Config); //支付成功的情形 if (payResponse != null && payResponse.Code == ResultCode.SUCCESS) { order.TradeStatus = TradeStatus.SUCCESS; return payResponse; } //如果返回结果是操作失败,或者返回结果不是操作处理中,就直接返回支付失败 if (payResponse == null || payResponse.Code == ResultCode.FAIL || payResponse.Code != ResultCode.INRROCESS) { return payResponse; } StringBuilder sb1 = new StringBuilder(); sb1.Append("{\"out_trade_no\":\"" + order.BillNumber + "\"}"); //以下是返回操作处理中的情形, 需要进行轮询 AlipayTradeQueryResponse queryResponse = await LoopQuery(sb1.ToString(), (AliPayConfig)order.Config); //用订单号trade_no进行轮询也是可以的。 if (queryResponse !=null) { if (string.Compare(queryResponse.Code, ResultCode.SUCCESS, false) == 0) { if (queryResponse.TradeStatus == "TRADE_FINISHED" || queryResponse.TradeStatus == "TRADE_SUCCESS") { order.TradeStatus = TradeStatus.SUCCESS; } else if (queryResponse.TradeStatus == "TRADE_CLOSED") { order.TradeStatus = TradeStatus.CLOSED; } return queryResponse; } } return payResponse; } private static async Task Pay(string biz_content, AliPayConfig config) { AlipayTradePayRequest payRequst = new AlipayTradePayRequest(); payRequst.BizContent = biz_content; //payRequst Dictionary paramsDict = (Dictionary)payRequst.GetParameters(); //new DefaultAopClient(Config.serverUrl, Config.appId, Config.merchant_private_key); AlipayTradePayResponse payResponse = await Clients(config).Execute(payRequst); return payResponse; } public static async Task Cancel(string billNumber, AliPayConfig config) { StringBuilder sb = new StringBuilder(); sb.Append("{\"out_trade_no\":\"" + billNumber + "\"}"); string biz_content = sb.ToString(); AlipayTradeCancelRequest cancelRequest = new AlipayTradeCancelRequest(); cancelRequest.BizContent = biz_content; AlipayTradeCancelResponse cancelResponse = await Clients(config).Execute(cancelRequest); if (null != cancelResponse) { if (cancelResponse.Code == ResultCode.FAIL && cancelResponse.RetryFlag == "Y") { cancelResponse = await CancelOrderRetry(biz_content, config); } } return cancelResponse; } private static async Task CancelOrderRetry(object o, AliPayConfig config) { int retryCount = 10; AlipayTradeCancelResponse cancelResponse = null; for (int i = 0; i < retryCount; ++i) { Thread.Sleep(5000); AlipayTradeCancelRequest cancelRequest = new AlipayTradeCancelRequest(); cancelRequest.BizContent = o.ToString(); // Dictionary paramsDict = (Dictionary)cancelRequest.GetParameters(); cancelResponse = await Clients(config).Execute(cancelRequest); if (null != cancelResponse) { if (cancelResponse.Code == ResultCode.FAIL) { //if (cancelResponse.Body.Contains("\"retry_flag\":\"N\"")) if (cancelResponse.RetryFlag == "N") { break; } } } if (i == retryCount - 1) { // 处理到最后一次,还是未撤销成功,需要在商户数据库中对此单最标记,人工介入处理 } } return cancelResponse; } private static async Task LoopQuery(string biz_content, AliPayConfig config) { AlipayTradeQueryRequest payRequst = new AlipayTradeQueryRequest(); payRequst.BizContent = biz_content; Dictionary paramsDict = (Dictionary)payRequst.GetParameters(); AlipayTradeQueryResponse payResponse = null; for (int i = 1; i <= 6; i++) { Thread.Sleep(5000); payResponse = await Clients(config).Execute(payRequst); if (string.Compare(payResponse.Code, ResultCode.SUCCESS, false) == 0) { if (payResponse.TradeStatus == "TRADE_FINISHED" || payResponse.TradeStatus == "TRADE_SUCCESS" || payResponse.TradeStatus == "TRADE_CLOSED") return payResponse; } } return payResponse; } } }