支付宝支付功能开发
一.准备工作
1.沙箱应用:https://openhome.alipay.com/platform/appDaily.htm
2.签名专区:https://docs.open.alipay.com/291/105971/
3.DEMO下载:https://docs.open.alipay.com/270/106291/
4.商家中心:https://b.alipay.com/signing/authorizedProductSet.htm?navKey=all#/?_k=53rjub
5.电脑网站支付开发文档:https://docs.open.alipay.com/270/alipay.trade.page.pay
6.开发指南:https://docs.open.alipay.com/200/105310/
二.编写代码
1.发起PC支付
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
OrderPaymentTB orderPayment = this.BaseService.GetModel<OrderPaymentTB>(u => u.OrderPaymentNo == tradeNo); string app_id = CachedConfigContext.Current.AlipayConfig.app_id; string subject = CachedConfigContext.Current.AlipayConfig.subject; string merchant_private_key = CachedConfigContext.Current.AlipayConfig.private_key; string alipay_public_key = CachedConfigContext.Current.AlipayConfig.alipay_public_key; string server_url = CachedConfigContext.Current.AlipayConfig.server_url;//正式环境 https://openapi.alipay.com/gateway.do string format = CachedConfigContext.Current.AlipayConfig.format; string version = CachedConfigContext.Current.AlipayConfig.version; string sign_type = CachedConfigContext.Current.AlipayConfig.sign_type; string input_charset = CachedConfigContext.Current.AlipayConfig.input_charset; DefaultAopClient client = new DefaultAopClient(server_url, app_id, merchant_private_key, format, version, sign_type, alipay_public_key, input_charset, false); AlipayTradePagePayRequest request = new AlipayTradePagePayRequest(); request.BizContent = "{" + " \"body\":\"\"," + " \"subject\":\"" + subject + "\"," + " \"out_trade_no\":\"" + orderPayment.OrderPaymentNo + "\"," + " \"total_amount\":" + orderPayment .Amount+ "," + " \"product_code\":\"FAST_INSTANT_TRADE_PAY\"" + " }"; request.SetReturnUrl(CachedConfigContext.Current.AlipayConfig.return_url); request.SetNotifyUrl(CachedConfigContext.Current.AlipayConfig.notify_url); AlipayTradePagePayResponse response = client.pageExecute(request); string form = response.Body; return View();
2.支付回调
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using Qxun.Framework.Utility; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Web; using System.Web.Mvc; using System.Xml.Serialization; using System.Collections.Specialized; using System.Transactions; using System.Collections; using Qxun.Framework.Web; using Qxun.Framework.Contract; using Qxun.Framework.Weixin.NativePay; using Aop.Api.Util; using Qxun.Core.Config; namespace QianxunApplication.Areas.Admin.Controllers { public class AlipayController : Controller { // // GET: /Admin/Alipay/ public ActionResult Callback() { LogHelper.Error("PC端支付宝支付回调"); SortedDictionary<string, string> sPara = GetRequestPost(); Response.Write("success"); if (sPara.Count > 0)//判断是否有带返回参数 { bool verifyResult = AlipaySignature.RSACheckV1(sPara, CachedConfigContext.Current.AlipayConfig.alipay_public_key, CachedConfigContext.Current.AlipayConfig.input_charset, CachedConfigContext.Current.AlipayConfig.sign_type, false); if (verifyResult)//验证成功 { LogHelper.Error("签名验证成功"); ///////////////////////////////////////////////////////////////////////////////////////////////////////////// //请在这里加上商户的业务逻辑程序代码 //——请根据您的业务逻辑来编写程序(以下代码仅作参考)—— //获取支付宝的通知返回参数,可参考技术文档中服务器异步通知参数列表 //商户订单号 string out_trade_no = Request.Form["out_trade_no"]; //支付宝交易号 string trade_no = Request.Form["trade_no"]; //交易状态 string trade_status = Request.Form["trade_status"]; LogHelper.Error("交易状态:" + trade_status); if (Request.Form["trade_status"] == "TRADE_FINISHED") { //判断该笔订单是否在商户网站中已经做过处理 //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序 //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的 //如果有做过处理,不执行商户的业务程序 //注意: //退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知 Response.Write("success"); //请不要修改或删除 } else if (Request.Form["trade_status"] == "TRADE_SUCCESS") { //判断该笔订单是否在商户网站中已经做过处理 //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序 //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的 //如果有做过处理,不执行商户的业务程序 //注意: //付款完成后,支付宝系统发送该交易状态通知 var model = ServiceContext.Current.BaseService.GetModel<OrderPaymentTB>(u => u.OrderPaymentNo == out_trade_no); if (model != null) { try { model.TradeOrderNo = trade_no; model.Remark = "alipay success;time=" + DateTime.Now.ToString(); ServiceContext.Current.TradeService.FinishOrderPayment(model); Response.Write("success"); //请不要修改或删除 } catch (Exception e) { LogHelper.Error(string.Format("支付宝支付回调,本地数据库查询不到该订单号{0}所对应的订单", out_trade_no)); Response.Write("success"); //请不要修改或删除 } } else { LogHelper.Error(string.Format("支付宝支付回调,本地数据库查询不到该订单号{0}所对应的订单", out_trade_no)); Response.Write("fail"); } } else { Response.Write("fail"); } //——请根据您的业务逻辑来编写程序(以上代码仅作参考)—— //Response.Write("success"); //请不要修改或删除 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// } else//验证失败 { LogHelper.Error("签名验证失败"); Response.Write("fail"); } } else { Response.Write("无通知参数"); } return View(); } public static void PrintKeysAndValues(NameValueCollection myCol) { IEnumerator myEnumerator = myCol.GetEnumerator(); Console.WriteLine(" KEY VALUE"); foreach (String s in myCol.AllKeys) { LogHelper.Error(string.Format("{0}: {1}", s, myCol[s])); } } /// <summary> /// 获取支付宝POST过来通知消息,并以“参数名=参数值”的形式组成数组 /// </summary> /// <returns>request回来的信息组成的数组</returns> public SortedDictionary<string, string> GetRequestPost() { int i = 0; SortedDictionary<string, string> sArray = new SortedDictionary<string, string>(); NameValueCollection coll; //Load Form variables into NameValueCollection variable. coll = Request.Form; // Get names of all forms into a string array. String[] requestItem = coll.AllKeys; for (i = 0; i < requestItem.Length; i++) { LogHelper.Error(string.Format("{0}: {1}", requestItem[i], Request.Form[requestItem[i]])); sArray.Add(requestItem[i], Request.Form[requestItem[i]]); } return sArray; } } }