借助小程序云开发实现小程序支付功能(含源码)

简介: 借助小程序云开发实现小程序支付功能(含源码)

我们在做小程序支付相关的开发时,总会遇到这些难题。小程序调用微信支付时,必须要有自己的服务器,有自己的备案域名,有自己的后台开发。这就导致我们做小程序支付时的成本很大。本节就来教大家如何使用小程序云开发实现小程序支付功能的开发。不用搭建自己的服务器,不用有自己的备案域名。只需要简简单单的使用小程序云开发。


老规矩先看效果图:

本节知识点

1,云开发的部署和使用

2,支付相关的云函数开发

3,商品列表

4,订单列表

5,微信支付与支付成功回调


支付成功给用户发送推送消息的功能会在后面讲解。


下面就来教大家如何借助云开发使用小程序支付功能。


支付所需要用到的配置信息

1,小程序appid

2,云开发环境id

3,微信商户号

4,商户密匙


一,准备工作


1,已经申请小程序,获取小程序 AppID 和 Secret 在小程序管理后台中,【设置】 →【开发设置】 下可以获取微信小程序 AppID 和 Secret。

2,微信支付商户号,获取商户号和商户密钥在微信支付商户管理平台中,【账户中心】→【商户信息】 下可以获取微信支付商户号。

在【账户中心】 ‒> 【API安全】 下可以设置商户密钥。


这里特殊说明下,个人小程序是没有办法使用微信支付的。所以如果想使用微信支付功能,必须是非个人账号(当然个人可以办个体户工商执照来注册非个人小程序账号)


3,微信开发者 IDE

 https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html

4,开通小程序云开发功能

https://edu.csdn.net/course/play/9604/204526


二,商品列表的实现


效果图如下,由于本节重点是支付的实现,所以这里只简单贴出关键代码。



wxml布局如下:

<view class="container">
  <view class="good-item" wx:for="{{goods}}" wx:key="*this" ontap="getDetail" data-goodid="{{item._id}}">
    <view class="good-image">
      <image src="{{pic}}"></image>
    </view>
    <view class="good-detail">
      <view class="title">商品: {{item.name}}</view>
      <view class="content">价格: {{item.price / 100}} 元 </view>
      <button
        class="button"
        type="primary"
        bindtap="makeOrder"
        data-goodid="{{item._id}}"
      >下单</button>
    </view>
  </view></view>

我们所需要做的就是借助云开发获取云数据库里的商品信息,然后展示到商品列表,关于云开发获取商品列表并展示本节不做讲解(感兴趣的同学可以翻看我的历史博客,有写过的)



三,支付云函数的创建


首先看下我们支付云函数都包含那些内容

简单先讲解下每个的用处

config下的index.js是做支付配置用的,主要配置支付相关的账号信息

lib是用的第三方的支付库,这里不做讲解。

重点讲解的是云函数入口 index.js


下面就来教大家如何去配置

1,配置config下的index.js,

这一步所需要做的就是把小程序appid,云开发环境ID,商户id,商户密匙。填进去。



2,配置入口云函数


详细代码如下,代码里注释很清除了,这里不再做单独讲解:

