支付宝扫码(Easy版)支付实现

2024-01-07 23:33:52

一 技术准备

1.1 二维码技术(java)

  • 二维码 (dimensional barcode) ,又称二维条码,是在一维条码的基础上扩展出的一种具有可读性的条码。

  • 设备扫描二维条码,通过识别条码的长度和宽度中所记载的二进制数据,可获取其中所包含的信息

  • 总之:二维码是信息的载体

  • 纠错级别: L、M、Q、H 由低到高。

    • 低级别的像素块更大,可以远距离识别,但是遮挡就会造成无法识别。
    • 高级别则相反,像素块小,允许遮挡一定范围,但是像素块更密集。
    QrConfig config = new QrConfig();
    config.setErrorCorrection(ErrorCorrectionLevel.H);
    

  • Hutool是一个Java工具包类库,对文件、流、加密解密、转码、正则、线程、XML等JDK方法进行封装,组成各种Util工具类。
  • 实现步骤:
  1. 导入maven依赖
    <dependency>
                <groupId>com.google.zxing</groupId>
                <artifactId>core</artifactId>
                <version>3.3.3</version>
            </dependency>
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>5.7.5</version>
            </dependency>
    
  2. 生成二维码
public static void main(String[] args) {
        QrConfig config = new QrConfig();
        config.setErrorCorrection(ErrorCorrectionLevel.H);
        config.setBackColor(Color.WHITE); // 设置背景颜色
        config.setForeColor(Color.blue); // 设置前景色
        config.setWidth(500);
        config.setHeight(500);
        QrCodeUtil.generate("yuanyou.blog.csdn.net",config,new File("path\\res.jpg"));
    }

在这里插入图片描述

1.2 支付宝沙箱环境准备

  • 沙箱环境:沙箱环境是协助开发者进行接口开发及主要功能联调的模拟环境
  1. 通过支付宝账号登录 支付宝开放平台
  2. 在控制台找到沙箱管理,手机、平板下载沙箱APP(沙箱环境目前只支持Android环境安装)
    在这里插入图片描述
  3. 使用沙箱账号进行的登录(有时候会出现错误,请多次尝试),账号和密码在沙箱账号页面有提供
    在这里插入图片描述

1.3 内网穿透

二 支付宝支付相关知识

2.1 各种支付方式

在这里插入图片描述

  1. 扫一扫支付:用户可以通过支付宝app的“扫一扫”功能,扫描商家的二维码进行支付,或者向商家展示自己的付款码供商家扫描。

  2. 付款码支付:用户打开支付宝app,展示付款码,由商家扫描用户的付款码完成交易。

  3. 条形码支付:用户展示支付宝app内的条形码,由商家扫描进行支付。

  4. 蓝牙支付:借助蓝牙技术,用户可以在支持蓝牙支付的设备附近完成支付。

  5. 在线支付(网页或APP内):在线购物时,选择支付宝作为支付方式,在跳转到支付宝支付页面后登录账户并确认支付。

  6. 面部识别支付:在具备面部识别功能的设备上,用户可以通过扫描面部信息来完成支付,称为“刷脸支付”。

  7. NFC支付:利用近场通讯(NFC)技术,用户只需将手机靠近支持NFC功能的POS机即可完成支付。

2.2 扫码付接入流程

在这里插入图片描述

2.3 系统交互流程(时序图)

在这里插入图片描述

2.4 加密逻辑

非对称加密:

  • 公钥:加密、验签
  • 私钥:解密、签名
  1. 支付宝公钥加密、应用私钥签名
  2. 支付宝私钥解密、应用公钥验签
  • 支付宝请求加密解密过程
    在这里插入图片描述
  • 支付宝响应加密解密过程
  1. 应用公钥加密,支付宝私钥签名
  2. 支付宝公钥验签,应用私钥解密

在这里插入图片描述

三 扫码支付实现

3.1 添加maven依赖(Easy版)

  • 两个版本SDK:easy版和通用版
  • Easy版maven地址
    <!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-easysdk -->
    <dependency>
        <groupId>com.alipay.sdk</groupId>
        <artifactId>alipay-easysdk</artifactId>
        <version>2.2.3</version>
    </dependency>
    
  • 通用版maven地址
    <dependency>
        <groupId>com.alipay.sdk</groupId>
        <artifactId>alipay-sdk-java</artifactId>
        <version>4.38.183.ALL</version>
    </dependency>
    

3.2 完善配置文件和配属属性类


