Using WeChat official account to display and pay for goods

Write at the front< Using WeChat official account to display and pay for goods (1) >This paper introduces the processing of the list and details of the goods. Next to the previous article, this article continues to introduce the wechat payment and shopping cart processing of the goods. In wechat payment, it also involves the processing of obtaining the wechat shared address, so that it is more convenient to enter the mail address information. The shopping cart can be obtained and processed from the local storage object, and also The shopping cart information recorded in the database can be obtained through the interface. This case introduces the shopping cart processing method through localStorage.

1. Wechat payment processing of goods

Wechat payment processing of goods involves two scenarios, one is direct purchase, the other is through the settlement method of shopping cart. There are differences between the two processing interfaces. The direct payment purchase interface is to carry out single settlement processing for the currently selected goods, with the default quantity of 1; the shopping cart order settlement is to use the records of shopping cart for wechat payment processing, shopping The cart can be acquired and processed from the local storage object, or the shopping cart information recorded in the database can be acquired through the interface. This case introduces the shopping cart processing method through the local storage.

The direct settlement interface for the selected goods is as follows.

The shopping cart settlement interface is as follows.

 

First, let's look at the wechat shared address processing interface. The code is as follows.

<!--Shipping address processing-->
<div class="weui-panel">
    <div class="weui-panel__bd">
        <div class="weui-media-box weui-media-box_small-appmsg">
            <div class="weui-cells">
                <div class="weui-cell weui-cell_access">
                    <div class="weui-cell__bd weui-cell_primary">
                        <p class="font-14"><span class="mg-r-10">Shipping address</span><span class="fr"><a onclick="GetAddress()" class="weui-btn_mini weui-btn_primary">Get wechat address</a></span></p>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<div class="wy-media-box weui-media-box_text address-select">
    <div class="weui-media-box_appmsg">
        <div class="weui-media-box__hd proinfo-txt-l" style="width:20px;"><span class="promotion-label-tit"><img src="~/Content/wechat/web/images/icon_nav_city.png" /></span></div>
        <div class="weui-media-box__bd">
            <a href="/h5/address" class="weui-cell_access">
                <h4 class="address-name"></h4>
                <div class="address-txt"></div>
            </a>
        </div>
        <div class="weui-media-box__hd proinfo-txt-l" style="width:16px;"><div class="weui-cell_access"><span class="weui-cell__ft"></span></div></div>
    </div>
</div>

To obtain the wechat share address, you need to cooperate with the JS code of wechat JSSDK for processing. The following is the processing code.

    <script language="javascript">
        var appid = '@ViewBag.appid';
        var noncestr = '@ViewBag.noncestr';
        var signature = '@ViewBag.signature';
        var timestamp = '@ViewBag.timestamp';

        wx.config({
            debug: false,
            appId: appid, // Required, the only sign of official account.
            timestamp: timestamp, // Required, generate signature timestamp
            nonceStr: noncestr, // Required, generate random string of signature
            signature: signature, // Required, signature, see Appendix 1
            jsApiList: [
               'checkJsApi',
               'chooseImage',
               'previewImage',
               'uploadImage',
               'downloadImage',
               'getLocalImgData',
               'openAddress'
            ]
        });

        //When all is ready
        wx.ready(function () {

        });

        //Get wechat share address
        function GetAddress() {
            wx.openAddress({
                success: function (res) {
                    var userName = res.userName; // Consignee Name 
                    var postalCode = res.postalCode; // Zip code
                    var provinceName = res.provinceName; // First level address of GB receiving address (province)
                    var cityName = res.cityName; // GB receiving address level 2 address (city)
                    var countryName = res.countryName; // GB receiving address level 3 address (country)
                    var detailInfo = res.detailInfo; // Detailed receiving address information
                    var nationalCode = res.nationalCode; // Ship to country code
                    var telNumber = res.telNumber; // Receiver mobile number

                    //$.alert(`${detailInfo}`);
                    $(".address-name").html(`<span>${userName}</span><span>${telNumber}</span>`);
                    $(".address-txt").text(`${detailInfo}`);
                }
            });
        }
    </script>

The product information purchased directly is to obtain the corresponding product information through ID and bind it to the control, as shown in the following interface code.

