本文转自:http://www.cnblogs.com/mysweet/archive/2012/05/19/2508534.html

最近这几天很忙,一边忙着准备一堆课程设计(8门专业课.....伤不起...时间都是靠挤),一边还要党校培训....呃......顺便做了一下购物车,订单和支付宝简单的流程.

上次,曾经说到一个URL管理的问题,比如我们很多页面为了性能考虑生成静态页面,我们经常

性刚开始的时候用动态页面+ajax的方式加载,页面静态化的时候,如果是新闻内容页,我们可以

把静态页面的URL地址保存在数据库中,但是,单个页面,比如,首页,会员空间的各个页面,就不

适合放在数据库中,这时候更适合写一个通用模块类似MVC中的"控制器"来控制页面的静态化

和URL重写,这就省去了一个一个很繁琐的过程.

打个比方,我们可以写一个通用模块调用:

这种方式类似asp.net 中MVC的控制器,

函数大致的代码思路:

   1:      /// <summary>
   2:      /// 获得路径(暂时只做静态页面管理)(/*在这里可以扩展出URL重写*/)
   3:      /// </summary>
   4:      /// <param name="PageUrl">页面的URL(不包括扩展名)</param>
   5:      /// <param name="QueryString">页面参数</param>
   6:      /// <returns></returns>
   7:      public static string GetURL(string PageUrl,string QueryString)
   8:      {
   9:          //页面路径
  10:          string PagePath = "";
  11:          
  12:          //如果当前的参数不为空,则加上?
  13:          if (QueryString != "")
  14:              QueryString = "?" + QueryString;
  15:          //如果是静态页面(从配置文件中读取静态页面状态(是否))
  16:          if (ReadURLConfig(PageUrl) == true)
  17:          {
  18:              PagePath=PageUrl + ".htm" + QueryString;
  19:          }
  20:          //如果是动态页面
  21:          else
  22:              PagePath = PageUrl + ".aspx" + QueryString;
  23:          //把相对路径转化为绝对路径
  24:          return   System.Web.VirtualPathUtility.ToAbsolute(PagePath); ;
  25:      }
  26:      /// <summary>
  27:      /// 从配置文件中读取是否生成静态页面
  28:      /// </summary>
  29:      /// <param name="PageName">页面的名称</param>
  30:      /// <returns></returns>
  31:      public static bool ReadURLConfig(string PageName)
  32:      {
  33:          //读取配置文件
  34:          string path = HttpContext.Current.Server.MapPath(@"~/Admin/ConfigManage/URLConfig.xml");
  35:          //XmlHelper.Read(path, "/Node/Element[@Attribute='Name']", "Attribute")
  36:          //是否生成HTML
  37:          string IsHtml="false";
  38:          IsHtml=XMlHelper.Read(path, "/PageSettings/Page[@PageName='"+PageName+"']", "IsHtml");
  39:          if (IsHtml.ToLower() == "true")
  40:          {
  41:              return true;
  42:          }
  43:          else return false;
  44:         
  45:      }

配置文件属性:(URL重写部分,还没有实现)

我们可以在后台设置那些页面要生成HTML和URL重写规则的定制.......

不过貌似还有好多没实现,正在思考中............

进入主题:

这次,主要是购物车的实现,购物车的实现,我是在数据库建立了一个购物车的临时表,本来打算用Cookies做,不过,先用数据库做,比较稳妥,Cookies涉及安全性处理需要做很多处理.呃....这个以后可能会深入实现.

首先是,当用户点击

呃.....就ajax加入购物车,然后弹出层,显示

主要是ajax,先加入购物车(加入购物车之前,要检查购物车是否存在此商品,如果存在,本来应该

把购物车中商品的数量+1,我这里是直接提示用户已加入购物车,这是个小BUG),然后回调计

算购物车中的宝贝数量和总金额.

代码不太重要,这里就不粘贴了.

主要是思路要清晰一些.接下来就是购物车结算.

这个用了一个框架(改改颜色就上了,不过感觉加载了好多js,呃,....不过总比asp.net服务端控

件实现要好得多).

这个也就是增删改查设计,不过值得一提的就是,我们尽量把大量的前台js代码单独放在一个文

件中,这样客户端的缓存起来第二次访问起来就只需要更少的请求.

前台代码非常简洁:

   1:  <%@ Page Language="C#" MasterPageFile="~/Member.master" AutoEventWireup="true" CodeFile="ShopingCart.aspx.cs"
   2:      Inherits="Member_ShopingCart" Title="购物车" %>
   3:   
   4:  <asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server">
   5:      <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
   6:      <link href="../css/buy.css" rel="stylesheet" type="text/css" />
   7:   
   8:      <script src="../Admin/scripts/jquery-1.6.2.min.js" type="text/javascript"></script>
   9:   
  10:      <script src="../Admin/scripts/miniui/miniui.js" type="text/javascript"></script>
  11:   
  12:      <link href="../Admin/scripts/miniui/themes/default/miniui2.css" rel="stylesheet"
  13:          type="text/css" />
  14:      <link href="../Admin/scripts/miniui/themes/icons.css" rel="stylesheet" type="text/css" />
  15:         <script src="../js/AjaxJsDeal/ShoppingCart.js" type="text/javascript"></script>
  16:      <style type="text/css">
  17:       
  18:          .New_Button, .Edit_Button, .Delete_Button, .Update_Button, .Cancel_Button
  19:          {
  20:              font-size:11px;color:#1B3F91;font-family:Verdana;  
  21:              margin-right:5px;
  22:          }
  23:         
  24:                       
  25:      </style>
  26:  </asp:Content>
  27:  <asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
  28:      <div class="zz">
  29:          <div class="gouwuche">
  30:              <div class="flow-steps">
  31:                  <ul class="num5">
  32:                      <li class="current"><span class="first">1. 查看购物车</span></li>
  33:                      <li><span>2. 确认订单信息</span></li>
  34:                      <li><span>3. 付款到支付宝</span></li>
  35:                      <li><span>4. 确认收货</span></li>
  36:                      <li class="last"><span>5. 评价</span></li>
  37:                  </ul>
  38:              </div>
  39:              <div class="pay_for">
  40:                  <div>
  41:                      商品总价(不含运费):<span>
  42:                          <label id="lbCountNum1" text="" />
  43:                      </span>元</div>
  44:                  <div>
  45:                      <a href="MemberOrders.aspx">
  46:                          <img src="../images/js_small_03.jpg" /></a><a href="MemberOrders.aspx"></a></div>
  47:              </div>
  48:              <div id="datagrid1" class="mini-datagrid" style="width: 700px; height: 250px;" allowresize="true" multiSelect="true"     
  49:                  url="Data/GetMemberInfo.ashx?method=SearchShoppingCart" idfield="Id">
  50:                  <div property="columns" style="color: Black">
  51:                  
  52:                      <div type="checkcolumn" width="30">
  53:                      </div>
  54:                      <div field="ProductId" width="60" headeralign="center" allowsort="true" renderer="onRenderProduct">
  55:                          产品Id</div>
  56:                      <div field="Picturepath" width="100" align="center" headeralign="center" renderer="onReaderPic">
  57:                          图片</div>
  58:                      <div field="ProductName" width="100" headeralign="center" allowsort="true" renderer="onRenderProductName">
  59:                          产品名称</div>
  60:                      <div field="SupperlierName" renderer="RendererSupperlierName" width="120">
  61:                          供应商</div>
  62:                      <div field="Price" width="80" allowsort="true">
  63:                          商品售价</div>
  64:                      <div field="Quantity" width="80" headeralign="center" >
  65:                      <input property="editor" class="mini-spinner" minValue="1"  renderer="onRenderQuantity" maxValue="9999"  value="1" style="width:100%;"/>
  66:                          购买数量</div>
  67:                  <div name="action" width="80" headerAlign="center" align="center" renderer="onActionRenderer" cellStyle="padding:0;">操作</div>
  68:                  </div>
  69:              </div>
  70:              <table width="700" class="order-table" cellpadding="0" cellspacing="0">
  71:                  <tfoot>
  72:                      <tr>
  73:                          <td colspan="4" class="point-info">
  74:                          <%--    <input type="button" onclick="remove" value="批量删除" />--%> <a class="mini-button" iconCls="icon-remove" onclick="remove">批量删除</a>
  75:                          </td>
  76:                          <td colspan="4">
  77:                              <div class="charge-info">
  78:                                  商品总价(不含运费):<span>
  79:                                      <label id="lbCountNum">
  80:                                      </label>
  81:                                  </span>元</div>
  82:                          </td>
  83:                      </tr>
  84:                      <tr>
  85:                          <td colspan="4">
  86:                          </td>
  87:                          <td colspan="4">
  88:                              <div class="piliang">
  89:                                  <a href="MemberOrders.aspx">
  90:                                      <img src="../images/js_big.jpg" /></a></div>
  91:                          </td>
  92:                      </tr>
  93:                  </tfoot>
  94:              </table>
  95:          </div>
  96:      </div>
  97:   
  98:      <script type="text/javascript">
  99:          mini.parse();
 100:   
 101:          var grid = mini.get("datagrid1");
 102:          grid.load({
 103:              key: "",
 104:              pageIndex: 0,
 105:              pageSize: 10,
 106:              sortField: "Id",
 107:              sortOrder: "asc"
 108:              })
 109:              //初始化
 110:              $(function(){
 111:              GetCartInfo();
 112:              });
 113:           
 114:      </script>
 115:   
 116:  </asp:Content>

