Xamarin.Forms C#微信支付寶支付接口(手機端)


 

 

 

目錄

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

背景

 接口實現

 

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

背景

服務端已寫好的,這裏的是手機端的調用。

SDK 已轉譯好了,==鏈接還沒寫好==

接口實現

微信接口

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

 

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

 

 

1.1  微信支付請求參數的構成:以下代碼using內容一樣

  
using System;
using System.Collections.Generic;
using System.Text;
  /// <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();
            }
        }
    }
    /// <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;
        }
    }

上面用到了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;
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章