對接第三方接口(短信,支付)

前言

第三方短信接口,支付接口普遍應用於金融領域與電商領域,這是我在14年工做時的一些經驗總結,如今分享出來,但願能對一部分朋友有所幫助!設計模式

內容

一:對接短信接口ide

對接短信接口大致分爲兩個步驟:網站

1. 根據接口文檔發送短信類容到短信網關;ui

2. 回調結果並獲取短信剩餘條數this

考慮到一個網站可能不止一個短信網關,我使用了工廠設計模式,下面附上代碼url

短信網關接口spa

    /// <summary>
    /// 短信網關接口
    /// </summary>
    public interface ISMS
    {
        /// <summary>
        /// 短信商
        /// </summary>
        SMSProvider Provider { get; }

        /// <summary>
        /// 發送短信
        /// </summary>
        /// <param name="destnumbers">要發送到的手機號碼</param>
        /// <param name="msg">要發送的內容</param>
        /// <param name="sendTime">發送時間 爲null表示馬上發送</param>
        int Send(string destnumbers, string msg, out SMSStatus status, DateTime? sendTime = null);

        /// <summary>
        /// 獲取餘額
        /// </summary>
        int Balance();

        /// <summary>
        /// 獲取上行短信內容
        /// </summary>
        /// <returns>返回null表示沒有獲取到上行短信</returns>
        List<SMSReply> GetReply();
    }

 

短信工廠類設計

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.IO;
using System.ComponentModel;

using SP.Studio.IO;
using SP.Studio.Core;

namespace SP.Studio.Gateway.SMS
{
    /// <summary>
    /// 短信工廠
    /// </summary>
    public class SMSFactory
    {
        public static ISMS CreateSMS(SMSConfig config)
        {
            ISMS sms = null;
            sms = (ISMS)Activator.CreateInstance(Type.GetType("SP.Studio.Gateway.SMS." + config.Provider),
                config.UserName,
                config.Password);
            return sms;
        }
    }

    /// <summary>
    /// 短信提供商
    /// </summary>
    public enum SMSProvider : byte
    {
        /// <summary>
        /// 無供應商
        /// </summary>
        None,
        /// <summary>
        /// 單元科技
        /// </summary>
        [Description("單元科技")]
        CCell,
        /// <summary>
        /// 單元科技 接口2
        /// </summary>
        [Description("單元科技")]
        CCell2,
        /// <summary>
        /// 億美科技
        /// </summary>
        [Description("億美科技")]
        EMay,
        /// <summary>
        /// /// <summary>
        /// 中國網建
        /// </summary>
        [Description("中國網建")]
        WebChinese,
        /// <summary>
        /// 國都
        /// </summary>
        [Description("國都")]
        Guodu,
        /// <summary>
        /// 企信通(鑫陽創投)
        /// </summary>
        [Description("企信通")]
        YDQXT,
        /// <summary>
        /// http://sdk.entinfo.cn:8061/
        /// </summary>
        [Description("DXC")]
        DXC,
        /// <summary>
        /// 凌凱科技 http://www.zhongguowuxian.com/Item/list.asp?id=1460
        /// </summary>
        [Description("凌凱科技")]
        LingKai,
        /// <summary>
        /// 玄武科技
        /// </summary>
        [Description("玄武科技")]
        MT,
        /// <summary>
        /// 單元科技新接口
        /// </summary>
        [Description("單元科技-3")]
        CCell3,
        /// <summary>
        /// 使用短信貓發送
        /// </summary>
        [Description("短信貓")]
        Modem = 100
    }

    /// <summary>
    /// 短信息配置類
    /// </summary>
    public class SMSConfig
    {
        public SMSProvider Provider { get; set; }

        public string UserName { get; set; }

        public string Password { get; set; }

    }
}
短信工廠類

 

實例rest

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

using SP.Studio.Net;
using SP.Studio.Text;

using SP.Studio.Security;

using SP.Studio.Web;
namespace SP.Studio.Gateway.SMS
{
    public class LingKai : SMSBase, ISMS
    {
        public LingKai(string userName, string password)
            : base(userName, password)
        {
        }

        public SMSProvider Provider
        {
            get { return SMSProvider.LingKai; }
        }

        public int Send(string destnumbers, string msg, out SMSStatus status, DateTime? sendTime = null)
        {
            if (!WebAgent.IsMobile(destnumbers))
            {
                status = SMSStatus.Number;
                return 0;
            }
            string url = string.Format("http://sdk.zhongguowuxian.com:98/ws/BatchSend.aspx?CorpID={0}&Pwd={1}&Mobile={2}&Content={3}&Cell=&SendTime=",
                this.UserName, this.Password, destnumbers, HttpUtility.UrlEncode(msg, Encoding.GetEncoding("GB2312")));

            string result = NetAgent.DownloadData(url, Encoding.GetEncoding("GB2312"));

            //大於等於0的數字,發送成功(獲得大於等於0的數字、做爲取報告的id);-一、賬號未註冊;-二、其餘錯誤;-三、密碼錯誤;-四、手機號格式不對;-五、餘額不足;-六、定時發送時間不是有效的時間格式;
            //-七、請在提交信息末尾添加中文企業簽名【】; -八、發送內容需在1到500個字之間;-九、 發送號碼爲空 

            this.SaveGateway(result);


            status = SMSStatus.Success;
            long code;
            if (long.TryParse(result, out code))
            {
                switch (code)
                {
                    case -1:
                    case -3:
                        status = SMSStatus.Account;
                        break;
                    case -2:
                    case -6:
                        status = SMSStatus.Other;
                        break;
                    case -4:
                    case -9:
                        status = SMSStatus.Number;
                        break;
                    case -5:
                        status = SMSStatus.Money;
                        break;
                    case -7:
                    case -8:
                        status = SMSStatus.Message;
                        break;
                }
            }
            else
            {
                status = SMSStatus.Other;
            }
            return status == SMSStatus.Success ? 1 : 0;
        }