const cloud = require('wx-server-sdk')
cloud.init()const app = require('tcb-admin-node');const pay = require('./lib/pay');const {
 mpAppId,
 KEY
} = require('./config/index');const {
 WXPayConstants,
 WXPayUtil
} = require('wx-js-utils');const Res = require('./lib/res');const ip = require('ip');/**
 *
 * @param {obj} event
 * @param {string} event.type 功能类型
 * @param {} userInfo.openId 用户的openid
 */exports.main = async function(event, context) { const {
  type,
  data,
  userInfo
 } = event; const wxContext = cloud.getWXContext() const openid = userInfo.openId;
 app.init(); const db = app.database(); const goodCollection = db.collection('goods'); const orderCollection = db.collection('order'); // 订单文档的status 0 未支付 1 已支付 2 已关闭
 switch (type) {  // [在此处放置 unifiedorder 的相关代码]
  case 'unifiedorder':
   {    // 查询该商品 ID 是否存在于数据库中,并将数据提取出来
    const goodId = data.goodId    let goods = await goodCollection.doc(goodId).get();    if (!goods.data.length) {     return new Res({      code: 1,      message: '找不到商品'
     });
    }    // 在云函数中提取数据,包括名称、价格才更合理安全,
    // 因为从端里传过来的商品数据都是不可靠的
    let good = goods.data[0];    // 拼凑微信支付统一下单的参数
    const curTime = Date.now();    const tradeNo = `${goodId}-${curTime}`;    const body = good.name;    const spbill_create_ip = ip.address() || '127.0.0.1';    // 云函数暂不支付 http 触发器,因此这里回调 notify_url 可以先随便填。
    const notify_url = 'http://www.qq.com'; //'127.0.0.1';
    const total_fee = good.price;    const time_stamp = '' + Math.ceil(Date.now() / 1000);    const out_trade_no = `${tradeNo}`;    const sign_type = WXPayConstants.SIGN_TYPE_MD5;    let orderParam = {
     body,
     spbill_create_ip,
     notify_url,
     out_trade_no,
     total_fee,
     openid,     trade_type: 'JSAPI',     timeStamp: time_stamp,
    };    // 调用 wx-js-utils 中的统一下单方法
    const {
     return_code,
     ...restData
    } = await pay.unifiedOrder(orderParam);    let order_id = null;    if (return_code === 'SUCCESS' && restData.result_code === 'SUCCESS') {     const {
      prepay_id,
      nonce_str
     } = restData;     // 微信小程序支付要单独进地签名,并返回给小程序端
     const sign = WXPayUtil.generateSignature({      appId: mpAppId,      nonceStr: nonce_str,      package: `prepay_id=${prepay_id}`,      signType: 'MD5',      timeStamp: time_stamp
     }, KEY);     let orderData = {
      out_trade_no,
      time_stamp,
      nonce_str,
      sign,
      sign_type,
      body,
      total_fee,
      prepay_id,
      sign,      status: 0, // 订单文档的status 0 未支付 1 已支付 2 已关闭
      _openid: openid,
     };     let order = await orderCollection.add(orderData);
     order_id = order.id;
    }    return new Res({     code: return_code === 'SUCCESS' ? 0 : 1,     data: {
      out_trade_no,
      time_stamp,
      order_id,
      ...restData
     }
    });
   }   // [在此处放置 payorder 的相关代码]
  case 'payorder':
   {    // 从端里出来相关的订单相信
    const {
     out_trade_no,
     prepay_id,
     body,
     total_fee
    } = data;    // 到微信支付侧查询是否存在该订单,并查询订单状态,看看是否已经支付成功了。
    const {
     return_code,
     ...restData
    } = await pay.orderQuery({
     out_trade_no
    });    // 若订单存在并支付成功,则开始处理支付
    if (restData.trade_state === 'SUCCESS') {     let result = await orderCollection
      .where({
       out_trade_no
      })
      .update({       status: 1,       trade_state: restData.trade_state,       trade_state_desc: restData.trade_state_desc
      });     let curDate = new Date();     let time = `${curDate.getFullYear()}-${curDate.getMonth() +          1}-${curDate.getDate()} ${curDate.getHours()}:${curDate.getMinutes()}:${curDate.getSeconds()}`;
    }    return new Res({     code: return_code === 'SUCCESS' ? 0 : 1,     data: restData
    });
   }  case 'orderquery':
   {    const {
     transaction_id,
     out_trade_no
    } = data;    // 查询订单
    const {     data: dbData
    } = await orderCollection
    .where({
     out_trade_no
    })
    .get();    const {
     return_code,
     ...restData
    } = await pay.orderQuery({
     transaction_id,
     out_trade_no
    });    return new Res({     code: return_code === 'SUCCESS' ? 0 : 1,     data: { ...restData,
      ...dbData[0]
     }
    });
   }  case 'closeorder':
   {    // 关闭订单
    const {
     out_trade_no
    } = data;    const {
     return_code,
     ...restData
    } = await pay.closeOrder({
     out_trade_no
    });    if (return_code === 'SUCCESS' &&
     restData.result_code === 'SUCCESS') {     await orderCollection
      .where({
       out_trade_no
      })
      .update({       status: 2,       trade_state: 'CLOSED',       trade_state_desc: '订单已关闭'
      });
    }    return new Res({     code: return_code === 'SUCCESS' ? 0 : 1,     data: restData
    });
   }
 }
}

其实我们支付的关键功能都在上面这些代码里面了。


再来看下,支付的相关流程截图


上图就涉及到了我们的订单列表,支付状态,支付成功后的回调。

今天就先讲到这里,后面会继续给大家讲解支付的其他功能。比如支付成功后的消息推送,也是可以借助云开发实现的。

