说是手机充值系统有点装了,其实就是调用了聚合数据的支付接口,其实挺简单的事 但是我发现博客园竟然没有类似文章,我就个出头鸟把我的代码贡献出来吧

首先说准备工作:

去聚合数据申请账号-添加手机支付的认证-认证通过后为账户充值。

上述工作完成后,开始准备开发要用到的必要参数:

appid:在个人中心-我的数据中可找到对应的APPKEY(每个不同的接口都需要使用对应的appkey)

openid:个人中心-用户中心-账户信息(这个是唯一的程序中会使用到)

对应的接口都有比较详细的数据接收已经返回参数的说明,具体开发中会用到,具体的请查看链接:https://www.juhe.cn/docs/api/id/85

接下来要准备开发中的用到几个辅助函数,在对应的API文档中有示例代码,也可以使用下面的:

    /// <summary>
/// Http (GET/POST)
/// </summary>
/// <param name="url">请求URL</param>
/// <param name="parameters">请求参数</param>
/// <param name="method">请求方法</param>
/// <returns>响应内容</returns>
static string sendPost(string url, IDictionary<string, string> parameters, string method)
{
if (method.ToLower() == "post")
{
HttpWebRequest req = null;
HttpWebResponse rsp = null;
System.IO.Stream reqStream = null;
try
{
req = (HttpWebRequest)WebRequest.Create(url);
req.Method = method;
req.KeepAlive = false;
req.ProtocolVersion = HttpVersion.Version10;
req.Timeout = ;
req.ContentType = "application/x-www-form-urlencoded;charset=utf-8";
byte[] postData = Encoding.UTF8.GetBytes(BuildQuery(parameters, "utf8"));
reqStream = req.GetRequestStream();
reqStream.Write(postData, , postData.Length);
rsp = (HttpWebResponse)req.GetResponse();
Encoding encoding = Encoding.GetEncoding(rsp.CharacterSet);
return GetResponseAsString(rsp, encoding);
}
catch (Exception ex)
{
return ex.Message;
}
finally
{
if (reqStream != null) reqStream.Close();
if (rsp != null) rsp.Close();
}
}
else
{
//创建请求
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url + "?" + BuildQuery(parameters, "utf8")); //GET请求
request.Method = "GET";
request.ReadWriteTimeout = ;
request.ContentType = "text/html;charset=UTF-8";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream myResponseStream = response.GetResponseStream();
StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8")); //返回内容
string retString = myStreamReader.ReadToEnd();
return retString;
}
}
/// <summary>
/// 把响应流转换为文本。
/// </summary>
/// <param name="rsp">响应流对象</param>
/// <param name="encoding">编码方式</param>
/// <returns>响应文本</returns>
static string GetResponseAsString(HttpWebResponse rsp, Encoding encoding)
{
System.IO.Stream stream = null;
StreamReader reader = null;
try
{
// 以字符流的方式读取HTTP响应
stream = rsp.GetResponseStream();
reader = new StreamReader(stream, encoding);
return reader.ReadToEnd();
}
finally
{
// 释放资源
if (reader != null) reader.Close();
if (stream != null) stream.Close();
if (rsp != null) rsp.Close();
}
}
/// <summary>
/// 组装普通文本请求参数。
/// </summary>
/// <param name="parameters">Key-Value形式请求参数字典</param>
/// <returns>URL编码后的请求数据</returns>
static string BuildQuery(IDictionary<string, string> parameters, string encode)
{
StringBuilder postData = new StringBuilder();
bool hasParam = false;
IEnumerator<KeyValuePair<string, string>> dem = parameters.GetEnumerator();
while (dem.MoveNext())
{
string name = dem.Current.Key;
string value = dem.Current.Value;
// 忽略参数名或参数值为空的参数
if (!string.IsNullOrEmpty(name))//&& !string.IsNullOrEmpty(value)
{
if (hasParam)
{
postData.Append("&");
}
postData.Append(name);
postData.Append("=");
if (encode == "gb2312")
{
postData.Append(HttpUtility.UrlEncode(value, Encoding.GetEncoding("gb2312")));
}
else if (encode == "utf8")
{
postData.Append(HttpUtility.UrlEncode(value, Encoding.UTF8));
}
else
{
postData.Append(value);
}
hasParam = true;
}
}
return postData.ToString();
}
/// <summary>
/// 获取时间戳
/// </summary>
/// <returns></returns>
public static string GetTimeStamp()
{
TimeSpan ts = DateTime.UtcNow - new DateTime(, , , , , , );
return Convert.ToInt64(ts.TotalSeconds).ToString();
}

