Laravel实现微信小程序支付

准备工作

微信小程序支付流程

首先我们需要大致了解微信小程序的支付的流程,主要分为如下几个步骤。这里以一次下单购买商品的场景为例。

  1. 用户在小程序中选购商品,点击提交订单。
  2. 小程序请求业务服务器,传入订单相关信息。
  3. 业务服务器将订单信息写入数据库,然后请求微信支付统一下单API,传入将订单相关数据和小程序相关id及签名。
  4. 微信支付统一下单API返回下单结果,支付订单号,签名等。业务服务器将这些信息返回给小程序。
  5. 小程序拉起微信支付,用户输入密码支付。
  6. 小程序获得支付结果,请求业务服务器更新订单数据。
  7. (可选)微信支付服务器访问业务服务器的回调URL,更新支付结果。

阅读文档

在开始开发前,请首先认真阅读微信支付官方文档EasyWechat文档的微信支付部分。

Laravel Eloquent ORM 关系查询

在信息系统中有很多一对多的关系,常见的一个例子是一个订单(order)中包含多种商品(product)。我们通常会使用一个order表来存储订单,同时使用一个product表来存储商品,并在product表中加入order_id外键来将产品关联到订单中。

在以前开发项目时,我一直使用先查询order,再通过order_id查询product,并遍历查询到的order对象,将product插入order中的做法。但是这样做非常不优雅,并且会严重影响性能。同时,由于数据库中没有外键约束,一旦业务代码中出现bug,则会影响数据的一致性。

在这次的项目开发中,我使用Laravel的Eloquent ORM来实现外键的关系查询。

一些概念

我们首先来复习一些数据库系统导论中的一些概念

主键(Primary Key)

主关键字(Primary Key)是表中的一个或多个字段,它的值用于唯一地标识表中的某一条记录。主键通常名为id,并且为自增。

外键(Foreign Key)

外键(Foreign Key)的作用是建立两个表之间的关联。下面这张图可以直观地展示外键的作用。

外键

连接(Join)

连接(Join)将两张表中能关联起来的数据连接后返回。关于连接的更多内容请参考这篇文章:图解 SQL 里的各种 JOIN — 码志

Laravel的Eloquent ORM中并没有实现Join,如果需要在Laravel中使用Join则需要在Query Builder中完成。请注意不要将本文所述内容和join混淆,Eloquent中的with方法的实现是通过模型中定义的关系另外进行一次查询,并没有使用join。

使用Laravel和jwt-auth编写API

JSON Web Token(JWT)是一个轻量级的认证规范,它允许用户和服务器之间传递安全可靠的信息。

在传统的WEB应用中,服务端成功的返回一个响应于两件事。其一是通过一种存储机制保存会话信息(SESSION)。每一个会话都有它独特的信息,常常是一个长的,随机化的字符串,它被用来让未来的请求检索信息。其次,包含在响应头里面的信息使客户端保存了一个COOKIE。服务器自动的在每个子请求里面加上了会话ID,这使得服务器可以通过检索SESSION中的信息来辨别用户。
API应该被设计成无状态的。这意味着没有登录,注销的方法,也没有SESSION和COOKIE。因此,我们引入JWT。

使用jwt进行认证和授权

认证

客户端向服务器发送用于登录的用户名和密码,服务器将用户名和密码和数据库比对成功后,将一条形如

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

的token返回给客户端,客户端应在本地存储这个token。
这条token被.分为三个部分:头部(Header),载荷(Payload)和签名(Signature)。其中头部的algtyp两个字段定义了此token所使用的加密算法和token类型;载荷中包含有认证用户的信息;签名则将头部和载荷以及key用base64编码后计算SHA256。

使用Composer

Composer 是 PHP 的一个依赖管理工具。它允许你申明项目所依赖的代码库,它会在你的项目中为你安装他们。

安装

curl -sS https://getcomposer.org/installer | php

让 composer 可以在全局进行调用

mv composer.phar /usr/local/bin/composer

将官方数据源修改为国内镜像

composer config -g repo.packagist composer https://packagist.phpcomposer.com