<!--Purchase information-->
<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="pro_info.html"><img id="productimg" class="weui-media-box__thumb" src="" alt=""></a></div>
            <div class="weui-media-box__bd">
                <h1 class="weui-media-box__desc"><a href="/h5/ProductDetail?id=@Request["ID"]" class="ord-pro-link"><span id="productname"></span></a></h1>
                <p class="weui-media-box__desc">Specifications:<span>set</span></p>
                <div class="clear mg-t-10">
                    <div class="wy-pro-pri fl">¥<em class="num font-15" id="price">0</em></div>
                    <div class="pro-amount fr"><div id="spinner-amount" class="Spinner"></div></div>
                </div>
            </div>
        </div>
    </div>
</div>

JS processing code is as follows

//Binding product details
function GetProductDetail() {
    var url = "/H5/GetProductDetail";
    var data = {
        id: "@Request["ID"]"
    }
    //Get data and bind interface
    $.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);
    });
}

For wechat payment processing, we can process our code by referring to the official interface definition.

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

Let's first display the amount summary interface, and then click the button to initiate wechat payment processing.

<!--Amount and initiated payment-->
<div class="wy-media-box weui-media-box_text">
    <div class="mg10-0 t-c">Total amount:<span class="wy-pro-pri mg-tb-5">¥<em class="num font-20" id="totalmoney">0</em></span></div>
    <div class="mg10-0"><a onclick="PayMoney()" class="weui-btn weui-btn_primary">Wechat payment</a></div>
    <div class="mg10-0"><a href="/h5/ProductList" class="weui-btn weui-btn_plain-primary">Return to product list</a></div>
</div>

Referring to the official case, the JS code we are dealing with is shown below.

        //Call processing of wechat payment
        function onBridgeReady() {
            //Unified order data
            var total_fee = parseFloat($("#totalmoney").text()) * 100;//Convert to units
            var data = {
                total_fee: total_fee,               //Order amount,In minutes
                body: $("#productname").text(),     //Brief description of goods or payment order
                detail: $("#productname").text(),   //Detailed list of commodity names
                openid: "@ViewBag.openid",      //Current user ID
                product_id: "@Request["ID"]",   //commodity ID, trade_type=NATIVE,This parameter must be passed
                trade_type: "JSAPI",        //Transaction type, JSAPI--Official account payment, NATIVE--Native scan payment APP--app payment
                attach: "Additional data",         // Additional data,In the query API And payment notice. This field is mainly used for the customized data of the order carried by the merchant
            };

            //Get pre order parameters and call payment processing
            var url = "/h5/GetPreOrder";
            $.getJSON(url, data, function (info) {
                WeixinJSBridge.invoke(
                    'getBrandWCPayRequest', {
                        "appId": info.appId,          //The name of the official account is imported from merchants.
                        "timeStamp": info.timeStamp,  //Time stamp, seconds since 1970
                        "nonceStr": info.nonceStr,    //Random string
                        "package": info.package,
                        "signType": info.signType,         //Wechat signature method:
                        "paySign": info.paySign //Wechat signature
                    },
                    function (res) {
                        switch (res.err_msg) {
                            case 'get_brand_wcpay_request:cancel':
                                $.alert("Cancel payment");
                                break;
                            case 'get_brand_wcpay_request:fail':
                                $.alert("Payment failed, possible reasons: wrong signature, not registered APPID,Project settings APPID Incorrect, registered APPID Mismatches with settings, other exceptions, etc.");
                                break;
                            case 'get_brand_wcpay_request:ok':
                                $.alert("Payment successful");
                                break;
                        }
                    });
            });
        }

        //Wechat payment
        function PayMoney() {
            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();
            }
        }

For the parameters required for payment here, we get the generation through / h5/GetPreOrder on the backend, and then asynchronously initiate the payment operation through JS.

The main operation of GetPreOrder is to get the corresponding parameters and return them to the front end according to the product information we passed in.

