当前位置 : 主页 > 编程语言 > java >

支付功能

来源:互联网 收集:自由互联 发布时间:2023-09-03
1.页面原型161-166 2.快钱demo搭建166 kq-demo 创建一个新的模块 直接完成即可 2.1搭建环境166 资源在E:\java学习\盈利宝\资料\资料\10-快钱支付\人民币网关\DEMO\JAVA\人民币网关支付\rmb\FI\WebRoot

1. 页面原型  161-166

支付功能_java

支付功能_java_02

2. 快钱demo搭建  166

kq-demo

创建一个新的模块

支付功能_maven_03

支付功能_spring_04

直接完成即可

2.1 搭建环境   166

资源在E:\java学习\盈利宝\资料\资料\10-快钱支付\人民币网关\DEMO\JAVA\人民币网关支付\rmb\FI\WebRoot

支付功能_spring_05

支付功能_java_06

支付功能_maven_07

支付功能_maven_08

2.2 工具类  166

新建一个java

支付功能_spring_09

支付功能_java_10

资源在E:\java学习\盈利宝\资料\资料\10-快钱支付\人民币网关\DEMO\JAVA\人民币网关支付\rmb\FI\src\Util

支付功能_java_11

支付功能_java_12

Pkipair

package Util;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;



//工具类  166
public class Pkipair {

    //生成签名   166
    public String signMsg( String signMsg) {

        String base64 = "";
        try {

            KeyStore ks = KeyStore.getInstance("PKCS12");

            //商户私钥文件
            String file = Pkipair.class.getResource("10012140356.pfx").getPath().replaceAll("%20", " ");
            System.out.println(file);

            FileInputStream ksfis = new FileInputStream(file);

            BufferedInputStream ksbufin = new BufferedInputStream(ksfis);

            char[] keyPwd = "123456".toCharArray();
            //char[] keyPwd = "YaoJiaNiLOVE999Year".toCharArray();
            ks.load(ksbufin, keyPwd);

            PrivateKey priK = (PrivateKey) ks.getKey("test-alias", keyPwd);
            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initSign(priK);
            signature.update(signMsg.getBytes("utf-8"));
            sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
            base64 = encoder.encode(signature.sign());

        } catch(FileNotFoundException e){
            System.out.println("123");
        }catch (Exception ex) {
            ex.printStackTrace();
        }
        System.out.println("test = "+base64);
        return base64;
    }
    
    //验签得方法  166
    public boolean enCodeByCer( String val, String msg) {
        boolean flag = false;
        try {
            
            //快钱得公钥文件
            String file = Pkipair.class.getResource("CFCA_sandbox.cer").toURI().getPath();//99bill[1].cert.rsa.20140803.cer
            System.out.println(file);                       //  99bill.cert.rsa.20140803.cer
            FileInputStream inStream = new FileInputStream(file);

            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            X509Certificate cert = (X509Certificate) cf.generateCertificate(inStream);

            PublicKey pk = cert.getPublicKey();

            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initVerify(pk);
            signature.update(val.getBytes());

            sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
            System.out.println(new String(decoder.decodeBuffer(msg)));
            flag = signature.verify(decoder.decodeBuffer(msg));
            System.out.println(flag);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("no");
        }
        return flag;
    }

}

2.3 拷贝私钥文件  166

资源在E:\java学习\盈利宝\资料\资料\10-快钱支付\人民币网关\DEMO\JAVA\人民币网关支付\rmb\FI\src\Util

支付功能_maven_13

支付功能_java_14

2.4 依赖  166

kq-demo

pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.bjpowernode</groupId>
  <artifactId>kq-demo</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>kq-demo Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <!--资源插件-->
    <resources>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.pfx</include>
        </includes>
      </resource>
    </resources>
  </build>
</project>

2.5 配置tomcat  167

支付功能_java_15

支付功能_maven_16

支付功能_java_17

支付功能_java_18

支付功能_maven_19

支付功能_maven_20

直接启动tomcat

支付功能_maven_21

启动成功

支付功能_java_22