关键性js文件:

   1:     //购物车汇总信息
   2:              function GetCartInfo(){
   3:               $.ajax({
   4:             url:"/Member/Data/GetMemberInfo.ashx?method=GetCartInfo",
   5:             type:"post",
   6:             success:function(text){
   7:             var DataJson=$.parseJSON(text);
   8:              if(DataJson.Status!='False')//执行成功!
   9:              {
  10:                  //显示当前购物车总数量和总价 
  11:                  $("#lbCountNum").text(DataJson.Data[0].CartSum); 
  12:                   $("#lbCountNum1").text(DataJson.Data[0].CartSum); 
  13:                   //$("#CartMsg").html('目前购物车中已有'+DataJson.Data[0].CartCount+'件宝贝,合计:<span>'+DataJson.Data[0].CartSum+'</span>元');         
  14:              }
  15:              else
  16:              alert("加载购物车汇总信息出错!");
  17:             }
  18:             });
  19:              }
  20:               //操作重绘
  21:               function onActionRenderer(e) {
  22:              var grid = e.sender;
  23:              var record = e.record;
  24:              var uid = record._uid;
  25:              var rowIndex = e.rowIndex;
  26:   
  27:              var s = ''
  28:                      + ' <a class="Edit_Button" href="javascript:editRow(\'' + uid + '\')">编辑</a>'
  29:                      + ' <a class="Delete_Button" href="javascript:delRow(\'' + uid + '\')">删除</a>';
  30:   
  31:              if (grid.isEditingRow(record)) {
  32:                  s = '<a class="Update_Button" href="javascript:updateRow(\'' + uid + '\')">更新</a>'
  33:                      + '<a class="Cancel_Button" href="javascript:cancelRow(\'' + uid + '\')">取消</a>'
  34:              }
  35:              return s;
  36:          }
  37:            
  38:              
  39:              //产品名称超链接重绘
  40:              function onRenderProductName(e){
  41:                 var record = e.record;
  42:              var uid = record._uid;
  43:              var rowIndex = e.rowIndex;
  44:               var row = grid.getRowByUID(uid);
  45:               var href='<a href="/Product/Product.aspx?ProductId='+row.ProductId+'" >'+ row.ProductName+'</a>';
  46:        return href;
  47:              }
  48:              //产品超链接重绘
  49:              function onRenderProduct(e){
  50:                 var record = e.record;
  51:              var uid = record._uid;
  52:              var rowIndex = e.rowIndex;
  53:               var row = grid.getRowByUID(uid);
  54:               var href='<a href="/Product/Product.aspx?ProductId='+row.ProductId+'" >'+ row.ProductId+'</a>';
  55:        return href;
  56:              
  57:              }
  58:         //图片重绘
  59:          function onReaderPic(e){
  60:            var record = e.record;
  61:              var uid = record._uid;
  62:              var rowIndex = e.rowIndex;
  63:               var row = grid.getRowByUID(uid);
  64:                var src= '<img src="../Admin/FileManage/GetImg.ashx?method=GetMainProductPic&type=small&fileName='+e.value+'" style="width:60px;height:40px;"/>';
  65:               var href='<a href="/Product/Product.aspx?ProductId='+row.ProductId+'" >'+ src+'</a>';
  66:        return href;
  67:          
  68:          }
  69:          //卖家网址重绘
  70:            function RendererSupperlierName(e) {
  71:              var record = e.record;
  72:              var uid = record._uid;
  73:              var rowIndex = e.rowIndex;
  74:               var row = grid.getRowByUID(uid);
  75:              var SupperlierName=row.SupperlierName;
  76:              var SupperlierId=row.SupperlierId;
  77:              var BelongType=row.BelongType;
  78:              var BelongWebSize;
  79:              if(BelongType==0)
  80:              {
  81:              BelongWebSize="/Master/MasterInfo.aspx?MasterId="+SupperlierId;
  82:              }
  83:              else
  84:               BelongWebSize="/Company/CompanyInfo.aspx?CompanyId="+SupperlierId;
  85:              var s = '<a href="'+BelongWebSize+'" >'+SupperlierName+'</a>';
  86:             
  87:              return s;
  88:          }
  89:             function editRow(row_uid) {
  90:              var row = grid.getRowByUID(row_uid);
  91:              if (row) {
  92:                  grid.cancelEdit();
  93:                  grid.beginEditRow(row);
  94:              }
  95:          }
  96:          function cancelRow(row_uid) {            
  97:              grid.reload();
  98:          }
  99:          function delRow(row_uid) {
 100:              var row = grid.getRowByUID(row_uid);
 101:              if (row) {
 102:                  if (confirm("确定删除此记录?")) {
 103:                      grid.loading("删除中,请稍后......");
 104:                      $.ajax({
 105:                          url: "Data/GetMemberInfo.ashx?method=RemoveShoppingCart&Id=" + row.Id,
 106:                          success: function (text) {
 107:                              grid.reload();
 108:                              GetCartInfo();
 109:                          },
 110:                          error: function () {
 111:                          }
 112:                      });
 113:                  }
 114:              }
 115:          }
 116:   
 117:          function updateRow(row_uid) {
 118:              var row = grid.getRowByUID(row_uid);
 119:   
 120:              var rowData = grid.getEditRowData(row);
 121:           if(parseInt(row.Num-row.Soldnum)<parseInt(rowData.Quantity))
 122:              {
 123:              alert("当前库存不足!");
 124:              rowData.Quantity=parseInt(row.Num-row.Soldnum);
 125:              return;
 126:              }
 127:              grid.loading("保存中,请稍后......");
 128:              var json = mini.encode([{Id: row.Id,Quantity:rowData.Quantity,ProductId:row.ProductId}]);
 129:              $.ajax({
 130:                  url: "Data/GetMemberInfo.ashx?method=SaveShoppingCart",
 131:                  data: {ShoppingCart:json},
 132:                  success: function (text) {
 133:                      grid.reload();
 134:                       GetCartInfo();
 135:                  },
 136:                  error: function (jqXHR, textStatus, errorThrown) {
 137:                      alert(jqXHR.responseText);
 138:                  }
 139:              });
 140:   
 141:          }
 142:          //批量删除
 143:           function remove(e) {
 144:              var rows = grid.getSelecteds();
 145:              if (rows.length > 0) {
 146:                  if (confirm("确定删除选中商品?")) {
 147:                      var ids = [];
 148:                      for (var i = 0, l = rows.length; i < l; i++) {
 149:                          var r = rows[i];
 150:                          ids.push(r.Id);
 151:                      }
 152:                      var id = ids.join(',');
 153:                      grid.loading("操作中,请稍后......");
 154:                      $.ajax({
 155:                           url: "Data/GetMemberInfo.ashx?method=RemoveShoppingCart&Id=" + id,
 156:                          success: function (text) {
 157:                              grid.reload();
 158:                               GetCartInfo();
 159:                          },
 160:                          error: function () {
 161:                          }
 162:                      });
 163:                  }
 164:              } else {
 165:                  alert("请选中一条记录");
 166:              }
 167:          }
 168:     //操作重绘
 169:               function onSumRenderer(e) {
 170:              var grid = e.sender;
 171:              var record = e.record;
 172:              var uid = record._uid;
 173:              var rowIndex = e.rowIndex;
 174:               var row = grid.getRowByUID(uid);
 175:              return row.Price*row.Quantity;
 176:          }

