支付寶App支付簽名和驗籤

代碼:java

using CMS.Utility.ReturnResult;
using OAuthWebAPI.Package;
using Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using Ninject;
using System.Data;
using Aop.Api;
using Aop.Api.Request;
using Aop.Api.Response;
using System.Text;
using System.Web;
using System.Web.Script.Serialization;
using Aop.Api.Util;

namespace ADT.TuDou.OAuthWebAPI.Controllers
{
    public class TestAliPayController : ApiController
    {
        private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        
        /// <summary>
        /// 支付寶同步通知
        /// AliPay/AliPayCallBack
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [AcceptVerbs("POST")]
        [Authorize]
        public HttpResponseMessage AliPayCallBack([FromBody]PostModel.AliPayCallBackModel data)
        {
            //參考:https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.o060pE&treeId=193&articleId=105302&docType=1
            MessagesDataCodeModel json = new MessagesDataCodeModel(false, "無效參數", 401);
            {
                try
                {
                    if (data.resultStatus == "9000")
                    {
                        json.Success = true;
                        json.Msg = "操做成功";
                        json.Code = 200;
                    }
                    else if (data.resultStatus == "8000")
                    {
                        json.Success = false;
                        json.Msg = "正在處理中";
                        json.Code = 203;
                    }
                    else if (data.resultStatus == "4000")
                    {
                        json.Success = false;
                        json.Msg = "訂單支付失敗";
                        json.Code = 204;
                    }
                    else if (data.resultStatus == "5000")
                    {
                        json.Success = false;
                        json.Msg = "重複請求";
                        json.Code = 205;
                    }
                    else if (data.resultStatus == "6001")
                    {
                        json.Success = false;
                        json.Msg = "用戶中途取消";
                        json.Code = 206;
                    }
                    else if (data.resultStatus == "6002")
                    {
                        json.Success = false;
                        json.Msg = "網絡鏈接出錯";
                        json.Code = 207;
                    }
                    else if (data.resultStatus == "6004")
                    {
                        json.Success = false;
                        json.Msg = "支付結果未知";
                        json.Code = 208;
                    }
                    else
                    {
                        json.Success = false;
                        json.Msg = "其餘未知錯誤";
                        json.Code = 209;
                    }
                }
                catch (Exception ex)
                {
                    json.Success = false;
                    json.Msg = "服務器無響應";
                    json.Code = 500;
                    json.Data = ex.Message;
                    logger.Error("AliPayController.AliPayCallBack", ex);
                }
                return ToJsonTran.ToJson(json);
            }
        }

        /// <summary>
        /// 阿里異步通知
        /// AliPay/Notify
        /// </summary>
        /// <returns></returns>
        [AcceptVerbs("POST")]
        public void Notify()
        {
            //驗籤(解決問題成功率90 %) issig爲false,通常有幾種可能:
            //一、支付寶公鈅(特別是PHP編程語言,必定要用demo中的支付寶公鑰文件)或者key有問題;
            //二、參與驗籤的待簽名字符串存在中文亂碼,或者多了商戶的自定義參數(異步通知地址帶自定義參數;),或者少了一些異步通知參數;
            //三、須要RSA驗籤,可是商戶用MD5驗籤;
            //四、驗籤的編碼格式有問題(主要是java和c#);
            //五、驗籤的代碼邏輯有問題,強烈建議參考demo的

            //[FromBody]PostModel.AliNotify data
            //參考地址:https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.XZMUaR&treeId=204&articleId=105301&docType=1
            //編碼(101-登陸無效,102-帳號無效,200-成功,201-失敗,202~299-其餘緣由1-99,300-無效提交方式,400-無效參數)
            MessagesDataCodeModel json = new MessagesDataCodeModel(false, "無效參數", 401);
            string result = "failed";
            try
            {
                #region 驗籤
                //獲取全部通知參數,其中sign不要解碼
                IDictionary<string, string> dic = GetParas();
                //string signContent = AlipaySignature.GetSignContent(dic);//驗簽字符串
                //支付寶公鑰
                string publicKeyPem_Alipay = HttpContext.Current.Server.MapPath("~/alipay/rsa_public_key_alipay.pem");
                //驗籤,公共類庫下載地址:
                bool ValidateSign = AlipaySignature.RSACheckV1(dic, publicKeyPem_Alipay, ConfigApi.AliPay_App_charset);
                #endregion

                #region 處理訂單
                if (ValidateSign)
                {
                    //處理訂單的業務邏輯...
                    result = "success";
                }
                else
                {
                    result = "RSACheckV1Error";
                    logger.Error("AliPayController.Notify【驗籤失敗】");
                }
                #endregion
            }
            catch (Exception ex)
            {
                logger.Error("AliPay/Notify", ex);
                result = "exception";
            }
            HttpContext.Current.Response.Write(result);
            HttpContext.Current.Response.End();
        }