浏览器访问http://localhost:8080/kq/index.jsp

支付功能_maven_23

支付功能_maven_24

点击提交

支付功能_spring_25

支付功能_spring_26

支付功能_spring_27

3. 测试支付跳转到页面167

3.1 新建一个模块

支付功能_spring_28

支付功能_spring_29

支付功能_spring_30

支付功能_maven_31

3.2 依赖  167

pom.xml

micr-pay

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<!--自己的父项目-->
	<parent>
		<groupId>com.bjpowernode</groupId>
		<artifactId>micr-parent</artifactId>
		<version>1.0.0</version>
		<relativePath/>
	</parent>

	<artifactId>micr-pay</artifactId>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>

		<!--dubbo公共项目依赖-->
		<dependency>
			<groupId>com.bjpowernode</groupId>
			<artifactId>micr-api</artifactId>
			<version>1.0.0</version>
		</dependency>

		<!--dubbo起步依赖-->
		<dependency>
			<groupId>org.apache.dubbo</groupId>
			<artifactId>dubbo-spring-boot-starter</artifactId>
		</dependency>

		<!--zookeeper起步依赖-->
		<dependency>
			<groupId>org.apache.dubbo</groupId>
			<artifactId>dubbo-dependencies-zookeeper</artifactId>
			<type>pom</type>
		</dependency>

		<dependency>
			<groupId>com.bjpowernode</groupId>
			<artifactId>micr-common</artifactId>
			<version>1.0.0</version>
			<scope>compile</scope>
		</dependency>

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

		<!--模板引擎依赖  169-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>

		<!--资源插件  170-->
		<resources>
			<resource>
				<directory>src/main/java</directory>
				<includes>
					<include>**/*.pfx</include>
				</includes>
			</resource>
		</resources>
		
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

改个名字

支付功能_java_32

3.3 配置文件  168

application.yml

micr-pay

server:
  port: 9000
  servlet:
    context-path: /pay

spring:
  thymeleaf:
    cache: false
  application:  #169
    name: micr-pay
dubbo: #169
  registry:
    address: zookeeper://localhost:2181
  scan:
    base-packages: com.bjpowernode.pay
  consumer:
    check: false
    timeout: 60000
    retries: 0

3.4 页面  168

micr-pay

kqForm.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>提交请求给快钱</h1>
    <form name="kqPay" action="https://sandbox.99bill.com/gateway/recvMerchantInfoAction.htm" method="get">
        <input type="hidden" name="inputCharset" value="<%=inputCharset%>" />
        <input type="hidden" name="pageUrl" value="<%=pageUrl%>" />
        <input type="hidden" name="bgUrl" value="<%=bgUrl%>" />
        <input type="hidden" name="version" value="<%=version%>" />
        <input type="hidden" name="language" value="<%=language%>" />
        <input type="hidden" name="signType" value="<%=signType%>" />
        <input type="hidden" name="signMsg" value="<%=signMsg%>" />
        <input type="hidden" name="merchantAcctId" value="<%=merchantAcctId%>" />
        <input type="hidden" name="payerName" value="<%=payerName%>" />
        <input type="hidden" name="payerContactType" value="<%=payerContactType%>" />
        <input type="hidden" name="payerContact" value="<%=payerContact%>" />
        <input type="hidden" name="payerIdType" value="<%=payerIdType%>" />
        <input type="hidden" name="payerId" value="<%=payerId%>" />
        <input type="hidden" name="payerIP" value="<%=payerIP%>" />
        <input type="hidden" name="orderId" value="<%=orderId%>" />
        <input type="hidden" name="orderAmount" value="<%=orderAmount%>" />
        <input type="hidden" name="orderTime" value="<%=orderTime%>" />
        <input type="hidden" name="orderTimestamp" value="<%=orderTimestamp%>" />
        <input type="hidden" name="productName" value="<%=productName%>" />
        <input type="hidden" name="productNum" value="<%=productNum%>" />
        <input type="hidden" name="productId" value="<%=productId%>" />
        <input type="hidden" name="productDesc" value="<%=productDesc%>" />
        <input type="hidden" name="ext1" value="<%=ext1%>" />
        <input type="hidden" name="ext2" value="<%=ext2%>" />
        <input type="hidden" name="payType" value="<%=payType%>" />
        <input type="hidden" name="bankId" value="<%=bankId%>" />
        <input type="hidden" name="redoFlag" value="<%=redoFlag%>" />
        <input type="hidden" name="pid" value="<%=pid%>" />

        <input type="submit" name="submit" value="提交到快钱">
    </form>
</body>
</html>

error.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>请求错误</h1>
</body>
</html>

3.4 控制类controller  168

KuaiQianController

micr-pay

package com.bjpowernode.pay.controller;

import org.apache.catalina.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.Resource;
import java.math.BigDecimal;

//支付功能   168
@Controller
@RequestMapping("/kq")
public class KuaiQianController {

    /*接收来自vue项目的支付充值请求   168*/
    @GetMapping("/rece/recharge")
    public String receFrontRechargeKQ(Integer uid,
                                      BigDecimal rechargeMoney){
        //默认是错误视图
        String view="err";
        if(uid != null && uid > 0 &&
                rechargeMoney != null && rechargeMoney.doubleValue() > 0 ){

        //提交支付请求给快钱的form页面(thymeleaf)   168
        view  = "kqForm";


        }

        return view;

    }
}

 小测一下  168

