Xamarin.Forms C#微信支付宝支付接口(手机端)


 

 

 

目录

Xamarin.Forms 微信支付宝支付接口

背景

 接口实现

 

Xamarin.Forms 微信支付宝支付接口

背景

服务端已写好的,这里的是手机端的调用。

SDK 已转译好了,==https://download.csdn.net/download/qq_21121397/11501649==

接口实现

微信接口

1. 在xamarin.forms工程中添加接口

 

    public interface IWeChat
    {
        void WXPay(Xamarin.AppFramework.WxPayReqItem req); 
   }
 

 

 

1.1  微信支付请求参数的构成:以下代码using内容一样

  
using System;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json;
  /// <summary>
    /// 微信客户端付款请求参数:从服务器返回的。
    /// 字段名称根据服务端定义的参数自行修改
    /// </summary>
    public class WxPayReqItem
    {
        public string prepay_id { get; set; }
        public string nonceStr { get; set; }
        public string sign
        {
            get
            {
                return WxInfo.SecSign(prepay_id, nonceStr,timestamp);
            }
        }
        public string timestamp
        {
            get
            {
                TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
                return Convert.ToInt64(ts.TotalSeconds).ToString();
            }
        }
 
        public string timestamp
        {
            get
            {
                TimeSpan ts = operatedate - new DateTime(1970, 1, 1, 0, 0, 0, 0);
                return Convert.ToInt64(ts.TotalSeconds).ToString();
            }
        }
        /// <summary>
        /// 时间戳
        /// </summary>
        [JsonIgnore]
        public DateTime operatedate { get; set; }

    }
    /// <summary>
    /// 微信信息
    /// </summary>
    public class WxInfo
    {
        /// <summary>
        /// 微信appid
        /// </summary>
        public static string AppId =  "";

        /// <summary>
        /// 商户号
        /// </summary>
        public static string PartnerId = " ";

        /// <summary>
        /// /商户平台API密钥
        /// </summary>
        public static string outkey = " ";


        /// <summary>
        /// 支付结果回调 ,回调结果里面带上支付方式和支付标志。
        /// </summary>
        public static AsyncMsg am_支付结果 = new AsyncMsg();

        public static WxUserInfo wxUserInfo = new WxUserInfo();

        /// <summary>
        /// 微信支付签名算法
        /// </summary>
        /// <param name="parameters"></param>
        /// <returns></returns>
        static string GetSignContent(IDictionary<string, string> parameters)
        {
            // 第一步:把字典按Key的字母顺序排序
            IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parameters);
            IEnumerator<KeyValuePair<string, string>> dem = sortedParams.GetEnumerator();
            // 第二步:把所有参数名和参数值串在一起
            StringBuilder query = new StringBuilder("");
            while (dem.MoveNext())
            {
                string key = dem.Current.Key;
                string value = dem.Current.Value;
                if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value))
                {
                    query.Append(key).Append("=").Append(value).Append("&");
                }
            }
            string content = query.ToString().Substring(0, query.Length - 1);
            return content;
        }

        /// <summary>
        /// 微信支付二次签名
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string SecSign(string prepayid, string noncestr,string timestamp)
        {
            //二次签名
            Dictionary<string, string> parameters1 = new Dictionary<string, string>();
            parameters1.Add("appid", AppId);
            parameters1.Add("partnerid", PartnerId);
            parameters1.Add("prepayid", prepayid);
            parameters1.Add("noncestr", noncestr);
            parameters1.Add("timestamp", timestamp);
            parameters1.Add("package", "Sign=WXPay");
            string content = GetSignContent(parameters1);
            //,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。
            //stringSignTemp=stringA+"&key=192006250b4c09247ec02edce69f6a2d" //注:key为商户平台设置的密钥key 
            string signResult =Xamarin.AppFramework.Helpers.CryptHelper.GetMD5(content + "&key=" + outkey).ToUpper();
            return signResult;
        }
    }





    /// <summary>
    /// 微信用户信息
    /// </summary>
    /// <returns></returns>
    public class WxUserInfo
    {
        /// <summary>
        /// 用户是否订阅该公众号标识,值为0时,代表此用户没有关注该公众号,拉取不到其余信息。
        /// </summary>
        public string subscribe { get; set; }

        /// <summary>
        /// 用户的标识,对当前公众号唯一
        /// </summary>
        public string openid { get; set; }

        /// <summary>
        /// 用户的昵称
        /// </summary>
        public string nickname { get; set; }

        /// <summary>
        /// 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
        /// </summary>
        public string sex { get; set; }

        /// <summary>
        /// 用户所在城市
        /// </summary>
        public string city { get; set; }
        /// <summary>
        /// 用户所在国家
        /// </summary>
        public string country { get; set; }
        /// <summary>
        /// 用户所在省份
        /// </summary>
        public string province { get; set; }
        /// <summary>
        /// 用户的语言,简体中文为zh_CN
        /// </summary>
        public string language { get; set; }

        /// <summary>
        /// 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。
        /// 例子:http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0
        /// </summary>
        public string headimgurl { get; set; }

        /// <summary>
        /// 用户关注时间,为时间戳。如果用户曾多次关注,则取最后关注时间
        /// </summary>
        public string subscribe_time { get; set; }
        /// <summary>
        /// 只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。
        /// </summary>
        public string unionid { get; set; }
        /// <summary>
        /// 公众号运营者对粉丝的备注,公众号运营者可在微信公众平台用户管理界面对粉丝添加备注
        /// </summary>
        public string remark { get; set; }
        /// <summary>
        /// 用户所在的分组ID(兼容旧的用户分组接口)
        /// </summary>
        public string groupid { get; set; }
        /// <summary>
        /// 用户被打上的标签ID列表
        /// </summary>
        public string tagid_list { get; set; }

        /// <summary>
        /// 返回用户关注的渠道来源,ADD_SCENE_SEARCH 公众号搜索,ADD_SCENE_ACCOUNT_MIGRATION 公众号迁移,
        /// ADD_SCENE_PROFILE_CARD 名片分享,ADD_SCENE_QR_CODE 扫描二维码,
        /// ADD_SCENEPROFILE LINK 图文页内名称点击,ADD_SCENE_PROFILE_ITEM 图文页右上角菜单,
        /// ADD_SCENE_PAID 支付后关注,ADD_SCENE_OTHERS 其他
        /// </summary>
        public string subscribe_scene { get; set; }

        /// <summary>
        /// 二维码扫码场景(开发者自定义)
        /// </summary>
        public string qr_scene { get; set; }

        /// <summary>
        /// 二维码扫码场景描述(开发者自定义)
        /// </summary>
        public string qr_scene_str { get; set; }

    }

