using System;
using System.Collections.Generic;
using Library;
using LitJson;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography;
using System.Text;
using System.IO;
using System.Net;
using MySystem.PxcModels;

namespace MySystem
{
    public class WeChatFunction
    {
        public WeChatFunction()
        {
        }


        #region 服务商平台商户进件提交申请单API

        public string MerchantCreate(PxcModels.MerchantAddInfo info, PxcModels.MerchantInfo merchant)
        {
            // pubkey = GetPublicKey();

            Dictionary<string, object> result = new Dictionary<string, object>();
            result.Add("business_code", info.BusinessCode); //业务申请编号

            PxcModels.WebCMSEntities dbpxc = new PxcModels.WebCMSEntities();
            //超级管理员信息
            Dictionary<string, object> contact_info = new Dictionary<string, object>();
            contact_info.Add("contact_name", RSAEncrypt(info.ContactName)); //超级管理员姓名
            contact_info.Add("contact_id_number", RSAEncrypt(info.ContactIdNumber)); //超级管理员身份证件号码
            // contact_info.Add("openid", info.OpenId); //超级管理员微信openid
            contact_info.Add("mobile_phone", RSAEncrypt(info.MobilePhone)); //联系手机
            contact_info.Add("contact_email", RSAEncrypt(info.ContactEmail)); //联系邮箱
            result.Add("contact_info", contact_info);

            //主体资料
            Dictionary<string, object> subject_info = new Dictionary<string, object>();
            subject_info.Add("subject_type", info.SubjectType); //主体类型

            Dictionary<string, object> business_license_info = new Dictionary<string, object>();
            business_license_info.Add("license_copy", GetMediaId("/bsserver_com" + info.LicenseCopy)); //营业执照照片
            business_license_info.Add("license_number", info.LicenseNumber); //注册号/统一社会信用代码
            business_license_info.Add("merchant_name", merchant.Name); //商户名称
            business_license_info.Add("legal_person", info.LegalPerson); //个体户经营者/法人姓名
            subject_info.Add("business_license_info", business_license_info); //营业执照

            // Dictionary<string, object> certificate_info = new Dictionary<string, object>();
            // certificate_info.Add("cert_copy", GetMediaId("/bsserver_com" + info.CertCopy)); //登记证书照片
            // certificate_info.Add("cert_type", info.CertType); //登记证书类型
            // certificate_info.Add("cert_number", info.CertNumber); //证书号
            // certificate_info.Add("merchant_name", info.CertMerchantName); //商户名称
            // certificate_info.Add("company_address", info.CompanyAddress); //注册地址
            // certificate_info.Add("legal_person", info.CertLegalPerson); //法人姓名
            // certificate_info.Add("period_begin", CheckForever(info.PeriodBegin)); //有效期限开始日期
            // certificate_info.Add("period_end", CheckForever(info.PeriodEnd)); //有效期限结束日期
            // subject_info.Add("certificate_info", certificate_info); //登记证书

            // Dictionary<string, object> organization_info = new Dictionary<string, object>();
            // organization_info.Add("organization_copy", GetMediaId("/bsserver_com" + info.OrganizationCopy)); //组织机构代码证照片
            // organization_info.Add("organization_code", info.OrganizationCode); //组织机构代码
            // organization_info.Add("org_period_begin", CheckForever(info.OrgPeriodBegin)); //组织机构代码证有效期开始日期
            // organization_info.Add("org_period_end", CheckForever(info.OrgPeriodEnd)); //组织机构代码证有效期结束日期
            // subject_info.Add("organization_info", organization_info); //组织机构代码证

            // subject_info.Add("certificate_letter_copy", GetMediaId("/bsserver_com" + info.CertificateLetterCopy)); //单位证明函照片

            Dictionary<string, object> identity_info = new Dictionary<string, object>();
            info.IdDocType = "IDENTIFICATION_TYPE_IDCARD";
            identity_info.Add("id_doc_type", info.IdDocType); //证件类型
            Dictionary<string, object> id_card_info = new Dictionary<string, object>();
            id_card_info.Add("id_card_copy", GetMediaId("/bsserver_com" + info.IdCardCopy)); //身份证人像面照片
            id_card_info.Add("id_card_national", GetMediaId("/bsserver_com" + info.IdCardNational)); //身份证人像面照片
            id_card_info.Add("id_card_name", RSAEncrypt(info.IdCardName)); //身份证姓名
            id_card_info.Add("id_card_number", RSAEncrypt(info.IdCardNumber)); //身份证号码
            id_card_info.Add("card_period_begin", CheckForever(info.CardPeriodBegin)); //身份证有效期开始时间
            id_card_info.Add("card_period_end", CheckForever(info.CardPeriodEnd)); //身份证有效期结束时间
            identity_info.Add("id_card_info", id_card_info); //身份证信息
            // identity_info.Add("owner", info.Owner == 1 ? true : false); //经营者/法人是否为受益人
            identity_info.Add("owner", true);
            subject_info.Add("identity_info", identity_info); //经营者/法人身份证件

            // if (info.Owner == 0)
            // {
            //     Dictionary<string, object> ubo_info = new Dictionary<string, object>();
            //     ubo_info.Add("id_type", info.UboInfoIdType); //证件类型
            //     ubo_info.Add("id_card_copy", GetMediaId("/bsserver_com" + info.UboInfoIdCardCopy)); //身份证人像面照片
            //     ubo_info.Add("id_card_national", GetMediaId("/bsserver_com" + info.UboInfoIdCardNational)); //身份证国徽面照片
            //     ubo_info.Add("id_doc_copy", GetMediaId("/bsserver_com" + info.UboInfoIdDocCopy)); //证件照片
            //     ubo_info.Add("name", RSAEncrypt(info.UboInfoName)); //受益人姓名
            //     ubo_info.Add("id_number", RSAEncrypt(info.UboInfoIdNumber)); //证件号码
            //     ubo_info.Add("id_period_begin", CheckForever(info.UboInfoIdPeriodBegin)); //证件有效期开始时间
            //     ubo_info.Add("id_period_end", CheckForever(info.UboInfoIdPeriodEnd)); //证件有效期结束时间
            //     subject_info.Add("ubo_info", ubo_info); //最终受益人信息(UBO)
            // }

            result.Add("subject_info", subject_info);

            //经营资料
            Dictionary<string, object> business_info = new Dictionary<string, object>();
            business_info.Add("merchant_shortname", info.MerchantShortname); //商户简称
            business_info.Add("service_phone", info.ServicePhone); //客服电话

            Dictionary<string, object> sales_info = new Dictionary<string, object>();
            info.SalesScenesType = "SALES_SCENES_STORE";
            sales_info.Add("sales_scenes_type", info.SalesScenesType.Split(',').ToList()); //经营场景类型

            Dictionary<string, object> biz_store_info = new Dictionary<string, object>();
            biz_store_info.Add("biz_store_name", info.BizStoreName); //门店名称
            PxcModels.OpenBankCityTable BizAddress = dbpxc.OpenBankCityTable.FirstOrDefault(m => m.CityName.EndsWith(info.BizAddressCode)) ?? new PxcModels.OpenBankCityTable();
            biz_store_info.Add("biz_address_code", BizAddress.Code); //门店省市编码
            biz_store_info.Add("biz_store_address", info.BizStoreAddress); //门店地址
            List<string> store_entrance_pic = new List<string>();
            store_entrance_pic.Add(GetMediaId("/bsserver_com" + info.StoreEntrancePic));
            biz_store_info.Add("store_entrance_pic", store_entrance_pic); //门店门头照片
            List<string> indoor_pic = new List<string>();
            indoor_pic.Add(GetMediaId("/bsserver_com" + info.IndoorPic));
            biz_store_info.Add("indoor_pic", indoor_pic); //店内环境照片
            biz_store_info.Add("biz_sub_appid", info.BizSubAppid); //线下场所对应的商家APPID
            sales_info.Add("biz_store_info", biz_store_info); //线下门店场景

            // Dictionary<string, object> mp_info = new Dictionary<string, object>();
            // mp_info.Add("mp_appid", info.MpAppid); //服务商公众号APPID
            // mp_info.Add("mp_sub_appid", info.MpSubAppid); //商家公众号APPID
            // mp_info.Add("mp_pics", GetMediaId("/bsserver_com" + info.MpPics)); //公众号页面截图
            // sales_info.Add("mp_info", mp_info); //公众号场景

            // Dictionary<string, object> mini_program_info = new Dictionary<string, object>();
            // mini_program_info.Add("mini_program_appid", info.MiniProgramAppid); //服务商小程序APPID
            // mini_program_info.Add("mini_program_sub_appid", info.MiniProgramSubAppid); //商家小程序APPID
            // mini_program_info.Add("mini_program_pics", GetMediaId("/bsserver_com" + info.MiniProgramPics)); //小程序截图
            // sales_info.Add("mini_program_info", mini_program_info); //小程序场景

            // Dictionary<string, object> app_info = new Dictionary<string, object>();
            // app_info.Add("app_appid", info.AppAppid); //服务商应用APPID
            // app_info.Add("app_sub_appid", info.AppSubAppid); //商家应用APPID
            // app_info.Add("app_pics", GetMediaId("/bsserver_com" + info.AppPics)); //商家应用APPID
            // sales_info.Add("app_info", app_info); //APP场景

            // Dictionary<string, object> web_info = new Dictionary<string, object>();
            // web_info.Add("domain", info.WebDomain); //互联网网站域名
            // web_info.Add("web_authorisation", GetMediaId("/bsserver_com" + info.WebAuthorisation)); //网站授权函
            // web_info.Add("web_appid", info.WebAppId); //互联网网站对应的商家APPID
            // sales_info.Add("web_info", web_info); //互联网网站场景

            // Dictionary<string, object> wework_info = new Dictionary<string, object>();
            // wework_info.Add("sub_corp_id", info.SubCorpId); //商家企业微信CorpID
            // wework_info.Add("wework_pics", GetMediaId("/bsserver_com" + info.WeworkPics)); //企业微信页面截图
            // sales_info.Add("wework_info", wework_info); //企业微信场景

            business_info.Add("sales_info", sales_info); //经营场景

            result.Add("business_info", business_info);

            //结算规则
            Dictionary<string, object> settlement_info = new Dictionary<string, object>();
            settlement_info.Add("settlement_id", info.SettlementId); //入驻结算规则ID
            string QualificationType = function.CheckNull(info.QualificationType);
            if (QualificationType.Contains(","))
            {
                QualificationType = QualificationType.Split(',')[0];
            }
            settlement_info.Add("qualification_type", QualificationType); //所属行业
            if (!string.IsNullOrEmpty(info.Qualifications))
            {
                List<string> Qualifications = new List<string>();
                Qualifications.Add(GetMediaId("/bsserver_com" + info.Qualifications));
                settlement_info.Add("qualifications", Qualifications); //特殊资质图片
            }
            settlement_info.Add("activities_id", info.ActivitiesId); //优惠费率活动ID
            settlement_info.Add("activities_rate", info.ActivitiesRate); //优惠费率活动值
            result.Add("settlement_info", settlement_info);

            //结算银行账户
            Dictionary<string, object> bank_account_info = new Dictionary<string, object>();
            bank_account_info.Add("bank_account_type", info.BankAccountType); //账户类型
            bank_account_info.Add("account_name", RSAEncrypt(info.AccountName)); //开户名称
            bank_account_info.Add("account_bank", info.AccountBank); //开户银行
            PxcModels.OpenBankCityTable BankAddress = dbpxc.OpenBankCityTable.FirstOrDefault(m => m.CityName.EndsWith(info.BankAddressCode)) ?? new PxcModels.OpenBankCityTable();
            bank_account_info.Add("bank_address_code", BankAddress.Code); //开户银行省市编码
            PxcModels.OpenBankTable BankBranch = dbpxc.OpenBankTable.FirstOrDefault(m => m.BankName == info.BankName) ?? new PxcModels.OpenBankTable();
            bank_account_info.Add("bank_branch_id", BankBranch.BankCode); //开户银行联行号
            bank_account_info.Add("bank_name", info.BankName); //开户银行全称（含支行）
            bank_account_info.Add("account_number", RSAEncrypt(info.AccountNumber)); //银行账号
            result.Add("bank_account_info", bank_account_info);
            dbpxc.Dispose();

            string req = Newtonsoft.Json.JsonConvert.SerializeObject(result);
            Dictionary<string, string> header = new Dictionary<string, string>();
            // 如何查看证书序列号？
            // 登陆商户平台【API安全】->【API证书】->【查看证书】，可查看商户API证书序列号。
            // 商户API证书和微信支付平台证书均可以使用第三方的证书解析工具，查看证书内容。或者使用openssl命令行工具查看证书序列号。
            // $ openssl x509 -in 1900009191_20180326_cert.pem -noout -serial
            // serial=1DDE55AD98ED71D6EDD4A4A16996DE7B47773A8C
            string merchantId = "1611167423";   //商户号
            string serialNo = "534165421BE2814DEC08F8D00BDAB9944B13646C";  //证书编号
            string resp = postJson("https://api.mch.weixin.qq.com/v3/applyment4sub/applyment/", req, prikey, merchantId, serialNo);
            function.WriteLog(resp, "商户进件日志");
            return resp;
        }

