自动充值平台开发进程之联通卡密一最终实现


最近一直忙于移动,联通,电信充值平台开发,需要做的软件也在特别多,有13800138000,空中充值,移动手机支付,联通卡密验证与提交,和三方接口的对接,

其中三方接口应该是最简单的,三方对口,如易宝,欧飞等,其中13800138000是通过猫池来进行语言拨号,来完成充值,我们不像别的大公司有专门的接口,移动手机支付和联通卡密,我们都做的是辅助软件来完成.

 

现把思路整理一下做个记录,方便日后,也给需要这方面的朋友一个参考吧

 

 

在开发之前,列一下我所用的到工个

开发工具和数据库不用多说 vs2010+sql2005,

还有抓包工具,HttpAnalyzerFullV5和WSExplorer,这两个工具的破解版网上一搜就能搜出一把把。

 

联通卡密辅助软件开发的几个重点

1.验证码,大部分人在验证码这块会卡住,验证码没过自动提交根本就谈不上,过验证码对于没有接触这块的人来说需要时间一研究,网上也有叫卖的

2.抓包,只有抓到数据包后,合理分的分析出有用的数据,才能去自动提交我们想要的数据。

我抓到的数据包如下图

HttpAnalyzerFullV5这个工具还是具好用的,有浏览器插件版和独立版

下面为独立版

插件版

开始抓包

在上面这个图中就是我用抓包工具抓到的数据,里面可以清楚的看到,需要post过来的参数名和对应的值,以及一起提交的cookie等相应的数据

 充值的手机号,充值的卡密,和验证码都在里面了呵呵,

今天就写到这里,下次再写

 

 

 

前两篇已把相应的准备工作和功能说明列了一下,今天就把详细的实现写一下,以后的将把13800138000的语音拨号系统,和手机短信群发的的实现也发上。

 

 

 

开始这次的内容。

首先就是需要用到模拟提交的两个类

 HttpHead.cs 这个类(其实是结构)它的主要功能就是封装了Http请求的一个头信息

using System;
using System.Net;
using System.Drawing;

namespace NetHelper {
    /// <summary>
    /// Http头信息设置
    /// </summary>
    public struct HttpHead {
        public String Host;    //主机
        public String Referer;   //引用
        public CookieCollection Cookies;  //cookies容器
        public String PostData;       //请求的传给服务器的参数
        public String Method;        //请求方式常见的POST,GET
        public String ContentType;       
        public String Html;         //响应的html代码
        public String AbsoluteUri;      
        public Bitmap Image;        //如果请求的是图片,这里返回一个Bitmap对象
        public Boolean IsImage;       //是否为图片
    }
}

HttpRequest.cs   //用来发起提交的

namespace NetHelper {
    using System;
    using System.Drawing;
    using System.IO;
    using System.Net;
    using System.Text;

