demo1984s 的个人博客 demo1984s 的个人博客

记录精彩的程序人生

目录
电商小程序实战03·订单提交与支付功能实现
/  

电商小程序实战03·订单提交与支付功能实现

本篇为《电商小程序实战》第三篇:订单提交与支付功能实现。

  • 内容简介:重点实现 订单提交和支付功能
  • 主要内容:
    • 订单生成:从购物车中获取商品信息,生成订单。
    • 填写收货地址:用户在订单页面填写收货地址。
    • 支付功能:集成微信支付,处理支付流程。
  • 目标:我们将通过实现商品的添加、删除、修改数量等功能,掌握本地存储(wx.setStorage 和 wx.getStorage)的使用。

    项目目录结构更新

为了实现订单提交与支付,我们需要创建一个新的页面 order 用于展示订单详情、填写收货地址、支付等。

在项目目录中创建以下文件结构:

ecommerce-mini-program/
├── miniprogram/
│   ├── pages/
│   │   ├── order/
│   │   │   ├── order.wxml
│   │   │   ├── order.wxss
│   │   │   ├── order.js
│   │   │   └── order.json

订单页面 order.wxml 创建

首先,我们创建订单页面的结构,展示订单商品、收货地址和支付按钮。

<!-- order.wxml -->
<view class="order-container">
  <!-- 订单商品列表 -->
  <view class="order-items">
    <view wx:for="{{orderItems}}" wx:key="id" class="order-item">
      <image class="product-image" src="{{item.imageUrl}}" mode="aspectFill"></image>
      <view class="order-info">
        <text class="product-name">{{item.name}}</text>
        <text class="product-price">¥{{item.price}}</text>
        <text class="product-quantity">x{{item.quantity}}</text>
      </view>
    </view>
  </view>

  <!-- 收货地址 -->
  <view class="address-section">
    <view wx:if="{{address}}">
      <text class="address-title">收货地址:</text>
      <text class="address">{{address}}</text>
    </view>
    <button wx:if="{{!address}}" class="choose-address" bindtap="chooseAddress">选择收货地址</button>
  </view>

  <!-- 订单总价 -->
  <view class="order-total">
    <text>订单总额:¥{{totalPrice}}</text>
  </view>

  <!-- 提交订单按钮 -->
  <button class="submit-order" bindtap="submitOrder">提交订单并支付</button>
</view>
  • 订单商品信息:通过 wx:for 循环展示购物车中的商品,包括商品名称、价格和数量。
  • 收货地址:如果用户已选择收货地址,则展示收货地址,否则显示“选择收货地址”按钮。

订单页面逻辑 order.js

接下来,我们编写 order.js,从本地存储中获取购物车商品数据,计算总价,并处理订单的生成。

// order.js
Page({
  data: {
    orderItems: [],    // 订单商品列表
    totalPrice: 0,     // 订单总价
    address: null      // 收货地址
  },

  // 页面加载时获取购物车数据并生成订单
  onLoad: function () {
    let cart = wx.getStorageSync('cart') || [];
    this.setData({
      orderItems: cart,
      totalPrice: this.calculateTotalPrice(cart)
    });
  },

  // 计算订单总价
  calculateTotalPrice: function (cart) {
    let totalPrice = 0;
    cart.forEach(item => {
      totalPrice += item.price * item.quantity;
    });
    return totalPrice;
  },

  // 选择收货地址
  chooseAddress: function () {
    wx.chooseAddress({
      success: (res) => {
        this.setData({
          address: res.provinceName + res.cityName + res.countyName + res.detailInfo
        });
      },
      fail: () => {
        wx.showToast({
          title: '地址选择失败',
          icon: 'none'
        });
      }
    });
  },

  // 提交订单并支付
  submitOrder: function () {
    if (!this.data.address) {
      wx.showToast({
        title: '请填写收货地址',
        icon: 'none'
      });
      return;
    }

    // 调用支付接口
    this.initiatePayment();
  },

  // 发起支付请求
  initiatePayment: function () {
    const orderData = {
      totalPrice: this.data.totalPrice,
      orderItems: this.data.orderItems
    };

    // 假设我们已在后台生成了支付订单,返回支付信息(这里模拟一个支付请求)
    wx.request({
      url: 'https://api.example.com/payment',  // 假设这是支付接口
      method: 'POST',
      data: orderData,
      success: (res) => {
        if (res.data.code === 0) {
          this.processPayment(res.data.paymentInfo);
        } else {
          wx.showToast({
            title: '支付请求失败',
            icon: 'none'
          });
        }
      },
      fail: () => {
        wx.showToast({
          title: '支付请求失败',
          icon: 'none'
        });
      }
    });
  },

  // 处理支付
  processPayment: function (paymentInfo) {
    wx.requestPayment({
      ...paymentInfo,
      success: (res) => {
        wx.showToast({
          title: '支付成功',
          icon: 'success'
        });
        this.clearCart();
      },
      fail: (res) => {
        wx.showToast({
          title: '支付失败',
          icon: 'none'
        });
      }
    });
  },

  // 支付成功后清空购物车
  clearCart: function () {
    wx.removeStorageSync('cart');
    wx.navigateTo({
      url: '/pages/order/order'  // 可以跳转到订单成功页面或首页
    });
  }
});

关键逻辑:

  • onLoad:加载购物车中的商品,并计算订单总价。
  • chooseAddress:调用微信 API 选择收货地址,并将地址存储在页面数据中。
  • submitOrder:在提交订单时,首先检查是否已选择收货地址,然后调用支付接口发起支付。
  • initiatePayment:模拟向后台发起支付请求,获取支付信息。
  • processPayment:调用微信支付接口进行支付,并根据支付结果进行处理。
  • clearCart:支付成功后,清空购物车数据。

订单页面样式 order.wxss

接着,我们为订单页面添加一些基本样式:

/* order.wxss */
.order-container {
  padding: 20px;
}

.order-items {
  margin-bottom: 20px;
}

.order-item {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
  border-bottom: 1px solid #eee;
  padding-bottom: 10px;
}

.product-image {
  width: 80px;
  height: 80px;
  margin-right: 15px;
}

.order-info {
  flex: 1;
}

.product-name {
  font-size: 16px;
  font-weight: bold;
}

.product-price, .product-quantity {
  font-size: 14px;
  color: #666;
}

.address-section {
  margin-bottom: 20px;
}

.address-title {
  font-size: 16px;
  font-weight: bold;
}

.address {
  font-size: 14px;
  color: #333;
}

.choose-address {
  width: 100%;
  padding: 10px;
  background-color: #f8f8f8;
  border: 1px solid #ccc;
  margin-top: 10px;
}

.order-total {
  font-size: 18px;
  font-weight: bold;
  text-align: right;
}

.submit-order {
  width: 100%;
  padding: 15px;
  background-color: #ff6600;
  color: white;
  font-size: 16px;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  margin-top: 20px;
}

支付接口集成

我们已经模拟了一个支付接口请求 wx.requestPayment,但在实际应用中,你需要通过后台生成订单,调用微信的支付 API 获取 paymentInfo,然后传递给前端进行支付。

确保你已经:

  • 在微信公众平台申请并配置好支付接口。
  • 后端生成订单并返回支付信息(如 prepay_id 等)。

小结

在本篇文章中,我们实现了:

  • 订单生成:从购物车中获取商品数据,展示订单详情。
  • 收货地址选择:通过 wx.chooseAddress API 选择收货地址。
  • 支付功能:集成微信支付 API,处理支付流程。

通过这几个步骤,我们完成了一个完整的电商小程序中的订单提交与支付功能。在后续的文章中,我们还可以进一步扩展功能,例如:

  • 订单状态管理
  • 订单列表功能