看看能不能跳转到页面

只启动micr-pay

浏览器输入http://localhost:9000/pay/kq/rece/recharge?uid=28&rechargeMoney=0.01

成功没问题

支付功能_maven_33

4. 为支付表单生成参数   169

4.1 业务实现类   169

4.1.1 工具类   170

micr-pay

支付功能_maven_34

Pkipair
package com.bjpowernode.util;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;


//工具类  166
public class Pkipair {

    //生成签名   166
    public String signMsg( String signMsg) {

        String base64 = "";
        try {

            KeyStore ks = KeyStore.getInstance("PKCS12");

            //商户私钥文件,改进此方法使之可以读到中文路径
            String filePath = Pkipair.class.getResource("10012140356.pfx").getPath().replaceAll("%20", " ");

            // 将编码后的路径进行解码
            String decodedPath = URLDecoder.decode(filePath, "UTF-8");

            // 替换路径中的 "%20" 为实际的空格字符
            String file = decodedPath.replaceAll("%20", " ");

            // 输出解码后的路径
            System.out.println("文件="+file);

            FileInputStream ksfis = new FileInputStream(file);

            BufferedInputStream ksbufin = new BufferedInputStream(ksfis);

            char[] keyPwd = "123456".toCharArray();

            ks.load(ksbufin, keyPwd);

            PrivateKey priK = (PrivateKey) ks.getKey("test-alias", keyPwd);
            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initSign(priK);
            signature.update(signMsg.getBytes("utf-8"));
            sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
            base64 = encoder.encode(signature.sign());

        } catch(FileNotFoundException e){
            e.printStackTrace();
        }catch (Exception ex) {
            ex.printStackTrace();
        }

        return base64;
    }

    //验签得方法  166
    public boolean enCodeByCer( String val, String msg) {
        boolean flag = false;
        try {

            //快钱得公钥文件
            //修改此方法使之可以读到中文路径
            String filePath = Pkipair.class.getResource("99bill[1].cert.rsa.20140803.cer").toURI().getPath();

            // 解码路径中的中文字符
            String file = URLDecoder.decode(filePath, StandardCharsets.UTF_8.toString());

            System.out.println("文件路径="+file);

            FileInputStream inStream = new FileInputStream(file);

            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            X509Certificate cert = (X509Certificate) cf.generateCertificate(inStream);

            PublicKey pk = cert.getPublicKey();

            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initVerify(pk);
            signature.update(val.getBytes());

            sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
            System.out.println(new String(decoder.decodeBuffer(msg)));
            flag = signature.verify(decoder.decodeBuffer(msg));
            System.out.println(flag);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("no");
        }
        return flag;
    }

}