    /// <summary>
    /// Http请求封装类,包括 POST,GET请求
    /// 幸福海
    /// </summary>
    public class HttpRequest {
        private CookieContainer cookies;
        public CookieContainer Cookies {
            get { return this.cookies; }
            set { this.cookies = value; }
        }
        /// <summary>
        /// Http请求
        /// 幸福海
        /// </summary>
        public HttpRequest() {
            this.Cookies = new CookieContainer();
        }
        /// <summary>
        /// 发送HTTP请求
        /// </summary>
        /// <param name="Head">HTTP头结构</param>
        /// <returns></returns>
        public String Send(ref HttpHead Head) {
            HttpWebResponse Response = null;
            String val = "";
            try {
                HttpWebRequest Request = (HttpWebRequest)HttpWebRequest.Create(Head.Host);
                Request.ProtocolVersion = new Version("1.1");
                Request.Referer = Head.Referer;
                Request.Accept = "*/*";
                Request.CookieContainer = this.Cookies;
                Request.Timeout = 100000;
                Request.Headers.Add("Accept-Language", "zh-CN");
                Request.KeepAlive = true;
                Request.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1;.NET CLR 2.0.50727)";

                if (Head.Method.ToLower() == "post") {
                    Request.Method = "POST";
                    if (String.IsNullOrEmpty(Head.ContentType)) {
                        Request.ContentType = "application/x-www-form-urlencoded";
                    }
                    else {
                        Request.ContentType = Head.ContentType;
                    }
                    if (Head.PostData != null && Head.PostData.Length > 0) {
                        Byte[] byteData = Encoding.Default.GetBytes(Head.PostData);
                        Request.ContentLength = byteData.Length;
                        Stream WriteStream = Request.GetRequestStream();
                        WriteStream.Write(byteData, 0, byteData.Length);
                        WriteStream.Close();
                    }
                }
                try {
                    Response = (HttpWebResponse)Request.GetResponse();
                }
                catch (WebException ex) {
                    if (ex.Response != null) {
                        Response = (HttpWebResponse)ex.Response;
                    }
                    else {
                        return "网络异常";
                    }
                }
                foreach (Cookie cookie in Request.CookieContainer.GetCookies(Request.RequestUri)) {
                    this.Cookies.Add(cookie);
                }
                Stream dataStream = Response.GetResponseStream();
                if (Head.IsImage) {
                    Bitmap img = new Bitmap(dataStream);
                    Head.Image = img;
                    return "";
                }
                else {
                    String encode = Response.CharacterSet;
                    if (encode == null) encode = "gb2312";
                    if (encode.ToLower() == "iso-8859-1") encode = "gb2312";
                    StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding(encode));
                    val = reader.ReadToEnd();
                    Head.AbsoluteUri = Response.ResponseUri.AbsoluteUri;
                    reader.Close();
                    dataStream.Close();
                    Response.Close();
                    Head.Html = val;
                }
            }
            catch {
                return "未知错误";
            }
            return val;
        }
    }
}