这几个函数具体的功能就不用说了 ,是代码很简单,都是网络链接发送请求和接受请求是时用的,我主要介绍的是点中未提供的一些

示例代码中用到了JsonObject这个类 代码中提供的是CSDN的链接,竟然还要2积分才能下载,坑爹啊 在这里我给大家分享出来吧 http://pan.baidu.com/s/1hsqF51y

在项目中应用DLL加入using Xfrog.Net;命名空间

准备工作结束

接下来就进入正式编码阶段了 ,开始前我准备说一下重点,其实接口的代码并不复杂,我想说了还是思路吧

1.验证当前账户余额是否够本次充值:调用 http://op.juhe.cn/ofpay/mobile/yue 具体参数参看:https://www.juhe.cn/docs/api/id/85

2.检测手机号是否可以充值:调用http://op.juhe.cn/ofpay/mobile/telcheck    具体参数参看:https://www.juhe.cn/docs/api/id/85/aid/213

3.调用手机直冲接口:   http://op.juhe.cn/ofpay/mobile/onlineorder       具体参数参看: https://www.juhe.cn/docs/api/id/85/aid/214

4.调用订单查询接口:http://op.juhe.cn/ofpay/mobile/ordersta                具体参数参看:https://www.juhe.cn/docs/api/id/85/aid/586

5.编写回调处理页面:QQ上搜索聚合数据的客服,给他账号和回调地址后,让他帮助设置,具体的回调地址接受参数查看:http://code.juhe.cn/docs/detail/id/1565

具体代码贴出:

            //1.账户余额查询
string url1 = "http://op.juhe.cn/ofpay/mobile/yue"; var parameters1 = new Dictionary<string, string>(); string timestamp = GetTimeStamp();
parameters1.Add("timestamp", timestamp); //当前时间戳,如:1432788379
parameters1.Add("key", appkey);//你申请的key
string signstr =openid+ appkey+timestamp;
parameters1.Add("sign", CommonManager.String.EncryptMD5SystemDefaultMethod(signstr, false, true)); //校验值,md5(&lt;b&gt;OpenID&lt;/b&gt;+key+timestamp),OpenID在个人中心查询 string result1 = sendPost(url1, parameters1, "get"); JsonObject newObj1 = new JsonObject(result1);
String errorCode1 = newObj1["error_code"].Value; //查询余额是否成功
if (errorCode1 == "")
{ //判断余额是否够本次充值
if (double.Parse(newObj1["result"]["money"].Value) > double.Parse(Integrals)) {
//msg.InnerText="余额充足!"; //5.检测手机号码是否能充值
string url5 = "http://op.juhe.cn/ofpay/mobile/telcheck"; var parameters5 = new Dictionary<string, string>(); parameters5.Add("phoneno", phone); //手机号码
parameters5.Add("cardnum", Integrals); //充值金额,目前可选:5、10、20、30、50、100、300
parameters5.Add("key", appkey);//你申请的key string result5 = sendPost(url5, parameters5, "get"); JsonObject newObj5 = new JsonObject(result5);
String errorCode5 = newObj5["error_code"].Value; if (errorCode5 == "")
{
//可以充值
//7.手机直充接口
string url7 = "http://op.juhe.cn/ofpay/mobile/onlineorder"; var parameters7 = new Dictionary<string, string>();
parameters7.Add("phoneno", phone); //手机号码
parameters7.Add("cardnum", Integrals); //充值金额,目前可选:5、10、20、30、50、100、300
parameters7.Add("orderid", orderstr); //商家订单号,8-32位字母数字组合
parameters7.Add("key", appkey);//你申请的key
string md5str = openid + appkey + phone + Integrals + orderstr;
parameters7.Add("sign", CommonManager.String.EncryptMD5SystemDefaultMethod(md5str, false, true)); //校验值,md5(&lt;b&gt;OpenID&lt;/b&gt;+key+phoneno+cardnum+orderid),OpenID在个人中心查询 string result7 = sendPost(url7, parameters7, "get"); JsonObject newObj7 = new JsonObject(result7);
String errorCode7 = newObj7["error_code"].Value; if (errorCode7 == "")
{
msg.InnerText = "充值订单创建成功,等待商户充值后查看订单状态!"; DbSession.Default.FromSql(
@"UPDATE TOP(1) TPropLog SET Jhorderid=@Jhorderid,PropStatus=@PropStatus WHERE ID = @ID")
.AddInputParameter("@ID", DbType.Int32, id)
.AddInputParameter("@PropStatus", DbType.Int32, )
.AddInputParameter("@Jhorderid", DbType.String, newObj7["result"]["sporder_id"].Value)
.Execute();
status.SelectedValue = "";
}
else
{
msg.InnerText = "充值订单失败!失败原因:" + newObj7["reason"].Value;
} }
else
{
msg.InnerText = "手机号不能充值!原因:" + newObj1["reason"].Value;
} }
else
{
msg.InnerText = "余额不足请充值!当前账户余额为:" + newObj1["result"]["money"].Value;
} }
else
{
msg.InnerText="余额查询失败!"; }