4.1.2 获取用户信息   169

micr-pay

KuaiQianService
package com.bjpowernode.pay.service;

import com.bjpowernode.api.model.User;
import com.bjpowernode.api.service.UserService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;

//支付业务实现类   169
@Service
public class KuaiQianService {
    
    @DubboReference(interfaceClass = UserService.class,version = "1.0")
    private UserService userService;
    
    //获取用户信息  169
    public User queryUser(Integer uid){
        User user = userService.queryById(uid);
        return user;
    }
}

4.1.3 生成快钱支付接口的数据参数   170

配置文件application.yml  171

支付功能_spring_35

redis: #171
    host: localhost
    port: 6379

注入StringRedisTemplate模板类

支付功能_maven_36

redis常量类  171

支付功能_maven_37

//redis自增   171
    public static final String KEY_RECHARGE_ORDERID = "RECHARGE:ORDERID:SEQ";
消费者实现类KuaiQianService   170-171

micr-pay

//创建快钱支付接口需要的请求参数  170
    //生成快钱支付接口的数据参数  Map是发送给快钱的所有请求参数 170
    public Map<String,String> generateFormData(Integer uid,String phone, BigDecimal rechargeMoney) {

        Map<String,String> data = new HashMap<>();

        //人民币网关账号,该账号为11位人民币网关商户编号+01,该参数必填。
        String merchantAcctId = "1001214035601";//
        //编码方式,1代表 UTF-8; 2 代表 GBK; 3代表 GB2312 默认为1,该参数必填。
        String inputCharset = "1";
        //接收支付结果的页面地址,该参数一般置为空即可。
        String pageUrl = "";
        //服务器接收支付结果的后台地址,该参数务必填写,不能为空。
        String bgUrl = "http://localhost:9000/pay/kq/rece/notify";
        //网关版本,固定值:v2.0,该参数必填。
        String version =  "v2.0";
        //语言种类,1代表中文显示,2代表英文显示。默认为1,该参数必填。
        String language =  "1";
        //签名类型,该值为4,代表PKI加密方式,该参数必填。
        String signType =  "4";
        //支付人姓名,可以为空。
        String payerName= "";
        //支付人联系类型,1 代表电子邮件方式;2 代表手机联系方式。可以为空。
        String payerContactType =  "2";
        //支付人联系方式,与payerContactType设置对应,payerContactType为1,则填写邮箱地址;payerContactType为2,则填写手机号码。可以为空。
        String payerContact =  phone;
        //指定付款人,可以为空
        String payerIdType =  "3";
        //付款人标识,可以为空
        String payerId =  String.valueOf(uid);
        //付款人IP,可以为空
        String payerIP =  "";
        //商户订单号,以下采用时间来定义订单号,商户可以根据自己订单号的定义规则来定义该值,不能为空。
        String orderId = "KQ"+generateOrderId();

        //订单金额,金额以“分”为单位,商户测试以1分测试即可,切勿以大金额测试。该参数必填。 171
        //stripTrailingZeros 去掉小数点后面得00.01 * 100 == 1.00  ->1
        //由于结果是 科学计数法  1 * 10^7  toPlainString 将科学计数法转为数字 100000*100 = 10000000 ,
        String orderAmount = rechargeMoney.multiply(new BigDecimal("100")).stripTrailingZeros().toPlainString();

        //订单提交时间,格式:yyyyMMddHHmmss,如:20071117020101,不能为空。
        String orderTime = new java.text.SimpleDateFormat("yyyyMMddHHmmss").format(new java.util.Date());
        //快钱时间戳,格式:yyyyMMddHHmmss,如:20071117020101, 可以为空
        String orderTimestamp = orderTime;
        //商品名称,可以为空。
        String productName= "智选理财产品";
        //商品数量,可以为空。
        String productNum = "1";
        //商品代码,可以为空。
        String productId = "10000";
        //商品描述,可以为空。
        String productDesc = "购买产品";
        //扩展字段1,商户可以传递自己需要的参数,支付完快钱会原值返回,可以为空。
        String ext1 = "";
        //扩展自段2,商户可以传递自己需要的参数,支付完快钱会原值返回,可以为空。
        String ext2 = "";
        //支付方式,一般为00,代表所有的支付方式。如果是银行直连商户,该值为10-1或10-2,必填。
        String payType = "00";
        //银行代码,如果payType为00,该值可以为空;如果payType为10-1或10-2,该值必须填写,具体请参考银行列表。
        String bankId = "";
        //同一订单禁止重复提交标志,实物购物车填1,虚拟产品用0。1代表只能提交一次,0代表在支付不成功情况下可以再提交。可为空。
        String redoFlag = "0";
        //快钱合作伙伴的帐户号,即商户编号,可为空。
        String pid = "";

        // signMsg 签名字符串 不可空,生成加密签名串
        String signMsgVal = "";
        signMsgVal = appendParam(signMsgVal, "inputCharset", inputCharset,data);
        signMsgVal = appendParam(signMsgVal, "pageUrl", pageUrl,data);
        signMsgVal = appendParam(signMsgVal, "bgUrl", bgUrl,data);
        signMsgVal = appendParam(signMsgVal, "version", version,data);
        signMsgVal = appendParam(signMsgVal, "language", language,data);
        signMsgVal = appendParam(signMsgVal, "signType", signType,data);
        signMsgVal = appendParam(signMsgVal, "merchantAcctId",merchantAcctId,data);
        signMsgVal = appendParam(signMsgVal, "payerName", payerName,data);
        signMsgVal = appendParam(signMsgVal, "payerContactType",payerContactType,data);
        signMsgVal = appendParam(signMsgVal, "payerContact", payerContact,data);
        signMsgVal = appendParam(signMsgVal, "payerIdType", payerIdType,data);
        signMsgVal = appendParam(signMsgVal, "payerId", payerId,data);
        signMsgVal = appendParam(signMsgVal, "payerIP", payerIP,data);
        signMsgVal = appendParam(signMsgVal, "orderId", orderId,data);
        signMsgVal = appendParam(signMsgVal, "orderAmount", orderAmount,data);
        signMsgVal = appendParam(signMsgVal, "orderTime", orderTime,data);
        signMsgVal = appendParam(signMsgVal, "orderTimestamp", orderTimestamp,data);
        signMsgVal = appendParam(signMsgVal, "productName", productName,data);
        signMsgVal = appendParam(signMsgVal, "productNum", productNum,data);
        signMsgVal = appendParam(signMsgVal, "productId", productId,data);
        signMsgVal = appendParam(signMsgVal, "productDesc", productDesc,data);
        signMsgVal = appendParam(signMsgVal, "ext1", ext1,data);
        signMsgVal = appendParam(signMsgVal, "ext2", ext2,data);
        signMsgVal = appendParam(signMsgVal, "payType", payType,data);
        signMsgVal = appendParam(signMsgVal, "bankId", bankId,data);
        signMsgVal = appendParam(signMsgVal, "redoFlag", redoFlag,data);
        signMsgVal = appendParam(signMsgVal, "pid", pid,data);

        System.out.println(signMsgVal);

        Pkipair pki = new Pkipair();
        //生成签名串  171
        String signMsg = pki.signMsg(signMsgVal);

        //需要signMsg
        data.put("signMsg",signMsg);

        return data;

    }

    /**************辅助工具方法   170***********************************/
    private String appendParam(String returns, String paramId, String paramValue,Map<String,String> data) {
        if (returns != "") {
            if (paramValue != "" && paramValue != null) {

                returns += "&" + paramId + "=" + paramValue;
            }

        } else {

            if (paramValue != "" && paramValue != null) {
                returns = paramId + "=" + paramValue;
            }
        }
        //如果data不等于空说明我传了这个参数  171
        if( data != null ){
            data.put(paramId,paramValue);
        }

        return returns;
    }

    //生成orderId  171
    private String generateOrderId(){
        //唯一值。1. 使用数据库的自增主键
        //       2. 使用redis的自增
        // orderId = 时间戳 +  redis的自增
        String key = RedisKey.KEY_RECHARGE_ORDERID;
        //redis自增increment
        Long incr = stringRedisTemplate.boundValueOps(key).increment();

        //实例格式化,保证在毫秒间也不会重复
        String orderId
                = DateFormatUtils.format(new Date(),"yyyyMMddHHmmssSSS") + incr;
        return orderId;
    }