这个类中最关键的是那个关联cookie,这里不详细说明,具体看代码,如果有不明白的地方,请提出来。

        //开始提交联通卡密,这就是那个按钮对应的事件
        private void BtnOk_Click(object sender, EventArgs e) {
            String strTel = tbTel.Text.Trim();
            String strPass = tbPass.Text.Trim();
            String Result = UnionCardPay(strTel, strPass);
            lblMsg.Text = BuilderErrMsg(Result);  //显示充值信息
        }

 

   //重填输入框,重置按钮事件
        private void BtnReset_Click(object sender, EventArgs e) {
            tbTel.Text = tbPass.Text = String.Empty;
        }

 

  //字符串中获取指定开始和结束的子串
        private String GetValue(string str, string s, string e) {
            Regex regex = new Regex("(?<=(" + s + "))[.\\s\\S]*?(?=(" + e + "))", RegexOptions.Multiline | RegexOptions.Singleline);
            return regex.Match(str).Value;
        }

        //对错误编码进行处理
        private String BuilderErrMsg(String errCode) {
            String val = "";
            switch (errCode) {
                case "001": val = "充值卡已使用"; break;
                case "002": val = "您输入的充值卡密码有误"; break;
                case "003": val = "您输入的交费充值号码不存在"; break;
                case "004": val = "请正确输入手机号码"; break;
                case "005": val = "验证码5次匹配不成功"; break;
                case "006": val = "充值卡已过期"; break;
                case "007": val = "充值失败"; break;
                case "008": val = "异常,或无法连接服务器"; break;
                case "888": val = "充值成功"; break;
            }
            return val;
        }

        //联通卡密提交
        String UnionCardPay(String tel, String pass) {
            try {
                String result = "";
                NetHelper.HttpHead head = new NetHelper.HttpHead();
                NetHelper.HttpRequest request = new NetHelper.HttpRequest();
                request.Cookies = new System.Net.CookieContainer();

                //充值初始化页
                head.Host = "http://upay.10010.com/web/Recharge/rechargeInit";
                head.Method = "GET";
                request.Send(ref head);
                result = head.Html;
                String state = GetValue(result, "name=\"secstate.state\" value=\"", "\" id=\"secstate.state\"/>");

                //自动过验证码
                Int16 index = 1;
                while (1 == 1) {
                    head.Host = "http://upay.10010.com/web/EsfWeb/VerifyCode.action?timestamp=" + DateTime.Now.ToString("yyyyMMddhhmmss");
                    head.IsImage = true;
                    head.Method = "GET";
                    request.Send(ref head);
                    Bitmap img = head.Image;
                    CheckImage imgChk = new CheckImage();
                    String chk = imgChk.GetCheckCode(img);

                    //提交充值号码和卡密
                    String para = "numbean.userNumBean.userSelNum=1&numbean.userNumBean.otherNum=" + tel + "&cardPwd=" + pass + "&verifyCode=" + chk;
                    para += "&numbean.cityCodeBean.provinceId=&numbean.cityCodeBean.cityId=&numbean.cityCodeBean.cityCode=&numbean.userNumBean.telNum=";
                    para += "&secstate.state=" + state;
                    head.Host = "http://upay.10010.com/web/Recharge/rechargeConfirm";
                    head.PostData = para;
                    head.IsImage = false;
                    head.Method = "POST";
                    head.Referer = "http://upay.10010.com/web/Recharge/rechargeInit";
                    request.Send(ref head);
                    result = head.Html;
                    state = GetValue(result, "name=\"secstate.state\" value=\"", "\" id=\"secstate.state\"/>");
                    result = GetValue(result, "<div id='ecs_err_msg_div' class='ceng_jinshi' cssStyle='' align='left'>", "</div>");//提交状态
                    //状态处理
                    if (result.Contains("验证码不正确")) { // 验证码匹配5次不正确。
                        if (index++ >= 5) {
                            return "005";
                        }
                        else {
                            continue; //重新跳转到验证码识别
                        }
                    }
                    break;
                }

                if (result.Contains("输入的充值卡已充值")) { //尊敬的用户您好,您输入的充值卡已充值,无法再次使用,请更换充值卡重新操作
                    return "001";
                }

                if (result.Contains("您输入的充值卡密码有误")) { //尊敬的用户您好,您输入的充值卡密码有误,请重新输入。
                    return "002";
                }

                if (result.Contains("您输入的交费充值号码不存在")) { // 尊敬的用户您好,您输入的交费充值号码不存在,请重新输入。
                    return "003";
                }

                if (result.Contains("请正确输入手机号码")) { //请正确输入手机号码。
                    return "004";
                }

                if (result.Contains("过期")) { //充值卡已过期。
                    return "006";
                }


                //确认充值结果
                head.Host = "http://upay.10010.com/web/Recharge/rechargeResult";
                head.Method = "POST";
                head.PostData = "secstate.state=" + state;
                head.Cookies = request.Cookies.GetCookies(new Uri(head.Host));
                head.Referer = "http://upay.10010.com/web/Recharge/rechargeConfirm";
                request.Send(ref head);
                result = head.Html;
                if (!result.Contains("<td>成功</td>")) { //最后一步没有完成,即充值失败
                    return "009";
                }
                return "888";
            }
            catch {
                return "009";
            }
        }

 

全部代码就这些,这里主要是给大家整理思路,主要是通过C#向服务器提交数据

现把联通卡密提交的顺序说一下

1,当我们启动抓包工具,开始提交数据的时候,我们会看到,有几个参数提到了服务器端

 

这几个,名称看上去怪怪的,原因很简单,主是因为联通这个站是JAVA来写到了,用了Bean,所有看上去名称就比较上

其实对我们来说无所谓

 

numbean.userNumBean.userSelNum 如果是给手机充值这个是1,固话小灵通,宽带就为2
numbean.userNumBean.otherNum   手机号码
cardPwd               卡密
verifyCode              验证码,

下面四个我们可以不管他了
numbean.cityCodeBean.provinceId
numbean.cityCodeBean.cityId
numbean.cityCodeBean.cityCode
numbean.userNumBean.telNum

这个参数非常重要,也就是一个隐藏域的东西,估计是一个加密字符串充,如果错了,就提交不上了。
secstate.state

 

最后当我们点提交的时候,就可以得到相应的信息,假如你还要获取订单号,和充值的金额,你只对html源进行分析,截取就行了

OK,这个联通的卡密就写到这里,由于第一次写东西,没有什么思路,呵呵,想到哪就写到哪了,毕竟文学功底有限,希望以后写文章这方面的功能加强些,