        #endregion

        #region 服务商平台查询申请单状态API

        public Dictionary<string, object> QueryMerchant(string BusinessCode)
        {
            Dictionary<string, object> return_result = new Dictionary<string, object>();
            try
            {
                string merchantId = "1611167423";   //商户号
                string serialNo = "534165421BE2814DEC08F8D00BDAB9944B13646C";  //证书编号
                string result = postJson("https://api.mch.weixin.qq.com/v3/applyment4sub/applyment/business_code/" + BusinessCode, "", prikey, merchantId, serialNo, "GET");
                function.WriteLog(result, "服务商平台查询申请单状态API");
                //{\"applyment_id\":2000002247709762,\"applyment_state\":\"APPLYMENT_STATE_FINISHED\",\"applyment_state_msg\":\"商户入驻申请已完成\",\"audit_detail\":[],\"business_code\":\"0123456789\",\"sign_url\":\"https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=gQFv7zwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyUXE1czkzb3JlUjIxZHpXbTF5Y2YAAgRjbe9hAwQAjScA\",\"sub_mchid\":\"1619775262\"}
                JsonData jsonObj = JsonMapper.ToObject(result);
                return_result.Add("applyment_id", jsonObj["applyment_id"].ToString()); //微信支付申请单号
                return_result.Add("applyment_state", jsonObj["applyment_state"].ToString()); //申请单状态
                return_result.Add("applyment_state_msg", jsonObj["applyment_state_msg"].ToString()); //申请状态描述
                if (jsonObj["applyment_state"].ToString() == "APPLYMENT_STATE_REJECTED")
                {
                    List<Dictionary<string, string>> audit_detail = new List<Dictionary<string, string>>();
                    JsonData auditObj = jsonObj["audit_detail"]; //驳回原因详情
                    // for (int i = 0; i < auditObj.Count; i++)
                    // {
                    //     Dictionary<string, string> row = new Dictionary<string, string>();
                    //     // row.Add("field", auditObj[i]["field"].ToString()); //字段名
                    //     // row.Add("field_name", auditObj[i]["field_name"].ToString()); //字段名称
                    //     row.Add("reject_reason", auditObj[i]["reject_reason"].ToString()); //驳回原因
                    //     audit_detail.Add(row);
                    // }
                    return_result.Add("reject_reason", auditObj[0]["reject_reason"].ToString());
                    return_result.Add("audit_detail", audit_detail); //申请状态描述
                }
                if (result.Contains("\"sign_url\":"))
                { 
                    return_result.Add("sign_url", jsonObj["sign_url"].ToString()); //进件通过申请，待商家签约的地址
                }
            }
            catch (Exception ex)
            {
                function.WriteLog(DateTime.Now.ToString() + "\r\n" + ex.ToString(), "服务商平台查询申请单状态API异常");
            }
            return return_result;
        }
        #endregion
        