相关文章
|
26天前
|
缓存 小程序 前端开发
商城/点餐/家政类小程序源码合集_微信抖音小程序源码开发从入门到精通实战
本文系统讲解如何利用现有源码快速开发商城、点餐、家政类微信/抖音小程序,涵盖环境搭建、核心功能实现、多平台部署与优化,提供完整技术方案。实战导向,助力开发者高效入门与落地。
|
26天前
|
小程序 PHP 图形学
热门小游戏源码(Python+PHP)下载-微信小程序游戏源码Unity发实战指南​
本文详解如何结合Python、PHP与Unity开发并部署小游戏至微信小程序。涵盖技术选型、Pygame实战、PHP后端对接、Unity转换适配及性能优化,提供从原型到发布的完整指南,助力开发者快速上手并发布游戏。
|
28天前
|
存储 小程序 Java
热门小程序源码合集:微信抖音小程序源码支持PHP/Java/uni-app完整项目实践指南
小程序已成为企业获客与开发者创业的重要载体。本文详解PHP、Java、uni-app三大技术栈在电商、工具、服务类小程序中的源码应用,提供从开发到部署的全流程指南,并分享选型避坑与商业化落地策略,助力开发者高效构建稳定可扩展项目。
|
3月前
|
小程序 Java 关系型数据库
圈子系统公众号app小程序系统源码圈子系统带即时通讯 多级圈子系统源码 兴趣小组系统开源 私密圈子系统代码 会员制社区系统
本圈子系统解决方案提供即时通讯、多级圈子、兴趣小组、私密社区及会员制管理功能。支持开源与商业方案,推荐ThinkSNS+、EasyClub及OpenFire等系统,并提供前后端技术选型建议,助力快速搭建社交平台。
148 0
|
4月前
|
消息中间件 缓存 小程序
婚恋交友相亲公众号app小程序系统源码「脱单神器」婚恋平台全套代码 - 支持快速二次开发
这是一套基于SpringBoot + Vue3开发的婚恋交友系统,支持微信公众号、Uniapp小程序和APP端。系统包含实名认证、智能匹配、视频相亲、会员体系等功能,适用于婚恋社交平台和相亲交友应用。后端采用SpringBoot 3.x与MyBatis-Plus,前端使用Vue3与Uniapp,支持快速部署和二次开发。适合技术团队或有经验的个人创业者使用。
277 8
|
6月前
|
监控 前端开发 小程序
陪练,代练,护航,代打小程序源码/前端UNIAPP-VUE2.0开发 后端Thinkphp6管理/具备家政服务的综合型平台
这款APP通过技术创新,将代练、家政、娱乐社交等场景融合,打造“全能型生活服务生态圈”。以代练为切入点,提供模块化代码支持快速搭建平台,结合智能匹配与技能审核机制,拓展家政服务和商业管理功能。技术架构具备高安全性和扩展性,支持多业务复用,如押金冻结、录屏监控等功能跨领域应用。商业模式多元,包括交易抽成、增值服务及广告联名,同时设计跨领域积分体系提升用户粘性,实现生态共生与B端赋能。
539 12
|
6月前
|
小程序 Java 关系型数据库
weixin163基于微信小程序的校园二手交易平台系统设计与开发ssm(文档+源码)_kaic
本文介绍了一款基于微信小程序的校园二手物品交易平台的开发与实现。该平台采用Java语言开发服务端,使用MySQL数据库进行数据存储,前端以微信小程序为载体,支持管理员和学生两种角色操作。管理员可管理用户、商品分类及信息、交易记录等,而学生则能注册登录、发布购买商品、参与交流论坛等。系统设计注重交互性和安全性,通过SSM框架优化开发流程,确保高效稳定运行,满足用户便捷交易的需求,推动校园资源共享与循环利用。
|
7月前
|
小程序 Java 关系型数据库
weixin116大学生就业平台微信小程序+ssm(文档+源码)_kaic
本文介绍了一款大学生就业平台微信小程序的开发过程,涵盖开发环境、系统设计、实现与测试等方面。该小程序基于微信平台特性,采用MYSQL数据库存储数据,确保系统稳定与安全,同时满足学生、企业和管理员不同权限用户的功能需求。通过简化操作流程,实现了招聘信息查看、简历投递等实用功能,旨在为用户提供便捷高效的求职体验,符合“操作简单,功能实用”的设计理念。
|
7月前
|
小程序 Java 关系型数据库
weixin030英语学习交流平台小程序+ssm(文档+源码)_kaic
本文介绍了英语学习交流平台小程序的开发全过程,包括系统分析、设计与实现。该小程序基于Java的SSM框架进行后端管理开发,使用MySQL作为数据库,并借助微信开发者工具确保系统稳定性。小程序设有管理员和用户两个角色,功能涵盖个人中心、每日打卡、学习计划、论坛交流等,具有操作简单、界面清晰、功能齐全的特点。通过技术可行性、经济可行性和操作可行性分析,证明了系统的实用性和高效性,为英语学习者提供了一个便捷的交流平台。
|
6月前
|
小程序 关系型数据库 Java
weixin168“返家乡”高校暑期社会实践微信小程序设计与开发ssm(文档+源码)_kaic
本文探讨高校暑期社会实践微信小程序的开发与应用,旨在通过信息化手段提升活动管理效率。借助微信小程序技术、SSM框架及MySQL数据库,实现信息共享、流程规范和操作便捷。系统涵盖需求分析、可行性研究、设计实现等环节,确保技术可行、操作简便且经济合理。最终,该小程序可优化活动发布、学生信息管理和心得交流等功能,降低管理成本并提高工作效率。