如果大家对这个联通卡密自动提交还不是很清楚的话,可以随你给我发信息.

 

前两篇已把相应的准备工作和功能说明列了一下,今天就把详细的实现写一下,以后的将把13800138000的语音拨号系统,和手机短信群发的的实现也发上。

开始这次的内容。

首先就是需要用到模拟提交的两个类

 HttpHead.cs 这个类(其实是结构)它的主要功能就是封装了Http请求的一个头信息

using System;
using System.Net;
using System.Drawing;

namespace NetHelper {
    /// <summary>
    /// Http头信息设置
    /// </summary>
    public struct HttpHead {
        public String Host;    //主机
        public String Referer;   //引用
        public CookieCollection Cookies;  //cookies容器
        public String PostData;       //请求的传给服务器的参数
        public String Method;        //请求方式常见的POST,GET
        public String ContentType;       
        public String Html;         //响应的html代码
        public String AbsoluteUri;      
        public Bitmap Image;        //如果请求的是图片,这里返回一个Bitmap对象
        public Boolean IsImage;       //是否为图片
    }
}

HttpRequest.cs   //用来发起提交的

namespace NetHelper {
    using System;
    using System.Drawing;
    using System.IO;
    using System.Net;
    using System.Text;

    /// <summary>
    /// Http请求封装类,包括 POST,GET请求
    /// 幸福海
    /// </summary>
    public class HttpRequest {
        private CookieContainer cookies;
        public CookieContainer Cookies {
            get { return this.cookies; }
            set { this.cookies = value; }
        }
        /// <summary>
        /// Http请求
        /// 幸福海
        /// </summary>
        public HttpRequest() {
            this.Cookies = new CookieContainer();
        }
        /// <summary>
        /// 发送HTTP请求
        /// </summary>
        /// <param name="Head">HTTP头结构</param>
        /// <returns></returns>
        public String Send(ref HttpHead Head) {
            HttpWebResponse Response = null;
            String val = "";
            try {
                HttpWebRequest Request = (HttpWebRequest)HttpWebRequest.Create(Head.Host);
                Request.ProtocolVersion = new Version("1.1");
                Request.Referer = Head.Referer;
                Request.Accept = "*/*";
                Request.CookieContainer = this.Cookies;
                Request.Timeout = 100000;
                Request.Headers.Add("Accept-Language", "zh-CN");
                Request.KeepAlive = true;
                Request.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1;.NET CLR 2.0.50727)";

                if (Head.Method.ToLower() == "post") {
                    Request.Method = "POST";
                    if (String.IsNullOrEmpty(Head.ContentType)) {
                        Request.ContentType = "application/x-www-form-urlencoded";
                    }
                    else {
                        Request.ContentType = Head.ContentType;
                    }
                    if (Head.PostData != null && Head.PostData.Length > 0) {
                        Byte[] byteData = Encoding.Default.GetBytes(Head.PostData);
                        Request.ContentLength = byteData.Length;
                        Stream WriteStream = Request.GetRequestStream();
                        WriteStream.Write(byteData, 0, byteData.Length);
                        WriteStream.Close();
                    }
                }
                try {
                    Response = (HttpWebResponse)Request.GetResponse();
                }
                catch (WebException ex) {
                    if (ex.Response != null) {
                        Response = (HttpWebResponse)ex.Response;
                    }
                    else {
                        return "网络异常";
                    }
                }
                foreach (Cookie cookie in Request.CookieContainer.GetCookies(Request.RequestUri)) {
                    this.Cookies.Add(cookie);
                }
                Stream dataStream = Response.GetResponseStream();
                if (Head.IsImage) {
                    Bitmap img = new Bitmap(dataStream);
                    Head.Image = img;
                    return "";
                }
                else {
                    String encode = Response.CharacterSet;
                    if (encode == null) encode = "gb2312";
                    if (encode.ToLower() == "iso-8859-1") encode = "gb2312";
                    StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding(encode));
                    val = reader.ReadToEnd();
                    Head.AbsoluteUri = Response.ResponseUri.AbsoluteUri;
                    reader.Close();
                    dataStream.Close();
                    Response.Close();
                    Head.Html = val;
                }
            }
            catch {
                return "未知错误";
            }
            return val;
        }
    }
}

