using Aop.Api.Response; using Com.Alipay.Domain; using Aop.Api; using Aop.Api.Request; using System.Text; using System.Threading; using Com.Alipay.Model; using Com.Alipay.Business; using System; using Newtonsoft.Json; using System.Threading.Tasks; namespace Com.Alipay { /// /// AlipayTradePayImpl 的摘要说明 /// public class AlipayTradeImpl : IAlipayTradeService { IAopClient client = null; public AlipayTradeImpl(string serverUrl, string appId, string merchant_private_key, string format, string version, string sign_type, string alipay_public_key, string charset) { client = new DefaultAopClient(serverUrl, appId, merchant_private_key, format, version, sign_type, alipay_public_key, charset); } #region 接口方法 public async Task tradePay(AlipayTradePayContentBuilder builder) { AlipayF2FPayResult payResult = new AlipayF2FPayResult(); try { AlipayTradePayRequest payRequest = new AlipayTradePayRequest(); payRequest.BizContent = JsonConvert.SerializeObject(builder); //payRequest.BizContent = builder.BuildJson(); AlipayTradePayResponse payResponse = await client.Execute(payRequest); //payRequest.SetBizModel(""); if (payResponse != null) { switch (payResponse.Code) { case ResultCode.SUCCESS: break; //返回支付处理中,需要进行轮询 case ResultCode.INRROCESS: AlipayTradeQueryResponse queryResponse = await LoopQuery(builder.out_trade_no, 10, 3000); //用订单号trade_no进行轮询也是可以的。 //轮询结束后还是支付处理中,需要调撤销接口 if (queryResponse != null) { if (queryResponse.TradeStatus == "WAIT_BUYER_PAY") { CancelAndRetry(builder.out_trade_no); payResponse.Code = ResultCode.FAIL; } payResponse = toTradePayResponse(queryResponse); } break; //明确返回业务失败 case ResultCode.FAIL: break; //返回系统异常,需要调用一次查询接口,没有返回支付成功的话调用撤销接口撤销交易 case ResultCode.ERROR: AlipayTradeQueryResponse queryResponse2 = await sendTradeQuery(builder.out_trade_no); if (queryResponse2 != null) { if (queryResponse2.TradeStatus == TradeStatus.WAIT_BUYER_PAY) { AlipayTradeCancelResponse cancelResponse = await CancelAndRetry(builder.out_trade_no); payResponse.Code = ResultCode.FAIL; } payResponse = toTradePayResponse(queryResponse2); } break; default: payResult.response = payResponse; break; } payResult.response = payResponse; return payResult; } else { AlipayTradeQueryResponse queryResponse3 = await sendTradeQuery(builder.out_trade_no); if (queryResponse3 != null) { if (queryResponse3.TradeStatus == TradeStatus.WAIT_BUYER_PAY) { AlipayTradeCancelResponse cancelResponse = await CancelAndRetry(builder.out_trade_no); payResponse.Code = ResultCode.FAIL; } payResponse = toTradePayResponse(queryResponse3); } payResult.response = payResponse; return payResult; } //return payResult; } catch(Exception e) { AlipayTradePayResponse payResponse = new AlipayTradePayResponse(); payResponse.Code = ResultCode.FAIL; payResponse.Body = e.Message; payResult.response = payResponse; return payResult; } } public async Task tradeQuery(string outTradeNo) { AlipayF2FQueryResult result = new AlipayF2FQueryResult(); try { AlipayTradeQueryContentBuilder build = new AlipayTradeQueryContentBuilder(); build.out_trade_no = outTradeNo; AlipayTradeQueryRequest payRequest = new AlipayTradeQueryRequest(); payRequest.BizContent = JsonConvert.SerializeObject(build); //payRequest.BizContent = build.BuildJson(); result.response = await client.Execute(payRequest); return result; } catch { result.response = null; return result; } } public async Task tradeRefund(AlipayTradeRefundContentBuilder builder) { AlipayF2FRefundResult refundResult = new AlipayF2FRefundResult(); try { AlipayTradeRefundRequest refundRequest = new AlipayTradeRefundRequest(); //refundRequest.BizContent = builder.BuildJson(); refundRequest.BizContent = JsonConvert.SerializeObject(builder); refundResult.response = await client.Execute(refundRequest); return refundResult; } catch { refundResult.response = null; return refundResult; } } public async Task tradePrecreate(AlipayTradePrecreateContentBuilder builder) { AlipayF2FPrecreateResult payResult = new AlipayF2FPrecreateResult(); try { AlipayTradePrecreateRequest payRequest = new AlipayTradePrecreateRequest(); //payRequest.BizContent = builder.BuildJson(); payRequest.BizContent = JsonConvert.SerializeObject(builder); payResult.response = await client.Execute(payRequest); return payResult; } catch { payResult.response = null; return payResult; } } /// /// 1.返回支付处理中,轮询订单状态 /// /// /// public async Task tradeLoopQuery(string out_trade_no, int count, int interval) { AlipayTradeQueryResponse queryResult = new AlipayTradeQueryResponse(); queryResult.TradeStatus = "TRADE_CLOSED"; for (int i = 0; i <= count; i++) { AlipayTradeQueryResponse queryResponse = await sendTradeQuery(out_trade_no); if (queryResponse != null && string.Compare(queryResponse.Code, ResultCode.SUCCESS, false) == 0) { queryResult = queryResponse; if (queryResult.TradeStatus == "TRADE_FINISHED" || queryResult.TradeStatus == "TRADE_SUCCESS" || queryResult.TradeStatus == "TRADE_CLOSED") return queryResult; } await Task.Delay(interval); } return queryResult; } public async Task tradePrecreate(AlipayTradePrecreateContentBuilder builder, string notify_url) { AlipayF2FPrecreateResult payResult = new AlipayF2FPrecreateResult(); try { AlipayTradePrecreateRequest payRequest = new AlipayTradePrecreateRequest(); //payRequest.BizContent = builder.BuildJson(); payRequest.BizContent = JsonConvert.SerializeObject(builder); payRequest.SetNotifyUrl(notify_url); payResult.response = await client.Execute(payRequest); return payResult; } catch { payResult.response = null; return payResult; } } #endregion #region 内部方法 private async Task tradeCancel(string outTradeNo) { try { AlipayTradeCancelRequest request = new AlipayTradeCancelRequest(); StringBuilder sb2 = new StringBuilder(); sb2.Append("{\"out_trade_no\":\"" + outTradeNo + "\"}"); request.BizContent = sb2.ToString(); AlipayTradeCancelResponse response = await client.Execute(request); return response; } catch { return null; } } private AlipayTradePayResponse toTradePayResponse(AlipayTradeQueryResponse queryResponse) { if (queryResponse == null || queryResponse.Code != ResultCode.SUCCESS) return null; AlipayTradePayResponse payResponse = new AlipayTradePayResponse(); if (queryResponse.TradeStatus == TradeStatus.WAIT_BUYER_PAY) { payResponse.Code = ResultCode.INRROCESS; } if (queryResponse.TradeStatus == TradeStatus.TRADE_FINISHED || queryResponse.TradeStatus == TradeStatus.TRADE_SUCCESS) { payResponse.Code = ResultCode.SUCCESS; } if (queryResponse.TradeStatus == TradeStatus.TRADE_CLOSED) { payResponse.Code = ResultCode.FAIL; } payResponse.Msg = queryResponse.Msg; payResponse.SubCode = queryResponse.SubCode; payResponse.SubMsg = queryResponse.SubMsg; payResponse.Body = queryResponse.Body; payResponse.BuyerLogonId = queryResponse.BuyerLogonId; payResponse.FundBillList = queryResponse.FundBillList; payResponse.OpenId = queryResponse.OpenId; payResponse.OutTradeNo = queryResponse.OutTradeNo; payResponse.ReceiptAmount = queryResponse.ReceiptAmount; payResponse.TotalAmount = queryResponse.TotalAmount; payResponse.TradeNo = queryResponse.TradeNo; return payResponse; } private async Task sendTradeQuery(string outTradeNo) { try { AlipayTradeQueryContentBuilder build = new AlipayTradeQueryContentBuilder(); build.out_trade_no = outTradeNo; AlipayTradeQueryRequest payRequest = new AlipayTradeQueryRequest(); //payRequest.BizContent = build.BuildJson(); payRequest.BizContent = JsonConvert.SerializeObject(build); AlipayTradeQueryResponse payResponse = await client.Execute(payRequest); return payResponse; } catch { return null; } } /// /// 1.返回支付处理中,轮询订单状态 /// 2.本示例中轮询了6次,每次相隔5秒 /// /// /// private async Task LoopQuery(string out_trade_no, int count, int interval) { AlipayTradeQueryResponse queryResult = null; for (int i = 1; i <= count; i++) { await Task.Delay(interval); AlipayTradeQueryResponse queryResponse = await sendTradeQuery(out_trade_no); if (queryResponse != null && string.Compare(queryResponse.Code, ResultCode.SUCCESS, false) == 0) { queryResult = queryResponse; if (queryResponse.TradeStatus == "TRADE_FINISHED" || queryResponse.TradeStatus == "TRADE_SUCCESS" || queryResponse.TradeStatus == "TRADE_CLOSED") return queryResponse; } } return queryResult; } /// /// 撤销订单 /// /// /// private async Task CancelAndRetry(string out_trade_no) { AlipayTradeCancelResponse cancelResponse = null; cancelResponse = await tradeCancel(out_trade_no); //如果撤销失败,新开一个线程重试撤销,不影响主业务 if (cancelResponse == null || (cancelResponse.Code == ResultCode.FAIL && cancelResponse.RetryFlag == "Y")) { await Task.Run(() => cancelThreadFunc(out_trade_no)); } return cancelResponse; } private async Task cancelThreadFunc(object o) { int RETRYCOUNT = 10; int INTERVAL = 10000; for (int i = 0; i < RETRYCOUNT; ++i) { await Task.Delay(INTERVAL); AlipayTradeCancelRequest cancelRequest = new AlipayTradeCancelRequest(); string outTradeNo = o.ToString(); AlipayTradeCancelResponse cancelResponse = await tradeCancel(outTradeNo); if (null != cancelResponse) { if (cancelResponse.Code == ResultCode.FAIL) { if (cancelResponse.RetryFlag == "N") { break; } } if ((cancelResponse.Code == ResultCode.SUCCESS)) { break; } } if (i == RETRYCOUNT - 1) { /** !!!!!!!注意!!!!!!!! 处理到最后一次,还是未撤销成功,需要在商户数据库中对此单最标记,人工介入处理*/ } } } #endregion } }