在前面随笔《
利用微信公众号实现商品的展示和支付(1)
》介绍了商品的列表和明细信息的处理,本篇随笔接着上一篇,继续介绍关于商品的微信支付和购物车处理方面,其中微信支付里面,也涉及到了获取微信共享地址的处理,从而个更加方便录入邮寄地址信息;购物车可以从本地的localStorage对象进行获取和处理,也可通过接口获取数据库记录的购物车信息,本案例介绍通过localStorage进行购物车处理方式。

1、商品的微信支付处理

商品的微信支付处理,其中涉及了两个场景,一个是直接购买,一个是通过购物车的结算方式,两个处理界面有所差异,直接付款购买的界面是对当前选中商品进行单项的结算处理,默认数量为1;而购物车订单结算则是利用购物车的记录进行微信支付的处理,购物车可以从本地的localStorage对象进行获取和处理,也可通过接口获取数据库记录的购物车信息,本案例介绍通过localStorage进行购物车处理方式。

对选中商品直接结算界面如下所示。

购物车结算界面如下所示。

先来看看微信共享地址的处理界面,代码如下所示。

<!--配送地址处理-->
<divclass="weui-panel">
    <divclass="weui-panel__bd">
        <divclass="weui-media-box weui-media-box_small-appmsg">
            <divclass="weui-cells">
                <divclass="weui-cell weui-cell_access">
                    <divclass="weui-cell__bd weui-cell_primary">
                        <pclass="font-14"><spanclass="mg-r-10">配送地址</span><spanclass="fr"><aonclick="GetAddress()"class="weui-btn_mini weui-btn_primary">获取微信地址</a></span></p>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<divclass="wy-media-box weui-media-box_text address-select">
    <divclass="weui-media-box_appmsg">
        <divclass="weui-media-box__hd proinfo-txt-l"style="width:20px;"><spanclass="promotion-label-tit"><imgsrc="~/Content/wechat/web/images/icon_nav_city.png" /></span></div>
        <divclass="weui-media-box__bd">
            <ahref="/h5/address"class="weui-cell_access">
                <h4class="address-name"></h4>
                <divclass="address-txt"></div>
            </a>
        </div>
        <divclass="weui-media-box__hd proinfo-txt-l"style="width:16px;"><divclass="weui-cell_access"><spanclass="weui-cell__ft"></span></div></div>
    </div>
</div>

获取微信共享地址,需要配合微信的JSSDK的JS代码进行处理,如下是处理的代码。

    <scriptlanguage="javascript">
        varappid= '@ViewBag.appid';varnoncestr= '@ViewBag.noncestr';varsignature= '@ViewBag.signature';vartimestamp= '@ViewBag.timestamp';

wx.config({
debug:
false,
appId: appid,
//必填,公众号的唯一标识 timestamp: timestamp,//必填,生成签名的时间戳 nonceStr: noncestr,//必填,生成签名的随机串 signature: signature,//必填,签名,见附录1 jsApiList: ['checkJsApi','chooseImage','previewImage','uploadImage','downloadImage','getLocalImgData','openAddress']
});
//所有准备好后 wx.ready(function() {

});
//获取微信共享地址 functionGetAddress() {
wx.openAddress({
success:
function(res) {varuserName=res.userName;//收货人姓名 varpostalCode=res.postalCode;//邮编 varprovinceName=res.provinceName;//国标收货地址第一级地址(省) varcityName=res.cityName;//国标收货地址第二级地址(市) varcountryName=res.countryName;//国标收货地址第三级地址(国家) vardetailInfo=res.detailInfo;//详细收货地址信息 varnationalCode=res.nationalCode;//收货地址国家码 vartelNumber=res.telNumber;//收货人手机号码 //$.alert(`${detailInfo}`); $(".address-name").html(`<span>${userName}</span><span>${telNumber}</span>`);
$(
".address-txt").text(`${detailInfo}`);
}
});
}
</script>

而直接购买的产品信息,就是通过ID获取对应商品信息,绑定在控件上即可,如下界面代码所示。

<!--购买商品信息-->
<divclass="wy-media-box weui-media-box_text">
    <divclass="weui-media-box__bd">
        <divclass="weui-media-box_appmsg ord-pro-list">
            <divclass="weui-media-box__hd"><ahref="pro_info.html"><imgid="productimg"class="weui-media-box__thumb"src=""alt=""></a></div>
            <divclass="weui-media-box__bd">
                <h1class="weui-media-box__desc"><ahref="/h5/ProductDetail?id=@Request["ID"]" class="ord-pro-link"><spanid="productname"></span></a></h1>
                <pclass="weui-media-box__desc">规格:<span></span></p>
                <divclass="clear mg-t-10">
                    <divclass="wy-pro-pri fl">¥<emclass="num font-15"id="price">0</em></div>
                    <divclass="pro-amount fr"><divid="spinner-amount"class="Spinner"></div></div>
                </div>
            </div>
        </div>
    </div>
</div>

JS处理代码如下所示

//绑定产品明细
functionGetProductDetail() {var url = "/H5/GetProductDetail";var data ={
id:
"@Request["ID"]"}//获取数据并绑定界面 $.getJSON(url, data, function(result) {
$(
"#productname").text(result.ProductName);
$(
"#price").text(result.Price);
$(
"#productimg").attr("src", result.Picture);//$("#description").text(result.Description); $("#totalmoney").text(result.Price);
});
}

而微信支付的处理,我们可以通过参考官方的接口定义来处理我们的代码。

https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6

我们先来金额汇总的界面展示,通过按钮我们发起微信支付的处理操作。

<!--金额及发起支付-->
<divclass="wy-media-box weui-media-box_text">
    <divclass="mg10-0 t-c">总金额:<spanclass="wy-pro-pri mg-tb-5">¥<emclass="num font-20"id="totalmoney">0</em></span></div>
    <divclass="mg10-0"><aonclick="PayMoney()"class="weui-btn weui-btn_primary">微信付款</a></div>
    <divclass="mg10-0"><ahref="/h5/ProductList"class="weui-btn weui-btn_plain-primary">返回产品列表</a></div>
</div>

参考下官方案例,我们处理的JS代码如下所示。

        //微信支付的调用处理
        functiononBridgeReady() {//统一下单的数据
            var total_fee = parseFloat($("#totalmoney").text()) * 100;//转换为分单位
            var data ={
total_fee: total_fee,
//订单金额,单位为分 body: $("#productname").text(), //商品或支付单简要描述 detail: $("#productname").text(), //商品名称明细列表 openid: "@ViewBag.openid", //当前用户标识 product_id: "@Request["ID"]", //商品ID, trade_type=NATIVE,此参数必传 trade_type: "JSAPI", //交易类型, JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付 attach: "附加数据", //附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据 };//获取预下单参数并调用支付处理 var url = "/h5/GetPreOrder";
$.getJSON(url, data,
function(info) {
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {"appId": info.appId, //公众号名称,由商户传入 "timeStamp": info.timeStamp, //时间戳,自1970年以来的秒数 "nonceStr": info.nonceStr, //随机串 "package": info.package,"signType": info.signType, //微信签名方式: "paySign": info.paySign //微信签名 },function(res) {switch(res.err_msg) {case 'get_brand_wcpay_request:cancel':
$.alert(
"取消支付");break;case 'get_brand_wcpay_request:fail':
$.alert(
"支付失败,可能的原因:签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常等。");break;case 'get_brand_wcpay_request:ok':
$.alert(
"支付成功");break;
}
});
});
}
//微信付款 functionPayMoney() {if (typeof WeixinJSBridge == "undefined") {if(document.addEventListener) {
document.addEventListener(
'WeixinJSBridgeReady', onBridgeReady, false);
}
else if(document.attachEvent) {
document.attachEvent(
'WeixinJSBridgeReady', onBridgeReady);
document.attachEvent(
'onWeixinJSBridgeReady', onBridgeReady);
}
}
else{
onBridgeReady();
}
}

这里的支付所需的参数,我们通过后端的/h5/GetPreOrder 获取生成,然后通过JS进行异步发起支付操作。