/// <summary>
/// Front end parameters required for pre generated order payment
/// </summary>
/// <param name="order">Order data</param>
/// <returns></returns>
public ActionResult GetPreOrder(PayOrderData order)
{
    dynamic obj = new ExpandoObject();
    if (order != null && order.total_fee > 0)
    {
        //Call payment API,Get unified order data
        var payApi = new TenPayApi(this.accountInfo);
        var preResult = payApi.UnifiedOrder(order);
        var prepay_id = preResult.prepay_id;//Prepaid call back ID


        //Generate data and signatures required for payment
        WxPayData data = new WxPayData();
        data.SetValue("appId", accountInfo.AppID);//public account  id
        data.SetValue("timeStamp", data.GenerateTimeStamp());//Random string         
        data.SetValue("nonceStr", data.GenerateNonceStr());//Random string
        data.SetValue("package", string.Format("prepay_id={0}", prepay_id));//Unified order interface returned prepay_id Parameter value, submission format is as follows: prepay_id=***     
        data.SetValue("signType", "MD5");//Signature type, default is MD5,Support HMAC-SHA256 and MD5. Note that this should be consistent with the signature type of unified order         
        data.SetValue("paySign", data.MakeSign(accountInfo.PayAPIKey));//autograph

        //Build an object used by the front end to configure the JS parameter
        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");
    }

    return ToJsonContent(obj);
}

In this way, we can initiate wechat payment processing operation.

Of course, in terms of JS, in addition to just using getBrandWCPayRequest to initiate payment processing, we can also use the chooseWXPay function of wechat JSSDK to initiate payment processing, as shown in the following code.

//Launch a wechat payment
function chooseWXPay() {
    //Unified order data
    var total_fee = parseFloat($("#totalmoney").text()) * 100;//Convert to units
    var data = {
        total_fee: total_fee,               //Order amount,In minutes
        body: $("#productname").text(),     //Brief description of goods or payment order
        detail: $("#productname").text(),   //Detailed list of commodity names
        openid: "@ViewBag.openid",      //Current user ID
        product_id: "@Request["ID"]",   //commodity ID, trade_type=NATIVE,This parameter must be passed
        trade_type: "JSAPI",        //Transaction type, JSAPI--Official account payment, NATIVE--Native scan payment APP--app payment
        attach: "Additional data",         // Additional data,In the query API And payment notice. This field is mainly used for the customized data of the order carried by the merchant
    };

    //Get pre order parameters and call payment processing
    var url = "/h5/GetPreOrder";
    $.getJSON(url, data, function (info) {
        wx.chooseWXPay({
            appId: info.appId,
            timestamp: info.timeStamp,  // Pay attention to wechat jssdk All uses in timestamp The fields are all lowercase. But the latest version of the payment background generation signature uses timeStamp The field name should be capitalized S character
            nonceStr: info.nonceStr,    // Random string of payment signature, no longer than 32 bits
            package: info.package,      // Returned by unified payment interface prepay_id Parameter value, submission format is as follows: prepay_id=***)
            signType: info.signType,    // Signature method, default to'SHA1',To use the new version of payment, you need to transfer in'MD5'
            paySign: info.paySign,      // Payment signature
            success: function (res) {   // Callback function after successful payment
                if (res.errMsg == 'chooseWXPay:ok') {
                    $.toast('Payment successful');
                    //setTimeout(function () {
                    //    window.location.href = "/";//Default to the home page
                    //}, 2000);
                    //window.location.href = "/Pay/order_details?orderId=" + $("#orderId").val();
                } else if (res.errMsg == 'chooseWXPay:cancel' || res.errMsg == 'chooseWXPay:fail') {
                    $.toast("Payment failure");
                    //window.location.href = "/Pay/order_details?orderId=" + $("#orderId").val();
                }
            },
            cancel: function () {
                $.toast("Payment cancelled by user 2");
                //window.location.href = "/Pay/order_details?orderId=" + $("#orderId").val();
            }
        });

        wx.error(function (res) {
            $.toast("Exception in call payment");
        });
    });
}

The same wechat payment effect can be achieved.  

 

2. Shopping cart handling of goods

As mentioned earlier, shopping cart can be acquired and processed from local storage object, or the shopping cart information recorded in database can be acquired through interface. This case introduces the shopping cart processing method through local storage.

In order to encapsulate the processing of localStorage shopping cart, we introduce an operation processing of this shopping cart, mainly including adding, updating, getting lists, clearing lists and other related operations.

Use the demo code for the above JS code as shown below.

<script>
    $(function () {
        var product = {
          'id': 1,      Attribute names are enclosed in quotation marks and separated by commas
          'name': 'Item 1',
          'num': 1,
          'price': 1
        };

        cart.addProduct(product);    Add item to cart
        var productlist = cart.getProductList();    Take out shopping cart items
        console.log(productlist);
        var isExist = cart.existProduct();
        console.log(isExist);
        cart.deleteProduct(1);
        var isExist1 = cart.existProduct();
        console.log(isExist1);
    });