里面有几个点注意一下:

1.需要sign签名的几个接口需要按照格式使用MD5进行一个转换,MD5转换的函数网上一大把相信你的项目中也有了我就不提供了 ,按照他提供的格式组织签名就行了

2.我的订单查询接口是写在另外一个函数里的,因为我的逻辑充值后单独可以查询,可根据情况自行更改。

3.回调页面是POST方式传值,所以接受的时候按照他提供的参数接收就行了,根据返回的订单号跟新本地数据

        //聚合话费充值回调页面,页面的设置需要联系聚合客服更改
protected void Page_Load(object sender, EventArgs e)
{ var sporder_id = CommonManager.Web.Request("sporder_id", "");//聚合订单ID
var orderid = CommonManager.Web.Request("orderid", ""); //鼎鼎订单ID
var sta = CommonManager.Web.Request("sta", ""); //充值状态1:成功 9:失败
if (sta == "")
{
//更新订单状态为充值成功
DbSession.Default.FromSql(
@"UPDATE TOP(1) TPropLog SET PropStatus=@PropStatus WHERE Jhorderid = @Jhorderid")
.AddInputParameter("@PropStatus", DbType.Int32, )
.AddInputParameter("@Jhorderid", DbType.String, sporder_id)
.Execute();
Response.Clear();
Response.Write("success");
Response.End();
}
if (sta == "")
{
//更新订单状态为充值成功
DbSession.Default.FromSql(
@"UPDATE TOP(1) TPropLog SET PropStatus=@PropStatus WHERE Jhorderid = @Jhorderid")
.AddInputParameter("@PropStatus", DbType.Int32, )
.AddInputParameter("@Jhorderid", DbType.String, sporder_id)
.Execute();
Response.Clear();
Response.Write("success");
Response.End();
//更新订单状态为充值失败
} }

重点回顾:

1.JsonObject.DLL下载

2.签名顺序和字符要按照提供的做

3.回调地址要找客服设置

4.单个手机号每天有充值数量和次数的限制,超过次数会导致订单一直提示进行中,最后失败,失败也会有回调提示的

5.测试的时候可以将vs自带的iis调试工具配合ngrok映射到外网,这样直接就可以调试回调页面,改天我会写一个简单的教程,如何使用vs默认的iis映射到外网进行调试(微信的外网调试也可以这么做,非常方便哦)

