current position:Home>Wechat payment development, java online payment project based on springboot + Vue architecture

Wechat payment development, java online payment project based on springboot + Vue architecture

2022-01-27 02:07:15 Code farmer research monk

Preface

This project is mainly studied through the following links
【 Silicon Valley 】 Wechat payment development , be based on SpringBoot+Vue Architecturally Java Online payment video tutorial

This article combines my own thinking and notes

The project is mainly based on
Back end technologies include :springboot+springmvc+restful+vue+mybatis-plus+mysql
Front end technology has :html+css+vue

The framework of this paper mainly introduces

  • Some introduction of wechat payment , Certificate of payment 、 Key and signature
  • Construction to implementation of the project
  • Basic payment API Interface

The knowledge points involved in the framework of this paper But look at my previous article
Basic knowledge of :

  1. java Zero foundation, from entry to mastery ( whole )
  2. javaSE 200000 word summary from introduction to mastery ( One )
  3. javaSE 200000 word summary from introduction to mastery ( Two )
  4. javaSE 200000 word summary from introduction to mastery ( 3、 ... and )

Server side :

  1. Spring Framework from introduction to learning ( whole )
  2. SpringMVC From entry to mastery ( whole )
  3. Mybatis From entry to mastery ( whole )
  4. MyBatis-plus From entry to mastery ( whole )

database

  1. Add, delete and change common syntax statements in the database ( whole )
  2. Common syntax of database query

web The server Tomcat Detailed configuration ( whole )

project management

  1. Maven Actual combat from entry to mastery ( whole )
  2. Maven Detailed configuration ( whole )

Front end knowledge points :

  1. html From entry to mastery ( whole )
  2. css Attributes from entry to mastery ( whole )
  3. JavaScript From entry to mastery ( whole )

1. Payment security

  • Plaintext : The message before encryption is called “ Plaintext ”(plain text)
  • Ciphertext : The encrypted text is called “ Ciphertext ”(cipher text)
  • secret key : Only by mastering special “ The key ” People who , To decrypt the encrypted text , there “ The key ” It's called “ secret key ”(key)

According to the way the key is used , Encryption can be divided into two categories : Symmetric and asymmetric encryption

1.1 Symmetric and asymmetric encryption

Symmetric encryption
characteristic : Use only one key , The key must be kept secret , Commonly used AES Algorithm

  • advantage : It's fast
  • shortcoming : The secret key needs to be shared by both sides of the information exchange , Once stolen , The message will be cracked , No secure key exchange

Asymmetric encryption
characteristic : Use two keys : Public and private keys , The public key can be distributed arbitrarily while the private key is kept secret , Commonly used RSA

  • advantage : Hackers can't crack the ciphertext after obtaining the public key , The problem of key exchange is solved
  • shortcoming : The computing speed is very slow

1.2 Identity Authentication

  • Public key encryption , The function of private key decryption is to encrypt information
  • Private key encryption , The function of public key decryption is identity authentication

Generally speaking, after public key encryption , Public keys are public , Decryption by private key

And if, in turn , Encryption by private key , Public key decryption , That's identity authentication , Your only key

1.3 Abstract algorithm

Mainly to ensure that the data has not been modified , Ensure the integrity of information

Abstract algorithm is what we often say Hash function 、 hash function (Hash Function), It can put any length of data “ Compress ” become
Fixed length 、 And unique “ Abstract ” character string , It's like generating a number for this piece of data “ The fingerprint ”.

The main features are :

  • Irreversible : Only algorithms , No secret key , Encryption only , Cannot decrypt
  • Problem friendliness : Want to crack , Only violence can be enumerated
  • Divergence : Just make a little change to the original text , The summary will change dramatically
  • Resistance to PengZhuangXing : The original text is different , The calculated summary should also be different

To highlight the integrity of the data , By adding a summary algorithm , Add it to the data
And the person who gets the data in order to verify the integrity of the data , Usually also through the summary algorithm , That is, hash , Judge whether the data are consistent , Determine whether there is any modification in turn

But if intercepted in the middle , Generate a new summary algorithm , It's hard to judge whether it has been modified by others

1.4 Digital signatures and digital certificates

digital signature :
After passing the data through the digest algorithm, it needs to be encrypted with the private key into a digital signature
And the people who get the data , It is necessary to decrypt through the public key and verify the integrity of the data through the digest algorithm

The above public key can be forged
A digital certificate is added for this purpose

