1.由于本人的项目是web版本的,因此选用native实现微信支付,在网站生成支付二维码,然后用户在手机上面用微信扫码付款。
2.本次实验微信支付的版本选用的是V2版本
3.支付订单的创建
a.商品订单是由我们本地系统生成的,商品订单必须唯一,当你使用某个商品订单去创建支付订单后,再用重复的商品订单去创建支付订单就会报错
b.支付订单是由微信平台生成的,我们只需调用相关的API接口,传入参数即可创建支付订单,每个支付订单也是唯一的,之后我们将使用这个支付订单来查询是否支付成功。
4.执行付款
用户拿微信扫描网站生成的二维码,并不是直接扣款。因为用户信不过卖家。而是自动访问微信平台,然后查询支付订单的详情(收款方、支付金额、订单备注等等),如果用户确认没有问题,就可以在手机上输入支付密码了。这个付款请求不是发给卖家的(怕卖家篡改支付金额),而是直接发送给微信平台的。微信平台先核对请求内容,然后执行扣款,最后把付款结果分别发送给商家的后端系统和付款人。
5.确认付款结果
创建支付订单的时候,其中的参数就包含了商户系统的接收付款结果的URL地址,微信服务器会向这个URL地址发送付款结果。但是万事万物总有个特殊情况,万一微信服务器的消息队列宕机了,或者出现短暂的网络故障,程序错误等原因,没能向商家的系统发送付款结果,那么商家系统中的订单状态就依然是未付款的状态。
与其被动等待付款结果的通知,不如让商家系统主动去查询付款结果。当用户手机微信显示付款成功,但是商户页面上没有出现付款成功的提示,这时候用户可以点击页面上的“已经付款成功”按钮。前端页面会向商户系统发送Ajax请求,商户系统会主动想微信服务器发起查询请求,核对该笔支付是否成功付款。如果付款成功,就修改商品订单为已付款状态。
6.付款结果推送给前端
因为接收到付款结果的是后端系统,前端页面要想收到数据就需要后端推送,一般有两种方法接收付款成功提示
方法1:前端弹出支付二维码开始,创建定时器每隔几秒向后端系统发出轮询请求,查看订单是否为已支付状态,返回成功支付则结束轮询
方法2:使用webSocket向前端页面推送结果
本次实验采用方法2,原因是方法1虽然实现简单,但是轮询访问会增加后端和服务器的压力
本项目是在罚款中用到微信支付的,因此使用罚款单的uuid作为商品编号
字段名 | 说明 |
---|---|
id | 主键 |
uuid | 做商品编号 |
user_id | 用户id |
amount | 罚款金额 |
type_id | 罚款类型 |
reason | 原因 |
prepay_id | 微信支付单ID |
status | 状态:1未缴纳,2已缴纳 |
create_time | 创建时间 |
DROP TABLE IF EXISTS `tb_amect`;
CREATE TABLE `tb_amect` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
`uuid` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'UUID',
`user_id` int NOT NULL COMMENT '用户ID',
`amount` decimal(10, 2) UNSIGNED NOT NULL COMMENT '罚款金额',
`type_id` int NOT NULL COMMENT '罚款类型',
`reason` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '罚款原因',
`prepay_id` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '微信支付单ID',
`status` tinyint NOT NULL COMMENT '状态:1未缴纳,2已缴纳',
`create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `unq_uuid`(`uuid`) USING BTREE,
UNIQUE INDEX `idx_prepayid`(`prepay_id`) USING BTREE,
INDEX `idx_user_id`(`user_id`) USING BTREE,
INDEX `idx_type_id`(`type_id`) USING BTREE,
INDEX `idx_status`(`status`) USING BTREE,
INDEX `idx_create_time`(`create_time`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 42 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '罚金表' ROW_FORMAT = DYNAMIC;
1.对于商家来说,想要开通微信支付,必须要去微信商户平台注册( https://pay.weixin.qq.com/index.php/core/home/login?return_url=%2F), 然后把工商登记证明、企业银行账户开户证明、组织机构代码证提交上去,经过半天的审核,如果没有问题,你就开通了微信支付功能。
2.如果想要在网站或者小程序上面使用微信支付,还要在微信公众平台上面关联你自己的微信商户账号。前提是你的微信开发者账号必须是企业身份,个人身份的开发者账号是无法调用微信支付API的。
如果电脑连接的是局域网,虽然局域网的IP是固定的,但是广域网的IP是动态的。也就是说,因为我们没有公网静态IP,所以我们的后端系统没办法接收到微信平台发送过来的付款结果通知。因此得实现内网穿透。
至于如何实现内网穿透,这里就不详细介绍了
微信支付系列其他部分