        /// <summary>
        /// RSA簽名
        /// AliPay/Sign
        /// 系統平臺 ios 、android
        /// pro_type 商品類型 購買官方錄音專輯=1,購買Vip會員=2,購買繪本=3,快樂英語=4,打賞優秀專家=5,打賞優秀機構=6,打賞優秀電臺=7,
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [AcceptVerbs("POST")]
        [Authorize]
        public HttpResponseMessage Sign([FromBody]PostModel.biz_content data)
        {
            //編碼(101-登陸無效,102-帳號無效,200-成功,201-失敗,202~299-其餘緣由1-99,300-無效提交方式,400-無效參數)
            MessagesDataCodeModel json = new MessagesDataCodeModel(false, "無效參數", 401);

            try
            {
                if (data != null)
                {
                    //生成簽名以前,編寫本身的驗證邏輯...
                    
                    //訂單編號
                    string out_trade_no = Guid.NewGuid().ToString().Replace("-", "");
                    double total_fee = 0.01;//費用 1分錢(測試)

                    #region 生成簽名
                    string publicKeyPem = HttpContext.Current.Server.MapPath("~/alipay/rsa_public_key.pem");//公鑰
                    string privateKeyPem = HttpContext.Current.Server.MapPath("~/alipay/rsa_private_key.pem");//私鑰
                    string app_id = ConfigApi.AliPay_App_app_id;//app支付,支付寶中該應用的ID
                    string seller_id = ConfigApi.AliPay_App_seller_id;//商戶帳戶
                    string method = ConfigApi.AliPay_App_method;//alipay.trade.app.pay
                    string charset = ConfigApi.AliPay_App_charset;//utf-8
                    string timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    string version = @"1.0";
                    string sign_type = @"RSA";
                    string timeout_express = "30m";
                    string notify_url = ConfigApi.AliPay_App_notify_url;
                    string body = data.body;
                    string subject = data.subject;

                    //拼接簽名使用的字符串【編碼】
                    string app_id_encode = HttpUtility.UrlEncode(app_id, Encoding.GetEncoding(charset));//
                    string charset_encode = HttpUtility.UrlEncode(charset, Encoding.GetEncoding(charset));//
                    string method_encode = HttpUtility.UrlEncode(method, Encoding.GetEncoding(charset));//
                    string sign_type_encode = HttpUtility.UrlEncode(sign_type, Encoding.GetEncoding(charset));//
                    string timestamp_encode = HttpUtility.UrlEncode(timestamp, Encoding.GetEncoding(charset));//
                    string version_encode = HttpUtility.UrlEncode(version, Encoding.GetEncoding(charset));//
                    string notify_url_encode = HttpUtility.UrlEncode(ConfigApi.AliPay_App_notify_url, Encoding.GetEncoding(charset));//
                    string body_encode = HttpUtility.UrlEncode(data.body, Encoding.GetEncoding(charset));//
                    string subject_encode = HttpUtility.UrlEncode(data.subject, Encoding.GetEncoding(charset));//
                    //訂單內容
                    string biz_content = "{\"body\":\"" + body + "\",\"subject\":\"" + subject + "\",\"out_trade_no\":\"" + out_trade_no + "\",\"timeout_express\":\"" + timeout_express + "\",\"total_amount\":\"" + total_fee + "\",\"seller_id\":\"" + seller_id + "\",\"product_code\":\"QUICK_MSECURITY_PAY\"}";
                    //將訂單內容編碼,必須和支付寶指定的編碼一致 utf-8
                    string biz_content_encode = HttpUtility.UrlEncode(biz_content, Encoding.GetEncoding(charset));
                    //構建簽名參數集合
                    IDictionary<string, string> dic = new Dictionary<string, string>();
                    dic.Add("app_id", app_id);
                    dic.Add("biz_content", biz_content);
                    dic.Add("charset", charset);
                    dic.Add("method", method);
                    dic.Add("notify_url", notify_url);
                    dic.Add("sign_type", sign_type);
                    dic.Add("timestamp", timestamp);
                    dic.Add("version", version);
                    //獲得簽名字符串
                    string result1 = Aop.Api.Util.AlipaySignature.RSASign(dic, privateKeyPem, charset, true, sign_type);
                    //把獲得的簽名字符串使用指定的格式編碼(utf-8),返回給客戶端再用utf-8解碼就好了
                    string result = HttpUtility.UrlEncode(result1, Encoding.GetEncoding(charset));
                    string jsonStr = Aop.Api.Util.AlipaySignature.GetSignContent(dic);//獲得簽名原字符串,客戶端要用(支付寶提供的方法)
                    //下面是我手動拼接的,其實阿里提供的有...
                    //@"app_id=" + app_id_encode + "&biz_content=" + biz_content_encode + "&charset=" + charset_encode + "&method=" + method_encode + "&notify_url=" + notify_url_encode + "&sign_type=" + sign_type_encode + "&timestamp=" + timestamp_encode + "&version=" + version_encode;
                    #endregion

                    #region 生成訂單,返回 out_trade_no
                    //生成訂單的邏輯...
                    #endregion
                    json.Success = true;
                    json.Msg = "操做成功";
                    json.Code = 200;
                    json.Data = new { TradeNo = out_trade_no, Sign = result, SignContent = jsonStr };
                }
            }
            catch (Exception ex)
            {
                json.Success = false;
                json.Msg = "服務器無響應";
                json.Code = 500;
                json.Data = ex.Message;
                logger.Error("AliPay/Sign", ex);
            }
            return ToJsonTran.ToJson(json);
        }
        public string GetPara(string ParaName)
        {
            string result = HttpContext.Current.Request[ParaName];
            if (!string.IsNullOrEmpty(result))
            {
                return result;
            }
            return "";
        }
        public string GetPara_Decode(string ParaName)
        {
            string result = HttpContext.Current.Request[ParaName];
            if (!string.IsNullOrEmpty(result))
            {
                return HttpUtility.UrlDecode(result, System.Text.Encoding.GetEncoding(ConfigApi.AliPay_App_charset));
            }
            return "";
        }
        public IDictionary<string, string> GetParas()
        {
            IDictionary<string, string> dic = new Dictionary<string, string>();
            for (int i = 0; i < HttpContext.Current.Request.Form.Keys.Count; i++)
            {
                string key = HttpContext.Current.Request.Form.Keys[i].ToString();
                string value = "";
                if (key != "sign")
                {
                    value = GetPara_Decode(key);
                }
                else
                {
                    value = GetPara(key);
                }
                if (!string.IsNullOrEmpty(value))
                {
                    dic.Add(key, value);
                }
            }
            return dic;
        }
    }
}

 簽名類:android

#region 支付簽名 實體類
    public class biz_content
    {
        /// <summary>
        /// 訂單描述 [傳入]
        /// </summary>
        public string body { get; set; }
        /// <summary>
        /// 訂單標題 [傳入]
        /// </summary>
        public string subject { get; set; }
        /// <summary>
        /// 付款總金額 [傳入]
        /// </summary>
        public string total_amount { get; set; }
        /// <summary>
        /// 訂單編號GUID
        /// </summary>
        public string out_trade_no { get; set; }
        /// <summary>
        /// 訂單有效時限
        /// </summary>
        public string timeout_express { get; set; }
    }
    #endregion

  

文檔:https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.9CZS6Q&treeId=193&articleId=105465&docType=1ios

主要看的有四篇:申請支付請求參數說明、客戶端同步返回、支付結構異步通知、交易操做接口express

服務端SDK下載:https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.huKVyy&treeId=54&articleId=103419&docType=1編程

相關文章
相關標籤/搜索