轉載請註明出處:http://leejunhui.com/2017/02/09/AliPayWithWebAPI/git
最近一個項目中須要本身先後臺全棧,幾經權衡以後,在仍是選擇了本身最爲熟悉的.NET WEB API技術來實現服務器端。多是因爲過久沒接觸.NET了,在對接支付寶APP支付的時候,遇到了很多坑,廢話很少說,直接上代碼吧。github
public class AliPayHelper { private static string APP_ID = ""; private static string CHARSET = "UTF-8"; /// <summary> /// 生成RSA簽名後的訂單字符串 /// </summary> /// <param name="price"></param> /// <param name="description"></param> /// <returns></returns> public static string createRSASignedOrderString(double price,string description) { Dictionary<string, string> orderStringDict = new Dictionary<string, string>(); orderStringDict.Add("app_id", APP_ID); orderStringDict.Add("method", "alipay.trade.app.pay"); orderStringDict.Add("format", "JSON"); orderStringDict.Add("charset", "utf-8"); orderStringDict.Add("sign_type", "RSA"); orderStringDict.Add("timestamp", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); orderStringDict.Add("version", "1.0"); orderStringDict.Add("notify_url", ""); orderStringDict.Add("biz_content", generateBizContentString(price.ToString(), description)); // 排序拼接成字符串 string orderInfo = AlipaySignature.GetSignContent(orderStringDict); string orderInfoEncoded = Core.CreateLinkStringUrlencode(orderStringDict, (new System.Text.UTF8Encoding())); // 簽名 string privateKeyPem = GetCurrentPath() + "rsa_private_key.pem"; string signString = AlipaySignature.RSASign(orderInfo, privateKeyPem, null, "RSA"); signString = HttpUtility.UrlEncode(signString, new UTF8Encoding()); // 加上sign string orderString = orderInfoEncoded + "&sign=" + signString; // 拼接最終返回給客戶端的字符串 return orderString; } static String BytesToBase64(Byte[] bytes) { try { return Convert.ToBase64String(bytes); } catch { return null; } } /// <summary> /// 獲取私鑰的路徑 /// </summary> /// <returns></returns> private static string GetCurrentPath() { string strPath = "/Helper/"; if (HttpContext.Current != null) { return HttpContext.Current.Server.MapPath(strPath); } else //非web程序引用 { strPath = strPath.Replace("/", "\\"); if (strPath.StartsWith("\\")) { //strPath = strPath.Substring(strPath.IndexOf('\\', 1)).TrimStart('\\'); strPath = strPath.TrimStart('\\'); } return System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, strPath); } } /// <summary> /// 生成業務參數 /// </summary> /// <param name="price"></param> /// <param name="descripiton"></param> /// <returns></returns> private static string generateBizContentString(string price, string descripiton) { Dictionary<string, string> bizContent = new Dictionary<string, string>(); bizContent.Add("subject", descripiton); bizContent.Add("body", descripiton); bizContent.Add("out_trade_no", generateOrderNumber()); bizContent.Add("timeout_express", "90m"); bizContent.Add("total_amount", price); bizContent.Add("product_code", "QUICK_MSECURITY_PAY"); string bizContentJsonString = (new System.Web.Script.Serialization.JavaScriptSerializer()).Serialize(bizContent); return bizContentJsonString; } private static string generateOrderNumber() { return DateTime.Now.ToString("yyyyMMddHHmmssfff"); } }
用法以下:web
public async Task<HttpResponseMessage> AliPaySignString(AlipayRequestModel model) { var response = new SingleModelResponse<String>() as ISingleModelResponse<String>; try { await Task.Run(() => { string orderString = AliPayHelper.createRSASignedOrderString(Convert.ToDouble(model.price), model.description); if (null == orderString) { response.DidError = true; response.info = "簽名失敗"; } else { response.Model = orderString; response.info = "簽名成功"; } }); } catch (Exception ex) { response.DidError = true; response.info = ex.InnerException.Message; } return response.ToHttpResponse(); }
上面的代碼主要乾了一件事情,生成簽名後的訂單字符串返回給app客戶端,而後app客戶端拿着這個字符串去調用支付寶SDK,發起支付請求。爲何要這麼麻煩呢?一切都是爲了安全,根據支付寶官方開發平臺的解釋,把簽名的過程放在服務器端是要比放在客戶端更爲安全的一種策略。
因爲網上關於.NET對接支付寶的文章和教程時效性都已經很低了,因此我把項目中的AliPayHelper
代碼放在這,供你們參考。
github代碼地址express