        #region 服务商平台申请退款API

        public Dictionary<string, string> Refund(string AppId, string MchId, string SubMchId, decimal RefundMoney, decimal TotalMoney, string OrderNo, string RefundNo)
        {
            Dictionary<string, string> return_result = new Dictionary<string, string>();
            int refund = (int)(RefundMoney * 100);
            int amount = (int)(TotalMoney * 100);
            //具体请求参数
            SortedList<string, object> par = new SortedList<string, object>();
            par.Add("sub_mchid", SubMchId); //子商户号
            par.Add("out_trade_no", OrderNo); //商户订单号
            par.Add("out_refund_no", RefundNo); //商户退款单号
            Dictionary<string, object> amountDic = new Dictionary<string, object>();
            amountDic.Add("refund", refund); //退款金额
            amountDic.Add("total", amount); //原订单金额
            amountDic.Add("currency", "CNY"); //退款币种
            par.Add("amount", amountDic); //金额信息

            string req = Newtonsoft.Json.JsonConvert.SerializeObject(par);
            function.WriteLog(req, "服务商平台申请退款API");
            try
            {
                string merchantId = MchId;   //商户号
                string serialNo = "534165421BE2814DEC08F8D00BDAB9944B13646C";  //证书编号                
                string result = postJson("https://api.mch.weixin.qq.com/v3/refund/domestic/refunds", req, prikey, merchantId, serialNo);
                function.WriteLog(result, "服务商平台申请退款API");
                JsonData jsonObj = JsonMapper.ToObject(result);
                return_result.Add("refund_id", jsonObj["refund_id"].ToString()); //微信支付退款单号
                return_result.Add("channel", jsonObj["channel"].ToString()); //退款渠道
                return_result.Add("user_received_account", jsonObj["user_received_account"].ToString()); //退款入账账户
                return_result.Add("status", jsonObj["status"].ToString()); //退款状态
                return_result.Add("payer_total", jsonObj["amount"]["payer_total"].ToString()); //用户支付金额
                return_result.Add("payer_refund", jsonObj["amount"]["payer_refund"].ToString()); //用户退款金额
                return_result.Add("settlement_refund", jsonObj["amount"]["settlement_refund"].ToString()); //应结退款金额
                return_result.Add("settlement_total", jsonObj["amount"]["settlement_total"].ToString()); //应结订单金额
                return_result.Add("discount_refund", jsonObj["amount"]["discount_refund"].ToString()); //优惠退款金额
            }
            catch (Exception ex)
            {
                function.WriteLog(DateTime.Now.ToString() + "\r\n" + ex.ToString(), "服务商平台申请退款API异常");
            }
            return return_result;
        }
        #endregion





