干货:如何借助小程序云开发实现小程序支付功能(含源码)

干货:如何借助小程序云开发实现小程序支付功能(含源码)

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

先看效果图:

在这里插入图片描述

本节知识点
  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. 开通小程序云开发功能

在工具内顶部按钮找到云开发 ,点击开通

二,商品列表的展现

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

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
    });
   }
 }
}

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

在这里插入图片描述
再来看下,支付的相关流程截图

在这里插入图片描述

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

原文转至知乎腾讯云开发官方

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
老规矩,先看本节效果图我们实现这个支付功能完全是借助小程序云开发实现的,不用搭建自己的服务器,不用买域名,不用备案域名,不用支持https。只需要一个简单的云函数,就可以轻松的实现微信小程序支付功能。核心代码就下面这些一,创建一个云开发小程序关于如何创建云开发小程序,这里我就不再做具体讲解。不知道怎么创建云开发小程序的同学,可以去翻看我之前的文章,或者看下我录制的视频:https://edu.csdn.net/course/play/9604/204528创建云开发小程序有几点注意的1,一定不要忘记在app.js里初始化云开发环境。2,创建完云函数后,一定要记得上传二, 创建支付的云函数1,创建云函数pay三,引入三方依赖tenpay我们这里引入三方依赖的目的,是创建我们支付时需要的一些参数。我们安装依赖是使用里npm 而npm必须安装node,关于如何安装node,我这里不做讲解,百度一下,网上一大堆。1,首先右键pay,然后选择在终端中打开2,我们使用npm来安装这个依赖。在命令行里执行 npm i tenpay安装完成后,我们的pay云函数会多出一个package.json 文件到这里我们的tenpay依赖就安装好了。四,编写云函数pay完整代码如下//云开发实现支付 const cloud = require('wx-server-sdk')cloud.init() //1,引入支付的三方依赖 const tenpay = require('tenpay'); //2,配置支付信息 const config = ;exports.main = async(event, context) => 一定要注意把appid,mchid,partnerKey换成你自己的。到这里我们获取小程序支付所需参数的云函数代码就编写完成了。不要忘记上传这个云函数。出现下图就代表上传成功五,写一个简单的页面,用来提交订单,调用pay云函数。这个页面很简单,1,自己随便编写一个订单号(这个订单号要大于6位)2,自己随便填写一个订单价(单位是分)3,点击按钮,调用pay云函数。获取支付所需参数。下图是官方支付api所需要的一些必须参数。下图是我们调用pay云函数获取的参数,和上图所需要的是不是一样。六,调用wx.requestPayment实现支付下图是官方的示例代码这里不在做具体讲解了,完整的可以看视频。实现效果1,调起支付键盘2,支付完成3,log日志,可以看出不同支付状态的回调上图是支付成功的回调,我们可以在支付成功回调时,改变订单支付状态。下图是支付失败的回调,下图是支付完成的状态。到这里我们就轻松的实现了微信小程序支付功能了。是不是很简单啊,完整的讲解可以看视频。
好的,下面我会详细讲解一下C语言编程的步骤,希望对考研小白有所帮助。 1. 定义问题 在编写程序之前,需要明确程序要解决的问题或任务。这一步通常涵盖以下方面: - 确定程序要实现功能 - 确定程序需要处理的数据类型 - 确定程序需要输入的数据 - 确定程序需要输出的数据 在这一步中,需要尽可能详细地描述程序的目标和要解决的问题,这样可以帮助后续步骤的顺利进行。 2. 设计算法 在定义问题之后,需要设计程序的算法,选择合适的数据结构和算法策略。这一步通常包括以下方面: - 确定程序的输入和输出 - 选择合适的数据结构 - 设计程序的逻辑流程,包括条件判断、循环结构等 - 评估程序的性能和复杂度 在设计算法时,要注意算法的正确性和可读性,算法应该能够正确地解决问题,并且易于理解和维护。 3. 编写程序 在完成算法设计后,就可以开始编写程序了。这一步通常包括以下方面: - 编写程序的源代码,按照算法设计的逻辑结构组织代码 - 使用C语言的语法规则,定义变量、函数等 - 使用控制语句和函数库,实现程序的功能 在编写程序的过程中,要注意代码的风格和可读性,代码应该具有良好的组织结构和注释,易于理解和维护。 4. 编译程序 编写程序后,需要使用编译器将程序源代码转换成可执行程序。这一步通常包括以下方面: - 使用编译器将程序源代码编译成二进制文件 - 编译过程中,需要检查代码是否符合C语言的语法规则,是否存在错误 编译后,会生成可执行文件。可以通过运行可执行文件,测试程序的功能是否正常。 5. 调试程序 运行程序并检查程序是否按照预期工作。如果出现错误,需要进行调试。这一步通常包括以下方面: - 分析程序的错误,确定出错的原因 - 修改代码,消除错误 - 重新编译程序,测试修改后的程序是否正常工作 在调试程序的过程中,需要使用调试工具和技术,如断点调试、输出调试等。 6. 优化程序 根据程序的性能需求,对程序进行优化。这一步通常包括以下方面: - 分析程序的性能瓶颈,确定需要优化的部分 - 使用合适的算法和数据结构,减少程序的运行时间和空间复杂度 - 对代码进行改进,优化程序的可读性和可维护性 在优化程序的过程中,需要注意程序的正确性和可读性,优化应该是有针对性的,避免过度优化导致新的问题。 7. 维护程序 对程序进行维护,修复已知的错误或更新程序以适应新的需求。这一步通常包括以下方面: - 定期检查程序,修复已知的错误 - 根据新的需求,对程序进行改进和扩展 在维护程序的过程中,需要注意程序的兼容性和可维护性,维护应该是持续性的,避免放任程序出现新的问题。 希望以上内容对考研小白有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值