393 lines
14 KiB
C#
393 lines
14 KiB
C#
using System;
|
||
using System.Text;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
using Alipay.AopSdk.Core;
|
||
using Alipay.AopSdk.Core.Request;
|
||
using Alipay.AopSdk.Core.Response;
|
||
using Alipay.AopSdk.Core.Util;
|
||
using Alipay.AopSdk.F2FPay.Domain;
|
||
using Alipay.AopSdk.F2FPay.Model;
|
||
|
||
|
||
namespace Alipay.AopSdk.F2FPay.Business
|
||
{
|
||
/// <summary>
|
||
/// AlipayTradePayImpl 的摘要说明
|
||
/// </summary>
|
||
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 AlipayF2FPayResult TradePay(AlipayTradePayContentBuilder builder)
|
||
{
|
||
AlipayF2FPayResult payResult = new AlipayF2FPayResult();
|
||
try
|
||
{
|
||
|
||
AlipayTradePayRequest payRequest = new AlipayTradePayRequest();
|
||
payRequest.BizContent = builder.BuildJson();
|
||
AlipayTradePayResponse payResponse = client.Execute(payRequest);
|
||
|
||
//payRequest.SetBizModel("");
|
||
|
||
if (payResponse != null)
|
||
{
|
||
|
||
switch (payResponse.Code)
|
||
{
|
||
case ResultCode.SUCCESS:
|
||
break;
|
||
|
||
//返回支付处理中,需要进行轮询
|
||
case ResultCode.INRROCESS:
|
||
|
||
AlipayTradeQueryResponse queryResponse = 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 = sendTradeQuery(builder.out_trade_no);
|
||
|
||
if (queryResponse2 != null)
|
||
{
|
||
if (queryResponse2.TradeStatus == TradeStatus.WAIT_BUYER_PAY)
|
||
{
|
||
AlipayTradeCancelResponse cancelResponse = 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 = sendTradeQuery(builder.out_trade_no);
|
||
if (queryResponse3 != null)
|
||
{
|
||
if (queryResponse3.TradeStatus == TradeStatus.WAIT_BUYER_PAY)
|
||
{
|
||
AlipayTradeCancelResponse cancelResponse = 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 AlipayF2FQueryResult TradeQuery(string outTradeNo)
|
||
{
|
||
return AsyncHelper.RunSync(async () => await TradeQueryAsync(outTradeNo));
|
||
}
|
||
|
||
public async Task<AlipayF2FQueryResult> TradeQueryAsync(string outTradeNo)
|
||
{
|
||
AlipayF2FQueryResult result = new AlipayF2FQueryResult();
|
||
try
|
||
{
|
||
|
||
AlipayTradeQueryContentBuilder build = new AlipayTradeQueryContentBuilder();
|
||
build.out_trade_no = outTradeNo;
|
||
AlipayTradeQueryRequest payRequest = new AlipayTradeQueryRequest();
|
||
payRequest.BizContent = build.BuildJson();
|
||
result.response = await client.ExecuteAsync(payRequest);
|
||
return result;
|
||
}
|
||
catch
|
||
{
|
||
result.response = null;
|
||
return result;
|
||
}
|
||
}
|
||
|
||
|
||
public AlipayF2FRefundResult TradeRefund(AlipayTradeRefundContentBuilder builder)
|
||
{
|
||
return AsyncHelper.RunSync(async () => await TradeRefundAsync(builder));
|
||
}
|
||
|
||
public async Task<AlipayF2FRefundResult> TradeRefundAsync(AlipayTradeRefundContentBuilder builder)
|
||
{
|
||
var refundResult = new AlipayF2FRefundResult();
|
||
try
|
||
{
|
||
|
||
AlipayTradeRefundRequest refundRequest = new AlipayTradeRefundRequest();
|
||
refundRequest.BizContent = builder.BuildJson();
|
||
refundResult.response = await client.ExecuteAsync(refundRequest);
|
||
return refundResult;
|
||
}
|
||
catch
|
||
{
|
||
refundResult.response = null;
|
||
return refundResult;
|
||
}
|
||
}
|
||
|
||
public AlipayF2FPrecreateResult TradePrecreate(AlipayTradePrecreateContentBuilder builder)
|
||
{
|
||
return AsyncHelper.RunSync(async () => await TradePrecreateAsync(builder));
|
||
}
|
||
|
||
public async Task<AlipayF2FPrecreateResult> TradePrecreateAsync(AlipayTradePrecreateContentBuilder builder)
|
||
{
|
||
AlipayF2FPrecreateResult payResult = new AlipayF2FPrecreateResult();
|
||
try
|
||
{
|
||
|
||
AlipayTradePrecreateRequest payRequest = new AlipayTradePrecreateRequest();
|
||
payRequest.BizContent = builder.BuildJson();
|
||
|
||
|
||
payResult.response = await client.ExecuteAsync(payRequest);
|
||
return payResult;
|
||
}
|
||
catch
|
||
{
|
||
payResult.response = null;
|
||
return payResult;
|
||
}
|
||
}
|
||
|
||
public AlipayF2FPrecreateResult TradePrecreate(AlipayTradePrecreateContentBuilder builder, string notify_url)
|
||
{
|
||
return AsyncHelper.RunSync(async () => await TradePrecreateAsync(builder, notify_url));
|
||
}
|
||
|
||
public async Task<AlipayF2FPrecreateResult> TradePrecreateAsync(AlipayTradePrecreateContentBuilder builder, string notify_url)
|
||
{
|
||
AlipayF2FPrecreateResult payResult = new AlipayF2FPrecreateResult();
|
||
try
|
||
{
|
||
AlipayTradePrecreateRequest payRequest = new AlipayTradePrecreateRequest();
|
||
payRequest.BizContent = builder.BuildJson();
|
||
payRequest.SetNotifyUrl(notify_url);
|
||
payResult.response = await client.ExecuteAsync(payRequest);
|
||
return payResult;
|
||
|
||
}
|
||
catch
|
||
{
|
||
payResult.response = null;
|
||
return payResult;
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
|
||
#region 内部方法
|
||
private AlipayTradeCancelResponse tradeCancel(string outTradeNo)
|
||
{
|
||
try
|
||
{
|
||
AlipayTradeCancelRequest request = new AlipayTradeCancelRequest();
|
||
StringBuilder sb2 = new StringBuilder();
|
||
sb2.Append("{\"out_trade_no\":\"" + outTradeNo + "\"}");
|
||
request.BizContent = sb2.ToString();
|
||
AlipayTradeCancelResponse response = 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 AlipayTradeQueryResponse sendTradeQuery(string outTradeNo)
|
||
{
|
||
try
|
||
{
|
||
AlipayTradeQueryContentBuilder build = new AlipayTradeQueryContentBuilder();
|
||
build.out_trade_no = outTradeNo;
|
||
AlipayTradeQueryRequest payRequest = new AlipayTradeQueryRequest();
|
||
payRequest.BizContent = build.BuildJson();
|
||
AlipayTradeQueryResponse payResponse = client.Execute(payRequest);
|
||
return payResponse;
|
||
}
|
||
catch
|
||
{
|
||
return null;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 1.返回支付处理中,轮询订单状态
|
||
/// 2.本示例中轮询了6次,每次相隔5秒
|
||
/// </summary>
|
||
/// <param name="biz_content"></param>
|
||
/// <returns></returns>
|
||
private AlipayTradeQueryResponse LoopQuery(string out_trade_no, int count, int interval)
|
||
{
|
||
AlipayTradeQueryResponse queryResult = null;
|
||
|
||
for (int i = 1; i <= count; i++)
|
||
{
|
||
Thread.Sleep(interval);
|
||
AlipayTradeQueryResponse queryResponse = 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;
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 撤销订单
|
||
/// </summary>
|
||
/// <param name="out_trade_no"></param>
|
||
/// <returns></returns>
|
||
private AlipayTradeCancelResponse CancelAndRetry(string out_trade_no)
|
||
{
|
||
AlipayTradeCancelResponse cancelResponse = null;
|
||
|
||
cancelResponse = tradeCancel(out_trade_no);
|
||
|
||
//如果撤销失败,新开一个线程重试撤销,不影响主业务
|
||
if (cancelResponse == null || (cancelResponse.Code == ResultCode.FAIL && cancelResponse.RetryFlag == "Y"))
|
||
{
|
||
ParameterizedThreadStart ParStart = new ParameterizedThreadStart(cancelThreadFunc);
|
||
Thread myThread = new Thread(ParStart);
|
||
object o = out_trade_no;
|
||
myThread.Start(o);
|
||
}
|
||
return cancelResponse;
|
||
}
|
||
|
||
private void cancelThreadFunc(object o)
|
||
{
|
||
int RETRYCOUNT = 10;
|
||
int INTERVAL = 10000;
|
||
|
||
for (int i = 0; i < RETRYCOUNT; ++i)
|
||
{
|
||
|
||
Thread.Sleep(INTERVAL);
|
||
AlipayTradeCancelRequest cancelRequest = new AlipayTradeCancelRequest();
|
||
string outTradeNo = o.ToString();
|
||
AlipayTradeCancelResponse cancelResponse = 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
|
||
}
|
||
} |