        /// <summary>
        ///獲取短信的剩餘量
        /// </summary>
        /// <returns></returns>
        public int Balance()
        {
            string url = string.Format("http://sdk.zhongguowuxian.com:98/WS/SelSum.aspx?CorpID={0}&Pwd={1}", this.UserName, this.Password);
            string result = NetAgent.DownloadData(url,Encoding.GetEncoding("GB2312"));
            int balance;
            int.TryParse(result, out balance);
            return balance;
        }

        public List<SMSReply> GetReply()
        {
            return new List<SMSReply>();
        }
    }
}
實例

 

二:對接支付接口code

對接支付接口大致步驟也分爲兩步,部分支付廠商可能存在小差別

1. 找到合適的支持廠商,簽定協議,拿到商戶code與簽名私鑰;

2. 根據提供對接文檔Post數據跳轉到支付網關;

3. 支付回調結果並驗證商戶網頁(通常作法是把回調地址傳給網關,在回調地址中驗證支付結果)

下面附上部分代碼

 

        /// <summary>
        /// Post數據,跳轉支付網關
        /// </summary>
        public override void GoGateway()
        {
            SortedDictionary<string, string> sParaTemp = new SortedDictionary<string, string>();
            if (this.PayMethod == "bankPay")    // 若是是網銀直接支付
            {
                sParaTemp.Add("defaultbank", this.defaultbank);
            }
            switch (this.Service)
            {
                case "create_partner_trade_by_buyer": //  若是是擔保支付
                case "trade_create_by_buyer":   // 雙功能收款
                    sParaTemp.Add("logistics_type", "POST");
                    sParaTemp.Add("logistics_fee", "0.00");
                    sParaTemp.Add("logistics_payment", "BUYER_PAY");
                    sParaTemp.Add("price", base.Money.ToString("0.00"));
                    sParaTemp.Add("quantity", "1");
                    break;
            }

            sParaTemp.Add("partner", this.Partner);
            sParaTemp.Add("_input_charset", _input_charset.ToLower());
            sParaTemp.Add("service", this.Service);
            sParaTemp.Add("payment_type", paymentType.ToString());
            sParaTemp.Add("notify_url", this.NotifyUrl);
            sParaTemp.Add("return_url", this.ReturnUrl);
            sParaTemp.Add("seller_email", this.SellerEmail);
            sParaTemp.Add("out_trade_no", base.OrderID);
            sParaTemp.Add("subject", base.Name);
            sParaTemp.Add("total_fee", base.Money.ToString("0.00"));
            sParaTemp.Add("body", base.Description);
            sParaTemp.Add("paymethod", this.PayMethod);
            sParaTemp.Add("anti_phishing_key", this.anti_phishing_key);
            sParaTemp.Add("exter_invoke_ip", this.clientIP);

            Encoding encoding = Encoding.GetEncoding(_input_charset);

            Dictionary<string, string> sPara = this.FilterPara(sParaTemp);
            //處理字符串
            string prestr = this.CreateLinkString(sPara);
            sPara.Add("sign", Sign(prestr)); //簽名驗證
            sPara.Add("sign_type", sign_type);

            string url = string.Format("{0}_input_charset={1}&{2}", GATEWAY, _input_charset, CreateLinkString(sPara));
            HttpContext.Current.Response.Redirect(url);
        }


        public override bool Verify(VerifyCallBack callback)
        {
            #region =========  DEBUG  ==========

            StringBuilder sb = new StringBuilder();
            sb.AppendLine(DateTime.Now + "\n");
            foreach (var keyValue in this.GetRequestGet())
            {
                sb.AppendFormat("{0}:{1}\t", keyValue.Key, keyValue.Value);
            }
            sb.AppendLine().AppendLine("------------------------");
            if (HttpContext.Current != null)
                System.IO.File.AppendAllText(HttpContext.Current.Server.MapPath("~/App_Data/Alipay.log"), sb.ToString(), Encoding.UTF8);

            #endregion

            SortedDictionary<string, string> inputPara = this.GetRequestGet();
            string notify_id = WebAgent.GetParam("notify_id");
            string sign = WebAgent.GetParam("sign");
            string status = WebAgent.GetParam("trade_status");
            Dictionary<string, string> sPara = this.FilterPara(inputPara);
            string preSignStr = this.CreateLinkString(sPara);
            if (this.Sign(preSignStr) != sign) return false;
            if (!string.IsNullOrEmpty(notify_id))
            {
                string veryfy_url = VERYFYURL + "partner=" + this.Partner + "&notify_id=" + notify_id;
                if (NetAgent.DownloadData(veryfy_url, Encoding.GetEncoding(_input_charset)) != "true") return false;
            }
            bool isSuccess = false;
            switch (status)
            {
                case "TRADE_SUCCESS":   // 高級即時到賬狀態下
                case "TRADE_FINISHED":  // 普通即時到賬狀態下
                case "WAIT_SELLER_SEND_GOODS":  // 擔保交易  等待賣家發貨

                    isSuccess = true;
                    break;
                default:
                    isSuccess = false;
                    break;
            }
            if (isSuccess) callback.Invoke();
            return isSuccess;
        }
View Code

 

 

 

相關文章
相關標籤/搜索