</script>

The shopping cart list interface is shown below. It is mainly used to expand and store the commodity information in the shopping cart, and to summarize and display it, as shown below.

 

The code for this page view is shown below.

<!--subject-->
<header class="wy-header">
    <div class="wy-header-icon-back"><span></span></div>
    <div class="wy-header-title">Shopping Cart</div>
</header>
<div class="weui-content" id="divCart">
</div>

<!--Bottom navigation-->
<div class="foot-black"></div>
<div class="weui-tabbar wy-foot-menu">
    <div class="npd cart-foot-check-item weui-cells_checkbox allselect">
        <div class="weui-cell allsec-well weui-check__label" for="all">
            <div class="weui-cell__hd">
                <input type="checkbox" class="weui-check" name="all-sec" id="all">
                <i class="weui-icon-checked"></i>
            </div>
            <div class="weui-cell__bd">
                <p class="font-14">All election</p>
            </div>
        </div>
    </div>
    <div class="weui-tabbar__item  npd">
        <p class="cart-total-txt">total:<i></i><em class="num font-16" id="zong1">0.00</em></p>
    </div>
    <a href="/h5/shopcartorder" class="red-color npd w-90 t-c">
        <p class="promotion-foot-menu-label">To settle</p>
    </a>
</div>

Here is to dynamically build the list data in divCart according to the data. The relevant JS code is shown below.

//Show shopping cart list
function showCartList() {
    var productlist = cart.getProductList();    //Take out shopping cart items
    $("#divCart").html("");

    //structure HTML control
    $.each(productlist, function (i, item) {
       var html = `
        <div class="weui-panel weui-panel_access">
            <div class="weui-panel__hd"><span>Guangzhou iqidi</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">Specifications:<span>set</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);
    });
    
    ...................

For quantity modification, we can modify the data in the shopping cart at the same time, as shown in the following code.

//Process the quantity change and update the corresponding products of shopping cart id Number of
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);
    });
});

Where updateProductNum is the modification of shopping cart data.

//Modify contents of shopping cart
function updateProductNum(id, number) {
    console.log(id + ':' + number);
    cart.updateProductNum(id, number);

    //Display quantity and amount            
    var amount = orderdetail.totalAmount;//Get total amount of shopping cart
    $("#zong1").text(amount);
}

The JS code of the specified goods for the emptying of shopping cart is shown below.

$(document).on("click", ".wy-dele", function () {
    $.confirm("Are you sure you want to delete this item from the shopping cart?", "confirm deletion?", function () {
        var id = $(this).parent().parent().find(".pro-id").val();
        cart.clearProduct(id);//Remove specified item
        showCartList();//Update list

        $.toast("File deleted!");
    }, function () {
        //Cancel operation
    });
});

The settlement page of shopping cart, which was introduced earlier, is as shown in the figure below, similar to the interface where we directly purchase goods.

The main difference in this area is that it also dynamically obtains information about one or more commodity records, as shown below.

The HTML view interface code is shown below.

        <div id="divCart">
            @*<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="pro_info.html"><img id="productimg" class="weui-media-box__thumb" src="" alt=""></a></div>
                    <div class="weui-media-box__bd">
                        <h1 class="weui-media-box__desc"><a href="/h5/ProductDetail?id=@Request["ID"]" class="ord-pro-link"><span id="productname"></span></a></h1>
                        <p class="weui-media-box__desc">Specifications:<span>set</span></p>
                        <div class="clear mg-t-10">
                            <div class="wy-pro-pri fl">¥<em class="num font-15" id="price">0</em></div>
                            <div class="pro-amount fr"><span class="font-13">Number×<em class="name">1</em></span></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>*@
        </div>

JS code is mainly to dynamically build the list, and the content in divCart is processed according to the shopping cart commodity list, as shown in the following code.

        //Show shopping cart list
        function showCartList() {
            var productlist = cart.getProductList();    //Take out shopping cart items
            $("#divCart").html("");

            //structure HTML control
            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">Specifications:<span>set</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">Number×<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);

            //Display quantity and amount
            var amount = orderdetail.totalAmount;//Get total amount of shopping cart
            $("#totalmoney").text(amount);
        }

Tags: ASP.NET Database Javascript Mobile PHP

Posted on Wed, 22 Apr 2020 05:02:36 -0700 by rohithmr