需要的信息和获取方式:

  • 沙箱应用APPID
    在这里插入图片描述
  • 应用私钥,应用公钥
    在这里插入图片描述
    在这里插入图片描述
  • 通知回调地址,使用coplar生成的https地址+/notify接口

  1. 在application.yml中添加配置
alipay:
  easy:
    protocol: https
    gatewayHost: openapi-sandbox.dl.alipaydev.com
    signType: RSA2
    appId: #沙箱应用的APPID
    merchantPrivateKey: #应用私钥
    alipayPublicKey: # 支付宝公钥
    notifyUrl: https://xxx.r6.cpolar.top/notify 
  1. 创建文件
    • AliPayProperties.java
    import lombok.Data;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    @Data
    @ConfigurationProperties(prefix = "alipay.easy")
    public class AliPayProperties {
        //请求协议
        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;
    }
    
    • AlipayConfig.java
    import com.alipay.easysdk.kernel.Config;
    import com.itheima.alipay.prop.AliPayProperties;
    import lombok.Data;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    @Data
    public class AlipayConfig {
        @Bean
        public Config config(AliPayProperties payProperties) {
            Config config = new Config();
            config.protocol = payProperties.getProtocol();
            config.gatewayHost = payProperties.getGatewayHost();
            config.signType = payProperties.getSignType();
            config.appId = payProperties.getAppId();
            config.merchantPrivateKey = payProperties.getMerchantPrivateKey();
            config.alipayPublicKey = payProperties.getAlipayPublicKey();
            //可设置异步通知接收服务地址(可选)
            config.notifyUrl = payProperties.getNotifyUrl();
            config.encryptKey = "";
            return config;
        }
    }
    

3.3 扫码支付controller实现

import cn.hutool.extra.qrcode.QrCodeUtil;
import com.alibaba.fastjson.JSONObject;
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.Config;
import com.alipay.easysdk.payment.common.models.AlipayTradeQueryResponse;
import com.alipay.easysdk.payment.facetoface.models.AlipayTradePrecreateResponse;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.io.File;

@RestController
@Slf4j
@AllArgsConstructor
public class EasyPayController {

    private final Config alipayConfig;


    @GetMapping("/pay")
    public String pay() throws Exception {
        Factory.setOptions(alipayConfig);
        //调用支付宝接口
        AlipayTradePrecreateResponse response = Factory.Payment.FaceToFace().preCreate("rtx 4090 24G", "1656235762657645", "20000");
        //解析结果
        String httpBody = response.getHttpBody();
        //转JSON对象
        JSONObject jsonObject = JSONObject.parseObject(httpBody);
        String qrUrl = jsonObject.getJSONObject("alipay_trade_precreate_response").get("qr_code").toString();
        //生成二维码
        QrCodeUtil.generate(qrUrl,300,300,new File("C:\\res.jpg"));
        return httpBody;
    }

    @PostMapping("/notify")
    public String notify(HttpServletRequest request){
        log.info("收到支付成功通知");
        String out_trade_no = request.getParameter("out_trade_no");
        log.info("流水号:{}",out_trade_no);
        //TODO 后续业务流程
        return "success";
    }

    @GetMapping("/query")
    public String query() throws Exception {
        Factory.setOptions(alipayConfig);
        AlipayTradeQueryResponse response = Factory.Payment.Common().query("1656235762657645");
        return response.getHttpBody();
    }
}

3.4 运行结果

2024-01-07 21:30:49.127  INFO 6628 --- [nio-8080-exec-3] c.i.alipay.controller.EasyPayController  : 收到支付成功通知
2024-01-07 21:30:49.128  INFO 6628 --- [nio-8080-exec-3] c.i.alipay.controller.EasyPayController  : 流水号:1656235762657645
  • 访问localhost:8080/query即可查询到付款成功的结果
{
  "alipay_trade_query_response": {
    "code": "10000",
    "msg": "Success",
    "buyer_logon_id": "hro***@sandbox.com",
    "buyer_pay_amount": "20000.00",
    "buyer_user_id": "2088722025453088",
    "buyer_user_type": "PRIVATE",
    "fund_bill_list": [
      {
        "amount": "20000.00",
        "fund_channel": "ALIPAYACCOUNT"
      }
    ],
    //...
}    
  • 沙箱环境的支付宝中可以查询到支付记录
    在这里插入图片描述

文章来源:https://blog.csdn.net/yang2330648064/article/details/135444498
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。