4.2 表单页面  172

加上thymeleaf表达式

micr-pay

kqForm.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <form name="kqPay" action="https://sandbox.99bill.com/gateway/recvMerchantInfoAction.htm" method="get">
        <input type="hidden" name="inputCharset" th:value="${inputCharset}" />
        <input type="hidden" name="pageUrl" th:value="${pageUrl}" />
        <input type="hidden" name="bgUrl" th:value="${bgUrl}" />
        <input type="hidden" name="version" th:value="${version}" />
        <input type="hidden" name="language" th:value="${language}" />
        <input type="hidden" name="signType" th:value="${signType}" />
        <input type="hidden" name="signMsg" th:value="${signMsg}" />
        <input type="hidden" name="merchantAcctId" th:value="${merchantAcctId}" />
        <input type="hidden" name="payerName" th:value="${payerName}" />
        <input type="hidden" name="payerContactType" th:value="${payerContactType}" />
        <input type="hidden" name="payerContact" th:value="${payerContact}" />
        <input type="hidden" name="payerIdType" th:value="${payerIdType}" />
        <input type="hidden" name="payerId" th:value="${payerId}" />
        <input type="hidden" name="payerIP" th:value="${payerIP}" />
        <input type="hidden" name="orderId" th:value="${orderId}" />
        <input type="hidden" name="orderAmount" th:value="${orderAmount}" />
        <input type="hidden" name="orderTime" th:value="${orderTime}" />
        <input type="hidden" name="orderTimestamp" th:value="${orderTimestamp}" />
        <input type="hidden" name="productName" th:value="${productName}" />
        <input type="hidden" name="productNum" th:value="${productNum}" />
        <input type="hidden" name="productId" th:value="${productId}" />
        <input type="hidden" name="productDesc" th:value="${productDesc}" />
        <input type="hidden" name="ext1" th:value="${ext1}" />
        <input type="hidden" name="ext2" th:value="${ext2}" />
        <input type="hidden" name="payType" th:value="${payType}" />
        <input type="hidden" name="bankId" th:value="${bankId}" />
        <input type="hidden" name="redoFlag" th:value="${redoFlag}" />
        <input type="hidden" name="pid" th:value="${pid}" />
    
         <input type="submit" name="submit" th:value="提交到快钱">
    </form>
