.NET WEB API 對接支付寶支付

.NET WEB API 對接支付寶支付

轉載請註明出處: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

相關文章
相關標籤/搜索