首页 > 代码库 > 转,关于购物车

转,关于购物车

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

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

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

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

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

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

image

这种方式类似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重写部分,还没有实现)

image

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

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

 

 

进入主题:

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

首先是,当用户点击

image

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

image

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

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

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

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

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

image

这个用了一个框架(改改颜色就上了,不过感觉加载了好多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=http://www.mamicode.com/"../css/buy.css" rel="stylesheet" type="text/css" />
   7:   
   8:      <script src=http://www.mamicode.com/"../Admin/scripts/jquery-1.6.2.min.js" type="text/javascript"></script>
   9:   
  10:      <script src=http://www.mamicode.com/"../Admin/scripts/miniui/miniui.js" type="text/javascript"></script>
  11:   
  12:      <link href=http://www.mamicode.com/"../Admin/scripts/miniui/themes/default/miniui2.css" rel="stylesheet"
  13:          type="text/css" />
  14:      <link href=http://www.mamicode.com/"../Admin/scripts/miniui/themes/icons.css" rel="stylesheet" type="text/css" />
  15:         <script src=http://www.mamicode.com/"../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=http://www.mamicode.com/"MemberOrders.aspx">
  46:                          <img src=http://www.mamicode.com/"../images/js_small_03.jpg" /></a><a href=http://www.mamicode.com/"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=http://www.mamicode.com/"1"  renderer="onRenderQuantity" maxValue=http://www.mamicode.com/"9999"  value=http://www.mamicode.com/"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=http://www.mamicode.com/"批量删除" />--%> <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=http://www.mamicode.com/"MemberOrders.aspx">
  90:                                      <img src=http://www.mamicode.com/"../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=http://www.mamicode.com/‘<a href="http://www.mamicode.com/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=http://www.mamicode.com/‘<a href="http://www.mamicode.com/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= http://www.mamicode.com/‘<img src="http://www.mamicode.com/Admin/FileManage/GetImg.ashx?method=GetMainProductPic&type=small&fileName=‘+e.value+‘" style="width:60px;height:40px;"/>‘;
  65:               var href=http://www.mamicode.com/‘<a href="http://www.mamicode.com/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="http://www.mamicode.com/‘+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 = http://www.mamicode.com/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:      }

接下来就是订单结算,

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

image

 

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

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

image

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

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

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

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

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

image

获取订单号的存储过程

   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

调用函数

image

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

image

接下来就是订单处理了:

我们需要处理哪些呢?

首先是提交用户的收货信息,再次检验库存状态,然后插入订单信息表和订单产品表,并且将商品表的产品数量更新,并且给用户发送订单邮件(我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 = http://www.mamicode.com/"";
  41:          //支付跳转URL
  42:          string TurnURL = "";
  43:          if (Status)
  44:          {
  45:              Data = http://www.mamicode.com/"恭喜您!下单成功!";
  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 = http://www.mamicode.com/"对不起!下单失败!";
  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 = http://www.mamicode.com/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=http://www.mamicode.com/‘" + 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请求参数,数字签名,等信息,交易成功然后按照请求读取参数检验数字签名是否正确.

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

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

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

image

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

   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=http://www.mamicode.com/"../css/buy.css" rel="stylesheet" type="text/css" />
   7:        <link href=http://www.mamicode.com/"../css/AliPay.css" rel="stylesheet" type="text/css" />
   8:         <script src=http://www.mamicode.com/"../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.mamicode.com/"http://www.alipay.com/"><span>支付宝首页</span></a>| <a target="_blank"
  39:                              href=http://www.mamicode.com/"https://b.alipay.com/home.htm"><span>商家服务</span></a>| <a target="_blank" href=http://www.mamicode.com/"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=http://www.mamicode.com/"确认收货"
  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>

转,关于购物车