上面用到了MD5加密:

using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;

namespace Xamarin.AppFramework.Helpers
{
    public class CryptHelper
    {
        private static readonly MD5 md5Hasher = MD5.Create();
        public static string CreateMD5(string text)
        {
            // Convert the input string to a byte array and compute the hash.
            byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(text));

            // Create a new Stringbuilder to collect the bytes
            // and create a string.
            StringBuilder sBuilder = new StringBuilder();

            // Loop through each byte of the hashed data 
            // and format each one as a hexadecimal string.
            for (int i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2"));
            }

            // Return the hexadecimal string.
            return sBuilder.ToString();

        }
        public static string GetMD5(string encypStr)
        {
            char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
            try
            {
                byte[] btInput = System.Text.Encoding.Default.GetBytes(encypStr);
                // 获得MD5摘要算法的 MessageDigest 对象
                MD5 mdInst = System.Security.Cryptography.MD5.Create();
                // 使用指定的字节更新摘要
                mdInst.ComputeHash(btInput);
                // 获得密文
                byte[] md = mdInst.Hash;
                // 把密文转换成十六进制的字符串形式
                int j = md.Length;
                char[] str = new char[j * 2];
                int k = 0;
                for (int i = 0; i < j; i++)
                {
                    byte byte0 = md[i];
                    str[k++] = hexDigits[(int)(((byte)byte0) >> 4) & 0xf];
                    str[k++] = hexDigits[byte0 & 0xf];
                }
                return new string(str);
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.StackTrace);
                return null;
            }
        }
    }
}

 