C#手机充值系统开发(基于聚合数据)的更多相关文章

  1. [系统开发] 基于Ansible的产品上线系统

    前言: 应部门急需,开发了一套基于Ansible Playbook的产品上线系统.由于时间很紧,UI直接套用了之前开发的一套perl cgi模板,后续计划用 django 重新编写. 个人感觉该系统的 ...

  2. [1]开发准备-使用C#.NET开发基于本地数据缓存的PC客户端

    小记:本人是PHPer,对C#.NET的开发只能说看得懂,也写得了功能略简单的PC客户端程序,下面的是本人开发一款名叫“理财速记”的PC客户端软件的全过程记录,期间包括比较繁琐的C#.NET资料查询等 ...

  3. [2]项目创建-使用C#.NET开发基于本地数据缓存的PC客户端

    1.新建项目->已安装->模板->Visual c#->Windows桌面->Windows窗体应用程序,截图如下: 图中1:输入项目名称-“MoneyNotes”,图中 ...

  4. 调用聚合数据新闻头条API

    基于聚合数据新闻头条接口 支持阅读新闻类型包括: 各类社会.国内.国际.体育.娱乐.科技等资讯,更新周期5-30分钟. 新闻内容类型的多选,支持皮肤功能. 使用前需要有聚合数据账号,并实名制后通过 新 ...

  5. 基于C/S架构的3D对战网络游戏C++框架 _05搭建系统开发环境与Boost智能指针、内存池初步了解

    本系列博客主要是以对战游戏为背景介绍3D对战网络游戏常用的开发技术以及C++高级编程技巧,有了这些知识,就可以开发出中小型游戏项目或3D工业仿真项目. 笔者将分为以下三个部分向大家介绍(每日更新): ...

  6. 基于ssh框架的在线考试系统开发的质量属性

    我做的系统是基于ssh框架的在线考试系统.在线考试系统有以下几点特性:(1)系统响应时间需要非常快,可以迅速的出题,答题.(2)系统的负载量也需要非常大,可以支持多人在线考试(3)还有系统的安全性也需 ...

  7. 基于SSH框架的网上书店系统开发的质量属性

    基于SSH框架的网上书店系统开发的质量属性 对于我的基于SSH框架的网上书店系统的开发要实现的质量属性有可用性.可修改性.性能.安全性.易用性和可测试性. 1.对于可用性方面的战术: 可用性(Avai ...

  8. SSM开发基于Java EE在线图书销售系统

           SSM(Spring+Spring MVC+MyBatis)开发基于Java EE在线图书销售系统  网站成功建立和运行很大部分取决于网站开发前的规划,因此为了在网站建立过程中避免一些不 ...

  9. 聚合数据董铭彦:小程序开发的兴起将带火API数据交易

    2016中关村大数据日活动近日在京举办,今年新进驻北京的聚合数据受邀参与,在13日举行的大数据交易专场论坛上,聚合数据副总裁董铭彦与参会嘉宾以"共筑数据交易产业生态,共享大数据时代红利&qu ...

随机推荐

  1. [Debug] Inspect and Style an Element in DevTools that Normally Disappears when Inactive

    It’s handy to inspect an element in your browser’s DevTools when you need to experiment or tweak it’ ...

  2. PS如何绘制虚线圆

    1 绘制一个圆的路径   2 选择铅笔工具,然后点击"画笔笔尖形状",选好笔尖的直径和间距(不同的直径对应不同的间距,没有标准数值,自己推拉滑动条就可以了)   3 在路径选项卡, ...

  3. MAVEN项目模块化

    maven的最大的特点之中的一个就是能够把项目模块化. 前面的一篇文章MAVEN创建并打包web项目已经创建了一个简单的webapp,注意这个webapp的打包方式是war. 假设如今又要划分出来一个 ...

  4. 基于cocos2d-x的跑酷游戏,不同高度地面的碰撞检測demo,有兴趣能够看一看

    1. demo大致分为4个模块: 地图,角色,障碍 逻辑检測认为和不同高度地面的碰撞.1次跳和2连跳的实现. 代码链接:http://download.csdn.net/detail/zangleng ...

  5. 【uoj35】后缀排序

    后缀数组模板题 #include<algorithm> #include<cstdlib> #include<cstring> #include<cstdio ...

  6. GuiLite 1.2 发布(希望通过这100+行代码来揭示:GuiLite的初始化,界面元素Layout,及消息映射的过程)

    经过开发群的长期验证,我们发现:即使代码只有5千多行,也不意味着能够轻松弄懂代码意图.痛定思痛,我们发现:虽然每个函数都很简单(平均长度约为30行),可以逐个击破:但各个函数之间如何协作,却很难说明清 ...

  7. 【OI】简单的分块

    介绍下简单的分块: 当我们遇到区间类问题的时候,如何保证我们快速而高效地完成操作? 答案是线段树分块. 所谓分块,就是把一个序列分成许多块分别维护.是不是想起了树状数组 这样能大大提高效率: 例如,我 ...

  8. 安卓图片载入之使用universalimageloader载入圆形圆角图片

    前言 话说这universalimageloader载入图片对搞过2年安卓程序都是用烂了再熟悉只是了.就是安卓新手也是百度就会有一大堆东西出来,今天为什么这里还要讲使用universalimagelo ...

  9. Android自己定义dialog中的EditText无法弹出键盘的解决

    近期我独立开发的项目<全医会>已经在内測其中了.非常快将会上架到各大应用市场.之前开发的几个项目都由于一些原因没有上架还是比較遗憾的.所以,近期我心情格外的好. 今天在做一个新项目,专为律 ...

  10. SpringMVC 运行过程

    加入jar包 在web.xml中配置DispatherServlet 加入SpringMVC配置文件 编写处理请求的处理器,并表示为处理器 编写视图 可见的运行流程: 实际的运行流程: