导航

使用 ping++做支付的流程

Posted on 2017-12-01 15:48  hlgba  阅读(1553)  评论(0)    收藏  举报

获取支付凭据

 /// <summary>
        /// 获取支付凭据
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>      
        [HttpPost]        
        [IsLoginAuthorizeAttribute]  
        public MessagesDataCode<string> GetPaymentCredential([FromBody] AlipayCharge model)
        {            
            MessagesDataCode<string> result = new MessagesDataCode<string>(false, "无效的参数", -300);
            if (model != null)
            {
                try
                {
                    Pingpp.Pingpp.SetApiKey("sk_live_v5KiDKS0Wz1Cnv5Oa19ebrTS"); //sk_test_zvHePSeH0SuHLqP4SGaPKWDS
                    string appId = "app_4WzfvTm9CGi1eLO0";
                    string ip = HttpContext.Current.Request.UserHostAddress;
                    logger.Error("支付获取到的Ip地址为:" + ip);
                    string OrderNum = DateTime.Now.ToString("yyyyMMddHHmmss") + new Random().Next(1, 1000); //唯一订单号
                    int UserId = ADT.Cache.Cache.CAC.Instance.GetUseridBySession(); //用户id                 
                    var chParams = new Dictionary<string, object>
            {
                // 推荐使用 8-20 位,要求数字或字母,不允许其他字符
                {"order_no",OrderNum },
                // 订单总金额, 人民币单位:分(如订单总金额为 1 元,此处请填 100)
                {"amount",1},
                // 支付使用的第三方支付渠道取值,请参考: https://www.pingxx.com/api#支付渠道属性值
                {"channel", model.channel},
                // 3 位 ISO 货币代码,人民币为  cny 。
                {"currency", "cny"},
                // 商品标题,该参数最长为 32 个 Unicode 字符,银联全渠道( upacp / upacp_wap )限制在 32 个字节。
                {"subject", model.subject},
                // 商品描述信息,该参数最长为 128 个 Unicode 字符, yeepay_wap 对于该参数长度限制为 100 个 Unicode 字符。
                {"body", model.body},
                // 发起支付请求客户端的 IP 地址,格式为 IPV4,如: 127.0.0.1
                {"client_ip",ip},
                {"app", new Dictionary<string, string> {{"id", appId}}},
                // 特定渠道发起交易时需要的额外参数,以及部分渠道支付成功返回的额外参数,详细参考 https://www.pingxx.com/api#支付渠道-extra-参数说明
                {"extra", new Dictionary<string,object>{
                    // 可选,开放平台返回的包含账户信息的 token(授权令牌,商户在一定时间内对支付宝某些服务的访问权限)。通过授权登录后获取的  alipay_open_id ,作为该参数的  value ,登录授权账户即会为支付账户,32 位字符串。
                    //{"extern_token", ""},
                    // 可选,是否发起实名校验,T 代表发起实名校验;F 代表不发起实名校验。
                    {"rn_check",'T'}
                }},
                // 可选:订单失效时间,用 Unix 时间戳表示。时间范围在订单创建后的 1 分钟到 15 天,默认为 1 天,创建时间以 Ping++ 服务器时间为准。 微信对该参数的有效值限制为 2 小时内;银联对该参数的有效值限制为 1 小时内。
                {"time_expire", CreateBase64.timeExpire()},
                // 可选:订单附加说明,最多 255 个 Unicode 字符。
                {"description",model.description}
            };

                    var ch = Charge.Create(chParams);
                    var test = JsonConvert.SerializeObject(ch);
                    result.Data = test;
                    result.Success = true;
                    result.Code = 0;
                    result.Msg = "成功获取支付凭据";


                    //在这里生成订单
                    PayLogBean PayModel = new PayLogBean();
                    PayModel.PayNo = OrderNum;
                    PayModel.PayTime = DateTime.Now;
                    PayModel.Type = model.channel;
                    PayModel.Valid = false;
                    PayModel.UserId = UserId;
                    PayModel.ChangeNum = model.ChangeNum;
                    PayModel.OrderType = model.OrderType;
                    if (!new PayLog().Add(PayModel))
                    {
                        logger.Error("创建订单失败,该用户Id为" + UserId);
                    }

                }

                catch (Exception ex)
                {
                    logger.Error("创建支付凭据对象发生异常:" + ex);
                }
            }            
            return result;
        }