这个GetPreOrder主要的操作就是根据我们传入的商品信息,然后获取对应的参数返回给前端。

/// <summary>
///预生成订单支付需要的前端参数/// </summary>
/// <param name="order">订单数据</param>
/// <returns></returns>
publicActionResult GetPreOrder(PayOrderData order)
{
dynamic obj = newExpandoObject();if (order != null && order.total_fee > 0)
{
//调用支付API,获取统一下单数据 var payApi = new TenPayApi(this.accountInfo);var preResult =payApi.UnifiedOrder(order);var prepay_id = preResult.prepay_id;//预支付回话标识//生成支付所需数据和签名 WxPayData data = newWxPayData();
data.SetValue(
"appId", accountInfo.AppID);//公众帐号id data.SetValue("timeStamp", data.GenerateTimeStamp());//随机字符串 data.SetValue("nonceStr", data.GenerateNonceStr());//随机字符串 data.SetValue("package", string.Format("prepay_id={0}", prepay_id));//统一下单接口返回的prepay_id参数值,提交格式如:prepay_id=*** data.SetValue("signType", "MD5");//签名类型,默认为MD5,支持HMAC-SHA256和MD5。注意此处需与统一下单的签名类型一致 data.SetValue("paySign", data.MakeSign(accountInfo.PayAPIKey));//签名//构建一个前端使用的对象,用于配置支付处理的JS参数 obj.appId =accountInfo.AppID;
obj.nonceStr
= data.GetValue("nonceStr");
obj.timeStamp
= data.GetValue("timeStamp");
obj.package
= data.GetValue("package");
obj.signType
= data.GetValue("signType");
obj.paySign
= data.GetValue("paySign");
}
returnToJsonContent(obj);
}

这样我们就可以发起微信支付处理操作了。

当然,我们JS方面,除了刚才利用getBrandWCPayRequest 来发起支付处理,我们还可以利用微信JSSDK的chooseWXPay函数支付发起处理的,如下代码所示。