不过注意的是,涉及到电子商务,客户端的数据都是不可靠的,所以我们的数据都是从数据库重

新读取.

后台c#处理代码:

   1:    /// <summary>
   2:      /// 购物车检索
   3:      /// </summary>
   4:      /// <param name="context"></param>
   5:      public void SearchShoppingCart(HttpContext context)
   6:      {
   7:          //用户id
   8:          string UserId = SessionHelper.GetSession("UserId").ToString();
   9:         // string key = context.Request["key"];
  10:          //分页
  11:          int pageIndex = Convert.ToInt32(context.Request["pageIndex"]);
  12:          int pageSize = Convert.ToInt32(context.Request["pageSize"]);
  13:          //字段排序
  14:          String sortField = context.Request["sortField"];
  15:          String sortOrder = context.Request["sortOrder"];
  16:          string strCondition = "";
  17:          VCartProductInfoBLL bll = new VCartProductInfoBLL();
  18:          if (Tools.IsNullOrEmpty(sortField))
  19:              sortField = "Id";
  20:          //查询条件
  21:          strCondition = " MemberId=" + UserId;
  22:          //分页数据读取
  23:          IEnumerable<VCartProductInfo> list = bll.ListByPagination(sortField, pageSize, pageIndex + 1, sortOrder == "asc" ? "1" : "0", strCondition);
  24:   
  25:          //获取总页数
  26:          int totalPage = bll.GetCount(strCondition);
  27:          //JSON 序列化
  28:          string json = Common.FormatToJson.MiniUiListToJson<VCartProductInfo>((IList<VCartProductInfo>)list, totalPage, "");
  29:          context.Response.Write(json);
  30:      }
  31:      /// <summary>
  32:      /// 保存到购物车
  33:      /// </summary>
  34:      /// <param name="context"></param>
  35:      public void SaveShoppingCart(HttpContext context)
  36:      {
  37:          //数据读取
  38:          String Cart = context.Request["ShoppingCart"];
  39:          string info = Cart.TrimStart('[');
  40:          info = info.TrimEnd(']');
  41:          JObject o = JObject.Parse(info);
  42:          Int64 Id = (Int64)o.SelectToken("Id");
  43:          int Quantity = (int)o.SelectToken("Quantity");
  44:          Int64 ProductId = (Int64)o.SelectToken("ProductId");
  45:          //库存判断(从数据库读取库存检验)
  46:          product CartInfo = new productBLL().Get(ProductId);
  47:          if (Quantity > (int)(CartInfo.Num.Value - CartInfo.Soldnum.Value))
  48:          {
  49:              context.Response.Write(Tools.WriteJsonForReturn(false, "库存数量不足!"));
  50:              return;
  51:          }
  52:          //更新购物车
  53:          ShoppingCart Shop=new ShoppingCart ();
  54:          Shop.Id=Id;
  55:          Shop.Quantity=Quantity;
  56:          bool Status=false;
  57:         Status=new ShoppingCartBLL().UpdateShoppingCart(Shop);
  58:         string Msg="";
  59:         if (Status)
  60:         {
  61:             Msg = "";
  62:         }
  63:         else
  64:             Msg = "库存不足!";
  65:         context.Response.Write(Tools.WriteJsonForReturn(Status, Msg));
  66:         
  67:      }
  68:      
  69:      /// <summary>
  70:      /// 获取购物车信息
  71:      /// </summary>
  72:      /// <param name="context"></param>
  73:      public void GetCartInfo(HttpContext context)
  74:      {
  75:          string UserId = (string)context.Session["UserId"];
  76:              
  77:          context.Response.Write(new ShoppingCartBLL().GetCartInfo(UserId));
  78:      }
  79:      /// <summary>
  80:      /// 删除购物车内容
  81:      /// </summary>
  82:      /// <param name="context"></param>
  83:      public void RemoveShoppingCart(HttpContext context)
  84:      {
  85:          String idStr = context.Request["Id"];
  86:          if (String.IsNullOrEmpty(idStr)) return;
  87:          //检验客户端字符串
  88:          if (Common.Tools.IsValidInput(ref idStr, true))
  89:          {
  90:              new ShoppingCartBLL().DeleteMoreID(idStr);
  91:          }
  92:      }

接下来就是订单结算,

呃...订单很丑...没做处理.....

其实,这里面大部分信息都是以前做会员信息管理的数据加载,只需要调用会员管理的js,根本业务逻辑都不用写....

相对来说难写一点的就是提交订单的处理,

首先我们要提交订单,我的数据库,设计了订单表和订单商品表,订单号是根据日期生成的,订单号的生成就是类似流水号生成,

这个很重要,因为大多数情况下,订单是日期生成,而且要保证唯一性,以前曾经总看到(数据库的id不设计成自增,然后varchar类型,程序生成id号),

这种设计方式就是严重没考虑并发处理的情况,如果同时n个人订单号根本就不能保证唯一性...

到网上搜索流水号生成,就能看到如何解决这个问题,其实就是建一张表,写存储过程的方式计算id,要保证id的唯一性.

我的这个是从博客园一个高手的日志上切下来的..

获取订单号的存储过程

   1:  USE [czcraft]
   2:  GO
   3:  /****** 对象:  StoredProcedure [dbo].[dpPMT_SGetMaintainSeq]    脚本日期: 05/19/2012 00:18:39 ******/
   4:  SET ANSI_NULLS ON
   5:  GO
   6:  SET QUOTED_IDENTIFIER ON
   7:  GO
   8:   
   9:  CREATE  PROC [dbo].[dpPMT_SGetMaintainSeq]
  10:  (
  11:  @MaintainCate VARCHAR(2)
  12:  )
  13:   AS 
  14:  --***********************累加编号************************************************* 
  15:  declare @MaintainNo VARCHAR(12) IF NOT EXISTS(SELECT * FROM NumSeq WHERE Cate=@MaintainCate AND DATEDIFF(DAY,CrTime,GETDATE())=0) BEGIN
  16:          INSERT INTO NumSeq(Cate,DateNo,Seq,CrTime) values(@MaintainCate,RIGHT(CONVERT(VARCHAR(4),YEAR(GETDATE())),2)+ REPLICATE('0',2-LEN(MONTH(GETDATE())))+CONVERT(VARCHAR(2),MONTH(GETDATE())),0,getdate()) END
  17:  ELSE
  18:      BEGIN
  19:          UPDATE NumSeq SET Seq=Seq+1 WHERE Cate=@MaintainCate AND DateNo=RIGHT(CONVERT(VARCHAR(4),YEAR(GETDATE())),2)+ REPLICATE('0',2-LEN(MONTH(GETDATE())))+CONVERT(VARCHAR(2),MONTH(GETDATE())) END 
  20:  --************************组合编号*************************************************************** 
  21:  SELECT @MaintainNo=Cate+DateNo+REPLICATE('0',6-LEN(Seq))+CONVERT(VARCHAR(6),Seq) FROM NumSeq WHERE Cate=@MaintainCate AND DateNo=RIGHT(CONVERT(VARCHAR(4),YEAR(GETDATE())),2)+ REPLICATE('0',2-LEN(MONTH(GETDATE())))+CONVERT(VARCHAR(2),MONTH(GETDATE())) SELECT @MaintainNo