验证签名

  public static class RSACryptoServiceProviderExtension
    {
        private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        public static bool VerifySignedHash(string strDataToVerify, string strSignedData, string strPublicKeyFilePath)
        {
            byte[] signedData = Convert.FromBase64String(strSignedData); //加密过的签名

            UTF8Encoding ByteConverter = new UTF8Encoding();          
            
            byte[] dataToVerify = ByteConverter.GetBytes(strDataToVerify);//源数据,使用相同的算法进行消息摘要 ,和解密后的签名比较
            try
            {
                string sPublicKeyPem = File.ReadAllText(strPublicKeyFilePath);                
                RSACryptoServiceProvider rsa = new RSACryptoServiceProvider { PersistKeyInCsp = false };             
                rsa.LoadPublicKeyPEM(sPublicKeyPem);
                if (rsa.VerifyData(dataToVerify, "SHA256", signedData))
                {
                    return true;
                }
             
            }
            catch (CryptographicException e)
            {              
                logger.Error(e.Message);
                
            }
            return false;

        }
        #region Methods

        /// <summary>Extension method which initializes an RSACryptoServiceProvider from a DER public key blob.</summary>  
        public static void LoadPublicKeyDER(this RSACryptoServiceProvider provider, byte[] DERData)
        {
            byte[] RSAData = RSACryptoServiceProviderExtension.GetRSAFromDER(DERData);
            byte[] publicKeyBlob = RSACryptoServiceProviderExtension.GetPublicKeyBlobFromRSA(RSAData);
            provider.ImportCspBlob(publicKeyBlob);
        }

        /// <summary>Extension method which initializes an RSACryptoServiceProvider from a DER private key blob.</summary>  
        public static void LoadPrivateKeyDER(this RSACryptoServiceProvider provider, byte[] DERData)
        {
            byte[] privateKeyBlob = RSACryptoServiceProviderExtension.GetPrivateKeyDER(DERData);
            provider.ImportCspBlob(privateKeyBlob);
        }

        /// <summary>Extension method which initializes an RSACryptoServiceProvider from a PEM public key string.</summary>  
        public static void LoadPublicKeyPEM(this RSACryptoServiceProvider provider, string sPEM)
        {
            byte[] DERData = RSACryptoServiceProviderExtension.GetDERFromPEM(sPEM);
            RSACryptoServiceProviderExtension.LoadPublicKeyDER(provider, DERData);
        }

        /// <summary>Extension method which initializes an RSACryptoServiceProvider from a PEM private key string.</summary>  
        public static void LoadPrivateKeyPEM(this RSACryptoServiceProvider provider, string sPEM)
        {
            byte[] DERData = RSACryptoServiceProviderExtension.GetDERFromPEM(sPEM);
            RSACryptoServiceProviderExtension.LoadPrivateKeyDER(provider, DERData);
        }

        /// <summary>Returns a public key blob from an RSA public key.</summary>  
        internal static byte[] GetPublicKeyBlobFromRSA(byte[] RSAData)
        {
            byte[] data = null;
            UInt32 dwCertPublicKeyBlobSize = 0;
            if (RSACryptoServiceProviderExtension.CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING,
                new IntPtr((int)CRYPT_OUTPUT_TYPES.RSA_CSP_PUBLICKEYBLOB), RSAData, (UInt32)RSAData.Length, CRYPT_DECODE_FLAGS.NONE,
                data, ref dwCertPublicKeyBlobSize))
            {
                data = new byte[dwCertPublicKeyBlobSize];
                if (!RSACryptoServiceProviderExtension.CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING,
                    new IntPtr((int)CRYPT_OUTPUT_TYPES.RSA_CSP_PUBLICKEYBLOB), RSAData, (UInt32)RSAData.Length, CRYPT_DECODE_FLAGS.NONE,
                    data, ref dwCertPublicKeyBlobSize))
                    throw new Win32Exception(Marshal.GetLastWin32Error());
            }
            else
                throw new Win32Exception(Marshal.GetLastWin32Error());
            return data;
        }

        /// <summary>Converts DER binary format to a CAPI CRYPT_PRIVATE_KEY_INFO structure.</summary>  
        internal static byte[] GetPrivateKeyDER(byte[] DERData)
        {
            byte[] data = null;
            UInt32 dwRSAPrivateKeyBlobSize = 0;
            IntPtr pRSAPrivateKeyBlob = IntPtr.Zero;
            if (RSACryptoServiceProviderExtension.CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING, new IntPtr((int)CRYPT_OUTPUT_TYPES.PKCS_RSA_PRIVATE_KEY),
                DERData, (UInt32)DERData.Length, CRYPT_DECODE_FLAGS.NONE, data, ref dwRSAPrivateKeyBlobSize))
            {
                data = new byte[dwRSAPrivateKeyBlobSize];
                if (!RSACryptoServiceProviderExtension.CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING, new IntPtr((int)CRYPT_OUTPUT_TYPES.PKCS_RSA_PRIVATE_KEY),
                    DERData, (UInt32)DERData.Length, CRYPT_DECODE_FLAGS.NONE, data, ref dwRSAPrivateKeyBlobSize))
                    throw new Win32Exception(Marshal.GetLastWin32Error());
            }
            else
                throw new Win32Exception(Marshal.GetLastWin32Error());
            return data;
        }

        /// <summary>Converts DER binary format to a CAPI CERT_PUBLIC_KEY_INFO structure containing an RSA key.</summary>  
        internal static byte[] GetRSAFromDER(byte[] DERData)
        {
            byte[] data = null;
            byte[] publicKey = null;
            CERT_PUBLIC_KEY_INFO info;
            UInt32 dwCertPublicKeyInfoSize = 0;
            IntPtr pCertPublicKeyInfo = IntPtr.Zero;
            if (RSACryptoServiceProviderExtension.CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING, new IntPtr((int)CRYPT_OUTPUT_TYPES.X509_PUBLIC_KEY_INFO),
                DERData, (UInt32)DERData.Length, CRYPT_DECODE_FLAGS.NONE, data, ref dwCertPublicKeyInfoSize))
            {
                data = new byte[dwCertPublicKeyInfoSize];
                if (RSACryptoServiceProviderExtension.CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING, new IntPtr((int)CRYPT_OUTPUT_TYPES.X509_PUBLIC_KEY_INFO),
                    DERData, (UInt32)DERData.Length, CRYPT_DECODE_FLAGS.NONE, data, ref dwCertPublicKeyInfoSize))
                {
                    GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
                    try
                    {
                        info = (CERT_PUBLIC_KEY_INFO)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(CERT_PUBLIC_KEY_INFO));
                        publicKey = new byte[info.PublicKey.cbData];
                        Marshal.Copy(info.PublicKey.pbData, publicKey, 0, publicKey.Length);
                    }
                    finally
                    {
                        handle.Free();
                    }
                }
                else
                    throw new Win32Exception(Marshal.GetLastWin32Error());
            }
            else
                throw new Win32Exception(Marshal.GetLastWin32Error());
            return publicKey;
        }

        /// <summary>Extracts the binary data from a PEM file.</summary>  
        internal static byte[] GetDERFromPEM(string sPEM)
        {
            UInt32 dwSkip, dwFlags;
            UInt32 dwBinarySize = 0;

            if (!RSACryptoServiceProviderExtension.CryptStringToBinary(sPEM, (UInt32)sPEM.Length, CRYPT_STRING_FLAGS.CRYPT_STRING_BASE64HEADER, null, ref dwBinarySize, out dwSkip, out dwFlags))
                throw new Win32Exception(Marshal.GetLastWin32Error());

            byte[] decodedData = new byte[dwBinarySize];
            if (!RSACryptoServiceProviderExtension.CryptStringToBinary(sPEM, (UInt32)sPEM.Length, CRYPT_STRING_FLAGS.CRYPT_STRING_BASE64HEADER, decodedData, ref dwBinarySize, out dwSkip, out dwFlags))
                throw new Win32Exception(Marshal.GetLastWin32Error());
            return decodedData;
        }

        #endregion Methods

        #region P/Invoke Constants

        /// <summary>Enumeration derived from Crypto API.</summary>  
        internal enum CRYPT_ACQUIRE_CONTEXT_FLAGS : uint
        {
            CRYPT_NEWKEYSET = 0x8,
            CRYPT_DELETEKEYSET = 0x10,
            CRYPT_MACHINE_KEYSET = 0x20,
            CRYPT_SILENT = 0x40,
            CRYPT_DEFAULT_CONTAINER_OPTIONAL = 0x80,
            CRYPT_VERIFYCONTEXT = 0xF0000000
        }

        /// <summary>Enumeration derived from Crypto API.</summary>  
        internal enum CRYPT_PROVIDER_TYPE : uint
        {
            PROV_RSA_FULL = 1
        }

        /// <summary>Enumeration derived from Crypto API.</summary>  
        internal enum CRYPT_DECODE_FLAGS : uint
        {
            NONE = 0,
            CRYPT_DECODE_ALLOC_FLAG = 0x8000
        }

        /// <summary>Enumeration derived from Crypto API.</summary>  
        internal enum CRYPT_ENCODING_FLAGS : uint
        {
            PKCS_7_ASN_ENCODING = 0x00010000,
            X509_ASN_ENCODING = 0x00000001,
        }

        /// <summary>Enumeration derived from Crypto API.</summary>  
        internal enum CRYPT_OUTPUT_TYPES : int
        {
            X509_PUBLIC_KEY_INFO = 8,
            RSA_CSP_PUBLICKEYBLOB = 19,
            PKCS_RSA_PRIVATE_KEY = 43,
            PKCS_PRIVATE_KEY_INFO = 44
        }

        /// <summary>Enumeration derived from Crypto API.</summary>  
        internal enum CRYPT_STRING_FLAGS : uint
        {
            CRYPT_STRING_BASE64HEADER = 0,
            CRYPT_STRING_BASE64 = 1,
            CRYPT_STRING_BINARY = 2,
            CRYPT_STRING_BASE64REQUESTHEADER = 3,
            CRYPT_STRING_HEX = 4,
            CRYPT_STRING_HEXASCII = 5,
            CRYPT_STRING_BASE64_ANY = 6,
            CRYPT_STRING_ANY = 7,
            CRYPT_STRING_HEX_ANY = 8,
            CRYPT_STRING_BASE64X509CRLHEADER = 9,
            CRYPT_STRING_HEXADDR = 10,
            CRYPT_STRING_HEXASCIIADDR = 11,
            CRYPT_STRING_HEXRAW = 12,
            CRYPT_STRING_NOCRLF = 0x40000000,
            CRYPT_STRING_NOCR = 0x80000000
        }

        #endregion P/Invoke Constants

        #region P/Invoke Structures

        /// <summary>Structure from Crypto API.</summary>  
        [StructLayout(LayoutKind.Sequential)]
        internal struct CRYPT_OBJID_BLOB
        {
            internal UInt32 cbData;
            internal IntPtr pbData;
        }

        /// <summary>Structure from Crypto API.</summary>  
        [StructLayout(LayoutKind.Sequential)]
        internal struct CRYPT_ALGORITHM_IDENTIFIER
        {
            internal IntPtr pszObjId;
            internal CRYPT_OBJID_BLOB Parameters;
        }

        /// <summary>Structure from Crypto API.</summary>  
        [StructLayout(LayoutKind.Sequential)]
        struct CRYPT_BIT_BLOB
        {
            internal UInt32 cbData;
            internal IntPtr pbData;
            internal UInt32 cUnusedBits;
        }

        /// <summary>Structure from Crypto API.</summary>  
        [StructLayout(LayoutKind.Sequential)]
        struct CERT_PUBLIC_KEY_INFO
        {
            internal CRYPT_ALGORITHM_IDENTIFIER Algorithm;
            internal CRYPT_BIT_BLOB PublicKey;
        }

        #endregion P/Invoke Structures

        #region P/Invoke Functions

        /// <summary>Function for Crypto API.</summary>  
        [DllImport("advapi32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool CryptDestroyKey(IntPtr hKey);

        /// <summary>Function for Crypto API.</summary>  
        [DllImport("advapi32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool CryptImportKey(IntPtr hProv, byte[] pbKeyData, UInt32 dwDataLen, IntPtr hPubKey, UInt32 dwFlags, ref IntPtr hKey);

        /// <summary>Function for Crypto API.</summary>  
        [DllImport("advapi32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool CryptReleaseContext(IntPtr hProv, Int32 dwFlags);

        /// <summary>Function for Crypto API.</summary>  
        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool CryptAcquireContext(ref IntPtr hProv, string pszContainer, string pszProvider, CRYPT_PROVIDER_TYPE dwProvType, CRYPT_ACQUIRE_CONTEXT_FLAGS dwFlags);

        /// <summary>Function from Crypto API.</summary>  
        [DllImport("crypt32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool CryptStringToBinary(string sPEM, UInt32 sPEMLength, CRYPT_STRING_FLAGS dwFlags, [Out] byte[] pbBinary, ref UInt32 pcbBinary, out UInt32 pdwSkip, out UInt32 pdwFlags);

        /// <summary>Function from Crypto API.</summary>  
        [DllImport("crypt32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool CryptDecodeObjectEx(CRYPT_ENCODING_FLAGS dwCertEncodingType, IntPtr lpszStructType, byte[] pbEncoded, UInt32 cbEncoded, CRYPT_DECODE_FLAGS dwFlags, IntPtr pDecodePara, ref byte[] pvStructInfo, ref UInt32 pcbStructInfo);

        /// <summary>Function from Crypto API.</summary>  
        [DllImport("crypt32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool CryptDecodeObject(CRYPT_ENCODING_FLAGS dwCertEncodingType, IntPtr lpszStructType, byte[] pbEncoded, UInt32 cbEncoded, CRYPT_DECODE_FLAGS flags, [In, Out] byte[] pvStructInfo, ref UInt32 cbStructInfo);

        #endregion P/Invoke Functions
    }

 

接受支付结果(异步)

 public HttpResponseMessage Index()
        {
            MessagesCode result = new MessagesCode(false, "无效的参数", -300);
            try
            {

                if (HttpContext.Current.Request.RequestType.ToUpper().Equals("POST"))
                {
                    //获取 post 的 event对象 
                    var inputData = ReadStream(HttpContext.Current.Request.InputStream);
                    //获取 header 中的签名
                    var sig = HttpContext.Current.Request.Headers.Get("x-pingplusplus-signature");

                    //公钥路径(请检查你的公钥 .pem 文件存放路径)

                    var path = HttpContext.Current.Server.MapPath("/Lib/public_key.pem");

                    //验证签名  
                    if (RSACryptoServiceProviderExtension.VerifySignedHash(inputData, sig, path))
                    {

                        var jObject = JObject.Parse(inputData);
                        var type = jObject.SelectToken("type");
                        var eventType = jObject.SelectToken("object");
                        if (eventType.ToString() == "event")//验证接收到的是否为 Event 对象。
                        {
                            if (type.ToString() == "charge.succeeded")
                            {   //在这里做支付成功的逻辑处理 1.订单状态改变 2.支付目的改变 3.这里要限制一下更新的次数,只有当订单是未支付时在进行下面的操作
                                var data = jObject.SelectToken("data");
                                var credentialObject = data["object"];//凭据对象 
                                var PayNo = credentialObject["order_no"];//订单号
                                logger.Error("接受到支付成功的事件");
                                bool IsOk = false;
                                PayLogBean model = new PayLog().GetModelById(PayNo.ToString());
                                if (model != null)
                                {
                                    if (model.Valid)
                                    {
                                        IsOk = true;
                                    }
                                    else
                                    {
                                        using (TransactionScope ts = new TransactionScope())
                                        {
                                            bool OneTrans = false;
                                            bool TwoTrans = false;
                                            OneTrans = new PayLog().UpdateValid(PayNo.ToString(), true);
                                            UserBean userModel = new User().GetModelById((int)model.UserId);                                         
                                            if (userModel != null)
                                            {
                                                if (model.OrderType ==1)
                                                {
                                                  
                                                    if (Convert.IsDBNull(userModel.Ranketime)|| userModel.RankId==1)//一定不是会员
                                                    {
                                                   
                                                        userModel.Rankbtime = DateTime.Now;
                                                        userModel.Ranketime = DateTime.Now.AddMonths((int)model.ChangeNum);                                                        
                                                        userModel.RankId = 2;
                                                    }
                                                    else
                                                    {//代表历史上是有会员的记录的
                                                     //判断当前是否为会员
                                                        if (userModel.RankId == 2 && userModel.Ranketime >= DateTime.Now)
                                                        {
                                                            userModel.Ranketime = userModel.Ranketime.AddMonths((int)model.ChangeNum);                                                            
                                                        }
                                                        else
                                                        {
                                                            userModel.RankId = 2;
                                                            userModel.Ranketime = DateTime.Now.AddMonths((int)model.ChangeNum);
                                                            userModel.Ranketime = DateTime.Now;
                                                          
                                                        }
                                                        
                                                    }
                                                    //更新用户信息
                                                    TwoTrans = new User().UpdateMemRoleByRMB(userModel);
                                                }
                                                else
                                                {
                                                   
                                                    userModel.Currency = userModel.Currency + model.ChangeNum;                                                  
                                                    TwoTrans = new User().UpdateCurrency(model.UserId, userModel.Currency);
                                                }
                                            }
                                            if (OneTrans&&TwoTrans)
                                            {
                                              
                                                IsOk = true;
                                                ts.Complete();
                                              
                                            }

                                        }
                                    }
                                }
                                if (IsOk)
                                {
                                    //在这里写日志
                                    if (model.OrderType == 1) //购买会员
                                    {
                                        //在这里加一个消费日志
                                        //需要拿这个有效时间去获得人民币的价格是多少
                                        List<ProductBean> productList = new Product().GetAllList().Where(p => p.ValidTime == model.ChangeNum).ToList();
                                        if (productList.Count > 0)
                                        {
                                            CreateBase64.CreateReclog(7, "人民币购买会员", Convert.ToInt64(productList[0].ProdutPrice), (int)model.UserId);
                                        }

                                    }
                                    else
                                    {//购买虚拟币
                                        CreateBase64.CreateReclog(2, "充虚拟币", model.ChangeNum, (int)model.UserId);
                                    }
                                    return Request.CreateResponse(HttpStatusCode.OK, "接受成功");
                                }

                            }
                        }

                    }

                }
            }

            catch (Exception ex)
            {
                logger.Error("接受ping++的支付订单消息发生异常:" + ex);
            }
            return Request.CreateResponse(HttpStatusCode.InternalServerError, "接受失败");

        }
        private static string ReadStream(Stream stream)
        {
            using (var reader = new StreamReader(stream, Encoding.UTF8))
            {
                return reader.ReadToEnd();
            }
        }

根据订单号获取支付状态

 /// <summary>
        /// 根据订单号获取支付状态
        /// </summary>
        /// <param name="order_no"></param>
        /// <returns></returns>
        [HttpGet]
        public MessagesDataCode<bool> GetOrderStatus(string order_no)
        {
            MessagesDataCode<bool> result = new MessagesDataCode<bool>(false, "无效的参数", -300);
            try
            {
                PayLogBean model = new PayLog().GetModelById(order_no);
                if (model != null)
                {
                    result.Data = model.Valid;
                    result.Code = 0;
                    result.Msg = "成功获取到订单状态";
                    result.Success = true;
                }
            }
            catch (Exception ex)
            {
                logger.Error("获取订单状态发生异常:"+ex);
            }
            return result;
        }