小程序云开发搜索功能的实现正则_码code | 如何借助小程序云开发实现小程序支付功能...

转载来源:编程小石头

我们在做小程序支付相关的开发时,总会遇到这些难题。小程序调用微信支付时,必须要有自己的服务器,有自己的备案域名,有自己的后台开发。这就导致我们做小程序支付时的成本很大。

本节就来教大家如何使用小程序·云开发实现小程序支付功能的开发。不用搭建自己的服务器,不用有自己的备案域名。只需要简简单单的使用小程序·云开发。

64e8adb3db8e50f4ae935c2bc042710f.gif

(小程序支付效果图)

本节知识点

1,云开发的部署和使用
2,支付相关的云函数开发
3,商品列表
4,订单列表
5,微信支付与支付成功回调

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

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

1,小程序appid
2,云开发环境id
3,微信商户号
4,商户密匙

准备工作

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

aa40d757702c254b8e186fbfcd7a1293.png

2,微信支付商户号在微信支付商户管理平台中获取商户号和商户密钥。

【账户中心】→【商户信息】 下可以获取微信支付商户号。

c5fe5df5956df61abdb7b253952a4981.png

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

5df6a87e2ef0dc0aeea87d6054599dd0.png

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

3,微信开发者 IDE

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

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

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

商品列表的实现

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

8ff4e323d51988025ddb222dbf691864.png

wxml布局如下:

class="container">

 class="good-item" wx:for="{{goods}}" wx:key="*this" ontap="getDetail" data-goodid="{{item._id}}">

   class="good-image">

     "{{pic}}">

   class="good-detail">

     class="title">商品: {{item.name}}

     class="content">价格:{{item.price / 100}} 元

       class="button"

       type="primary"

       bindtap="makeOrder"

       data-goodid="{{item._id}}"

     >下单

 </view>view>

我们所需要做的就是借助云开发获取云数据库里的商品信息,然后展示到商品列表,关于云开发获取商品列表并展示本节不做讲解。

9c4b563e87772bcbf12f2724d1d35096.png

支付云函数的创建

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

a57923389ef2620e62f7f71c23ae80dd.png

简单先讲解下每个的用处:

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

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

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

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

1,配置config下的index.js,
这一步所需要做的就是把小程序appid,云开发环境ID,商户id,商户密匙。填进去。

41698878e8c47f99711040ccc5aa9b44.png

2,配置入口云函数

6e76f9ebb471ff5ebd54e93e675b83af.png

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

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

   });

  }

}

}

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

71ba75c9ce79bbd7321b3773b65c3a8a.png

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

287fda7cb6a66d31e2eb2c63a04ddbc6.png

上图就涉及到了我们的订单列表,支付状态,支付成功后的回调。其实支付的其他功能,比如支付成功后的消息推送也是可以借助云开发实现的,欢迎大家自己动手去尝试。

如果你想学习小程序·云开发,欢迎扫码进群,这周四晚将进行《小程序·云开发实战:从0到1快速开发电商小程序》的直播课程分享。

321a514d78bedd1177d60ab13a944f39.png

推荐阅读:

2768777b23894463de958ccd6c496a77.png

f0858ed74097486d49bc9825d2f86cb8.png

2f7263e41bc2c538b3ebe84f22f72ad6.gif

17b0e62437140d6547cb17576053e96d.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/411606.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python接口自动化(二十五)--unittest断言——下(详解)

简介 本篇还是回归到我们最初始的话题&#xff0c;想必大家都忘记了&#xff0c;没关系看这里&#xff1a;传送门 没错最初的话题就是登录&#xff0c;由于博客园的登录机制改变了&#xff0c;本篇以我找到的开源免费的登录API为案例&#xff0c;结合 unittest 框架写 2 个用例…

使用C#和Excel进行报表开发(五)-操作单元格边框和颜色 【转】

在用Excel作报表的时候&#xff0c;可能需要操作单元格的边框和填充颜色和纹理等操作&#xff0c;下面的代码说明如何设置选中的单元格的填充纹理和边框try{ThisApplication new Excel.Application();ThisWorkbook ThisApplication.Workbooks.Open("z:\\Book1.xls"…

输入 3 个正数,判断能否构成一个三角形。

package com.my.demo;import java.util.Scanner;public class Triangle {public static void main(String[] args) {System.out.println("请输入三个正整数&#xff1a;");Scanner sc1new Scanner(System.in);int asc1.nextInt();int bsc1.nextInt();int csc1.nextIn…

mysql-bin磁盘满数据库重启不_liunx磁盘空间满了,导致mysql数据库无法启动

如何启动/遏制/重启MySQLA、1、启动圆式1、哄骗 service 启动&#xff1a;service mysqld start2、哄骗 mysqld 脚本启动&#xff1a;/etc/inint.d/mysqld start3、哄骗 safe_mysqld 启动&#xff1a;safe_mysqld&二、遏制1、哄骗 service 启动&#xff1a;service mysqld …

[html] title与h1的区别、b与strong的区别、i与em的区别?

[html] title与h1的区别、b与strong的区别、i与em的区别&#xff1f; title 是 网页标题标签 h1 是文本标签 默认与word的h1相似为最大的标题显示 b 为文本加粗标签 与word的加粗功能相似 strong 为强调语气&#xff0c; 也是为文本加粗 与b标签是有不同 i 标签为斜体 常用于阿…

两个日期的 月差

datediff(DateInterval.Month,date1,date2) 转载于:https://www.cnblogs.com/lhuser/articles/1288289.html

[html] HTML5的文件离线储存怎么使用,工作原理是什么?

[html] HTML5的文件离线储存怎么使用&#xff0c;工作原理是什么&#xff1f; localstorge 利用浏览器的本地存储可以缓存信息 &#xff0c;在创建数据的时候引入创建好的数据 cookie 好像也可以个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&…

springboot忽略证书_SpringBoot获取resource下证书失败

1.第一种失败的情况&#xff1a;本来使用Spring的上下文容器获取文件&#xff0c;将证书文件放在resource下&#xff0c;编译后获取文件会出现报错java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : DerInputStream.getLength():…

看一个国家的国民教育&#xff0c;要看他的公共厕所。 看一个男人的品味&#xff0c;要看他的袜子。 看一个女人是否养尊处优&#xff0c;要看她的手。 看一个人的气血&#xff0c;要看他的头发。 看一个人的心术&#xff0c;要看他的眼神。 看一个人的身价&#xff0c;要…

死锁产生的原因及条件和手写死锁

什么是死锁&#xff1f; 由于两个或者多个线程互相持有对方所需要的资源&#xff0c;导致线程处于等待状态&#xff0c;造成死锁。 为什么会产生死锁&#xff08;为什么会互相占用对方的资源&#xff09; 因为系统资源不足。 进程运行推进的顺序不合适。 资源分配不当等。产生死…

[html] iframe框架都有哪些优缺点?

[html] iframe框架都有哪些优缺点&#xff1f; 优点重载页面时不需要重载整个页面&#xff0c;只需要重载页面中的一个框架页技术易于掌握&#xff0c;使用方便&#xff0c;可主要应用于不需搜索引擎来搜索的页面方便制作导航栏缺点会产生很多页面&#xff0c;不容易管理*不容…

mysql 默认page大小_Innodb优化之修改页大小

MySQL在使用innodb引擎的时候页大小默认是16K&#xff0c;这个大小对于很多应用来说太大了&#xff0c;很多在其他数据如ORACLE运行良好的应用迁移到innodb后发现IO压力偏大&#xff0c;MySQL本身没有提供修改页大小的参数&#xff0c;但是我们可以通过修改源码重新编译mysql来…

[导入]C# Tips 2 右键单击listBox时弹出右键菜单并选中单击的行

C#,Listbox,右键,菜单,选中文章来源:http://blog.csdn.net/geyunfei_hit/archive/2008/07/16/2661153.aspx 转载于:https://www.cnblogs.com/geyunfei/archive/2008/10/08/1306335.html

[html] 常见的浏览器内核都有哪些?并介绍下你对内核的理解

[html] 常见的浏览器内核都有哪些&#xff1f;并介绍下你对内核的理解 Webkit Blink Gecko Trident个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题

python真的可以减少工作强度_用Python写几行代码,一分钟搞定一天工作量,同事直呼:好家伙!...

前几天有一个读者说最近要整理几千份文件&#xff0c;头都要整秃了&#xff0c;不知道能不能用Python解决&#xff0c;我们来看一下&#xff0c;你也可以思考一下。由于涉及文件私密所以具体内容已做脱敏处理。大概是这样&#xff0c;一个文件夹下有多份会议通知信息(本文以 7 …

[html] 说说你对html中的置换元素和非置换元素的理解

[html] 说说你对html中的置换元素和非置换元素的理解 置换元素是指&#xff1a;浏览器根据元素的标签和属性&#xff0c;来决定元素的具体显示内容。例如&#xff1a;浏览器根据标签的src属性显示图片。根据标签的type属性决定显示输入框还是按钮。非置换元素&#xff1a;浏览器…

Jmeter之逻辑控制器(Logic Controller)

一、简单控制器&#xff08;Simple Controller&#xff09;&#xff1a; 作用&#xff1a;这是Jmeter里最简单的一个控制器&#xff0c;它可以让我们组织我们的采样器和其它的逻辑控制器&#xff08;分组功能&#xff09;&#xff0c;提供一个块的结构和控制&#xff0c;并不具…

python需要掌握的词汇量_北大保安英语词汇量1.5万,会用Python编程,孟母三迁真有道理...

这就是良好学习环境的重要性啊&#xff0c;不然你以为“孟母三迁”是咋来的&#xff1f;人家孟母为了孩子有个好的学习环境&#xff0c;宁愿搬三次家。而这些保安小哥一步到位&#xff0c;直接就进入了无数人梦寐以求的最高学府&#xff0c;想不牛都不行啊。01、北大是最高学府…

oracle中日期处理方法 汇总

Day: dd number 12 dy abbreviated fri day spelled out friday ddspth spelled out, ordinal twelfth Month: mm number 03 mon abbreviated mar month spelled out march Year: yy two digits 98 yyyy four digits 1998 24小时格式下时间范围为: 0:00:00 - 23:5…

Spark-Streaming基础

Spark课堂笔记 Spark生态圈&#xff1a;Spark Core &#xff1a; RDD&#xff08;弹性分布式数据集&#xff09;Spark SQLSpark StreamingSpark MLLib&#xff1a;协同过滤&#xff0c;ALS&#xff0c;逻辑回归等等 --> 机器学习Spark Graphx &#xff1a; 图计算 重点在前三…