调用函数

这样,我们每次插入数据的时候,只要调用这个存储过程就能保证每次生成的订单号都不一样,

接下来就是订单处理了:

我们需要处理哪些呢?

首先是提交用户的收货信息,再次检验库存状态,然后插入订单信息表和订单产品表,并且将商品表的产品数量更新,并且给用户发送订单邮件(我copy的卓越网邮件的HTML布局,哈哈),

这里粘贴主要模块代码:

提交订单:

   1:   /// <summary>
   2:      /// 订单提交
   3:      /// </summary>
   4:      /// <param name="context"></param>
   5:      public void SubmitOrderData(HttpContext context)
   6:      {
   7:            string UserId = (string)context.Session["UserId"];
   8:          if(Tools.IsNullOrEmpty(UserId))
   9:          {
  10:              return;
  11:          }
  12:          string Name = context.Request["Name"];
  13:          string Email = context.Request["Email"];
  14:          string Province = context.Request["Province"];
  15:          string City = context.Request["City"];
  16:          string Country = context.Request["Country"];
  17:          string Address = context.Request["Address"];
  18:          string ZipCode = context.Request["ZipCode"];
  19:          string MobilePhone = context.Request["MobilePhone"];
  20:          string TelPhone = context.Request["TelPhone"];
  21:          //订单信息保存
  22:          orders order = new orders();
  23:          order.ConsigneeName = Name;
  24:          order.ConsigneeRealName = Name;
  25:          order.ConsigneeEmail = Email;
  26:          order.ConsigneeProvince = Province;
  27:          order.ConsigneeZip = ZipCode;
  28:          order.UserId =Convert.ToInt32(UserId);
  29:          order.ConsigneeAddress = City + Country + Address;
  30:          order.OrderDate = DateTime.Now;
  31:          order.ConsigneePhone = MobilePhone;
  32:          order.ConsigneeTel = TelPhone;
  33:          order.OrderId = ordersBLL.GetOrderId();
  34:          ordersBLL bll = new ordersBLL();
  35:          string ReturnProductName = "";
  36:          //下单
  37:          bool Status = bll.SaveOrder(ref order, out ReturnProductName);
  38:          //去除最后的,
  39:          ReturnProductName = ReturnProductName.Remove(ReturnProductName.Length - 1, 1);
  40:          string Data = "";
  41:          //支付跳转URL
  42:          string TurnURL = "";
  43:          if (Status)
  44:          {
  45:              Data = "恭喜您!下单成功!";
  46:              //支付平台的跳转URL生成
  47:              PayInfo info=new PayInfo ();
  48:              info.SaleEmail="tianzhuanghu@qq.com";
  49:              info.OrderId=order.OrderId;
  50:              info.ProductName = ReturnProductName;
  51:             
  52:              info.Remark=order.ConsigneeName+"在"+order.ShopDate.Value.ToShortDateString()+"购买商品,共计:"+order.TotalPrice.Value.ToString ();
  53:              info.TotalFre = order.FactPrice.Value.ToString ();
  54:              Pay pay = new Pay();
  55:             TurnURL=pay.BuildURL(info);
  56:          }
  57:          else
  58:              Data = "对不起!下单失败!";
  59:          //返回的json数据
  60:          string ReturnJson = "{\"Status\":\"" + Status + "\",\"Data\":\"" + Data + "\",\"URL\":\""+TurnURL+"\"}"; ;
  61:           context.Response.Write(ReturnJson);
  62:      
  63:      }
 
订单提交BLL:
   1:   #region 保存订单
   2:          /// <summary>
   3:          /// 保存订单
   4:          /// </summary>
   5:          /// <param name="order">订单</param>
   6:          /// <param name="ReturnProductNames">返回产品名称列表</param>
   7:          /// <returns></returns>
   8:          public bool SaveOrder(ref orders order,out string ReturnProductNames)
   9:          {
  10:              ReturnProductNames = "";
  11:              //查询条件(购物车视图中查询)
  12:              string Condition = " MemberId=" + order.UserId;
  13:              //(需要读取购物车,然后,插入订单商品表和订单表)
  14:              //订单产品信息列表
  15:              List<orderproduct> listOrder = new List<orderproduct>();
  16:              IEnumerable<VCartProductInfo> CartProducts = new VCartProductInfoDAL().ListAll(Condition);
  17:              order.TotalPrice = 0.0;
  18:              order.FactPrice = 0.0;
  19:              foreach (VCartProductInfo CartProduct in CartProducts)
  20:              {
  21:                  orderproduct OrderProduct = new orderproduct();
  22:                  OrderProduct.AddTime = DateTime.Now;
  23:                  OrderProduct.OrderId = order.OrderId;
  24:                  OrderProduct.ProId = CartProduct.ProductId.Value.ToString();
  25:                  OrderProduct.ProImg = CartProduct.Picturepath;
  26:                  OrderProduct.ProName = CartProduct.ProductName;
  27:                  ReturnProductNames += OrderProduct.ProName + ",";
  28:                  OrderProduct.ProNum = CartProduct.Quantity;
  29:                  OrderProduct.ProPrice = CartProduct.Price;
  30:                  OrderProduct.ProOtherPara = "";
  31:                  OrderProduct.Remark = "";
  32:                  OrderProduct.Specification = "";
  33:                  //加入到产品订单信息列表中
  34:                  listOrder.Add(OrderProduct);
  35:                  //总价计算
  36:                  order.TotalPrice += OrderProduct.ProPrice.Value * OrderProduct.ProNum.Value;
  37:                  //实际总价
  38:                  order.FactPrice += OrderProduct.ProPrice.Value * OrderProduct.ProNum.Value;
  39:              }
  40:              //支付状态为等待付款
  41:              order.PaymentStatus = orders.ePaymentStatus.WaitPay.GetHashCode().ToString();
  42:              //订单状态为未支付
  43:              order.OrderStatus = orders.eOrderStatus.NotPay.GetHashCode().ToString();
  44:   
  45:              //订单状态
  46:              order.IsOrderNormal = 0;
  47:              order.Remark = "";
  48:              order.ShopDate = DateTime.Now;
  49:              order.OrderDate = DateTime.Now;
  50:              //返回订单执行状态
  51:              bool Status = new ordersDAL().AddOrders(order, listOrder);
  52:              if (Status)
  53:              {
  54:                  //给客户发邮件
  55:                  SMTP smtp = new SMTP(order.ConsigneeEmail);
  56:                  smtp.SendMail("潮州工艺平台", SendToCustomContentHtml(order, listOrder));
  57:   
  58:              }
  59:              return Status;
  60:   
  61:          }