2.  android平台下实现:用到了plugin.currentActivity,需要nuget下载引用。                                                                            2.1 2.1 实现接口

using Android.Content;
using Android.Graphics;
using Android.Widget;
using AndroidHUD;
using Com.Tencent.MM.Sdk.Modelmsg;
using Com.Tencent.MM.Sdk.Openapi;
using System;
using System.IO;
using Saobag.Droid;
 
[assembly: Xamarin.Forms.Dependency(typeof(Interface.Droid.WeChat))]
namespace Interface.Droid
{
    /// <summary>
    /// 微信相关
    /// </summary>
    class WeChat :  Xamarin.AppFramework.Interface.IWeChat
    {

        Context CurrentContext => Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity;
        /// <summary>
        /// 微信支付
        /// </summary>
        public void WXPay(Xamarin.AppFramework.WxPayReqItem wxreq)
        {
            try
            {
                wxapi.Droid.WXPayEntryActivity.wxpay(wxreq);
            }
            catch (Exception ex)
            {
                Android.Widget.Toast.MakeText(CurrentContext, "支付异常:" + ex.Message, ToastLength.Long).Show();
            }
        }    
    }
}

2.2 微信支付及回调接口


using Android.App;
using Android.Content;
using Android.OS;
using Android.Widget;
using Com.Tencent.MM.Sdk.Modelbase;
using Com.Tencent.MM.Sdk.Openapi;
using Com.Tencent.MM.Sdk.Modelpay;
using Xamarin.Forms;

namespace wxapi.Droid
{
    //xamarin对于Activity的路径是根据Name来发起的, 本身命名空间和类名只是工程内部使用。
    //微信回调的根据是这里的Name: 应用包名+.wxapi.WXPayEntryActivity 构成,不能有差错,否则无法回调。
    [Activity(Label = "WXPayEntryActivity", Name = "com.cstc.Saobag.wxapi.WXPayEntryActivity", Theme = "@android:style/Theme.Translucent", LaunchMode = Android.Content.PM.LaunchMode.SingleTop, Exported = true)]
    ///微信支付回调
    public class WXPayEntryActivity : Activity, IWXAPIEventHandler
    {
        private static IWXAPI wxApi;
 
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            // Create your application here
            wxApi = WXAPIFactory.CreateWXAPI(this, Xamarin.AppFramework.WxInfo.AppId);
            wxApi.HandleIntent(Intent, this);
        }

 
        public void OnReq(BaseReq req)
        {
            //  throw new NotImplementedException();
        }

        public void OnResp(BaseResp resp)
        {
            switch (resp.MyErrCode)
            {
                case BaseResp.ErrCode.ErrOk:

                    Device.BeginInvokeOnMainThread(() =>
                    {
                        Toast.MakeText(this.BaseContext, "支付成功", ToastLength.Short).Show();
                    });

                    Xamarin.AppFramework.WxInfo.am_支付结果.OnCompletion(null, "充值");
 
 

                    Finish();
                    break;
                case BaseResp.ErrCode.ErrAuthDenied:
                   
                    Device.BeginInvokeOnMainThread(() =>
                    {
                        Toast.MakeText(this.BaseContext, "支付失败", ToastLength.Short).Show();
                    });

                    Xamarin.AppFramework.WxInfo.am_支付结果.OnCancel(null, "充值");
  
                    Finish();
                    break;
                case BaseResp.ErrCode.ErrUserCancel:
                

                    Device.BeginInvokeOnMainThread(() =>
                    {
                        Toast.MakeText(this.BaseContext, "取消支付", ToastLength.Short).Show();
                    });
                    Xamarin.AppFramework.WxInfo.am_支付结果.OnCancel(null, "充值");
                    
                    Finish();
                    break;
            }
        }

        /// <summary>
        /// 调用微信支付
        /// </summary>
        /// <param name="req"></param>
        public static void wxpay(Xamarin.AppFramework.WxPayReqItem req)
        {
            if (wxApi == null)
            {
                //不同工程使用的时候记得修改命名空间。
                wxApi = WXAPIFactory.CreateWXAPI(Saobag.Droid.MainActivity.mainActivity, Xamarin.AppFramework.WxInfo.AppId);
            }
            wxApi.RegisterApp(Xamarin.AppFramework.WxInfo.AppId);

                      PayReq payReq = new PayReq();
            payReq.AppId = Xamarin.AppFramework.WxInfo.AppId;
            payReq.PartnerId = Xamarin.AppFramework.WxInfo.PartnerId; 
            payReq.PrepayId = req.prepay_id;
            payReq.PackageValue = "Sign=WXPay";
            payReq.NonceStr = req.nonceStr;
            payReq.TimeStamp = req.timestamp;
            payReq.Sign = req.sign;
            bool isflag = wxApi.SendReq(payReq);        }
    }
}

2.3 支付宝android直接实现接口,处理回调值。

using Android.Content;
using Android.Widget;
using System;
using Xamarin.Forms;
using Saobag.Droid;

[assembly: Xamarin.Forms.Dependency(typeof(Interface.Droid.Ali))]
namespace Interface.Droid
{
    public class Ali : Xamarin.AppFramework.Interface.IAli
    {
        /// <summary>
        /// Android 实现支付宝支付
        /// </summary>
        /// <param name="orderInfo">订单信息</param>
        public void AliPay(string orderInfo)
        {
            Com.Alipay.Sdk.App.PayTask pa = new Com.Alipay.Sdk.App.PayTask(MainActivity.mainActivity);
            string result = pa.Pay(orderInfo);

            if (result.Contains("6001"))
            {
                Device.BeginInvokeOnMainThread(() =>
                {
                    Toast.MakeText(MainActivity.mainActivity, "取消支付", ToastLength.Short).Show();
                });

                Xamarin.AppFramework.AliInfo.am_支付结果.OnCancel(null, "充值");

            }
            else if (result.Contains("9000"))
            {
                Device.BeginInvokeOnMainThread(() =>
                {
                    Toast.MakeText(MainActivity.mainActivity, "支付成功", ToastLength.Short).Show();
                });
                Xamarin.AppFramework.AliInfo.am_支付结果.OnCompletion(null, "充值");

            }
            else if (result.Contains("4000"))
            {
                Device.BeginInvokeOnMainThread(() =>
                {
                    Toast.MakeText(MainActivity.mainActivity, "支付失败", ToastLength.Short).Show();
                });

                Xamarin.AppFramework.AliInfo.am_支付结果.OnCancel(null, "充值");

            }


        }
    }
}

3. IOS平台下实现:

首先要配置:infolist,高级里面要添加url类型,用于支付后跳回程序。微信为appid,支付宝为scheme,也就是向支付宝申请支付填的包名

3.1 实现接口

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Foundation;
using UIKit;
using Xamarin.Forms;
using WeChatBinding;

[assembly: Xamarin.Forms.Dependency(typeof(Interface.iOS.WeChat))]
namespace Interface.iOS
{
    public class WeChat :  Xamarin.AppFramework.Interface.IWeChat
    {
 
        public static WXApi WXapi;

 

        public void WXPay(Xamarin.AppFramework.WxPayReqItem req)
        {
            PayReq request = new PayReq();
            request.PartnerId = Xamarin.AppFramework.WxInfo.PartnerId;
            request.PrepayId = req.prepay_id;
            request.Package = @"Sign=WXPay";
            request.NonceStr = req.nonceStr;
            request.TimeStamp = Convert.ToUInt32(req.timestamp);
            request.Sign = req.sign;
            WXApi.SendReq(request);
        }
    }
}
 
using AlipaySDKBinding;
using Xamarin.Forms;

