这个文章不会说具体0到1的代码流程,我会着重讲几个问题的解决

准备以下依赖

  "md5": "^2.2.1",
"xml-js": "^1.6.11",
"xmldom": "^0.1.27"

支付主要遇到的问题如下:

1.获取openid

2.统一下单,拿到预单号(我起的,全名叫预支付交易会话标识)

3.再次签名调起支付

4.支付后的处理

1.获取openid很简单,调用Taro.login()拿到code,传给后端获取openid,这个必须后端拿

2.统一下单的几个问题:

大概需要这么些必填参数:

{
appid: '', // appid
mch_id: '', // 商户id
nonce_str:'', // 随机字符串
body: '', // 商品简单描述
out_trade_no: '', // 商户系统内部订单号,唯一
total_fee: '', // 订单总金额,单位为分
spbill_create_ip: '', // 你的ip,要后端传给你
notify_url: '', // 通知地址,微信调的,告诉你支付的情况
trade_type: 'JSAPI',
openid: ''
}

①随机字符串

②签名

③XML的组装与解析

export function randomString(len = 32) {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
const maxPos = chars.length;
let pwd = '';
for (let i = 0; i < len; i++) {
pwd += chars.charAt(Math.floor(Math.random() * maxPos));
}
return pwd;
}

准备一个参数如下

const params = {
appid: '',
mch_id: '',
nonce_str:randomString(32),
body: '',
out_trade_no: '',
total_fee: '',
spbill_create_ip: '',
notify_url: '',
trade_type: 'JSAPI',
openid: ''
}

签名:

const sign = signFunc(params)
params.sign = sign

签名函数

export function signFunc(data) {
// 1.对key字典排序
const sortArr = Object.keys(data).sort() // 2.转URL键值对
// const qsString = stringify(sortObj)
let qsString = ''
sortArr.map((t, index) => {
if (index === 0) {
qsString = `${t}=${data[t]}`
} else {
qsString = `${qsString}&${t}=${data[t]}`
}
}) // 3.拼接string+key
const stringSignTemp = qsString + `&key=${key}` // 4.MD5签名
const sign = md5(stringSignTemp).toUpperCase() return sign
}

注意,我注释的那句,是一个叫做qs的npm库提供 ,不要用它对参数生成 URL键值对,因为它会把 再次签名时,会把=转成%3d

    console.log(stringify({
package: 'prepay_id=wx2017033010242291fcfe0db70013231072'
}))

输出:

package=prepay_id%3Dwx2017033010242291fcfe0db70013231072

这样的值不符合要求,md5处理后是和官方对不上 ,一定要package=prepay_id=wx2017033010242291fcfe0db70013231072

统一下单的参数必须是xml

发送请求,header要设置如下

'Content-Type': 'text/plain',
const xml =
`<xml>
<appid>${params.appid}</appid>
<openid>${ConfirmStore.openId}</openid>
<body>${params.body}</body>
<mch_id>${params.mch_id}</mch_id>
<nonce_str>${params.nonce_str}</nonce_str>
<notify_url>${params.notify_url}</notify_url>
<out_trade_no>${params.out_trade_no}</out_trade_no>
<spbill_create_ip>${params.spbill_create_ip}</spbill_create_ip>
<total_fee>${params.total_fee}</total_fee>
<trade_type>${params.trade_type}</trade_type>
<sign>${params.sign}</sign>
</xml>`
Taro.request({
url: `${unifyOrderUrl}`,
header: {
'Content-Type': 'text/plain',
},
method: 'POST',
data: {
xml,
},
})

返回结果,xml的解析

由于小程序无dom,所以不可用 DOMParser() ,解决办法是使用xmldom这个库

示例写法:xml字符串转json

// 若结果data为以下
const data = `
<xml>
 <appid></appid>
 <timeStamp></timeStamp>
 <nonce_str></nonce_str>
 <package></package>
 <signType></signType>   
</xml>` const doc = new DOMParser().parseFromString(data);
const result = convert.xml2json(doc, { compact: true, spaces: 4 });
const { xml } = JSON.parse(result)

xml直接用即可

3可以参考2,主要问题也是签名

4.记得做好支付成功或者失败的处理

注意事项:

1.调用支付使用的noncestr这个参数必须和商家服务器调用统一下单接口返回的那个noncestr一致

https://developers.weixin.qq.com/community/develop/doc/000c209934c8d0bad528fc8bc56800

2.请在小程序后台,把微信支付统一下单URLhttps://api.mch.weixin.qq.com/pay/unifiedorder加到安全域名中

Taro/JS/H5/小程序:纯前端解决小程序微信支付统一下单和调起支付的更多相关文章

  1. 原创:微信小程序调用【统一下单】、【支付】、【支付回调】api并处理请求

    1.服务器端使用TP3.2处理(随便写在一个Controller里面) /* 小程序报名,生成订单 */ public function make_order(){ if(IS_POST){ $dat ...

  2. 微信授权、获取用户openid-纯前端实现——jsonp跨域访问返回json数据会报错的纯前端解决办法

    近来,倒霉的后台跟我说让我拿个openid做微信支付使用,寻思很简单,开始干活. 首先引导用户打开如下链接,只需要将appid修改为自己的就可以,redirect_url写你的重定向url https ...

  3. H5商城,纯前端静态页面

    发布时间:2018-09-28   技术:jquery1.10.1+swipeSlide+jquery.mmenu+jquery.touchSwipe+cityinit   概述 纯手写H5商城,2年 ...

  4. 小程序clearinterval无效解决

    小程序clearinterval无效解决 小程序clearinterval清除定时器无效,原因是定时器使用与清除方法不对导致的,我们应将定时器绑定变量,这样在关闭页面清空定时器clearinterva ...

  5. springboot+微信小程序实现微信支付【统一下单】

    说明: 1)微信支付必须有营业执照才可以申请 2)微信支付官方api是全套的,我这是抽取其中的统一下单api,做了一个简单的封装 首先看看微信支付 商户系统和微信支付系统主要交互: 1.小程序内调用登 ...

  6. 纯前端H5小应用_localStorage存储

    开发缘由[需求发现和分析] 想要送朋友一个礼物,但是想了想,街上买的东西,em~,我们这样的猿确实不会选礼物啊,由此就想利用自己手中的工具和知识做点有用的东西吧,抱枕是礼物,钢笔是礼物,电子产品也是礼 ...

  7. 微信小程序开发——前端如何区分小程序运行环境

    前言: 之前用vue做h5项目,对于接口请求,都是根据前端访问域名来判断运行环境,然后自动适配对应的服务器地址的.这样的好处就是在开发.测试及发布上线全程都不需要手动去改接口请求地址,只要提前配置好就 ...

  8. 通过微信小程序看前端

    前言 2016年9月22日凌晨,微信官方通过“微信公开课”公众号发布了关于微信小程序(微信应用号)的内测通知.整个朋友圈瞬间便像炸开了锅似的,各种揣测.介绍性文章在一夜里诞生.而真正收到内测邀请的公众 ...

  9. JS魔法堂之实战:纯前端的图片预览

    一.前言 图片上传是一个普通不过的功能,而图片预览就是就是上传功能中必不可少的子功能了.在这之前,我曾经通过订阅input[type=file]元素的onchange事件,一旦更改路径则将图片上传至服 ...

随机推荐

  1. 关于使用IDEA,使用Maven打包项目

    关于使用IDEA,使用Maven打包项目 在近期的一个接口项目中,使用的是SpringBoot + Maven的配置, 由于使用IDEA不久,不太熟悉使用Maven进行项目打包.记录一下. 由于使用的 ...

  2. Autoware 笔记 No. 5——基于GNSS的定位

    1. 前言 在之前的笔记No.2 中,我们直接采用ndt_matching的方法实现定位,但需要在打开rviz中,通过2D Pose Estimate指定初始位置.加入GNSS后,可以帮助ndt_ma ...

  3. SpringBoot整合kafka(实现producer和consumer)

    本文代码使用的是Spring Boot 2.1.8.RELEASE 版本 <parent> <groupId>org.springframework.boot</grou ...

  4. 分享windows 10 下部署 elasticsearch 和 logstash (二)

    接上一篇,es部署很简单,很快就弄好了. 但是还是有很多不玩美. 比如说:主机是本地的IP或机器名,端口是固定的9200. 而且是只有一个节点,我要在一台机器上部署多个节点呢. 经过一段时间的摸索,做 ...

  5. Google开发者F12工具面板-network详解

    1 开发者工具面板    面板上包含了Elements面板.Console面板.Sources面板.Network面板.Performance面板.Memory面板.Application面板.Sec ...

  6. python3模块

    一.sys模块 import sys #print(sys.path) #打印环境变量 #print(sys.argv) print(sys.argv[3]) Sys.argv[ ]其实就是一个列表, ...

  7. Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就绪,挂起,运行) ,***协程概念,yield模拟并发(有缺陷),Greenlet模块(手动切换),Gevent(协程并发)

    Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就 ...

  8. 小鸟初学Shell编程(九)环境变量变量配置文件

    介绍 在上一篇使用完了环境变量,并且知道PATH环境变量概念,那么我们对命令的执行就有了一定深入的理解.那么PATH环境变量或其他环境变量是保存在哪呢?那么这篇文章主要介绍环境变量配置文件. 配置文件 ...

  9. 去除数组空格 php

    public function trimArray($params){ if (!is_array($params)) return trim($params); return array_map([ ...

  10. 9. [mmc subsystem] host(第三章)——sdhci-pltfm说明

    一.sdhci-pltfm说明 sdhci-pltfm并不是实际某个host的driver. sdhci-pltfm是指在sdhci core的基础上,提供了统一对sdhci_host的必要属性进行解 ...