支付宝小程序支付及支付后异步通知 C# NeCore3.1
十年河东,十年河西,莫欺少年穷
学无止境,精益求精
1、支付异步通知
using AliyunHelper.AliPayHelper; using Aop.Api.Util; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using SugarDbContext; using swapCommon; using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using System.Web; namespace swapAlipay.Controllers { /// <summary> /// https://github.com/alipay/alipay-easysdk/tree/master/csharp /// https://www.cnblogs.com/carlpeng/p/13468878.html /// </summary> [AllowAnonymous] public class ReviceController : BaseController { private readonly ILogger<ReviceController> logger; public ReviceController(ILogger<ReviceController> logger) { this.logger = logger; } /// <summary> /// Alipay回调通知 /// /// {"app_id":"","auth_app_id":"","body":"租赁","buyer_logon_id":"1***@qq.com","buyer_open_id":"","buyer_pay_amount":"0.01","charset":"UTF-8","fund_bill_list":"[{\"amount\":\"0.01\",\"fundChannel\":\"ALIPAYACCOUNT\"}]","gmt_create":"2024-11-28 14:51:11","gmt_payment":"2024-11-28 14:51:19","invoice_amount":"0.01","merchant_app_id":"2021004195648040","notify_id":"2024112801222145120091841466598371","notify_time":"2024-11-28 14:51:20","notify_type":"trade_status_sync","out_trade_no":"","point_amount":"0.00","receipt_amount":"0.01","seller_email":"chenwolong2022@163.com","seller_id":"2088260077052221","sign":"","sign_type":"RSA2","subject":"租赁","total_amount":"0.01","trade_no":"","trade_status":"TRADE_SUCCESS","version":"1.0"} /// </summary> /// <returns></returns> [AllowAnonymous] [HttpPost] [Route("AliPayNotify")] public ActionResult AliPayNotify() { logger.LogError("AliPayNotify---支付宝回调---开始"); string result = "success"; SortedDictionary<string, string> sarray = new SortedDictionary<string, string>(); var keys = Request.Form.Keys; if (keys != null) { foreach (string key in keys) { sarray.Add(key, Request.Form[key]); } } logger.LogError(JsonConvert.SerializeObject(sarray)); if (sarray.Count > 0) { string app_id = Request.Form["app_id"]; var alipayConst = AlipayConst.GetAliPayConst(app_id); //alipayPublicKey 支付宝公钥 Charset:UTF-8 SignType:RSA2 var safe = AlipaySignature.RSACheckV1(sarray, alipayConst.alipayPublicKey, alipayConst.Charset, alipayConst.SignType, false); if (safe) //验签成功 && 关键业务参数校验成功 { string out_trade_no = Request.Form["out_trade_no"]; //获取ali传过来的参数的值 string trade_no = Request.Form["trade_no"]; string trade_status = Request.Form["trade_status"]; string total_amount = Request.Form["total_amount"]; string buyer_id = Request.Form["buyer_id"]; string buyer_logon_id = Request.Form["buyer_logon_id"]; if (trade_status != "TRADE_SUCCESS") { result = "fail"; } else { //具体业务 } } else//验证失败 { result = "fail"; } } return Content(result); } } }
2、支付代码
using System; using System.Collections.Generic; using Aop.Api; using Aop.Api.Request; using Aop.Api.Response; using Aop.Api.Domain; using Aop.Api.Util; using AliyunHelper.AliPayHelper.AlipayModels; namespace AliyunHelper.AliPayHelper { public class AlipayTradeHelper { public static AlipayTradeCreateResponse CreateAliOrder(AlipayTradeDto data) { var parm = AlipayConst.GetAliPayConst(data.AppId); // 初始化SDK IAopClient alipayClient = new DefaultAopClient(GetAlipayConfig(parm)); // 构造请求参数以调用接口 AlipayTradeCreateRequest request = new AlipayTradeCreateRequest(); AlipayTradeCreateModel model = new AlipayTradeCreateModel(); request.SetNotifyUrl(parm.NotifyUrl); // 设置商户订单号 model.OutTradeNo = "Ali" + DateTime.Now.ToString("yyyyMMddHHmmssfff"); // 设置产品码 model.ProductCode = "JSAPI_PAY"; // 设置小程序支付中 model.OpAppId = data.AppId; // 设置订单总金额 model.TotalAmount = data.TotalAmount; // 设置可打折金额 model.DiscountableAmount = data.DiscountAmount; // 设置订单标题 model.Subject = "租赁"; // 设置订单附加信息 model.Body = "租赁"; // uid参数未来计划废弃,存量商户可继续使用,新商户请使用openid。请根据应用-开发配置-openid配置选择支持的字段。 // model.BuyerId = "2088102146225135"; // 设置买家支付宝用户唯一标识 model.BuyerOpenId = data.OpenId; // 设置商户门店编号 model.StoreId = "NJ_001"; //SignParams agreementSignParams = new SignParams(); //agreementSignParams.SignNotifyUrl = parm.NotifyUrl; //model.AgreementSignParams = agreementSignParams; request.SetBizModel(model); // 第三方代调用模式下请设置app_auth_token // request.PutOtherTextParam("app_auth_token", "<-- 请填写应用授权令牌 -->"); AlipayTradeCreateResponse response = alipayClient.Execute(request); if (!response.IsError) { Console.WriteLine("调用成功"); } else { Console.WriteLine("调用失败"); } return response; } private static AlipayConfig GetAlipayConfig(ConstDto parm) { string privateKey = parm.privateKey; string alipayPublicKey = parm.alipayPublicKey; AlipayConfig alipayConfig = new AlipayConfig(); alipayConfig.ServerUrl = "https://openapi.alipay.com/gateway.do"; alipayConfig.AppId = parm.AppId; alipayConfig.PrivateKey = privateKey; alipayConfig.Format = "json"; alipayConfig.AlipayPublicKey = alipayPublicKey; alipayConfig.Charset = parm.Charset; alipayConfig.SignType = parm.SignType; return alipayConfig; } } }
支付Model相关
public class AlipayTradeDto { /// <summary> /// 小程序APPID /// </summary> public string AppId { get; set; } /// <summary> /// 总金额 /// </summary> public string TotalAmount { get; set; } /// <summary> /// 折扣金额 /// </summary> public string DiscountAmount { get { return GetDiscountAmount(); } } public string OpenId { get; set; } /// <summary> /// 是否打折 不传不打折 1 打折 /// </summary> public int? Discountable { get; set; } /// <summary> /// 打八折 就传值8 不传不打折 传值较小 打骨折 /// </summary> public int? Discount { get; set; } private string GetDiscountAmount() { var DiscountAmount = this.TotalAmount; if (Discountable.HasValue&& Discountable.Value == 1&& Discount.HasValue&& Discount.Value>0&&Discount.Value<10) { DiscountAmount = (Convert.ToDouble(TotalAmount) * Discount.Value).ToString("0.00"); } return DiscountAmount; } }
及
public class ConstDto { /// <summary> /// 应用公钥 /// </summary> public string publicKey { get; set; } /// <summary> /// 应用私钥 /// </summary> public string privateKey { get; set; } /// <summary> /// 支付宝公钥 /// </summary> public string alipayPublicKey { get; set; } /// <summary> /// 支付宝小晨曦APPId /// </summary> public string AppId { get; set; } /// <summary> /// AES秘钥 /// </summary> public string AesKey = "LnmGMYjhVxy2sJz5miL9JQ=="; public string NotifyUrl { get; set; } public string Charset { get; set; } public string SignType { get; set; } } public class AlipayConst { public static ConstDto GetAliPayConst(string appid) { ConstDto dto = new ConstDto(); ///充电宝小程序 if (appid== "202xxxxx040") { dto.privateKey= "MII。。。"; dto.alipayPublicKey = "MII。。。"; dto.publicKey = "MII。。。"; dto.AppId = "2022022222222222xxx";// dto.Charset = "UTF-8"; dto.SignType = "RSA2"; dto.NotifyUrl = "https://xxx.com/swapAlipay/api/v1/Revice/AliPayNotify"; return dto; } return null; } }
@天才卧龙
退款:
using System; using System.Collections.Generic; using Aop.Api; using Aop.Api.Request; using Aop.Api.Response; using Aop.Api.Domain; using Aop.Api.Util; using AliyunHelper.AliPayHelper.AlipayModels; namespace AliyunHelper.AliPayHelper { public class AlipayRefundHelper { public static AlipayTradeRefundResponse Refund(RefundDto data) { // 初始化SDK IAopClient alipayClient = new DefaultAopClient(GetAlipayConfig(data.Appid)); // 构造请求参数以调用接口 AlipayTradeRefundRequest request = new AlipayTradeRefundRequest(); AlipayTradeRefundModel model = new AlipayTradeRefundModel(); // 设置商户订单号 model.OutTradeNo = data.OutTradeNo; // 设置支付宝交易号 model.TradeNo = data.TradeNo; // 设置退款金额 model.RefundAmount = data.RefundAmount; // 设置退款原因说明 model.RefundReason = "正常退款"; //退款请求号。 标识一次退款请求,需要保证在交易号下唯一,如需部分退款,则此参数必传。 注:针对同一次退款请求,如果调用接口失败或异常了,重试时需要保证退款请求号不能变更,防止该笔交易重复退款。支付宝会保证同样的退款请求号多次请求只会退一次。 // 设置退款请求号 model.OutRequestNo = DateTime.Now.ToString("yyyyMMddHHmmssfff"); // 设置退分账明细信息 // 设置查询选项 //设置针对账期交易 //model.RelatedSettleConfirmNo = "2024041122001495000530302869"; request.SetBizModel(model); // 第三方代调用模式下请设置app_auth_token // request.PutOtherTextParam("app_auth_token", "<-- 请填写应用授权令牌 -->"); AlipayTradeRefundResponse response = alipayClient.Execute(request); if (!response.IsError) { Console.WriteLine("调用成功"); } else { Console.WriteLine("调用失败"); } return response; } private static AlipayConfig GetAlipayConfig(string appid) { var constData = AlipayConst.GetAliPayConst(appid); string privateKey = constData.privateKey; string alipayPublicKey = constData.alipayPublicKey; AlipayConfig alipayConfig = new AlipayConfig(); alipayConfig.ServerUrl = "https://openapi.alipay.com/gateway.do"; alipayConfig.AppId = appid; alipayConfig.PrivateKey = privateKey; alipayConfig.Format = "json"; alipayConfig.AlipayPublicKey = alipayPublicKey; alipayConfig.Charset = "UTF-8"; alipayConfig.SignType = "RSA2"; return alipayConfig; } } }
public class RefundDto { /// <summary> /// 商户订单号 /// </summary> public string OutTradeNo { get; set; } /// <summary> /// 支付宝交易号 /// </summary> public string TradeNo { get; set; } /// <summary> /// 退款金额 单位:元 /// </summary> public string RefundAmount { get; set; } public string Appid { get; set; } }