1使用場景在APP(是APP,不是其他,網頁或者其他調用方式不同)中內集成支付寶支付
2去支付平台申請一個APPID(唯一標識) ,商家賬號(PID,沒有就自己申請一個)
3下載一個支付寶開放平台開發助手(其他的也行,只有能生成公鑰私鑰),生成公鑰和私鑰(私鑰不能泄露),然后上傳公鑰生成支付寶公鑰
應用公鑰:商戶自己生成的RSA公鑰(與應用私鑰必須匹配,生成的時候注意是java版本還是其他版本),需要將這個公鑰上傳到開發平台,驗證是否是商戶發起的,支付寶會生成對應的公鑰。
應用私鑰:商戶自己生成RSA私鑰(與應用公鑰必須匹配,不能泄露),使用私鑰對請求字符串加密
支付寶公鑰:商戶使用該公鑰驗證該結果是否是支付寶返回的
4服務端.net core webapi) sdk,用nuget包管理(也可以去支付寶官網下載https://docs.open.alipay.com/54/106370/)
5設置相關類
/// <summary> /// 調用阿里支付接口參數設置 /// </summary> public class AlipayConfig { /// <summary> /// 發起請求的應用ID。沙箱與線上不同,請更換代碼中配置; /// </summary> public string AppId { get; set; } /// <summary> /// 用於支付寶賬戶登錄授權業務的入參 pid /// </summary> public string PId { get; set; } /// <summary> /// 支付寶私匙 /// </summary> public string PrivateKey { get; set; } /// <summary> /// 應用公鑰 /// </summary> public string Publickey { get; set; } /// <summary> /// 支付寶公匙 /// </summary> public string AlipayPublicKey { get; set; } /// <summary> /// 服務器異步通知路徑 /// </summary> public string notify_url { get; set; } /// <summary> /// 公匙類型/簽名類型 /// </summary> public string SignType { get; set; } /// <summary> /// 編碼格式 /// </summary> public string CharSet { get; set; } /// <summary> /// 向支付寶發起請求的網關。沙箱與線上不同,請更換代碼中配置;沙箱:https://openapi.alipaydev.com/gateway.do上線https://openapi.alipay.com/gateway.do /// </summary> public string GatewayUrl { get; set; } /// <summary> /// 調用的接口版本 /// </summary> public string Version { get; set; } /// <summary> /// 僅支持JSON /// </summary> public string Format { get; set; } public bool KeyFromFile { get; set; } }
這些都是必填的,在appsetting中讀取
"Alipay": { "AppId": "申請的appid","PId": "商戶id","PrivateKey": "私鑰","Publickey": "公鑰", "AlipayPublicKey": "阿里公鑰", "notify_url": "回調函數地址", "SignType": "RSA2", "CharSet": "UTF-8", "GatewayUrl": "https://openapi.alipay.com/gateway.do", "Version": "2.0", "Format": "json", "KeyFromFile": false } /// <summary>
6 在startup注入
var alipay = Configuration.GetSection("Alipay"); services.Configure<AlipayConfig>(alipay);
7 在業務邏輯層
public class OrderService : IOrderService, IBaseService { private readonly IAopClient _client; private readonly AlipayConfig _alipayConfig;public OrderService(IOptionsMonitor<AlipayConfig> alipayConfig) { _alipayConfig = alipayConfig.CurrentValue; _client = new DefaultAopClient(_alipayConfig.GatewayUrl, _alipayConfig.AppId, _alipayConfig.PrivateKey, _alipayConfig.Format, _alipayConfig.Version, _alipayConfig.SignType, _alipayConfig.AlipayPublicKey, _alipayConfig.CharSet, _alipayConfig.KeyFromFile); } /// <summary> /// 支付寶統一下單 /// </summary> /// <param name="price"></param> /// <param name="orderNumber"></param> /// <returns></returns> public async Task<string> AliOrderAsync(int price, string orderNumber) { //SDK已經封裝掉了公共參數,這里只需要傳入業務參數。以下方法為sdk的model入參方式(model和biz_content同時存在的情況下取biz_content)。 // 組裝業務參數model AlipayTradeAppPayModel model = new AlipayTradeAppPayModel(); //訂單總金額,單位為元,精確到小數點后兩位,取值范圍[0.01,100000000],必選 model.TotalAmount = (price).ToString(); //商品的標題 / 交易標題 / 訂單標題 / 訂單關鍵字等。必選 model.Subject = "購買商品的標題"; ///外部第三方的訂單號,必選 model.OutTradeNo = orderNumber; AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest(); // 設置同步回調地址 request.SetReturnUrl(""); // 設置異步通知接收地址() request.SetNotifyUrl(_alipayConfig.notify_url); // 將業務model載入到request request.SetBizModel(model); var response = _client.SdkExecute(request); // Console.WriteLine($"訂單支付發起成功,訂單號:{response.Body}"); //直接傳客戶端,不需要做form表單轉換為json格式 return response.Body; }
8 然后在控制器中調用就可以了
9 客戶端喚起支付寶界面進行支付,支付成功之后,會調用服務器的回調函數,主要作用是來驗證訂單信息,更新數據庫
需要注意的是回調函數不能帶有參數,只能post請求
/// <summary> /// Alipay回調通知 /// </summary> /// <returns></returns> [HttpPost] public async Task<string> 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]); } } if (sarray.Count > 0) { var notifyId = Request.Form["notify_id"].ToString(); var sign = Request.Form["sign"].ToString(); bool verifyresult = _paynotifyservice.GetVerifyResult(sarray, notifyId, sign); if (verifyresult) //驗簽成功 && 關鍵業務參數校驗成功 { 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"]; string app_id = Request.Form["app_id"]; var status = await _paynotifyservice.AlipayNotifyAsync(out_trade_no, trade_no, trade_status, float.Parse(total_amount), buyer_logon_id); //進行數據的更新 if (status != 1) { result = "fail"; } } else//驗證失敗 { result = "fail"; } } return result; }
/// <summary> /// 調用阿里支付接口回調函數更新數據庫 /// </summary> /// <param name="OrderNumber"></param> /// <param name="aliOrderNo"></param> /// <param name="payStauts"></param> /// <param name="totalAmout"></param> /// <param name="buyerId"></param> /// <returns></returns> public async Task<int> AlipayNotifyAsync(string OrderNumber, string aliOrderNo, string payStauts, double totalAmout, string buyerId) { var result = -1; if (payStauts.Equals("TRADE_SUCCESS") || payStauts.Equals("TRADE_FINISHED")) { //此處應該校驗交易金額是否正確。需要比對float或者double類型數據 //邏輯處理,更新數據庫中訂單狀態 result = 1; } return result; } public bool GetVerifyResult(SortedDictionary<string, string> sarray, string notifyId, string sign) { var alinotify = new Notify(_alipayConfig.CharSet, _alipayConfig.SignType, _alipayConfig.PId, _alipayConfig.GatewayUrl, _alipayConfig.AlipayPublicKey); //對異步通知進行驗簽 bool verifyresult = alinotify.Verify(sarray, notifyId, sign); return verifyresult; }
至此,訂單的整個流程就完成了