发送邮件:

   1:    #region 生成给客户发的HTML内容(亚马逊布局)
   2:          /// <summary>
   3:          /// 生成给客户发的HTML内容(亚马逊)
   4:          /// </summary>
   5:          /// <param name="order"></param>
   6:          /// <param name="ProductsList"></param>
   7:          /// <returns></returns>
   8:          public string SendToCustomContentHtml(orders order, IEnumerable<orderproduct> ProductsList)
   9:          {
  10:              //获取当前http上下文
  11:              System.Web.HttpContext context = System.Web.HttpContext.Current;
  12:              //主页
  13:              string Default = context.Request.Url.Scheme + "://" + context.Request.Url.Authority + System.Web.VirtualPathUtility.ToAbsolute("~/Default.aspx");
  14:              //会员订单网址
  15:              string webpath = context.Request.Url.Scheme + "://" + context.Request.Url.Authority + System.Web.VirtualPathUtility.ToAbsolute("~/Member/MemberOrders.aspx");
  16:              //文件流读取
  17:              StringBuilder sb=new StringBuilder ();
  18:              sb.Append(File.ReadAllText (context.Server.MapPath("~/Other/SendToCustomContent.html"),Encoding.UTF8));
  19:              sb.Replace("$ConsigneeRealName", order.ConsigneeRealName);
  20:              sb.Replace("$ConsigneeEmail", order.ConsigneeEmail);
  21:              sb.Replace("$ConsigneeRealName", order.ConsigneeRealName);
  22:              sb.Replace("$ConsigneeAddress", order.ConsigneeAddress);
  23:              sb.Replace("$ConsigneeProvince", order.ConsigneeProvince);
  24:              sb.Replace("$ConsigneeZip", order.ConsigneeZip);
  25:              sb.Replace("$TotalPrice", order.TotalPrice.Value.ToString ());
  26:              sb.Replace("$webpath", webpath);
  27:              sb.Replace("$OrderId", order.OrderId);
  28:              sb.Replace("$TotalPrice", order.TotalPrice.Value.ToString ());
  29:              sb.Replace("$Carriage", order.Carriage.ToString ());//
  30:              sb.Replace("$TotalPrice", order.TotalPrice.Value.ToString ());
  31:              sb.Replace("$FactPrice", order.FactPrice.Value.ToString ());
  32:              sb.Replace("$DateTime", DateTime.Now.AddDays(3).ToShortDateString());
  33:   
  34:              //商品内容生成
  35:              int num = 0;
  36:              StringBuilder TempData = new StringBuilder();
  37:              foreach (orderproduct Product in ProductsList)
  38:              {
  39:                  string temp3 = @"<table><tbody>
  40:  <tr valign='top'><td></td><td><font size='-1' face='verdana,arial,helvetica'><b>" + (++num) + @"</b></font></td><td><font size='-1' face='verdana,arial,helvetica'><b>" + Product.ProName + @"</b><br>
  41:  <span class='price'>¥ " + Product.ProPrice + @"</span><br>现在有货<br>&nbsp; 卖家: <a href='" + Default + @"' target='_blank'>潮州工艺品集团</a> </font></td></tr></tbody></table>";
  42:                  TempData.Append(temp3);
  43:                  
  44:   
  45:              }
  46:              //商品主体信息替换
  47:              sb.Replace("$Body", TempData.ToString ());
  48:              //sb.Replace("$Carriage", order.Carriage);
  49:   
  50:   
  51:             
  52:              return sb.ToString();
  53:   
  54:          }

DAL中保存订单处理:

   1:   #region 下单
   2:          /// <summary>
   3:          /// 下单
   4:          /// </summary>
   5:          /// <param name="Info">订单信息</param>
   6:          /// <param name="OrderProductsList">订单产品信息</param>
   7:          /// <returns></returns>
   8:          public bool AddOrders(orders order, IEnumerable<orderproduct> OrderProductsList)
   9:          {
  10:              //执行事务状态
  11:              bool Status = false;
  12:              StringBuilder sb = new StringBuilder();
  13:              SqlHelper.Open();
  14:              //开始事务
  15:              SqlHelper.BeginTrans();
  16:              foreach (orderproduct product in OrderProductsList)
  17:              {
  18:                  //插入订单产品表信息
  19:                  sb.AppendFormat("insert into orderproduct(OrderId,ProId,ProClass,ProName,ProImg,ProPrice,ProNum,AddTime,ProOtherPara,Specification,Remark) output inserted.Id values('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}');", product.OrderId, product.ProId, product.ProClass, product.ProName, product.ProImg, product.ProPrice, product.ProNum, product.AddTime, product.ProOtherPara, product.Specification, product.Remark);
  20:                  //产品数量修改
  21:                  sb.AppendFormat("update product set Num=Num-{0},Soldnum=Soldnum+{0} where Id={1};", product.ProNum, product.ProId);
  22:                  //删除购物车中的产品
  23:                  sb.AppendFormat("delete from ShoppingCart where ProductId={0} and MemberId={1};", product.ProId, order.UserId);
  24:   
  25:              }
  26:              //订单信息添加
  27:              sb.AppendFormat("insert into orders(OrderId,UserId,ShopDate,OrderDate,ConsigneeRealName,ConsigneeName,ConsigneePhone,ConsigneeProvince,ConsigneeAddress,ConsigneeZip,ConsigneeTel,ConsigneeEmail,TotalPrice,FactPrice,Remark,OrderStatus,PaymentStatus,IsOrderNormal) values('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}','{12}','{13}','{14}','{15}','{16}','{17}');", order.OrderId, order.UserId, order.ShopDate, order.OrderDate, order.ConsigneeRealName, order.ConsigneeName, order.ConsigneePhone, order.ConsigneeProvince, order.ConsigneeAddress, order.ConsigneeZip, order.ConsigneeTel, order.ConsigneeEmail, order.TotalPrice, order.FactPrice, order.Remark, order.OrderStatus, order.PaymentStatus, order.IsOrderNormal);
  28:              Status = SqlHelper.ExecuteNonQuery(sb.ToString());
  29:              if (Status)
  30:              {
  31:                  SqlHelper.CommitTrans();
  32:                  return true;
  33:              }
  34:              else
  35:              {
  36:                  SqlHelper.RollbackTrans();
  37:                  return false;
  38:              }
  39:   
  40:   
  41:          }

在这里,为了更节省性能,我用StringBuilder拼接字符串,也没有用参数化查询的方式.(注意这里采用事务处理)

然后就是支付平台的实现,其实支付平台说简单点是非常容易的,只需要按照支付的接口提供http请求参数,数字签名,等信息,交易成功然后按照请求读取参数检验数字签名是否正确.

这部分内容,我是准备集成多种支付平台设计,今天只展示支付宝部分.

在设计这部分,我们需要去查看支付宝接口模拟,一般申请支付宝都会提供一个接口测试程序,等等,

我们在做之前,为了考虑多种支付平台的配置,首先定义一些配置信息,