//发起一个微信支付
functionchooseWXPay() {//统一下单的数据
    var total_fee = parseFloat($("#totalmoney").text()) * 100;//转换为分单位
    var data ={
total_fee: total_fee,
//订单金额,单位为分 body: $("#productname").text(), //商品或支付单简要描述 detail: $("#productname").text(), //商品名称明细列表 openid: "@ViewBag.openid", //当前用户标识 product_id: "@Request["ID"]", //商品ID, trade_type=NATIVE,此参数必传 trade_type: "JSAPI", //交易类型, JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付 attach: "附加数据", //附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据 };//获取预下单参数并调用支付处理 var url = "/h5/GetPreOrder";
$.getJSON(url, data,
function(info) {
wx.chooseWXPay({
appId: info.appId,
timestamp: info.timeStamp,
//支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符 nonceStr: info.nonceStr, //支付签名随机串,不长于 32 位 package: info.package, //统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***) signType: info.signType, //签名方式,默认为'SHA1',使用新版支付需传入'MD5' paySign: info.paySign, //支付签名 success: function (res) { //支付成功后的回调函数 if (res.errMsg == 'chooseWXPay:ok') {
$.toast(
'支付成功');//setTimeout(function () { //window.location.href = "/";//这里默认跳转到主页 //}, 2000); //window.location.href = "/Pay/order_details?orderId=" + $("#orderId").val(); } else if (res.errMsg == 'chooseWXPay:cancel' || res.errMsg == 'chooseWXPay:fail') {
$.toast(
"支付失败");//window.location.href = "/Pay/order_details?orderId=" + $("#orderId").val(); }
},
cancel:
function() {
$.toast(
"用户取消了支付2");//window.location.href = "/Pay/order_details?orderId=" + $("#orderId").val(); }
});

wx.error(
function(res) {
$.toast(
"调用支付出现异常");
});
});
}

同样可以实现一样的微信支付效果。

2、商品的购物车处理

前面介绍过,购物车可以从本地的localStorage对象进行获取和处理,也可通过接口获取数据库记录的购物车信息,本案例介绍通过localStorage进行购物车处理方式。

为了封装对localStorage购物车的处理,我们引入一个对这个购物车的操作处理,主要就是添加、更新、获取列表、清空列表等相关操作。

对于以上JS的代码使用demo代码如下所示。

<script>$(function() {varproduct={'id':1,      属性名用引号括起来,属性间由逗号隔开'name':'商品1','num':1,'price':1};

cart.addProduct(product); 商品加入到购物车
varproductlist=cart.getProductList(); 取出购物车商品
console.log(productlist);
varisExist=cart.existProduct();
console.log(isExist);
cart.deleteProduct(
1);varisExist1=cart.existProduct();
console.log(isExist1);
});
</script>

购物车列表界面如下所示,主要就是展开存储里面的商品信息,并汇总展示,如下所示。

这个页面视图的代码如下所示。

<!--主体-->
<headerclass="wy-header">
    <divclass="wy-header-icon-back"><span></span></div>
    <divclass="wy-header-title">购物车</div>
</header>
<divclass="weui-content"id="divCart">
</div>

<!--底部导航-->
<divclass="foot-black"></div>
<divclass="weui-tabbar wy-foot-menu">
    <divclass="npd cart-foot-check-item weui-cells_checkbox allselect">
        <divclass="weui-cell allsec-well weui-check__label"for="all">
            <divclass="weui-cell__hd">
                <inputtype="checkbox"class="weui-check"name="all-sec"id="all">
                <iclass="weui-icon-checked"></i>
            </div>
            <divclass="weui-cell__bd">
                <pclass="font-14">全选</p>
            </div>
        </div>
    </div>
    <divclass="weui-tabbar__item  npd">
        <pclass="cart-total-txt">合计:<i></i><emclass="num font-16"id="zong1">0.00</em></p>
    </div>
    <ahref="/h5/shopcartorder"class="red-color npd w-90 t-c">
        <pclass="promotion-foot-menu-label">去结算</p>
    </a>
</div>

这里主要就是根据数据,动态构建divCart里面的列表数据,相关的JS代码如下所示。

//显示购物车列表
functionshowCartList() {var productlist = cart.getProductList();    //取出购物车商品
    $("#divCart").html("");//构建HTML控件
    $.each(productlist, function(i, item) {var html =`<div class="weui-panel weui-panel_access">
            <div class="weui-panel__hd"><span>广州爱奇迪</span><a href="javascript:;" class="wy-dele"></a></div>
            <div class="weui-panel__bd">
                <div class="weui-media-box_appmsg pd-10">
                    <div class="weui-media-box__hd check-w weui-cells_checkbox">
                        <div class="weui-check__label" for="cart-pto1">
                            <div class="weui-cell__hd cat-check"><input type="checkbox" class="weui-check" name="cartpro" id="cart-pto1"><i class="weui-icon-checked"></i></div>
                        </div>
                    </div>
                    <div class="weui-media-box__hd"><a href="/h5/ProductDetail?id=${item.id}"><img class="weui-media-box__thumb" src="${item.picture}" alt=""></a></div>
                    <div class="weui-media-box__bd">
                        <h1 class="weui-media-box__desc"><a href="/h5/ProductDetail?id=${item.id}" class="ord-pro-link">${item.name}</a></h1>
                        <p class="weui-media-box__desc">规格:<span>套</span></p>
                        <div class="clear mg-t-10">
                            <div class="wy-pro-pri fl">¥<em class="num font-15">${item.price}</em></div>
                            <div class="pro-amount fr">
                                <div class="weui-count">
                                    <a class="weui-count__btn weui-count__decrease"></a>
                                    <input class="weui-count__number" type="number" value="${item.num}" />
                                    <a class="weui-count__btn weui-count__increase"></a>
                                    <input type="hidden" class="pro-id" value="${item.id}"/>
                                 </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>`;
$("#divCart").append(html);
});

...................

对于数量的修改,我们同时修改购物车里面的数据即可,如下代码所示。

//对数量改变进行处理,更新购物车的对应产品id的数量
var MAX = 99, MIN = 1;
$(
'.weui-count__decrease').each(function(i) {
$(
this).click(function(e) {var $input = $(e.currentTarget).parent().find('.weui-count__number');var number = parseInt($input.val() || "0") - 1 if (number < MIN) number =MIN;
$input.val(number);
var id = $(e.currentTarget).parent().find(".pro-id").val();
updateProductNum(id, number);
});
});
$(
'.weui-count__increase').each(function(i) {
$(
this).click(function(e) {var $input = $(e.currentTarget).parent().find('.weui-count__number');var number = parseInt($input.val() || "0") + 1 if (number > MAX) number =MAX;
$input.val(number);
var id = $(e.currentTarget).parent().find(".pro-id").val();
updateProductNum(id, number);
});
});

其中updateProductNum是对购物车数据的修改。

//修改购物车的内容
functionupdateProductNum(id, number) {
console.log(id
+ ':' +number);
cart.updateProductNum(id, number);
//显示数量和金额 var amount = orderdetail.totalAmount;//获取购物车的总金额 $("#zong1").text(amount);
}

购物车的清空指定商品的JS代码如下所示。

$(document).on("click", ".wy-dele", function() {
$.confirm(
"您确定要把此商品从购物车删除吗?", "确认删除?", function() {var id = $(this).parent().parent().find(".pro-id").val();
cart.clearProduct(id);
//移除指定商品 showCartList();//更新列表 $.toast("文件已经删除!");
},
function() {//取消操作 });
});

购物车的结算页面,前面介绍过了,就是如下图所示,类似我们直接购买商品的界面。

这个地方主要差异在于也是动态获取一个或多个商品记录的信息,如下所示。

HTML视图界面代码如下所示。

        <divid="divCart">@*<divclass="wy-media-box weui-media-box_text">
            <divclass="weui-media-box__bd">
                <divclass="weui-media-box_appmsg ord-pro-list">
                    <divclass="weui-media-box__hd"><ahref="pro_info.html"><imgid="productimg"class="weui-media-box__thumb"src=""alt=""></a></div>
                    <divclass="weui-media-box__bd">
                        <h1class="weui-media-box__desc"><ahref="/h5/ProductDetail?id=@Request["ID"]" class="ord-pro-link"><spanid="productname"></span></a></h1>
                        <pclass="weui-media-box__desc">规格:<span></span></p>
                        <divclass="clear mg-t-10">
                            <divclass="wy-pro-pri fl">¥<emclass="num font-15"id="price">0</em></div>
                            <divclass="pro-amount fr"><spanclass="font-13">数量×<emclass="name">1</em></span></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>*@</div>

JS代码主要就是动态构建列表,divCart里面的内容实现根据购物车商品列表进行处理,如下代码所示。

        //显示购物车列表
        functionshowCartList() {var productlist = cart.getProductList();    //取出购物车商品
            $("#divCart").html("");//构建HTML控件
            var html = "";
$.each(productlist,
function(i, item) {
html
+=`<div class="wy-media-box weui-media-box_text"> <div class="weui-media-box__bd"> <div class="weui-media-box_appmsg ord-pro-list"> <div class="weui-media-box__hd"><a href="/h5/ProductDetail?id=${item.id}"><img id="productimg" class="weui-media-box__thumb" src="${item.picture}" alt=""></a></div> <div class="weui-media-box__bd"> <h1 class="weui-media-box__desc"><a href="/h5/ProductDetail?id=${item.id}" class="ord-pro-link">${item.name}</a></h1> <p class="weui-media-box__desc">规格:<span>套</span></p> <div class="clear mg-t-10"> <div class="wy-pro-pri fl">¥<em class="num font-15" id="price">${item.price}</em></div> <div class="pro-amount fr"><span class="font-13">数量×<em class="name">${item.num}</em></span></div> <input type="hidden" class="pro-id" value="${item.id}"/> </div> </div> </div> </div> </div>`; });
$(
"#divCart").append(html);//显示数量和金额 var amount = orderdetail.totalAmount;//获取购物车的总金额 $("#totalmoney").text(amount);
}

标签: none

添加新评论