digital certificate :
Digital certificate solution “ Public key trust ” problem , It can prevent hackers from forging public keys .
Public keys cannot be distributed directly , The distribution of public key must use digital certificate , Digital certificate by CA Issued by

The specific digital certificate generation process is as follows :
Through the hash algorithm, that is, the summary algorithm, the information is generated, and then through CA The encryption of the private key becomes a digital certificate

A Send data with digital certificate ,B After getting the data , The integrity is determined by the hash algorithm, that is, the digest algorithm , Re pass CA Determine whether the public key can be taken out , After taking it out is A The public key of .B Then take the A Public key to decrypt , And the summary algorithm to determine the integrity of the data

Let's do some science popularization https The digital certificate of :
 Insert picture description here

2. At the beginning of the project

2.1 Build tests

establish springboot Project
adopt idea compiler new One spring initializr Project ,java8 Version of
And server usage https://start.aliyun.com, It will be faster

Specific about springboot See my previous articles for relevant knowledge
springboot From entry to mastery ( whole )

Modify the following here pom The dependent file under the file is changed to web, Mainly for the start of the web page

<!--web-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Configure a port number ( Resource file )

server:
  port: 8090 # Service port 

spring:
  application:
    name: payment-demo # Name of application 

Configure an interface , To test springboot Start of

@RestController // Mainly for transmission json An annotation of the data 
@RequestMapping("/api/product")
public class ProductController {
    


    @GetMapping("/test")
    public String test(){
    

        return "hello";
    }
}

Enter... In the browser url by
http://localhost:8090/api/product/test To test

A few notes :
In the building springboot When
Use maven management jar Don't use the version number indiscriminately when packaging
( Don't use annotations indiscriminately jar Package versions )

 Insert picture description here

2.2 introduce Swagger

Automatically generate interface documents and related test interfaces
test get post delete It's convenient to wait for the interface

One is dependent files, the other is ui The presentation interface depends on the package

<!--Swagger-->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.7.0</version>
</dependency>
<!--Swagger ui-->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.7.0</version>
</dependency>

Configure a configuration class

adopt bean Object injection
A document object such as text

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class Swagger2Config {
    

    @Bean
    public Docket docket(){
    

        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(new ApiInfoBuilder().title(" Code farmer research monk wechat payment case interface document ").build());
    }
}

Then enter the following page in the web address http://localhost:8090/swagger-ui.html#/
 Insert picture description here

In order to better pass url And swagger Better integration of
The following can be added to the code module of the business layer ,@Api(tags = " Commodity management "),@ApiOperation(" Test interface ")
This annotation @ApiOperation(" ) only one value value , therefore value Values can be omitted

@Api(tags = " Commodity management ")
@RestController // Mainly for transmission json An annotation of the data 
@RequestMapping("/api/product")
public class ProductController {
    

	@ApiOperation(" Test interface ")
    @GetMapping("/test")
    public String test(){
    

        return "hello";
    }
}

Then it will be displayed in the page

 Insert picture description here

2.3 introduce lombok

For better interaction between front and back ends , Define a unified result
It mainly displays the response code , The response message
And then put one in the dependency package lombok
Mainly can simplify the development , Automatic generation get、set Other methods

( The premise is that there is lombok Plug in for )

<!--lombok-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

The main code modules are

@Data
public class R {
    

    private Integer code; // Response code 
    private String message; // The response message 
    private Map<String, Object> data = new HashMap<>();

    public static R ok(){
    
        R r = new R();
        r.setCode(0);
        r.setMessage(" success ");
        return r;
    }

    public static R error(){
    
        R r = new R();
        r.setCode(-1);
        r.setMessage(" Failure ");
        return r;
    }

    public R data(String key, Object value){
    
        this.data.put(key, value);
        return this;
    }

}

adopt @Data This annotation looks at its structure structure , You can also see the automatic generation get and set Other methods

About @Data This note can be found in my previous article
spring in @Data Annotation detailed analysis
 Insert picture description here

Transmit some specific information to the front end
adopt data This hash is transmitted

public R data(String key, Object value){
    
       this.data.put(key, value);
       return this;
   }

Enter a certain value in the display interface to see
Chain operation , Multiple values can be transmitted

@ApiOperation(" Test interface ")
   @GetMapping("/test")
   public R test(){
    

       return R.ok().data("message", "hello").data("now", new Date());
   }

In particular, if this transmission new Date() The data of , Not a standard format
If you want to change to the desired format
You can add in the resource file ( Self time json Data format )
yyyy-MM-dd HH:mm:ss Specific date , Minutes and seconds ,GMT+8 And the time zone

jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8

 Insert picture description here

3. database

adopt navicat Software or native mysql Build the database
By running a specific database script or writing your own database

Specifically sql The script is as follows

USE `payment_demo`;

/*Table structure for table `t_order_info` */

CREATE TABLE `t_order_info` (
  `id` bigint(11) unsigned NOT NULL AUTO_INCREMENT COMMENT ' Order id',
  `title` varchar(256) DEFAULT NULL COMMENT ' Order title ',
  `order_no` varchar(50) DEFAULT NULL COMMENT ' Merchant order number ',
  `user_id` bigint(20) DEFAULT NULL COMMENT ' user id',
  `product_id` bigint(20) DEFAULT NULL COMMENT ' Payment products id',
  `total_fee` int(11) DEFAULT NULL COMMENT ' Order amount ( branch )',
  `code_url` varchar(50) DEFAULT NULL COMMENT ' Order QR code connection ',
  `order_status` varchar(10) DEFAULT NULL COMMENT ' The order status ',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT ' Creation time ',
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ' Update time ',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;


/*Table structure for table `t_payment_info` */

CREATE TABLE `t_payment_info` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT ' Payment record id',
  `order_no` varchar(50) DEFAULT NULL COMMENT ' Merchant order number ',
  `transaction_id` varchar(50) DEFAULT NULL COMMENT ' Payment system transaction number ',
  `payment_type` varchar(20) DEFAULT NULL COMMENT ' Payment type ',
  `trade_type` varchar(20) DEFAULT NULL COMMENT ' Type of transaction ',
  `trade_state` varchar(50) DEFAULT NULL COMMENT ' Transaction status ',
  `payer_total` int(11) DEFAULT NULL COMMENT ' Pay the amount ( branch )',
  `content` text COMMENT ' Notification parameters ',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT ' Creation time ',
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ' Update time ',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;


/*Table structure for table `t_product` */

CREATE TABLE `t_product` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT ' goods id',
  `title` varchar(20) DEFAULT NULL COMMENT ' Name of commodity ',
  `price` int(11) DEFAULT NULL COMMENT ' Price ( branch )',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT ' Creation time ',
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ' Update time ',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

/*Data for the table `t_product` */

insert  into `t_product`(`title`,`price`) values ('Java Course ',1);
insert  into `t_product`(`title`,`price`) values (' Big data course ',1);
insert  into `t_product`(`title`,`price`) values (' Front end courses ',1);
insert  into `t_product`(`title`,`price`) values ('UI Course ',1);

/*Table structure for table `t_refund_info` */

CREATE TABLE `t_refund_info` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT ' Refund form id',
  `order_no` varchar(50) DEFAULT NULL COMMENT ' Merchant order number ',
  `refund_no` varchar(50) DEFAULT NULL COMMENT ' Merchant refund slip No ',
  `refund_id` varchar(50) DEFAULT NULL COMMENT ' Payment system refund No ',
  `total_fee` int(11) DEFAULT NULL COMMENT ' Original order amount ( branch )',
  `refund` int(11) DEFAULT NULL COMMENT ' Refund amount ( branch )',
  `reason` varchar(50) DEFAULT NULL COMMENT ' Reason for refund ',
  `refund_status` varchar(10) DEFAULT NULL COMMENT ' Refund status ',
  `content_return` text COMMENT ' Request refund return parameters ',
  `content_notify` text COMMENT ' Refund result notification parameters ',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT ' Creation time ',
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ' Update time ',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

 Insert picture description here

stay java In the code module
Import dependency package of database

<!--mysql  drive -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

<!--MyBatis-Plus: yes MyBatis The enhancement of -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.3.1</version>
</dependency>

Add a connection to the database
 Insert picture description here

  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/payment_demo?serverTimezone=GMT%2B8&characterEncoding=utf-8
    username: root
    password: 123456

Version number of the database if yes 5 about , The name of the version is com.mysql.jdbc.Driver
If it is 8 Version number of , The name of the version is com.mysql.cj.jdbc.Driver, Even in pom No version number is given in the file , The system will also default to 8 Version of
The specific download method can be through maven engineering
You can also download it as follows

  1. mysql-connector-java-8.0.26.rar
  2. MySql Connector Java 5.1.23.rar

Code module about database
Entity classes that require database tables , The mapping file , And the code module of business logic
Can pass mybatis Reverse engineering one key generation
See my previous article for details
mybatis Detailed configuration explanation of reverse engineering ( whole )

3.1 Entity class

There are four forms , There are also public column names , So you can set up a public class , Then by inheritance
 Insert picture description here

When naming, if the table is different from the entity class , Can pass @TableName("t_order_info") This annotation is mapped
If the column name is different from that of the database , You can also map , But it's best to use the naming rules of humps ,mybatisplus Will help transform
 Insert picture description here
( adopt lombok Plug in for Can be generated automatically get、set Other methods )

If the database has a primary key, you also need to configure an annotation in the primary key
Define the primary key policy : Auto increment following the primary key of the database @TableId(value = "id", type = IdType.AUTO)

 Insert picture description here

3.2 Mapping class

 Insert picture description here

Inherit BaseMapper
 Insert picture description here

This class , yes mybatis-plus Unified use in maper

Dynamically generate some specific interfaces

 Insert picture description here

xml The document also doesn't have some written code

Add :
After compiling target Directory , No generation xml file
By default ,java The directory is not java The code cannot be generated

Resource path matching options
Give Way maven China Africa java Files are also generated

<build>
    <!--  The project will be packaged with java In the directory *.xml Files are also packaged  -->
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
    </resources>
    
</build>

Let the run file find xml file

Application's mapper How to find
Mainly this line of code

mapper-locations: classpath:com/paymentdemo/mapper/xml/*.xml 

By the way, add the log configuration file

 Insert picture description here

3.3 service class

 Insert picture description here

Inherited IService
 Insert picture description here

It defines some abstract methods such as addition, deletion, modification and query, as well as some paging and batch processing methods
 Insert picture description here

3.4 Configuration class

It is mainly to start the transaction
And scan mapping files

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@MapperScan("com.paymentdemo.mapper")
@EnableTransactionManagement // Enable transaction management 
public class MyBatisPlusConfig {
    


}

3.5 Business logic

After adding the database
You can call the data of the database

@CrossOrigin // Open front-end cross domain access 
@Api(tags = " Commodity management ")
@RestController
@RequestMapping("/api/product")
public class ProductController {
    

    @Resource
    private ProductService productService;


    @GetMapping("/list")
    public R list(){
    

        List<Product> list = productService.list();
        return R.ok().data("productList", list);
    }

}

Then you can access the data in the page

http://localhost:8090/swagger-ui.html#!/21830216973164929702/listUsingGET

 Insert picture description here

 Insert picture description here

At the same time, you can also see the output of the log in the terminal
 Insert picture description here

4. Front end interface

The front-end interface is mainly vue+javascript+html

At first, I installed node Installation package , It can be installed through the official website

After installation , Again cmd Search under command node -v You can find the version number
 Insert picture description here

Enter... In the front-end construction project npm run serve

 Insert picture description here

The default is to open the front-end interface
But the back-end interface is built , And after the front-end interface , There is no connection , So there will be an error logging in
 Insert picture description here

The port number in the front end is 8080, But the back-end port number is 8090, So it's a different port number , Cross domain analysis is required

The way of communication is ajax The way
You need to add an annotation to the back-end code , Delegates are cross domain access requests
@CrossOrigin // Open front-end cross domain access
 Insert picture description here

4.1 vue

Specific opening vue The code module of vscode This software
The specific installation can be downloaded through the official website
Generally, it's better for novices to add three plug-ins (chinese Chinese bag of 、vuehelper Help documents, etc )

Generally, if the image is not installed for downloading , It will be downloaded through domestic links , Generally, it's more card
So again cmd Enter these two lines below the command line

  • npm config set registry https://registry.npm.taobao.org ,npm install The installation of will be downloaded through the image address of Taobao

  • npm install -g @vue/cli Conduct global scaffold installation

Under normal installation :( appear warn Don't be afraid of , appear error Be afraid of )
 Insert picture description here
If you can't install it, you can check my article
appear npm ERR code EPERM npm ERR syscall mkdir npm ERR path B:\nodejs\node_global_cacache Solutions for

vscode Shortcut keys :

crtl + ~ Open the terminal
ctrl + l Scroll the terminal to the top

Create a new project vue create Project name
Run this project npm run serve -- --port Port number
first -- Representatives are placeholders , No need to fill in , the second – It's the port number

vue Page components :

  • The file displayed on the page
  • Required script
  • Page style

Specific and simple vue The page structure is as follows :
 Insert picture description here
App.vue The main contents of the page are :

<!-- Define the page structure -->
<template>
  <div>
  

  </div>
</template>

<!-- Define page script -->
<script> export default {
       } </script>

The knowledge points of design are :
Data binding , Two way binding, etc
Simple interface

<!-- Define the page structure -->
<template>
  <div>
    <h1>Vue Case study </h1>
    <!--  interpolation  -->
    <p>{
   {course}}</p>
    <p>
      <!--  Instructions  -->
      <input type="text" v-model="course">
    </p>
    <p>
      <!--  event  -->
      <button @click="toPay()"> To pay </button>
    </p>
  </div>
</template>

<!-- Define page script -->
<script> export default {
       //  Defining data  data () {
       return {
       course: ' Wechat payment ' } }, //  Define methods  methods: {
       toPay(){
       console.log(' To pay ') } } } </script>

5. The main function

Import payment parameters : Merchant number 、app Key, etc
Load the merchant's key : Use of asymmetric keys , Use of public and private keys
Obtain platform certificate and signature checker : Two certificates of wechat platform and website
obtain HttpClient object : Remote request access , Establish a remote connection

5.1 Wechat payment parameters

The official website of wechat payment is as follows
Wechat payment official website

Specific wechat payment parameters include :

  • The serial number of the certificate , Just as CA digital signature
    send out : The merchant's private key file is loaded into the application mainly for signature
    Sign for : Then send it to the server of wechat , Wechat the certificate corresponding to the serial number of the certificate , Then verify the signature through the public key

  • APIV3 The key is mainly symmetric encryption

  • APPID It's a public official account. id

  • Wechat server address , Send a payment request to the wechat server

  • Receive notification of results , Also to the local server ( Website ) Return a result address ( Intranet through , Different address )

#  Wechat payment related parameters 
#  Merchant number 
wxpay.mch-id= cell-phone number 
#  Merchant API Certificate serial number 
wxpay.mch-serial-no=34345964330B66427E0D3D28826C4993C77E631F

#  Merchant private key file 
wxpay.private-key-path=apiclient_key.pem
# APIv3 secret key 
wxpay.api-v3-key=UDuLFDcmy5Eb6o0nTNZdu6ek4DDh4K8B
# APPID
wxpay.appid=wx74862e0dfcf69954
#  Wechat server address 
wxpay.domain=https://api.mch.weixin.qq.com
#  Receiving result notification address 
#  Be careful : Every time you restart ngrok, You need to modify this configuration according to the actual situation 
wxpay.notify-domain=https://500c-219-143-130-12.ngrok.io

# APIv2 secret key 
wxpay.partnerKey: T6m9iK73b0kn9g5v426MKfHQH7X8rKwb

5.2 Configuration class

A configuration class is mainly made to correspond to the payment parameters of wechat one by one

@Configuration
@PropertySource("classpath:wxpay.properties") // Read configuration file 
@ConfigurationProperties(prefix="wxpay") // Read wxpay node 
@Data // Use set Methods will wxpay The values in the node are populated into the properties of the current class 
@Slf4j
public class WxPayConfig {
    

    //  Merchant number 
    private String mchId;

    //  Merchant API Certificate serial number 
    private String mchSerialNo;

    //  Merchant private key file 
    private String privateKeyPath;

    // APIv3 secret key 
    private String apiV3Key;

    // APPID
    private String appid;

    //  Wechat server address 
    private String domain;

    //  Receiving result notification address 
    private String notifyDomain;

    // APIv2 secret key 
    private String partnerKey;
    
}

After the configured configuration file is clicked in, you can't enter the page
Its configuration file can be configured as spring Configuration file for

The method is as follows :
 Insert picture description here

Add the corresponding dependent package

<!--  Generate metadata information of custom configuration  -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

Restart or clean after
You can use the information of the configuration file crtl+ Right click Enter its configuration class

5.3 Load private key file

You need to import its private key file
Mainly for signature , To encrypt

Specifically api Documents can be viewed
Wechat payment developer document

Its java Linguistic api Documents can be viewed
java api file

Need to add dependency package

<dependency>
    <groupId>com.github.wechatpay-apiv3</groupId>
    <artifactId>wechatpay-apache-httpclient</artifactId>
    <version>0.3.0</version>
</dependency>

The specific loading code is as follows
 Insert picture description here
The code modules are as follows

// Example : The private key is stored in a file 
PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(
        new FileInputStream("/path/to/apiclient_key.pem"));

// Example : The private key is String character string 
PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(
        new ByteArrayInputStream(privateKey.getBytes("utf-8")));

copyright notice
author[Code farmer research monk],Please bring the original link to reprint, thank you.
https://en.cdmana.com/2022/01/202201270206476840.html

Random recommended