这个类中最关键的是那个关联cookie,这里不详细说明,具体看代码,如果有不明白的地方,请提出来。

        //开始提交联通卡密,这就是那个按钮对应的事件
        private void BtnOk_Click(object sender, EventArgs e) {
            String strTel = tbTel.Text.Trim();
            String strPass = tbPass.Text.Trim();
            String Result = UnionCardPay(strTel, strPass);
            lblMsg.Text = BuilderErrMsg(Result);  //显示充值信息
        }

 

   //重填输入框,重置按钮事件
        private void BtnReset_Click(object sender, EventArgs e) {
            tbTel.Text = tbPass.Text = String.Empty;
        }

 

  //字符串中获取指定开始和结束的子串
        private String GetValue(string str, string s, string e) {
            Regex regex = new Regex("(?<=(" + s + "))[.\\s\\S]*?(?=(" + e + "))", RegexOptions.Multiline | RegexOptions.Singleline);
            return regex.Match(str).Value;
        }

        //对错误编码进行处理
        private String BuilderErrMsg(String errCode) {
            String val = "";
            switch (errCode) {
                case "001": val = "充值卡已使用"; break;
                case "002": val = "您输入的充值卡密码有误"; break;
                case "003": val = "您输入的交费充值号码不存在"; break;
                case "004": val = "请正确输入手机号码"; break;
                case "005": val = "验证码5次匹配不成功"; break;
                case "006": val = "充值卡已过期"; break;
                case "007": val = "充值失败"; break;
                case "008": val = "异常,或无法连接服务器"; break;
                case "888": val = "充值成功"; break;
            }
            return val;
        }

        //联通卡密提交
        String UnionCardPay(String tel, String pass) {
            try {
                String result = "";
                NetHelper.HttpHead head = new NetHelper.HttpHead();
                NetHelper.HttpRequest request = new NetHelper.HttpRequest();
                request.Cookies = new System.Net.CookieContainer();

                //充值初始化页
                head.Host = "http://upay.10010.com/web/Recharge/rechargeInit";
                head.Method = "GET";
                request.Send(ref head);
                result = head.Html;
                String state = GetValue(result, "name=\"secstate.state\" value=\"", "\" id=\"secstate.state\"/>");

                //自动过验证码
                Int16 index = 1;
                while (1 == 1) {
                    head.Host = "http://upay.10010.com/web/EsfWeb/VerifyCode.action?timestamp=" + DateTime.Now.ToString("yyyyMMddhhmmss");
                    head.IsImage = true;
                    head.Method = "GET";
                    request.Send(ref head);
                    Bitmap img = head.Image;
                    CheckImage imgChk = new CheckImage();
                    String chk = imgChk.GetCheckCode(img);

                    //提交充值号码和卡密
                    String para = "numbean.userNumBean.userSelNum=1&numbean.userNumBean.otherNum=" + tel + "&cardPwd=" + pass + "&verifyCode=" + chk;
                    para += "&numbean.cityCodeBean.provinceId=&numbean.cityCodeBean.cityId=&numbean.cityCodeBean.cityCode=&numbean.userNumBean.telNum=";
                    para += "&secstate.state=" + state;
                    head.Host = "http://upay.10010.com/web/Recharge/rechargeConfirm";
                    head.PostData = para;
                    head.IsImage = false;
                    head.Method = "POST";
                    head.Referer = "http://upay.10010.com/web/Recharge/rechargeInit";
                    request.Send(ref head);
                    result = head.Html;
                    state = GetValue(result, "name=\"secstate.state\" value=\"", "\" id=\"secstate.state\"/>");
                    result = GetValue(result, "<div id='ecs_err_msg_div' class='ceng_jinshi' cssStyle='' align='left'>", "</div>");//提交状态
                    //状态处理
                    if (result.Contains("验证码不正确")) { // 验证码匹配5次不正确。
                        if (index++ >= 5) {
                            return "005";
                        }
                        else {
                            continue; //重新跳转到验证码识别
                        }
                    }
                    break;
                }

                if (result.Contains("输入的充值卡已充值")) { //尊敬的用户您好,您输入的充值卡已充值,无法再次使用,请更换充值卡重新操作
                    return "001";
                }

                if (result.Contains("您输入的充值卡密码有误")) { //尊敬的用户您好,您输入的充值卡密码有误,请重新输入。
                    return "002";
                }

                if (result.Contains("您输入的交费充值号码不存在")) { // 尊敬的用户您好,您输入的交费充值号码不存在,请重新输入。
                    return "003";
                }

                if (result.Contains("请正确输入手机号码")) { //请正确输入手机号码。
                    return "004";
                }

                if (result.Contains("过期")) { //充值卡已过期。
                    return "006";
                }


                //确认充值结果
                head.Host = "http://upay.10010.com/web/Recharge/rechargeResult";
                head.Method = "POST";
                head.PostData = "secstate.state=" + state;
                head.Cookies = request.Cookies.GetCookies(new Uri(head.Host));
                head.Referer = "http://upay.10010.com/web/Recharge/rechargeConfirm";
                request.Send(ref head);
                result = head.Html;
                if (!result.Contains("<td>成功</td>")) { //最后一步没有完成,即充值失败
                    return "009";
                }
                return "888";
            }
            catch {
                return "009";
            }
        }

 