我是把支付宝接口配置成一个网站,然后,通过网关调用,进行模拟

   1:  using System;
   2:  using System.Data;
   3:  using System.Configuration;
   4:  using System.Linq;
   5:  using System.Web;
   6:  using System.Web.Security;
   7:  using System.Web.UI;
   8:  using System.Web.UI.HtmlControls;
   9:  using System.Web.UI.WebControls;
  10:  using System.Web.UI.WebControls.WebParts;
  11:  using System.Xml.Linq;
  12:   
  13:  /// <summary>
  14:  ///PayInfo 的摘要说明
  15:  /// </summary>
  16:  public class PayInfo
  17:  {
  18:      public PayInfo()
  19:      {
  20:          //
  21:          //TODO: 在此处添加构造函数逻辑
  22:          //
  23:      }
  24:      /// <summary>
  25:      /// 商户
  26:      /// </summary>
  27:      public string SaleManId { get; set; }
  28:      /// <summary>
  29:      /// 回调地址
  30:      /// </summary>
  31:      public string CallBackUrl { get; set; }
  32:      /// <summary>
  33:      /// 产品名称
  34:      /// </summary>
  35:      public string ProductName { get; set; }
  36:   
  37:      /// <summary>
  38:      /// 订单号
  39:      /// </summary>
  40:      public string OrderId { get; set; }
  41:      /// <summary>
  42:      /// 总金额
  43:      /// </summary>
  44:      public string TotalFre { get; set; }
  45:      /// <summary>
  46:      /// 卖家邮箱
  47:      /// </summary>
  48:      public string SaleEmail { get; set; }
  49:      /// <summary>
  50:      /// 数字签名
  51:      /// </summary>
  52:      public string Sign { get; set; }
  53:      /// <summary>
  54:      /// 备注信息
  55:      /// </summary>
  56:      public string Remark { get; set; }
  57:   
  58:  }
  59:  /// <summary>
  60:  /// 支付回调信息
  61:  /// </summary>
  62:  public class PayCallBackInfo
  63:  {
  64:      /// <summary>
  65:      /// 支付类型
  66:      /// </summary>
  67:      public Pay.PayType PayType { get; set; }
  68:      /// <summary>
  69:      /// 订单号
  70:      /// </summary>
  71:      public string OrderId { get; set; }
  72:      /// <summary>
  73:      /// 支付机构
  74:      /// </summary>
  75:      public string PayMode { get; set; }
  76:      /// <summary>
  77:      /// 支付金额
  78:      /// </summary>
  79:      public string PayFre { get; set; }
  80:      /// <summary>
  81:      /// 金额币种
  82:      /// </summary>
  83:      public string MoneyType { get; set; }
  84:      /// <summary>
  85:      /// 备注1
  86:      /// </summary>
  87:      public string Remark1 { get; set; }
  88:      /// <summary>
  89:      /// 备注2
  90:      /// </summary>
  91:      public string Remark2 { get; set; }
  92:      /// <summary>
  93:      /// 数字签名
  94:      /// </summary>
  95:      public string Sign { get; set; }
  96:      /// <summary>
  97:      /// 状态码
  98:      /// </summary>
  99:      public Pay.ReturnCode ReturnCode { get; set; }
 100:      /// <summary>
 101:      /// 回发的消息
 102:      /// </summary>
 103:      public string Msg { get; set; }
 104:  }
 105:  /// <summary>
 106:  /// 支付配置信息
 107:  /// </summary>
 108:  public class PayConfig
 109:  {
 110:      /// <summary>
 111:      /// 支付类型
 112:      /// </summary>
 113:      public Pay.PayType PayType { get; set; }
 114:      /// <summary>
 115:      /// 商户帐号
 116:      /// </summary>
 117:      public string v_mid { get; set; }
 118:      /// <summary>
 119:      /// 商户密码
 120:      /// </summary>
 121:      public string v_pwd { get; set; }
 122:      /// <summary>
 123:      /// 网关地址
 124:      /// </summary>
 125:      public string PayUrl { get; set; }
 126:  }
   1:  using System;
   2:  using System.Data;
   3:  using System.Configuration;
   4:  using System.Linq;
   5:  using System.Web;
   6:  using System.Web.Security;
   7:  using System.Web.UI;
   8:  using System.Web.UI.HtmlControls;
   9:  using System.Web.UI.WebControls;
  10:  using System.Web.UI.WebControls.WebParts;
  11:  using System.Xml.Linq;
  12:  using Common;
  13:  using czcraft.BLL;
  14:   
  15:  /// <summary>
  16:  ///Pay 的摘要说明
  17:  /// </summary>
  18:  public class Pay
  19:  {
  20:      //支付平台的配置信息
  21:      public readonly  PayConfig config;
  22:      public Pay()
  23:      {
  24:          //获取支付平台的配置信息
  25:          config = GetPayConfig();
  26:          //
  27:          //TODO: 在此处添加构造函数逻辑
  28:          //
  29:      }
  30:      /// <summary>
  31:      /// 支付类型
  32:      /// </summary>
  33:      public enum PayType
  34:      {
  35:          /// <summary>
  36:          /// 支付宝
  37:          /// </summary>
  38:          Alipay = 0,
  39:          /// <summary>
  40:          /// 网银在线
  41:          /// </summary>
  42:          ChinaBank = 1
  43:      }
  44:      /// <summary>
  45:      /// 回调状态码(支付宝才有)
  46:      /// </summary>
  47:      public enum ReturnCode
  48:      {
  49:          /// <summary>
  50:          /// 支付成功!
  51:          /// </summary>
  52:          ok = 0,
  53:          /// <summary>
  54:          /// 支付失败!
  55:          /// </summary>
  56:          error = 1
  57:      }
  58:   
  59:      #region 构造支付的URL
  60:      /// <summary>
  61:      /// 构造支付的URL(从配置文件中读取出支付平台配置信息然后构造支付的网关信息(支付平台由配置文件决定)(初步只提供网银在线和支付宝两种模式中的一种)
  62:      /// </summary>
  63:      /// <param name="Info">支付信息(支付宝支付需要输入总金额,产品名称,订单号,卖家邮箱)</param>
  64:      /// <returns></returns>
  65:      public string BuildURL(PayInfo Info)
  66:      {
  67:          //获取支付平台的配置信息
  68:          //PayConfig config = GetPayConfig();
  69:          //支付的地址
  70:          string PayUrl = "";
  71:          switch (config.PayType)
  72:          {
  73:              //支付宝支付
  74:              case PayType.Alipay:
  75:                  PayUrl = BuildAlipayURL(Info, config);
  76:                  break;
  77:              //网银在线支付
  78:              case PayType.ChinaBank:
  79:                  PayUrl = BuildChinaBackUrl(Info, config);
  80:                  break;
  81:              default:
  82:                 PayUrl= "#";
  83:                 break;
  84:          }
  85:          return PayUrl;
  86:      }
  87:      #endregion
  88:   
  89:      #region 支付完成回调处理
  90:      /// <summary>
  91:      /// 支付完成回调处理
  92:      /// </summary>
  93:      /// <param name="Msg">回调信息</param>
  94:      /// <returns></returns>
  95:      public PayCallBackInfo CallBackPayInfo()
  96:      {
  97:         string Msg = "";
  98:          PayCallBackInfo CallBackInfo = new PayCallBackInfo();
  99:          switch (config.PayType)
 100:          {
 101:              //支付宝支付
 102:              case PayType.Alipay:
 103:                  CallBackInfo = CallBackAlipayInfo();
 104:                  break;
 105:              //网银在线支付
 106:              case PayType.ChinaBank:
 107:                  CallBackInfo = CallBackChinaBankInfo();
 108:                  break;
 109:              default:
 110:                  CallBackInfo = null;
 111:                  break;
 112:          }
 113:          return CallBackInfo;
 114:      }
 115:      #region 支付宝支付完成回调处理
 116:      /// <summary>
 117:      /// 支付宝支付完成回调处理
 118:      /// </summary>
 119:      /// <param name="Msg">回调信息</param>
 120:      /// <returns></returns>
 121:      private PayCallBackInfo CallBackAlipayInfo()
 122:      {
 123:          //回调信息
 124:         string Msg = "";
 125:          System.Web.HttpContext context = System.Web.HttpContext.Current;
 126:          //订单号
 127:          string OrderId = context.Request["out_trade_no"];
 128:          //回调状态码
 129:          string ReturnCode = context.Request["returncode"];
 130:          //总金额
 131:          string TotalFre = context.Request["total_fee"];
 132:          //数字签名
 133:          string Sign = context.Request["sign"];
 134:          //数字签名(本地计算的)
 135:          string Md5Sign = CommonHelper.GetMD5(OrderId + ReturnCode + TotalFre + config.v_pwd);
 136:          //回调信息
 137:          PayCallBackInfo CallBackInfo = new PayCallBackInfo();
 138:          if (Md5Sign.Equals(Sign))
 139:          {
 140:              //支付成功!
 141:              if (ReturnCode.Equals(Pay.ReturnCode.ok.ToString()))
 142:              {
 143:                  Msg = "支付成功!";
 144:                  CallBackInfo.Msg = Msg;
 145:                  CallBackInfo.OrderId = OrderId;
 146:                  CallBackInfo.PayFre = TotalFre;
 147:                  CallBackInfo.ReturnCode = Pay.ReturnCode.ok;
 148:              }
 149:              else
 150:              {
 151:                  Msg = "支付失败!";
 152:               
 153:                  CallBackInfo.Msg = Msg;
 154:                  CallBackInfo.ReturnCode = Pay.ReturnCode.error;
 155:              }
 156:   
 157:          }
 158:          else
 159:          {
 160:              Msg = "数据被篡改!";
 161:              CallBackInfo.Msg = Msg;
 162:              CallBackInfo.ReturnCode = Pay.ReturnCode.error;
 163:          }
 164:          return CallBackInfo;
 165:      } 
 166:      #endregion
 167:      #region 网银在线支付完成回调处理
 168:      /// <summary>
 169:      /// 网银在线支付完成回调处理(未实现)
 170:      /// </summary>
 171:      /// <param name="Msg">回调信息</param>
 172:      /// <returns></returns>
 173:      private PayCallBackInfo CallBackChinaBankInfo()
 174:      {
 175:          //回调信息
 176:        string  Msg = "";
 177:          PayCallBackInfo CallBackInfo = new PayCallBackInfo();
 178:          return CallBackInfo;
 179:      } 
 180:      #endregion
 181:      #endregion
 182:      #region 支付宝平台的网关URL
 183:      /// <summary>
 184:      /// 支付宝平台的网关URL
 185:      /// </summary>
 186:      /// <param name="info">支付信息</param>
 187:      /// <param name="config">系统支付配置</param>
 188:      /// <returns></returns>
 189:      private string BuildAlipayURL(PayInfo info, PayConfig config)
 190:      {
 191:          System.Web.HttpContext context = System.Web.HttpContext.Current;
 192:          //为按顺序连接 总金额、 商户编号、订单号、商品名称、商户密钥的MD5值。
 193:          //支付宝数字签名
 194:          string SignMd5 = CommonHelper.GetMD5(info.TotalFre + config.v_mid + info.OrderId + info.ProductName + config.v_pwd);
 195:          //回调网址
 196:          string webpath = context.Server.UrlEncode(context.Request.Url.Scheme + "://" + context.Request.Url.Authority + System.Web.VirtualPathUtility.ToAbsolute("~/Member/Data/DealAlipayCallBack.ashx"));
 197:          //商品名称
 198:          string ProductName = System.Web.HttpContext.Current.Server.UrlEncode(info.ProductName);
 199:          //备注
 200:          string Remark = System.Web.HttpContext.Current.Server.UrlEncode(info.Remark);
 201:          //支付的URL地址
 202:          string PayURL = config.PayUrl + "?partner=" + config.v_mid + "&return_url=" + webpath + "&subject=" + ProductName + "&body=" + Remark + "&out_trade_no=" + info.OrderId + "&total_fee=" + info.TotalFre + "&seller_email=" + info.SaleEmail + "&sign=" + SignMd5;
 203:          return PayURL;
 204:   
 205:      }
 206:      #endregion
 207:   
 208:      #region 网银在线平台的网关URL
 209:      /// <summary>
 210:      /// 网银在线平台的网关URL(等待实现)
 211:      /// </summary>
 212:      /// <param name="info">支付信息</param>
 213:      /// <param name="config">系统支付配置</param>
 214:      /// <returns></returns>
 215:      private string BuildChinaBackUrl(PayInfo info, PayConfig config)
 216:      {
 217:          return "";
 218:   
 219:      }
 220:      #endregion
 221:   
 222:      #region 获取系统配置信息(支付相关)
 223:      /// <summary>
 224:      /// 获取系统配置信息(支付相关)
 225:      /// </summary>
 226:      /// <returns></returns>
 227:      public PayConfig GetPayConfig()
 228:      {
 229:          PayConfig info = new PayConfig();
 230:          //读取配置文件信息
 231:          string path = System.Web.HttpContext.Current.Server.MapPath(@"~/Admin/ConfigManage/config.xml");
 232:          //系统配置中的支付类型
 233:          string ConfigPayType = XMlHelper.Read(path, "/Root/Pay", "PayType");
 234:          //商户帐号
 235:          string v_mid = XMlHelper.Read(path, "/Root/Pay/" + ConfigPayType, "v_mid");
 236:          //商户密码
 237:          string v_pwd = XMlHelper.Read(path, "/Root/Pay/" + ConfigPayType, "v_pwd");
 238:          //支付网关
 239:          string PayUrl = XMlHelper.Read(path, "/Root/Pay/" + ConfigPayType + "/PayUrl", "");
 240:   
 241:   
 242:          info.PayType = ConfigPayType == PayType.Alipay.ToString() ? PayType.Alipay : PayType.ChinaBank;
 243:          info.v_mid = v_mid;
 244:          info.v_pwd = v_pwd;
 245:          info.PayUrl = PayUrl;
 246:   
 247:          return info;
 248:   
 249:      }
 250:      #endregion
 251:   
 252:  }

然后支付回调处理:

   1:  <%@ WebHandler Language="C#" Class="DealAlipayCallBack" %>
   2:   
   3:  using System;
   4:  using System.Web;
   5:  //处理关于支付宝回调
   6:  public class DealAlipayCallBack : IHttpHandler {
   7:      
   8:      public void ProcessRequest (HttpContext context) {
   9:          //支付回调
  10:          Pay pay = new Pay();
  11:          PayCallBackInfo CallBackInfo = pay.CallBackPayInfo();
  12:          if (CallBackInfo.ReturnCode == Pay.ReturnCode.ok)
  13:          {
  14:              CallBackInfo.Msg = "恭喜您,支付成功!我们会尽快发货!如果您收货就可以继续确认收货!";
  15:          }
  16:          else
  17:              CallBackInfo.Msg = "对不起,支付失败!!失败信息 :" + CallBackInfo.Msg + "请联系支付宝有关人员!";
  18:          //回调信息
  19:          string Msg = System.Web.HttpContext.Current.Server.UrlEncode(CallBackInfo.Msg);
  20:          Common.JScript.JavaScriptLocationHref("../PayCallBack.aspx?ReturnCode=" + CallBackInfo.ReturnCode.ToString() + "&Msg=" + Msg + "&OrderId=" + CallBackInfo.OrderId + "&PayFre=" + CallBackInfo.PayFre);
  21:      }
  22:   
  23:      public bool IsReusable {
  24:          get {
  25:              return false;
  26:          }
  27:      }
  28:   
  29:  }

