生成二维码
使用Hutool工具类生成二维码
引入对应的依赖
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.5</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.3</version>
</dependency>
生成二维码的代码为下:
@Test
public void createCode() {
//generate方法需要传入的参数有: 需要被生成二维码的链接,宽,高, 对应的文件名
QrCodeUtil.generate("https://hutool.cn/", 300, 300, FileUtil.file("D:/qrcode.jpg"));
}
生成对应的链接的二维码,存到到D盘且名字为qrcode.jpg。
如果我们需要生成的二维码要传给前端,这时我们需要生成Base64格式。
对应的代码为下:
@Test
public void createBase64() {
//generateAsBase64方法需要传入的参数有:需要生成二维码的链接,QrConfig对象(用于存储宽和高),对应的图片格式
String base64 = QrCodeUtil.
generateAsBase64("https://hutool.cn/", new QrConfig(300, 300), "png");
System.out.println(base64);
}
对应的效果为下:
面试考点
问:你们公司是怎么生成二维码的?
答:在刚开始的时候我们将对应的支付链接通过hutool工具类生成对应的二维码图片,但是后续的高并发的场景下服务器非常的卡,因为服务器要同时处理大量的二维码生成业务。以在后续我们直接将链接传给前端,通过前端的js工具类生成对应的二维码。
支付宝沙盒环境准备
支付宝沙盒地址
下载支付宝沙盒安卓软件
该软件的账号为下:
扫码支付的流程
流程的步骤为下:
1.商户系统调用alipay.trade.precreate方法设置二维码的有效时间,此时调用到支付宝系统,支付宝系统返回二维码链接。
2.商户系统通过方法将二维码链接生成对应的二维码,发送到支付宝app。
3.用户通过打开支付宝app扫描对应的二维码,进行支付,商户会通过获取支付宝系统返回的信息处理支付结果。
4.并不是每次支付都会返回结果,如果出现网络问题就不会返回对应的结果,所以我们需要是设置定时任务,轮询查询交易的状态。(我们会使用xxl-job)
公钥和私钥
目前的加密算法可以分为:对称加密,非对称加密。
对称加密:也叫传统加密,加密和解密都使用相同的密钥,它要求发送方和接收方在安全通信之前,要设定好一个密钥,如果要密钥被非法人员获取,其就可以进行加密和解密,所以该密钥的安全性十分的重要。
目前存在的对称加密的算法为下:
- AES (默认
AES/ECB/PKCS5Padding
) - ARCFOUR
- Blowfish
- DES (默认
DES/ECB/PKCS5Padding
) - DESede
- RC2
- PBEWithMD5AndDES
- PBEWithSHA1AndDESede
- PBEWithSHA1AndRC2_40
非对称加密:使用私钥进行加密,使用公钥进行加密,私钥是私有的不会对外暴露,而公钥是共有的,公钥的所有者可以对私钥的所有者进行验证。最常用的就是RSA和DSA。
- 签名:使用私钥加密,公钥解密。用于让所有公钥所有者验证私钥所有者的身份,并且用来防止私钥所有者发布的内容被篡改,但是不用来保证内容不被他人获得。
- 加密:用公钥加密,私钥解密。用于向公钥所有者发布信息,这个信息可能被他人篡改,但是无法被他人获得。
应用请求三方中私钥公钥的使用
三方返回信息给应用中私钥公钥的使用:
EasySDK
引入对应的依赖
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-easysdk</artifactId>
<version>2.2.0</version>
</dependency>
创建参数类
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Data
@ConfigurationProperties(prefix = "ali.pay")
@Configuration
public class AliProperties {
//请求协议
private String protocol;
// 请求网关
private String gatewayHost;
// 签名类型 RSA2
private String signType;
// 应用ID
private String appId;
// 应用私钥
private String merchantPrivateKey;
// 支付宝公钥
private String alipayPublicKey;
// 异步通知接收服务地址
private String notifyUrl;
// 设置AES密钥
private String encryptKey;
}
创建配置类
import com.alipay.easysdk.kernel.Config;
import com.example.alipaydemo.entity.AliProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class aliPayConfig {
@Bean
public Config getOptions(AliProperties aliProperties) {
Config config = new Config();
config.protocol = aliProperties.getProtocol();
config.gatewayHost = aliProperties.getGatewayHost();
config.signType = aliProperties.getSignType();
//设置对应的appId
config.appId = aliProperties.getAppId();
//设置私钥
config.merchantPrivateKey = aliProperties.getMerchantPrivateKey();
config.alipayPublicKey = aliProperties.getAlipayPublicKey();
//可设置异步通知接收服务地址(可选)
config.notifyUrl = "";
//可设置AES密钥,调用AES加解密相关接口时需要(可选) <-- 请填写您的AES密钥,例如:aa4BtZ4tspm2wnXLb1ThQA== -->
config.encryptKey = "";
return config;
}
}
创建对应的Controller层
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.Config;
import com.alipay.easysdk.kernel.util.ResponseChecker;
import com.alipay.easysdk.payment.facetoface.models.AlipayTradePrecreateResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class easyAliPayController {
@Autowired
Config config;
@GetMapping("/createOrder")
public AlipayTradePrecreateResponse Create(String orderId) {
//设置对应的参数
Factory.setOptions(config);
//设置项目名,对应的订单号,对应的金额
try {
AlipayTradePrecreateResponse response = Factory.Payment.FaceToFace()
.preCreate("餐掌柜-餐饮消费",
orderId, "0.01");
// 3. 处理响应或异常
if (ResponseChecker.success(response)) {
System.out.println("调用成功");
System.out.println(response.getHttpBody());
return response;
} else {
System.err.println("调用失败,原因:" + response.msg + "," + response.subMsg);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
在application.yml中配置对应的信息
ali:
pay:
protocol: https
gatewayHost: openapi.alipay.com
signType: RSA2
appId: 9021000128687668
merchantPrivateKey:
alipayPublicKey:
encryptKey: zgJr83uwsyEHG5LCh63d4Q==
notifyUrl:
最终完成测试。
easySDK的方法有下: