# 小程序如何接入微信支付？你可能会遇上这些坑 \| 技术宝典

- 作者：John Deng
- 发布时间：2016-12-16 18:40
- 原文：https://www.ifanr.com/minapp/736647

![feature](https://s3.ifanr.com/wp-content/uploads/2016/10/feature.jpg)

微信支付于 2013 年正式发布，一路走来，作为内测开发团队的爱范儿明显感觉到，微信支付的接口稳定程度有质的提升，围绕支付相关的场景也配备了对应的接口。

微信小程序的发布，随机附送了一个微信支付模块，该模块使用起来的情况如何？知晓程序（微信号 zxcx0101）现在就来告诉你。

### 业务流

我们先总览微信支付的一些基本情况。

微信支付有以下支付模式:

- 微信客户端内的网页支付 (JSAPI)
- 扫码支付 (PC 端，移动支付终端)
- 刷卡支付 (支付终端扫描)
- app 支付 (iOS, Android)

各种支付交互流程可通过[微信支付文档](https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=2_1)进行查看，在此不赘述。

关注微信号 zxcx0101，回复「**支付文档**」，获得微信支付文档原文链接。

#### 1. 支付发起

所有支付方式都需要通过 「统一下单」的 API 来获取一个支付凭证。

但在小程序内测期间，还没有「统一下单」的概念。HTML 5 应用发起支付需要直接通过前端构造参数来发起（不经过后端验证），很容易造成支付凭证泄露等安全问题。

为此，微信支付将其流程进行了优化：在所有支付场景中插入「统一下单」的特性。**推荐开发者在后端完成支付参数的构建等行为。**

该优化带来以下好处:

- 尽可能让开发者不犯低级错误，造成财务损失。
- 简化构造支付参数的复杂度，所有支付方式可共享一个支付后端接口。

通过「统一下单」获取到相对应 prepay\_id 或者 code\_url 等参数，即可通过各种支付模式的 SDK 来进行微信支付的发起。

#### 2. 支付结果接收

微信支付发起完成后，微信还需要提供一个通知系统，以便及时让应用知道用户已经完成支付，进行下一步的业务操作。

通知方式为一个 POST 请求，payload 为支付的状态信息，以及支付订单信息。

**需要注意的是，必须对通知参数进行签名验证，以确保安全。**

进行签名验证时，除去签名字段（一般参数名为: sign）不需要参与签名外，其余所有接收到的参数均需要参与签名。

#### 3. 周边接口

**通过 「支付发起」、「支付结果接收」，即可完成一个简单的微信支付系统。**当然，微信还提供以下接口:

- 查询订单
- 取消订单
- 申请退款
- 查询退款
- 下载对账单

具体使用可以参考[微信支付文档](https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_7&index=4#)，根据自身业务情况适当的进行采用。

### 绊脚石

嗯，没错，我们吃了一次螃蟹。

在小程序刚内测的时候，我们就决定使用微信支付模块，毕竟我们要实现的是一个电商应用 (电商没支付算什么嘛）。

关注微信号 zxcx0101，回复「**电商**」，获得电商类小程序开发教程。

在开发过程中，我们掉了一些坑。

#### 1. 支付凭证

**小程序的微信支付需要单独去申请**，因为小程序是有独立的 appid，不能使用以前的支付账户。

即使是全网发布也不能，因为小程序不是一个 HTML 5 应用。

#### 2. 统一下单参数

统一下单时需要注意将 trade\_type 设置为 JSAPI，同时 openid 需要使用与小程序相关联的 openid。

#### 3. 签名方式

MD5！MD5！MD5！

微信公众文档有很多 SHA1, MD5 的签名要求，微信支付相关的签名，暂时暂时暂时都是使用 MD5。

小程序端在发起微信支付的时候，是通过以下方式来进行发起:

![screen-shot-2016-10-25-at-5-12-17-pm](https://s3.ifanr.com/wp-content/uploads/2016/10/Screen-Shot-2016-10-25-at-5.12.17-PM-360x133.png)

按照微信文档签名的要求，参与签名的字段应该为：

- `timeStamp`
- `nonceStr`
- `package`
- `signType`

OK，按照签名算法得到的签名，去发起支付，居然提示失败了。

经过与微信对接人员沟通后，参与签名的字段还需要加上 `appid`，哦，不对，是 `appId`（请严重区分驼峰命名的大小写）。

对这样的结果我表示不服，随即我翻阅了微信支付所有文档，终于在微信 JSSDK 的文档中找到一行备注。

> 备注：`prepay_id` 通过微信支付统一下单接口拿到，`paySign` 采用统一的微信支付 `Sign` 签名生成方法，注意这里 `appId` 也要参与签名，`appId` 与 `config` 中传入的 `appId` 一致，即最后参与签名的参数有 `appId`、`timeStamp`、`nonceStr`、`package`、`signType`。

怪我咯（黑人问号） ……

#### 4. `timestamp` 类型

小程序端发起微信支付的方式已经贴在上面了，但没那么简单，继续贴文档说明。

> `timeStamp DateInt` 时间戳从 1970 年 1 月 1 日 00:00:00 至今的秒数，即当前的时间。

文档告诉我们 `timeStamp` 应该带着 `int` 类型传入。我们前端的同学照做了，然后就过来骂我。

> 你们后端参数是不是有问题！提示 `timeStamp` 不存在了都？

经过排查，传入的 `timeStamp` 的值类型应该为 `String`。

### 结尾语

总体上，**小程序接入微信支付还是比较简单的**，没有过多复杂的设置。

如果之前开发过微信支付后端的开发者，还可以复用同一个支付模块。

微信文档的编写不严谨，使得开发舒爽度严重被削减。相信随着时间推进，文档会慢慢完善，毕竟以前也是这么过来的。

**本文由知晓程序原创出品，关注微信号 zxcx0101，回复「我要体验」，获取亲手体验小程序的资格。**

快速关注知晓程序↓↓↓

![zxcx](https://s3.ifanr.com/wp-content/uploads/2016/11/zxcx-1.jpg)**知晓程序（微信号 zxcx0101）是爱范儿旗下专注于小程序生态的公众号。我们提供最全面、新鲜的小程序资讯（消息、观点、指南、活动）和服务，在这里你能了解到关于小程序的一切。**