回调前台页面:

   1:  <%@ Page Language="C#" MasterPageFile="~/Member.master" AutoEventWireup="true" CodeFile="PayCallBack.aspx.cs"
   2:      Inherits="Member_PayCallBack" Title="支付回调" %>
   3:   
   4:  <asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server">
   5:      <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
   6:      <link href="../css/buy.css" rel="stylesheet" type="text/css" />
   7:        <link href="../css/AliPay.css" rel="stylesheet" type="text/css" />
   8:         <script src="../js/queryUrlParams.js" type="text/javascript"></script>
   9:   
  10:  <style type="text/css">
  11:    .MoneyFont
  12:    {
  13:        font-family:Verdana, Geneva, sans-serif;
  14:      font-size:18px;
  15:      font-weight:bold;
  16:      color:#F60;
  17:    }
  18:        
  19:  </style>
  20:  </asp:Content>
  21:  <asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
  22:     <div class="zz">
  23:          <div class="gouwuche">
  24:              <div class="flow-steps">
  25:                  <ul class="num5">
  26:                      <li class="done"><span class="first">1. 查看购物车</span></li>
  27:                      <li class="done current-prev"><span>2. 确认订单信息</span></li>
  28:                      <li class="current"><span>3. 付款到支付宝</span></li>
  29:                      <li><span>4. 确认收货</span></li>
  30:                      <li class="last"><span>5. 评价</span></li>
  31:                  </ul>
  32:              </div>
  33:              <div id="main">
  34:                  <div id="head">
  35:                      <div id="logo">
  36:                      </div>
  37:                      <dl class="alipay_link">
  38:                          <a target="_blank" href="http://www.alipay.com/"><span>支付宝首页</span></a>| <a target="_blank"
  39:                              href="https://b.alipay.com/home.htm"><span>商家服务</span></a>| <a target="_blank" href="http://help.alipay.com/support/index_sh.htm">
  40:                                  <span>帮助中心</span></a>
  41:                      </dl>
  42:                      <span class="title">支付宝纯担保交易付款快速通道</span>
  43:                      <!--<div id="title" class="title">支付宝纯担保交易付款快速通道</div>-->
  44:                  </div>
  45:                  <div class="cashier-nav">
  46:                      <ol>
  47:                          <li>1、确认付款信息 →</li>
  48:                          <li>2、付款 →</li>
  49:                          <li class="last current">3、付款完成</li>
  50:                      </ol>
  51:                  </div>
  52:                  <div id="body" style="clear: left">
  53:                      <dl class="content1">
  54:                          <dt>订单号:</dt>
  55:                          <dd>
  56:                             
  57:                              <span id="OrderId"></span>
  58:                          </dd>
  59:                          <dt>付款金额:</dt>
  60:                          <dd>
  61:                         
  62:                              ¥:<span  class="MoneyFont" id="PayFre"></span>
  63:                          </dd>
  64:                          <dt>支付状态:</dt>
  65:                          <dd>
  66:                            
  67:                    <span style="color:Red" id="Msg"></span>
  68:                          </dd>
  69:                          <dt></dt>
  70:                          <dd>
  71:                              <span class="new-btn-login-sp">
  72:                                  <input type="button" id="BtnAlipay" name="BtnAlipay" class="new-btn-login" value="确认收货"
  73:                                      style="text-align: center" />
  74:                              </span>
  75:                          </dd>
  76:                      </dl>
  77:                  </div>
  78:                  <div id="foot1">
  79:                      <ul class="foot-ul">
  80:                          <li>支付宝版权所有 2011-2015 ALIPAY.COM </li>
  81:                      </ul>
  82:                  </div>
  83:              </div>
  84:          </div>
  85:      </div>
  86:      <script type="text/javascript">
  87:           //获得回调过来的信息
  88:           $(function(){
  89:       var ReturnCode=$.query.get("ReturnCode"); 
  90:       var Msg=$.query.get("Msg");
  91:       var OrderId=$.query.get("OrderId");
  92:       var PayFre=$.query.get("PayFre");
  93:           if(ReturnCode=="ok")
  94:           $("#Msg").text("恭喜您,支付成功!我们会尽快发货!如果您收货就可以继续确认收货!");
  95:           else
  96:           $("#Msg").text("对不起,支付失败!!失败信息 :"+Msg+"请联系支付宝有关人员!");
  97:          $("#OrderId").text(OrderId);
  98:           $("#PayFre").text(PayFre);
  99:           });
 100:      
 101:       
 102:      </script>
 103:  </asp:Content>

程序截图:

效果图就是这样子

我的google code开源网站首页:http://code.google.com/p/tzhsweetsourse/ 最近准备换份工作,希望大家帮忙推荐推荐!

[转]一步一步asp.net_购物车订单与支付宝的更多相关文章

  1. 如何一步一步用DDD设计一个电商网站(十)—— 一个完整的购物车

     阅读目录 前言 回顾 梳理 实现 结语 一.前言 之前的文章中已经涉及到了购买商品加入购物车,购物车内购物项的金额计算等功能.本篇准备把剩下的购物车的基本概念一次处理完. 二.回顾 在动手之前我对之 ...

  2. 如何一步一步用DDD设计一个电商网站(六)—— 给购物车加点料,集成售价上下文

    阅读目录 前言 如何在一个项目中实现多个上下文的业务 售价上下文与购买上下文的集成 结语 一.前言 前几篇已经实现了一个最简单的购买过程,这次开始往这个过程中增加一些东西.比如促销.会员价等,在我们的 ...

  3. 一步一步搭框架(asp.netmvc+easyui+sqlserver)-03

    一步一步搭框架(asp.netmvc+easyui+sqlserver)-03 我们期望简洁的后台代码,如下: using System; using System.Collections.Gener ...

  4. 一步一步搭框架(asp.netmvc+easyui+sqlserver)-02

    一步一步搭框架(asp.netmvc+easyui+sqlserver)-02 我们期望简洁带前台代码,如下: <table id="dataGrid" class=&quo ...

  5. 一步一步搭框架(asp.netmvc+easyui+sqlserver)-01

    一步一步搭框架(asp.netmvc+easyui+sqlserver)-01 要搭建的框架是企业级开发框架,适用用企业管理信息系统的开发,如:OA.HR等 1.框架名称:sampleFrame. 2 ...

  6. (转) 一步一步学习ASP.NET 5 (四)- ASP.NET MVC 6四大特性

    转发:微软MVP 卢建晖 的文章,希望对大家有帮助.原文:http://blog.csdn.net/kinfey/article/details/44459625 编者语 : 昨晚写好的文章居然csd ...

  7. (转) 一步一步学习ASP.NET 5 (二)- 通过命令行和sublime创建项目

    转发:微软MVP 卢建晖 的文章,希望对大家有帮助. 注:昨天转发之后很多朋友指出了vNext的命名问题,原文作者已经做出了修改,后面的标题都适用 asp.net 5这个名称. 编者语 : 昨天发了第 ...

  8. .NET跨平台:在Mac上跟着错误信息一步一步手写ASP.NET 5程序

    今天坐高铁时尝试了一种学习ASP.NET 5的笨方法,从空文件夹开始,根据运行dnx . kestrel命令的错误信息,一步一步写代码,直至将一个最简单的ASP.NET程序运行起来. 尝试的具体步骤如 ...

  9. ASP.NET MVC 3 Model【通过一简单实例一步一步的介绍】

    今天主要讲Model的两个方面: 1. ASP.Net MVC 3 Model 简介 通过一简单的事例一步一步的介绍 2. ASP.Net MVC 3 Model 的一些验证 MVC 中 Model ...

随机推荐

  1. 【JAVA、C++】LeetCode 021 Merge Two Sorted Lists

      Merge two sorted linked lists and return it as a new list. The new list should be made by splicing ...

  2. 【leetcode】clone-graph

    写在前面的话: 看了看自己的博客,从一月底开始就没怎么更新过,我也确实将近5个月没怎么写代码了.今天突然觉得有些心慌,感觉手都已经生疏了.果然,随便找了道题就卡住了.隐约感觉要用map但又不太记得用法 ...

  3. 【VirtualBox】端口转发,ssh

    端口转发 VirualBox的设置 - 网络 - 端口转发 里面有主机IP.主机端口.子系统IP.子系统端口 设置后的含义是:当外部访问主机IP:主机端口后,将会把访问映射到虚拟机的子系统IP和子系统 ...

  4. ACdream 1195 Sudoku Checker (数独)

    Sudoku Checker Time Limit:1000MS     Memory Limit:64000KB     64bit IO Format:%lld & %llu Submit ...

  5. July 19th, Week 30th Tuesday, 2016

    The good seaman is known in bad weather. 惊涛骇浪,方显英雄本色. You can't be afraid to fail. It's the only way ...

  6. 今天装了一个RTI工具

    就是一个协议,需要在本机运行,今天天气有变,还要陈到家里来安装光纤宽带,昨天晚上家里下了一场雷电交加的大雨,电停了一会

  7. /bin/dd if=/path/to/source-file of=/path/to/backup-file

    [root@ok virhost]# qemu-img info 05t.img image: 05t.img file format: raw virtual size: 10G (10737418 ...

  8. .net学习之多线程、线程死锁、线程通信 生产者消费者模式、委托的简单使用、GDI(图形设计接口)常用的方法

    1.多线程简单使用(1)进程是不执行代码的,执行代码的是线程,一个进程默认有一个线程(2)线程默认情况下都是前台线程,要所有的前台线程退出以后程序才会退出,进程里默认的线程我们叫做主线程或者叫做UI线 ...

  9. 把一个SVN项目的目录结构 导入到另外一个空白的SVN项目里

    1 选好源目录,选中“check out” 2 选中想要的目录结构 3 选择具体的目录 4 确定,最后开始更新,成功!

  10. CC2540开发板学习笔记(二)——按键

    一.实验内容 用按键S1控制LED1的亮和灭 二.实验过程 1.电路原理: 可以看出,当S按下P0.0和P0.1接地,反之则接高电压. 2.寄存器使用: 依旧应该首先进行3个基本寄存器的设定,对LED ...