全部代码就这些,这里主要是给大家整理思路,主要是通过C#向服务器提交数据

现把联通卡密提交的顺序说一下

1,当我们启动抓包工具,开始提交数据的时候,我们会看到,有几个参数提到了服务器端

 

这几个,名称看上去怪怪的,原因很简单,主是因为联通这个站是JAVA来写到了,用了Bean,所有看上去名称就比较上

其实对我们来说无所谓

 

numbean.userNumBean.userSelNum 如果是给手机充值这个是1,固话小灵通,宽带就为2
numbean.userNumBean.otherNum   手机号码
cardPwd               卡密
verifyCode              验证码,

下面四个我们可以不管他了
numbean.cityCodeBean.provinceId
numbean.cityCodeBean.cityId
numbean.cityCodeBean.cityCode
numbean.userNumBean.telNum

这个参数非常重要,也就是一个隐藏域的东西,估计是一个加密字符串充,如果错了,就提交不上了。
secstate.state

 

最后当我们点提交的时候,就可以得到相应的信息,假如你还要获取订单号,和充值的金额,你只对html源进行分析,截取就行了

OK,这个联通的卡密就写到这里,由于第一次写东西,没有什么思路,呵呵,想到哪就写到哪了,毕竟文学功底有限,希望以后写文章这方面的功能加强些,

如果大家对这个联通卡密自动提交还不是很清楚的话,可以随你给我发信息.

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
系统 1. 确定系统需求 首先,我们需要确定这套卡密验证系统的需求,包括: - 支持生成卡密 - 支持校验卡密 - 支持使用卡密后的处理(如记录使用情况、更新卡密状态等) 2. 设计数据库结构 根据系统需求,我们需要设计一套数据库结构,其中至少包括以下表: - 卡密表:包括卡密编号、卡密状态、卡密类型等字段 - 订单表:包括订单编号、订单状态、订单金额等字段 - 使用记录表:包括使用记录编号、卡密编号、使用时间等字段 3. 开发后端接口 接下来,我们需要开发一套后端接口,包括: - 生成卡密接口:根据用户传入的卡密类型、数量等信息生成卡密,并插入卡密表中 - 校验卡密接口:根据用户传入的卡密编号和订单编号,判断卡密是否可用,并更新卡密状态和订单状态 - 使用记录接口:记录卡密的使用情况,包括卡密编号、使用时间等信息 4. 开发前端页面 最后,我们需要开发一套前端页面,包括: - 生成卡密页面:用户可以在该页面选择卡密类型、数量等信息,并提交生成卡密请求 - 校验卡密页面:用户可以在该页面输入卡密编号和订单编号,进行卡密校验 - 使用记录页面:管理员可以在该页面查看卡密的使用记录,包括卡密编号、使用时间等信息 总之,使用nodejs开发一套卡密验证系统需要考虑数据库结构设计、后端接口开发、前端页面开发等多个方面,需要有一定的技术实力和项目经验。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值