[assembly: Xamarin.Forms.Dependency(typeof(Interface.iOS.Ali))]
namespace Interface.iOS 
{
    public class Ali : Xamarin.AppFramework.Interface.IAli
    {

        /// <summary>
        /// 支付报支付
        /// </summary>
        /// <param name="orderInfo">订单明细</param>
        public void AliPay(string orderInfo)
        {
            //支付宝回调实际上不走这里的CompletionBlock,而是走appdelegate里面的openurl 
            //注意scheme需要在infolist--高级,urltype那里添加软件的标识符,这里调用传入,支付成功后才能返回软件
            AlipaySDKBinding.AlipaySDK.DefaultService.PayOrder(orderInfo, "com.cstc.sample",
                new CompletionBlock(aa => { }));
        }
 
 
    }
 
}

3.2 微信回调委托

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Foundation;
using UIKit;
using WeChatBinding;
using BigTed;
using Xamarin.Forms;
using System.Threading.Tasks;

namespace wxapi
{
    public class WxDelegate : WXApiDelegate
    {
 
        public override void OnReq(BaseReq req)
        {
            //base.OnReq(req); 
        }

        public override void OnResp(BaseResp resp)
        {
            if (resp is PayResp)
            {
                #region 微信支付回调
                PayResp response = (PayResp)resp;
                switch (response.ErrCode)
                {
                    case 0:

                        Show_Toast("支付成功");
 
                        Xamarin.AppFramework.WxInfo.am_支付结果.OnCompletion(null, "充值");
                        break;
                    default:

                        Xamarin.AppFramework.WxInfo.am_支付结果.OnCancel(null, "充值");
                        Show_Toast("支付失败");

                        break;
                }
                #endregion
            }
           }
       }
 
      
    }
}

3.3 支付回调

using System;
using System.Collections.Generic;
using System.Linq;

using Foundation;
using UIKit;
using WeChatBinding;
using BigTed;


