微信小程序实战之实现微信支付+购物车功能,还可以在线填写资料哦!寺庙必备小程序功能

我们来看看一下效果图吧!

我是用微信开发工具的,所以到了支付功能会提示用二维码扫描,如果在真机上就是支付弹框输入支付密码的页面了!


 这个页面的功能如下

1、典型的购物车,勾选价格与物品件数都发生变换

2、在线填写信息,支付的时候回把页面上的信息全部都存储数据库里面

3、微信支付功能


这个页面的wxml如下

<view class='header1'>
  <view class='header'>
    <view class='header_con flex_between'>
      <view class='left'>
        共计{{items.length}}件商品
      </view>
    </view>
  </view>
</view>

<view class='header2'>
  <view class='header'>
    <view class='header_con flex_between'>
      <input value='牌位列表' disabled='{{title_disabled}}' focus="{{!title_disabled}}">
      </input>
    </view>
  </view>
</view>

<!-- 以上无标签缺少 -->
<view class='onlinechoose'>
  <view class='hotel_list flex_center' wx:for="{{items}}" wx:key="items" wx:for-item="i">
    <view class='list_cons flex_start'>

<!-- 单选 -->
      <view data-id="{{index}}" data-variable="{{i}}" bindtap='select'>
        <view wx:if="{{management_good}}" class='lefts'>
          <block wx-if="{{!i.checked}}">
            <view class='icon_none'></view>
          </block>
          <block wx-if="{{i.checked}}">
            <icon type="success" size="30" color="red" />
          </block>
        </view>
      </view>
<!-- 单选 -->

      <view class='right'>
    
        <view class='name'>
          <view style="background-color:red;color:white">{{i.father}}</view>
          <view class="nb">
            <input value="{{i.fname}}" placeholder="请填写姓名" bindblur="eidtfname" data-id="{{index}}" class="instyle" />
          </view>
        </view>

        <view class='name'>
          阳上
          <view class="na"> {{i.child}} </view>
          <view class="na">
            <input value="{{i.cname}}" placeholder="请填写姓名" bindblur="eidtcname" data-id="{{index}}" class="instyle" />
          </view>
        </view>

        <view class='name'>
          地址
          <view class="nb">
            <input value="{{i.address}}" bindblur="eidtadd" data-id="{{index}}" class="instyle" placeholder="请填写地址"></input>
          </view>
        </view>

        <view class='name'>
          牌价{{i.price}}
          <view class="sign-setting-border {{i.price==50?'selected':''}} " bindtap="selectApply" data-id="50" data-pr="{{index}}">大牌位</view>
          <view class="sign-setting-border {{i.price==500?'selected':''}}" bindtap="selectApply" data-id="500" data-pr="{{index}}">小牌位</view>
          </view>

      </view>
      <!-- right -->
    </view>
    <!-- 一个小的for循环 -->
  </view>
  <!-- 完整的 -->
</view>
<!-- 大封口 -->


<!-- 姓名 -->
<view class="vname" style="margin-top:9rpx">
  姓 名
  <view class="nb">
    <input placeholder="请输入付款人姓名" value='{{oname}}' bindinput='setoname' class="instyle"></input>
  </view>
</view>

<view class="vname">
  手机号码
  <view class="nb">
    <input placeholder="请输入付款人手机号码" value='{{tell}}' bindinput='settell' class="instyle"></input>
  </view>
</view>
<!-- 手机号码 -->
<view class='bottom flex_between' wx:if="{{management_good}}">
  <view class='left flex_start'>
    <block wx:if="{{select_all}}">
      <view bindtap='select_none' class='flex_start'>
        <icon type="success" size="30" color="red" />
        <view>
          取消全选
        </view>
      </view>
    </block>
    <block wx:if="{{!select_all}}">
      <view bindtap='select_all' class='flex_start'>
        <view class='select_none'>
        </view>
        <view>
          全选
        </view>
      </view>
    </block>
  </view>
  <view class='right flex_end'>
    <view style='text-align:right'>
      <view class='all'>
        共计{{middlearr.length}}个牌位
      </view>
    </view>
    <view bindtap='paygoods' class='sure'>
      支付{{money}}元
    </view>
  </view>
</view>

wxss页面如下

.instyle{
  border: 0.5px solid #cfcfcf;
}