        #region 敏感信息加密

        // string pubkey = "MIIBCgKCAQEAxK9K2ElQ0rUMwNFW4xMx7kmkpDlp7WGQ8VffXLpudJBIrRVFWJN7dlinCGu67ZATf+/GZvLSSzQPWejHEsI9vUp9ej0x5iZDHGc9/shNUjd03ORkKo/Ohj3Ju19RzX4mh+GoinKGiuKX8CdGPXPe7UObKWyETrDcxrit6VCJQjE604aNtVeAUE+41mOpCLGzTgAKt4psfHxsBRtqlveH4cH/51ip+cGkC/u36gfDMKaRluVfFO3ETxDkI94BwNtnthcA4WDKha+wjtB6HIJ5xxHV550+cfdkl4j8UKU6pB+C5JRNgvjAf6ljg/TF+cGF1d8C6IbYYodYKloqN2DzrwIDAQAB"; //公钥
        string pubkey = "MIID3DCCAsSgAwIBAgIUU0FlQhvigU3sCPjQC9q5lEsTZGwwDQYJKoZIhvcNAQELBQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsTFFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3QgQ0EwHhcNMjEwNjMwMDMwOTA5WhcNMjYwNjI5MDMwOTA5WjBuMRgwFgYDVQQDDA9UZW5wYXkuY29tIHNpZ24xEzARBgNVBAoMClRlbnBheS5jb20xHTAbBgNVBAsMFFRlbnBheS5jb20gQ0EgQ2VudGVyMQswCQYDVQQGDAJDTjERMA8GA1UEBwwIU2hlblpoZW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC64SIwN1afgge2pjFeNZAlKz5ZdJw8W/hisaIJnkzbE/1oG5n+SgtbMLfBLBFp0zMyT5SP5ve5aJAvUjwnRwQoDG+4z3jE8vLyjFLxoy5sWGex8+FBC5hs81oAUHuazigi5NcSH9Ji/8Lq3zFh8Az4+ZchQ14SFhSGTifSZfdTX5wYDEv3DKDYgQvvAgDgjBF1Uj91NpVD7ruQjAJ7MwZvUX7rnYFnQggFQwIBWazNXaGa7OpO6Xbf+uNtbl436My7WQX+ffjmtYmcgND60mgn/rFQMg5r+Q+J8mDgIaAzCmr3xW31OIvAD1iYV0ksTyQntD5pOzCYdHZPDOZCqYlHAgMBAAGjgYEwfzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIE8DBlBgNVHR8EXjBcMFqgWKBWhlRodHRwOi8vZXZjYS5pdHJ1cy5jb20uY24vcHVibGljL2l0cnVzY3JsP0NBPTFCRDQyMjBFNTBEQkMwNEIwNkFEMzk3NTQ5ODQ2QzAxQzNFOEVCRDIwDQYJKoZIhvcNAQELBQADggEBAEgXlFe4MpFUUnj6gJt5KoPpzLTNOXDHsglUrAobq/HlmDBOF8yCUFvtbRaJxUSQVFfo/2zag8J57YNMo2If1HkD1LMEGAcPGNS+aho9SgCFbLG+c82nNICl8g8oe1HNS7IpRjacSfrKIYt5VL5lHHC5ZJaKq0Ez9c7bfPGC6CaA8WDnApFZut5qhYNMBUYZZjAMVIZ2G/kIsxbo1oUpVEnQq5YQxPUDWdYKxdTvo7uXXpWv6qo761Hid24R7mdrGEuHZNBfxYCt1wJQNlcGVgCjk8PPo73mO0zYRwV0x7pNkFFbiP7aetf6RB82YUbuNkvql83Ox+e22ByMi8lOUZo=";
        string prikey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQD7f7VmtjtLJaY+oJkMgDN9dDE082ZOgquHorPrtJNEdf7VjRFLMoKOoiQsT4OgVq3lNN2KKndd5ahsegSq7Ng7aYJq7IDH584RWEGbekEn0M10aXThdk9dPSCMXBPFR6y4gMvV4R6pVbPBxoSFMI6ty+EqfZLP9Cxvxx7msIKEB46r2R6gYL7j061ytoURavUxGAZxMXnCAEckbrssiFwhLTmX6TtC8MVPyUfLPUh07ArRZxK2F0hpX35Te0Jda7xkulbWtz4EB8KPXr0bJGO/oUo+Prqpdjy0+zKMfMvBP6NG1Hnh3z7yBhlYIe4vymFQU1Wy0OtrEbrU1OdJiq5XAgMBAAECggEAJ7biAWczc8ltOCSKJpQ0DVKE1rS86hbuWUvTF5x7SOtNI5HUMki2nylxhuHDilVFvpUbis7r7JLwhri59ffSqYcexh20tFyhiNGkApZKpavuVby1bUkOfU3CzwdXQ+bumnAUQCD9g4X6DdZ4ZMPnNACm/Nu5jEcloT0TXyBua8SpmlFMYgo/x8XOTT4dEeubwNsfEpmSeWcQRJLJI5ujGgmmZLiAs7F3VlCJFNtQa1KT3a1EDhD5jajeQAzsPpQ48i/joOqE71RlVr77z4Ethr8o1Cc16K9Md2AtVesMZ6eZNqKkQ/qC3vnxk5Sy25tuVmOCXa81ErIf9Tf/JwhymQKBgQD/TXnYxEzYJCqa7/Ck6QqBHQf4ak1OVz7/NY7bmxYT5ez4eJKzrh+xQYWBq/UmKeEiH5QI6T3MVo7L20tbeuYLQwYpgb+BpOKHFne2ODOgDYreNREB06Ww2qAQYCqwyBnTqt7UthDmcXhcPojwxNLSJAOCQhld9TOOmK1db33PIwKBgQD8L5KiN9XRFCvUH6rhUcs/8lmGR2N8zSTts+BNCwIPGQWE0UvbjroyNxVbq6cXXlZZ6H07vEAgaIrLIkwLgen2IwsuOiyaEMvRP9oGwC+LnpP+9sxbW5w5do1hfyeGiSPPgSYIWZMOOwX+qfqXDMM3whJP1hk4El87kC+kl2URPQKBgQC4kTc8ebWgMI1Ik5wibIN2khlYAum+cB6P/BU6OCU+32NwwiI0mfY5fEfbVgiVvYMP20p3Ir/VgOIdCH2zNecnTx4eVbmwLRbDWH/VEU5pMEEroauY6XyInZVIIW3bfd4GAyqzFqijIHdGIMN5ZKGQ4A5VVhnmrkTGmyQCP37xhwKBgQCaLW+Fc4NqTt240x+Cn6IWV1E6UfzV+QmBtb4E/BznJBIGsHqjIbBeMOUC5X/DPq6mSwf9dEr0RVXNeQtq4aMrEyOrwG8yReCF7naaN/cZcfrjHvmzRN/PFda766Q7kS5ul3OsGS9ZvOYeWsdUf73+Ic1WN/u1Fy5X2P/3rYNhtQKBgAIioAq8psFdy/itpJryaWdmDM6fM6ctp5P6VBWOVp2JGkOzHboiXFToJJBtmi7Rdp8AN1aYBbtVX1o0+RmfEiHqXn84GpSNT6tGirHvARi5ab3jvn+bkUWjZYOGd96hus8GirA+wQb/V92Ms3jS5VUS1HBfHaTGT5G2Slrr8YZu"; //私钥
        public string RSAEncrypt(string text)
        {
            byte[] publicKey = Convert.FromBase64String(pubkey);
            // var rsa = RSA.Create();
            // rsa.ImportRSAPublicKey(publicKey, out _);
            // var buff = rsa.Encrypt(Encoding.UTF8.GetBytes(text), RSAEncryptionPadding.OaepSHA1);
            // return Convert.ToBase64String(buff);
            using (var x509 = new X509Certificate2(publicKey))
            {
                using (var rsa = x509.GetRSAPublicKey())
                {
                    var buff = rsa.Encrypt(Encoding.UTF8.GetBytes(text), RSAEncryptionPadding.OaepSHA1);
                    return Convert.ToBase64String(buff);
                }
            }
        }
        public string postJson(string url, string postData, string privateKey, string merchantId, string serialNo, string method = "POST")
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = method;
            request.ContentType = "application/json;charset=UTF-8";
            request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3100.0 Safari/537.36";
            request.Accept = "application/json";