namespace Saobag.iOS
{
    // The UIApplicationDelegate for the application. This class is responsible for launching the 
    // User Interface of the application, as well as listening (and optionally responding) to 
    // application events from iOS.
    [Register("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
    {
        //
        // This method is invoked when the application has loaded and is ready to run. In this 
        // method you should instantiate the window, load the UI into it and then make the window
        // visible.
        //
        // You have 17 seconds to return from this method, or iOS will terminate your application.
        //
        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            global::Xamarin.Forms.Forms.Init();
            Xamarin.AppFramework.MConfig.screenWidth = UIScreen.MainScreen.Bounds.Width; //屏幕宽度

            WXApi.RegisterApp(Xamarin.AppFramework.WxInfo.AppId);

            LoadApplication(new App());

            return base.FinishedLaunching(app, options);
        }


        /// <summary>
        /// 支付宝支付回调, IOS9.3以上
        /// </summary>
        /// <param name="app"></param>
        /// <param name="url"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
        {
            return ThirpartyResult(url);
        }


        /// <summary>
        /// 微信回调,IOS9.3以下支付宝支付回调 
        /// </summary>
        /// <param name="application"></param>
        /// <param name="url"></param>
        /// <param name="sourceApplication"></param>
        /// <param name="annotation"></param>
        /// <returns></returns>
        public override bool OpenUrl(UIApplication application, NSUrl url, string sourceApplication, NSObject annotation)
        {
            return ThirpartyResult(url);
        }


        private bool ThirpartyResult(NSUrl url)
        {
            Xamarin.AppFramework.MConfig.WriteLog(url.ToString());
            if (url.Scheme.Equals(Xamarin.AppFramework.WxInfo.AppId))
            {
                wxapi.WxDelegate d = new wxapi.WxDelegate();
                bool b = WXApi.HandleOpenURL(url, d);
                return b;
            }
            else if (url.Host.Equals("safepay"))
            {
                return AliPayResult(url);
            }
            else
                return true;
        }

        private bool AliPayResult(NSUrl url)
        {
            if (url.Host.Equals("safepay"))
            {
                string resultStatus = "";
                try
                {
                    Xamarin.Forms.Device.BeginInvokeOnMainThread(() =>
                    {
                        AlipaySDKBinding.AlipaySDK.DefaultService.ProcessOrderWithPaymentResult(url,
                        new AlipaySDKBinding.CompletionBlock(aa =>
                        {
                            try
                            {
                                string result = System.Web.HttpUtility.UrlDecode(url.ToString());
                                string[] lists = result.Split("?"); //分解获取?后面的内容
                                Xamarin.AppFramework.AliResponse user = (Xamarin.AppFramework.AliResponse)Newtonsoft.Json.JsonConvert.DeserializeObject(lists[1], typeof(Xamarin.AppFramework.AliResponse));
                                resultStatus = user.memo.ResultStatus;
                            }
                            catch (Exception ex)
                            {
                                BTProgressHUD.ShowToast("支付失败", true, 2000);
                                Xamarin.AppFramework.AliInfo.am_支付结果.OnCancel(null, "支付宝支付");
                            }


                        }));
                        如果支付失败
                        if (!resultStatus.Equals("9000"))
                        {
                            BTProgressHUD.ShowToast("支付失败", true, 2000);
                            Xamarin.AppFramework.AliInfo.am_支付结果.OnCancel(null, "支付宝支付");
                        }
                        else
                        {
                            BTProgressHUD.ShowToast("支付成功", true, 2000);
                            //如果支付成功
                            Xamarin.AppFramework.AliInfo.am_支付结果.OnCompletion(null, "支付宝支付");
                        }
                    });
                }
                catch (Exception ex)
                {
                    return false;
                }
            }
            return true;
        }
    }
}

 

忘记把这个回调类补上。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Xamarin.AppFramework
{
 
    /// <summary>
    /// 异步回调
    /// </summary>
    public class AsyncMsg
    {
        /// <summary>
        /// 委托事件
        /// </summary>
        /// <param name="tag">数据内容</param>
        /// <param name="e">消息</param>
        public delegate void AsyncMsgEventHandler(object tag, string e);

        /// <summary>
        /// 完成
        /// </summary>
        public event AsyncMsgEventHandler Completion;

        /// <summary>
        /// 取消或失败
        /// </summary>
        public event AsyncMsgEventHandler Cancel;

        public bool IsCompletion = false;//是否完成
        public bool IsCancel = false;//是否取消
 
        /// <summary>
        /// 
        /// </summary>
        public string Tag { get; set; } = "";
        public object TagObj { get; set; } = "";


        /// <summary>
        /// 完成时触发
        /// </summary>
        /// <param name="tag">数据内容</param>
        /// <param name="e">消息</param>
        public void OnCompletion(object tag, string e)
        {
            if (Completion != null)
            {
                Completion(tag, e);
                IsCompletion = true;
            }
        }


        public void OnCompletion()
        {
            OnCompletion(null, "");
        }

        /// <summary>
        /// 取消或失败触发
        /// </summary>
        /// <param name="tag">数据内容</param>
        /// <param name="e">消息</param>
        public void OnCancel(object tag, string e)
        {
            if (Cancel != null)
            {
                Cancel(tag, e);
                IsCancel = true;
            }
        }
        public void OnCancel()
        {
            OnCancel(null, "");
        }
    }
}

2020-1-2 补充说明,之前的时间戳用下面这个写法有问题,  return datime.UtcNow,每一次使用timestamp的时候,值都会发生变化,所以 sign加密时候的时间戳的值和上传的时间戳其实是不一致的,只是因为取得是秒值,所以发生错误的概率不大。今天调用了另一个业务接口,是毫秒级的,一直签名错误,发现了这个问题,所以我在上面加了一个字段operatedate,在调用的时候赋值,时间戳就不会发生变化。

        public string timestamp
        {
            get
            {
                TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
                return Convert.ToInt64(ts.TotalSeconds).ToString();
            }
        }
  • 7
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 17
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值