.header1{
  background-color: #f5f5f5;
}
.header2{
  background-color: #ffffff;
}
.header {
  width: 100%;
  height: 80rpx;
  border-bottom: 1rpx solid #d6d6d6;
}
.header .header_con {
  width: 700rpx;
  height: 80rpx;
  margin: 0 auto;
  color: #333;
  font-size: 30rpx;
}
.header .header_con image{
  width: 44rpx;
  height: 44rpx;
}
.header .header_con .right{
  color: #ff4965;
}
.bottom{
  width: 100%;
  height: 100rpx;
  border-top: 1rpx solid #d6d6d6;
  background-color: #fff;
  position: relative;
}
.bottom .left{
  margin-left: 25rpx;
}
.bottom .left .select_none{
  width: 60rpx;
  height: 60rpx;
  border: 1rpx solid #d6d6d6;
  border-radius: 50%;
}
.bottom .right .all{
  color: #ff830f;
  font-size: 26rpx;
}
.bottom .right .gray{
  color: #666666;
  font-size: 22rpx;
}
.bottom .right .sure{
  margin-left: 22rpx;
  width: 220rpx;
  height: 100rpx;
  line-height: 100rpx;
  text-align: center;
  background-color: #ff4965;
  color: #fff;
}

/*列表*/
.onlinechoose{
  width: 750rpx;
  margin-top: 15rpx;
  background-color: #ffffff;
  font-size: 32rpx;
}
.onlinechoose .hotel_list{
  width: 750rpx;
  height:350rpx;
  border-bottom: 1rpx solid #d6d6d6;
  background-color: #ffffff;
}
.onlinechoose .hotel_list .icon_none{
  width: 50rpx;
  height: 50rpx;
  border: 1rpx solid #113852;
  border-radius: 50%;
}
.onlinechoose .hotel_list .list_cons{
  width: 700rpx;
  height: 200rpx;
}
.onlinechoose .list_cons .lefts{
  width: 80rpx;
}
.onlinechoose .list_cons image{
  width: 200rpx;
  height: 200rpx;
  margin-right: 25rpx;
}
.list_cons .right{
  width: 395rpx;
  height: 200rpx;
}
.list_cons .right .name{
  font-size: 32rpx;
  color: #333333;
  font-weight: 700;
  letter-spacing: 3rpx;
  margin-bottom: 20rpx;
}
.list_cons .right .list1{
    margin-bottom: 17rpx;
}
.list_cons .right .list1 .condition1{
  font-size: 28rpx;
  color: #999999;
  margin-bottom: 15rpx;
}
.list_cons .right .list1 .condition2{
  font-size: 24rpx;
  color: #999999;
}
.list_cons .right .list1 .act{
  color: #2d8622;
}
.list_cons .right .list1 .r{
  font-size: 24rpx;
  color: #ff4965;
}
.list_cons .right .list1 .big{
  font-size: 32rpx;
}
.list_cons .right .lists2{
  height: 36rpx;
   line-height: 36rpx;
   font-size: 22rpx;
}
.list_cons .right .lists2 .left{
  width: 162rpx;
  text-align: center; 
  color: #ff4965;
  border: 1rpx solid #ff4965;
  box-sizing: border-box;
  border-radius: 5rpx;
}
.list_cons .right .lists2 .right2{
  color: #999999;
}
.flex_center{
  display: flex;
  display: -webkit-flex;
  justify-content: center;
  align-items: center;
}
.flex_between{
  display: flex;
  display: -webkit-flex;
  justify-content: space-between;
  align-items: center;
}
.flex_start{
  display: flex;
  display: -webkit-flex;
  justify-content: flex-start;
  align-items: center;
}
.flex_end{
  display: flex;
  display: -webkit-flex;
  justify-content: flex-end;
  align-items: center;
}
.name{
  display: flex;  
  flex-direction: row;  
  width: 500px;
  margin-bottom:17px;
}
.na{
  width: 93px;
  margin-left: 15px;
}
.nb{
  margin-left: 50px;
}
.nc{
  margin-left: 50px;
  margin-top: 10px;
}
.vname{
  display: flex;  
  flex-direction: row;  
  width: 500px;
  margin-bottom:17px;
  margin-left: 44px;
}
/* 布局 */
.sign-setting-border{
margin-left: 2%;
width: 12%;
float: left;
height: 24px;
line-height: 26px;
border-radius: 20px;
background-color: #ffffff;
color: #999999;
font-size: 14px;
text-align: center;
font-family: -apple-system;
margin-bottom: 15px;
border: 1px solid #DBDBDB;
}
.selected{
  background-color: #FFA404;
  color: rgba(255, 255, 255, 1);
  border:1px solid #FFA404;
}

js代码如下

Page({
  data: {
    title_disabled: true,//控制修改表头名字
    management_good: false,
    select_all: false,
    middlearr: [],
    tell:'',
    oname:'',
    idx:'',
    money:0,
    applyList: [{ id: "50", name: "小牌位" },
      { id: "500", name: "大牌位" }],
    items: [
      { father: "先祖父", fname: "", address: "", child: "孝孙", cname: "",price:'50', checked: false },
      { father: "先祖母", fname: "", address: "", child: "孝孙", cname: "", price: '50', checked: false },
      { father: "先父", fname: "", address: "", child: "孝子", cname: "", price: '50',checked: false },
      { father: "先母", fname: "", address: "", child: "孝子", cname: "", price: '50',checked: false },
      { father: "姓氏门中", fname: "", address: "", child: "孝后裔", cname: "", price: '50',checked: false },
      { father: "冤亲债主", fname: "", address: "", child: "结冤人", cname: "", price: '50', checked: false },
      { father: "无名婴儿", fname: "", address: "", child: "母亲", cname: "", price: '50', checked: false },
      { father: "普利十方", fname: "", address: "", child: " ", cname: "", price: '50',checked: false },
      { father: "四生六道", fname: "", address: "", child: "", cname: "", price: '50',checked: false},
    ]
  },
  selectApply: function (e) {
    let id = e.target.dataset.id
    let pr = e.target.dataset.pr
    console.log(id,pr)
    var fname = 'items[' + pr + '].price'
    this.setData({ [fname]: id });
    //更新总价
    var all = 0;
    var arr = this.data.items;
    for (let i = 0; i < arr.length; i++) {
      if (arr[i].checked) {
        all = all + Number(arr[i].price);
      }
    };
    this.setData({
      money: all
    })
     //更新总价
    },
  onLoad:function(){
    this.management()

  },
  //变更fname成功
  eidtfname(event){
    var c = event.detail.value;
    var id = event.currentTarget.dataset.id;
    var fname = 'items[' + id + '].fname'
    this.setData({ [fname]:c});
  },
  //变更cname成功
  eidtcname(event) {
    var c = event.detail.value;
    var id = event.currentTarget.dataset.id;
    var cname = 'items[' + id + '].cname'
    this.setData({ [cname]: c });
  },
  //变更地址成功
  eidtadd(event) {
    var c = event.detail.value;
    var id = event.currentTarget.dataset.id;
    var address = 'items[' + id + '].address'
    this.setData({ [address]: c });
  },
  paygoods:function(){
    var arr2 = this.data.middlearr;
     //1、校验,必须被勾选才能支付
    if (arr2.length>0){
      //2、被勾选的fname cname address必须不为空
      for(let i=0;i<arr2.length;i++){
        if (arr2[i].fname == "" || arr2[i].cname==""||arr2[i].address==""){
          wx.showToast({
            title: '失败,信息没填',
            icon: 'fail',
            duration: 1000,
            mask: true
          })
          return;
        }
      }
   //3、手机号码,姓名不能为空
   if(this.data.oname==""){
     wx.showToast({
       title: '姓名不能为空',
       icon: 'fail',
       duration: 1000,
       mask: true
     })
     return;
   }
      if (this.data.tell == "" ){
        wx.showToast({
          title: '手机号码不能为空',
          icon: 'fail',
          duration: 1000,
          mask: true
        })
        return;
      }
      console.log(this.data.money);
    //3、手机号码,姓名不能为空
    //拉起支付
      this.pay(arr2);
      console.log("获取的购物车是:", arr2);
     //拉起支付
    }else{
      wx.showToast({
        title: '未勾选清单',
        icon: 'fail',
        duration: 1000,
        mask: true
      })
      return;
    }
   
  },
  //支付功能
  pay(arr2) {
    var that=this;
    const db = wx.cloud.database({});
    const cont = db.collection('info');
    const bcont = db.collection('bill');
    var timestamp = that.getNowFormatDate();
    var money = that.data.money;
    money = (money * 100).toFixed()
    console.log("支付的金额是:", money);
    wx.cloud.callFunction({
      name: 'payment',
      data: { total_fee: money }, // 可传入相关参数。
      success: res => {
        var list = res.result
        console.log("统一下单信息:",list)
        if (!res.result.appId) return
        wx.requestPayment({
          ...res.result,
          success: res => {
            //把订单信息存储起来
             for(let i=0;i<arr2.length;i++){
               //把数据给云数据库
               cont.add({
                 data: {
                   father:arr2[i].father,
                   fname: arr2[i].fname,
                   child: arr2[i].child,
                   cname: arr2[i].cname,
                   address:arr2[i].address,
                   tell: that.data.tell,
                   oname: that.data.oname,
                   date: timestamp,
                   preid: list.package,
                 },
                 success: function (res) {
                   console.log(res._id)
                   wx.showModal({
                     title: '成功',
                     content: '立牌位成功',
                     showCancel: false
                   })
                 }
               });
               //把数据给云数据库
             }//for
            //信息存储起来
            //存储账单信息
            bcont.add({
              data: {
                preid: list.package,
                openid: list.appId,
                oname: that.data.oname,
                money: that.data.money,
                date: timestamp,
                tell: that.data.tell
              },
              success: function (res) {
                wx.showModal({
                  title: '成功',
                  content: '阿弥陀佛',
                  showCancel: false
                })
              }
            });
            //存储账单信息
          }
        })
      }
    })
  },
  //设置手机号码
  settell(e) {
    this.setData({
      tell: e.detail.value
    })
  },
  //设置订单姓名
  setoname(e) {
    this.setData({
      oname: e.detail.value
    })
  },
  // 改变类目的名字
  change_classname: function () {
    let that = this;
    that.setData({
      title_disabled: !that.data.title_disabled,
    });
    //  这里自动获取焦点
  },
  finish_classname: function () {
    let that = this;
    that.setData({
      title_disabled: !that.data.title_disabled,
    })
  },
  // 管理商品
  management: function () {
    let that = this;
    that.setData({
      management_good: true,
    })
  },
  // 选择
  select: function (e) {
    var that = this;
    let arr2 = [];
    if (that.data.management_good == false) {
      return;
    } else {
      var arr = that.data.items;
      var index = e.currentTarget.dataset.id;
      var itm = e.currentTarget.dataset.variable;
      arr[index].checked = !arr[index].checked;
      //这里进行赋值处理
      console.log(itm);
      //计算总价格
      var all=0;
      for (let i = 0; i < arr.length; i++) {
        if (arr[i].checked) {
          arr2.push(arr[i]);
          all = all + Number(arr[i].price);
        }
      };
      that.setData({
        items: arr,
        middlearr: arr2,
        money:all
      })
    }
  },
//设置时间
  getNowFormatDate:function() {//获取当前时间
    var time = Math.round(new Date() / 1000)
    console.log("时间戳位:", time);
    return time;
  },
  // 全选
  select_all: function () {
    let that = this;
    that.setData({
      select_all: !that.data.select_all
    })
    if (that.data.select_all) {
      let arr = that.data.items;
      let arr2 = [];
      var all=0;
      for (let i = 0; i < arr.length; i++) {
        if (arr[i].checked == true) {
          arr2.push(arr[i]);
          all = all + Number(arr[i].price);
        } else {
          arr[i].checked = true;
          arr2.push(arr[i]);
          all = all + Number(arr[i].price);
        }
      }
      that.setData({
        items: arr2,
        middlearr: arr2,
        money:all
      })
    }
  },
  // 取消全选
  select_none: function () {
    let that = this;
    that.setData({
      select_all: !that.data.select_all
    })
    let arr = that.data.items;
    let arr2 = [];
    for (let i = 0; i < arr.length; i++) {
      arr[i].checked = false;
      arr2.push(arr[i]);
    }
    that.setData({
      items: arr2,
      middlearr: []
    })
  },
})

后端我是用的是云开发的云函数

支付功能是payment函数

需要安装依赖wx-server-sdk与tenpay

这里有一个详细的例子讲解微信支付的  https://blog.csdn.net/tian_jiangnan/article/details/105527674

//云开发实现支付
const cloud = require('wx-server-sdk')
cloud.init()

//1,引入支付的三方依赖
const tenpay = require('tenpay');
//2,配置支付信息
const config = {
  appid: 'appid',
  mchid: '商户号',
  partnerKey: '商户key',
  notify_url: 'https://www.baidu.com/',
  spbill_create_ip: '127.0.0.1' //这里填这个就可以
};

exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()
  let {
    total_fee
  } = event;
  //3,初始化支付
  const api = tenpay.init(config);
  const nonceStr = Math.random().toString(36).substr(2, 15)
  const timeStamp = parseInt(Date.now() / 1000) + ''
  const out_trade_no = "otn" + nonceStr + timeStamp
  let result = await api.getPayParams({
    out_trade_no: out_trade_no,
    body: '牌位',
    total_fee: total_fee, //订单金额(分),
    openid: wxContext.OPENID //付款用户的openid
  });
  return result;
}

这里我只用到了两个云函数,一个是payment一个是login

至于安装依赖可以看看我 

这里有一个详细的例子讲解微信支付的  https://blog.csdn.net/tian_jiangnan/article/details/105527674  里面有详细步骤


最后不要忘记把两个云函数上传并且部署


在app.js里面配置云开发环境

//app.js
App({
  onLaunch: function () {
    if (!wx.cloud) {
      console.error('请使用 2.2.3 或以上的基础库以使用云能力')
    } else {
      wx.cloud.init({
        env: '你的云开发环境的ID',
        traceUser: true,
      })
      //获取openid
      /**
     * 打开小程序的时候首先获得用户openid
     */
      wx.cloud.callFunction({
        name: 'login',
        data: {},
        success: res => {
          this.globalData.openid = res.result.openid
        },
        fail: err => {
          console.error('[云函数] [login] 调用失败', err)
        }
      })
    //获取openid
      //获取openid
    }
    //获取openid
    this.globalData = {

    }

  }
})

发布了123 篇原创文章 · 获赞 4 · 访问量 5660

猜你喜欢

转载自blog.csdn.net/tian_jiangnan/article/details/105594249