</body>
</html>

4.3 控制类controller   169

KuaiQianController

micr-pay

package com.bjpowernode.pay.controller;

import com.bjpowernode.api.model.User;
import com.bjpowernode.pay.service.KuaiQianService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Map;

//支付功能   168
@Controller
@RequestMapping("/kq")
public class KuaiQianController {

    @Resource
    private KuaiQianService kQService;

    /*接收来自vue项目的支付充值请求   168*/
    @GetMapping("/rece/recharge")
    public String receFrontRechargeKQ(Integer uid,
                                      BigDecimal rechargeMoney,
                                      Model model){
        //默认是错误视图
        String view="err";
        if(uid != null && uid > 0 &&
                rechargeMoney != null && rechargeMoney.doubleValue() > 0 ){

            //1. 检查uid是否是有效用户  169
            User user = kQService.queryUser(uid);
            if(user != null){
                //创建快钱支付接口需要的请求参数
                Map<String,String> data = kQService.generateFormData(uid,user.getPhone(),rechargeMoney);
                //将data数据放入到request中 ,
                // 然后我们的表单kqForm就可以在request中取数据了 171
                model.addAllAttributes(data);

                //提交支付请求给快钱的form页面(thymeleaf)   168
                view  = "kqForm";
            }


        }

        return view;

    }

    //接收快钱给商家的支付结果 , 快钱以get方式,发送请求给商家  170
    @GetMapping("/rece/notify")
    @ResponseBody
    public String payResultNotify(HttpServletRequest request){
        return "ok";
    }

}

4.4 测试   172

启动micr-dataservice

debug启动micr-pay

浏览器输入http://localhost:9000/pay/kq/rece/recharge?uid=28&rechargeMoney=0.01

点击按钮跳转到快钱得支付页面

支付功能_spring_38

看看控制台输出签名串和私钥文件路径(中文我们做了处理)

如下

//商户私钥文件,改进此方法使之可以读到中文路径
            String filePath = Pkipair.class.getResource("10012140356.pfx").getPath().replaceAll("%20", " ");

            // 将编码后的路径进行解码
            String decodedPath = URLDecoder.decode(filePath, "UTF-8");

            // 替换路径中的 "%20" 为实际的空格字符
            String file = decodedPath.replaceAll("%20", " ");

            // 输出解码后的路径
            System.out.println("文件="+file);

            FileInputStream ksfis = new FileInputStream(file);

            BufferedInputStream ksbufin = new BufferedInputStream(ksfis);

支付功能_java_39

看看页面,成功拿到数据参数

支付功能_java_40

成功跳转

支付功能_maven_41

5. 创建充值记录和把订单号存放到redis  172

5.1 业务实现类   172

5.1.1 定义常量类   172

micr-common

支付功能_maven_42

//充值状态  172
    public static final int RECHARGE_STATUS_PROCESSING = 0; //充值中
    public static final int RECHARGE_STATUS_SUCCESS = 1; //充值成功
    public static final int RECHARGE_STATUS_FAIL = 2; //充值失败

5.1.2 业务接口   172

RechargeService

micr-api

//添加充值记录   172
    int addRechargeRecord(RechargeRecord record);

5.1.3 业务实现类   172

micr-dataservice

RechargeServiceImpl

//添加充值记录   172
    @Override
    public int addRechargeRecord(RechargeRecord record) {
        
        return rechargeMapper.insertSelective(record);
    }

创建充值记录实现类KuaiQianService    172

micr-pay

//创建充值记录   172
    public boolean addRecharge(Integer uid,
                                BigDecimal rechargeMoney,
                                String orderId) {
        RechargeRecord record = new RechargeRecord();
        record.setChannel("KQ");
        record.setRechargeDesc("快钱充值");
        record.setRechargeMoney(rechargeMoney);
        record.setRechargeNo(orderId);
        record.setRechargeStatus(YLBConstant.RECHARGE_STATUS_PROCESSING);
        record.setRechargeTime(new Date());
        record.setUid(uid);
        int rows = rechargeService.addRechargeRecord(record);

        return rows > 0;
    }

5.2  把订单号存放到redis   172

5.2.1 常量类  172

micr-common

支付功能_spring_43

//orderIds   172
    public static final String KEY_ORDERID_SET = "RECHARGE:ORDERID:SET";

5.2.2 业务实现类  172

KuaiQianService

micr-pay

//把订单号存放到redis   172
    public void addOrderIdToRedis(String orderId) {
        String key  = RedisKey.KEY_ORDERID_SET;
        stringRedisTemplate.boundZSetOps(key).add(orderId, new Date().getTime());
    }

5.3 控制类controller   172

KuaiQianController

micr-pay

支付功能_spring_44

//创建充值记录   172
kQService.addRecharge(uid,rechargeMoney,data.get("orderId"));

//把订单号存放到redis   172
kQService.addOrderIdToRedis(data.get("orderId"));

5.4 测试  173

启动micr-dataservice

启动micr-pay

浏览器输入http://localhost:9000/pay/kq/rece/recharge?uid=28&rechargeMoney=0.01

支付功能_spring_45

看看数据库充值表

支付功能_maven_46

看看redis中成功存入订单号

支付功能_maven_47

上一篇:学习aop以及nginx
下一篇:没有了
网友评论