            string Authorization = GetAuthorization(url, method, postData, privateKey, merchantId, "62B64854B768D344249FDB9E6EF4A1232C000E84");
            request.Headers.Add("Authorization", Authorization);
            request.Headers.Add("Wechatpay-Serial", serialNo);
            if (!string.IsNullOrEmpty(postData))
            {
                byte[] paramJsonBytes;
                paramJsonBytes = System.Text.Encoding.UTF8.GetBytes(postData);
                request.ContentLength = paramJsonBytes.Length;
                Stream writer;
                try
                {
                    writer = request.GetRequestStream();
                }
                catch (Exception)
                {
                    writer = null;
                    Console.Write("连接服务器失败!");
                }
                writer.Write(paramJsonBytes, 0, paramJsonBytes.Length);
                writer.Close();
            }

            HttpWebResponse response;
            try
            {
                response = (HttpWebResponse)request.GetResponse();
            }
            catch (WebException ex)
            {
                response = ex.Response as HttpWebResponse;
            }
            Stream resStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(resStream);
            string text = reader.ReadToEnd();
            return text;
            //{\"code\":\"PARAM_ERROR\",\"message\":\"请确认待处理的消息是否为加密后的密文\"}
            //{\"applyment_id\":2000002247709762}
        }

        #endregion

        #region 图片上传

        public string GetMediaId(string imgPath)
        {
            if (string.IsNullOrEmpty(imgPath))
            {
                return "";
            }
            string key = "wechatpic:" + function.MD5_16(imgPath);
            string media_id = RedisDbconn.Instance.Get<string>(key);
            if (!string.IsNullOrEmpty(media_id))
            {
                return media_id;
            }
            string filePath = function.getPath(imgPath);
            var filename = Path.GetFileName(filePath);
            FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
            Byte[] imgBytesIn = new Byte[fs.Length];
            fs.Read(imgBytesIn, 0, imgBytesIn.Length);
            fs.Close();

            byte[] hash = SHA256Managed.Create().ComputeHash(imgBytesIn);

            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < hash.Length; i++)
            {
                builder.Append(hash[i].ToString("x2"));
            }
            var sha256 = builder.ToString();
            string metaStr = "{\"filename\":\""+ filename + "\",\"sha256\":\"" + sha256 + "\"}";
            media_id = UploadImgApi(metaStr, imgBytesIn, filename);
            RedisDbconn.Instance.Set(key, media_id);
            return media_id;
        }

        public string UploadImgApi(string metaStr, Byte[] imgBytesIn,string filename)
        {
            string url = "https://api.mch.weixin.qq.com/v3/merchant/media/upload";
            
            string merchantId = "1611167423";   //商户号
            string serialNo = "62B64854B768D344249FDB9E6EF4A1232C000E84";  //证书编号
            string privateKey = prikey;
            #region 定义请求体中的内容 并转成二进制

            string boundary = "lc199aecd61b4653ef";
            string Enter = "\r\n";
            string campaignIDStr1
                = "--" + boundary
                + Enter
                + "Content-Disposition: form-data; name=\"meta\";"
                + Enter
                + "Content-Type:application/json;"
                + Enter
                + Enter
                + metaStr
                + Enter
                + "--" + boundary
                + Enter
                + "Content-Disposition:form-data;name=\"file\";filename=\""+ filename + "\";"
                + Enter
                + "Content-Type:image/jpeg"
                + Enter
                + Enter;
            byte[] byteData2
                = imgBytesIn;
            string campaignIDStr3 
                = Enter
                + "--" + boundary 
                + Enter;
            var byteData1 = System.Text.Encoding.UTF8.GetBytes(campaignIDStr1);

            var byteData3 = System.Text.Encoding.UTF8.GetBytes(campaignIDStr3);
            #endregion

            string transactionsResponse = UploadImg_postJson(url, byteData1, byteData2, byteData3, metaStr, privateKey, merchantId, serialNo, boundary, "POST");
            var result=JsonMapper.ToObject(transactionsResponse);
            return result["media_id"].ToString();
        }
        public string UploadImg_postJson(string url, byte[] b1, byte[] b2, byte[] b3, string metaStr, string privateKey, string merchantId, string serialNo, string boundary, string method = "POST")
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = method;
            //request.ContentType = "application/json;charset=UTF-8";
            request.ContentType = "multipart/form-data;boundary=" + boundary;
            request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3100.0 Safari/537.36";
            request.Accept = "application/json";
            string Authorization = GetAuthorization(url, method, metaStr, privateKey, merchantId, serialNo);
            request.Headers.Add("Authorization", Authorization);

            Stream writer;
            try
            {
                writer = request.GetRequestStream();
            }
            catch (Exception)
            {
                writer = null;
            }
            writer.Write(b1, 0, b1.Length);
            writer.Write(b2, 0, b2.Length);
            writer.Write(b3, 0, b3.Length);
            writer.Close();

            HttpWebResponse response;
            try
            {
                response = (HttpWebResponse)request.GetResponse();
            }
            catch (WebException ex)
            {
                response = ex.Response as HttpWebResponse;
            }
            Stream resStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(resStream);
            string text = reader.ReadToEnd();
            return text;
        }
        protected string GetAuthorization(string url, string method, string jsonParame, string privateKey, string merchantId, string serialNo)
        {
            var uri = new Uri(url);
            string urlPath = uri.PathAndQuery;
            string nonce = Guid.NewGuid().ToString();
            var timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
            //数据签名     HTTP请求方法\n接口地址的url\n请求时间戳\n请求随机串\n请求报文主体\n
            method = string.IsNullOrEmpty(method) ? "" : method;
            string message = string.Format("{0}\n{1}\n{2}\n{3}\n{4}\n", method, urlPath, timestamp, nonce, jsonParame);
            string signTxt = Sign(message, privateKey);

            //Authorization和格式
            string authorzationTxt = string.Format("WECHATPAY2-SHA256-RSA2048 mchid=\"{0}\",nonce_str=\"{1}\",timestamp=\"{2}\",serial_no=\"{3}\",signature=\"{4}\"",
                merchantId,
                nonce,
                timestamp,
                serialNo,
                signTxt
                );
            return authorzationTxt;
        }

        protected string Sign(string message, string privateKey)
        {
            byte[] keyData = Convert.FromBase64String(privateKey);
            byte[] data = System.Text.Encoding.UTF8.GetBytes(message);
            var rsa = RSA.Create();
            rsa.ImportPkcs8PrivateKey(keyData, out _);
            return Convert.ToBase64String(rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1));

            // using (CngKey cngKey = CngKey.Import(keyData, CngKeyBlobFormat.Pkcs8PrivateBlob))
            // using (RSACng rsa = new RSACng(cngKey))
            // {
            //     return Convert.ToBase64String(rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1));
            // }
        }

        #endregion

        #region 获取文件sha256

        public string GetSha256(FileStream stream)
        { 
            using (SHA256 mySHA256 = SHA256.Create())
            {
                byte[] hashValue = mySHA256.ComputeHash(stream);
                return Encoding.UTF8.GetString(hashValue);
            }
        }

        #endregion

        #region 判断长期

        public string CheckForever(DateTime? time)
        {
            if (time == null)
            {
                return "";
            }
            if (time.Value.Year >= 2050)
            {
                return "长期";
            }
            return time.Value.ToString("yyyy-MM-dd");
        }

        #endregion


    }
}
