支付宝H5

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.17</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.joko</groupId>
    <artifactId>H5zfbPay</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>H5zfbPay</name>
    <description>H5zfbPay</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>4.34.0.ALL</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.9</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

application.yml

aliconfig: #沙箱环境
  APPID: 9021000127602831
    #商户私钥(应用私钥),您的PKCS8格式RSA2私钥
  PRIVATE_KEY: MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCVhcRpW6bLwxhQV/v34iPIrajQKyOxXqkGlAFdMk3f5mxbWIdvJOx0d+PMByaFtiCOdWSOy2T8EWFqlYKnUzv3p3WovTgfLb2smkdTJbjaWN3MhqlQVzMfCxRK0Ax4mw308HM5YQe44VG7T2xg6mcT2lPhol9caHvVd408iVxZ7QG+fnm+imq+No3InPx8NNKmf0cgcwYmJQ3ovjY8aU7RrhiQpncKUbz7CTTh4oXrDMOP7pDCHAOuWuc8QPLWbKPubw/awX0o3QY0HYWpxZ2963mZRCL84KdTVWwWpG2CYdsEMlv36j4KT1nhoZQ5ONfMDbtPIFtT9x1UEWXqSJe5AgMBAAECggEAYjPX+yaR1vQMrQAMYhLpU60S2Z3rtFuqgcKFXtNiKDKrahcr5EiI8DmpqF/t4hXrLgVWBR769T7pD1qg1AqrsQ0QDsIv8PJWx90QCUEWNnn1OpYa78RFtBbPvg8EkdWshfnCg6YBr2B1EKOqV8C78GMNgnzlSsjoxBvf7Cl/OSOYQAKJ9Aur1gbQ3RGyM0zEviHzsztB06eRAa2896kDggvx6JS7+BVpZIcPAkeGxn6Fb0TJ65A2C0i7qPcC69e4qVwKEzCJHyMO2WpnFct7/W/Pw4icMjfMScQspTcpmETCcMioxcF0yqhQ1+fsZFXoRXas0wdkTaDFmCqjB8oj7QKBgQDeuyMgkYvGQGrltMi2UEdZFCySbVSIv3CBt9Z1VMrLbRM8CzUmkKuxBB+s55zcKk6fNnZ7wUgOHuF7g+aIFB5SpTXm2/CMfVg5lYejBXq1MvCOzZ28JeEMSCHkPLlG+RP35kIrzvRKAKHhZtm20gIynLMRBUAZwxH9UFAK8XGPkwKBgQCr20J/7rJJ6YHv++GNqTsJWRd5rNnEAsvPeuTrLXGE5DNl9DMqTIvQtBza8Z2CCPxai3NsiwGjf9DVBexH+QN2+BtG8JwcubJVcJj8qTzR5qywHveFlvMNpkZUEdOa+AJ5Xc7rk5GuMG/mEVOF8vF1uK1gPM1RMi4ThnN9LgQTAwKBgFQ2d1qaDTohIwnE59qe0cspaIzYj4zArT4ujwR/0clGbW5XYno5WuEsCPnr/I/14xIpmnTCKIdGP8TeoywyRyDCXHX0FKhZwCDNm6IUsUePggrMTWZVABkPsNjF6Nuf01/4jG5Z6l2MjahWpdyM3M3cF4xI6uqSqduYIRtyHJjHAoGASoEX51aYPKrbBitwsXV4fqj9IGbrUarUqPJiZAKjgDVegwjHVcMxqh0rlU/CNSmoHajvNVNeNn+nDXMv6FPwSJdvW+XcCCgJRDk4WfEUyPr0SrZiIKw8WuKHAtNnpXt3tx4QItkrAxVErb09NIkKXTrfDyXM7TKP/y7+yno0kfkCgYA29rZa3Uv5l8JQM3W9ng83K7z60sszeMQ38JkrxRy8I6gNeMSY1U5sAYfGDhNRDLGkm/y1iLr1IwEolPQeRMMTP3PxkgKCAWmxnOPAlXEjIXStACiWzdh3GaPUIB0yzfi7ic5Tm0VbAINdNgcpiirBJHWDgoUW9woldkQwSUbGYw==
    #商户公钥(应用公钥)
  PUBLIC_KEY: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlYXEaVumy8MYUFf79+IjyK2o0CsjsV6pBpQBXTJN3+ZsW1iHbyTsdHfjzAcmhbYgjnVkjstk/BFhapWCp1M796d1qL04Hy29rJpHUyW42ljdzIapUFczHwsUStAMeJsN9PBzOWEHuOFRu09sYOpnE9pT4aJfXGh71XeNPIlcWe0Bvn55vopqvjaNyJz8fDTSpn9HIHMGJiUN6L42PGlO0a4YkKZ3ClG8+wk04eKF6wzDj+6QwhwDrlrnPEDy1myj7m8P2sF9KN0GNB2FqcWdvet5mUQi/OCnU1VsFqRtgmHbBDJb9+o+Ck9Z4aGUOTjXzA27TyBbU/cdVBFl6kiXuQIDAQAB
    #支付宝公钥,对应APPID下的支付宝公钥。
  ALIPUBLIC_KEY: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkJkjJYAwwlQyLrbMUaZdct76kE+npfGalua5ux/5WEszMWdDv/LtXC2ey5/7Mr7Ni8A5LRrsZcxfhD09twMpn1HbPM+FKnGVms8U+5gdzWODeVrZTidDaHHayF+GkxSAXlhdmgrTaq6byGc58DCPkczlCArFl4fDb/RUvYPWqiz+BGWZQWxgL/XqBIOIU53vtnL9O19VrMNJa8DXsjMxfWFlyDPolnw+B9G8QVXrp3nnz0qf5upXQVUulBgCzHau45H0alMono3oQFMpHCBuXmjyju3gV2JGzm2ep0kDBOGLu4TjeMC0tHyFsIU0FavyYT66GnIckc4QhljebXtbhwIDAQAB
    #沙箱账号:lvthgb5393@sandbox.com   沙箱登录/支付密码:111111
    #服务器异步通知页面路径
  NOTIFY_URL: http://localhost:8080//notify_payResult
    #页面跳转同步通知页面路径
  RETURN_YRL:
    #用户付款中途退出返回商户网站的地址
  QUIT_URL:
    #签名方式
  SIGN_TYPE: RSA2
    #字符编码格式
  CHARSET: utf-8
    #支付宝网关(注意这是沙箱的网关,正式的网关为:https://openapi.alipay.com/gateway.do)
  GATEWAY: https://openapi-sandbox.dl.alipaydev.com/gateway.do
    #角色身份
  PID: 2088721012173356
    #过期时间
  TIMEOUT: 60m

H5zfbPayApplication

package com.spring;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class H5zfbPayApplication {
    public static void main(String[] args) {
        SpringApplication.run(H5zfbPayApplication.class, args);
    }
}

config.AlipayProperties

package com.spring.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix="aliconfig")
public class AlipayProperties {
    public  String APPID;
    public  String PRIVATE_KEY;
    public  String PUBLIC_KEY;
    public  String ALIPUBLIC_KEY;
    public  String NOTIFY_URL;
    public  String RETURN_URL;
    public  String QUIT_URL;
    public  String SIGN_TYPE;
    public  String CHARSET;
    public  String GATEWAY;
    public  String PID;
    public  String TIMEOUT;
}

controller.H5payController

package com.spring.controller;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.internal.util.AlipayUtils;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeWapPayResponse;
import com.spring.util.AlipayUtil;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import static com.spring.util.AlipayUtil.staticAliPayProperties;
@Controller
public class H5payController {
    //前端传入商品名、支付金额,订单号由系统生成,创建订单
    //lvthgb5393@sandbox.com
    @GetMapping("/createOrder/{subject}/{amount}")
    @ResponseBody
    public String createOrder(@PathVariable String amount, @PathVariable String subject) throws AlipayApiException {
        AlipayClient alipayClient= AlipayUtil.alipayClient;
        AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
        //异步接收地址,仅支持http/https,公网可访问
        request.setNotifyUrl(staticAliPayProperties.NOTIFY_URL);
        //同步跳转地址,仅支持http/https
        request.setReturnUrl(staticAliPayProperties.RETURN_URL);
        /******************必传参数***************/
        JSONObject bizContent = new JSONObject();
        //商户订单号,商家自定义,保持唯一性
        bizContent.put("out_trade_no",AlipayUtil.getOut_trade_no());
        //支付金额,最小值0.01元
        bizContent.put("total_amount", amount);
        //订单标题,不可使用特殊符号
        bizContent.put("subject", subject);
        /******可选参数******/
        //手机网站支付默认传值FAST_INSTANT_TRADE_PAY
        bizContent.put("product_code", "QUICK_WAP_WAY");
        //bizContent.put("time_expire", "2022-08-01 22:00:00");
         商品明细信息,按需传入
        JSONArray goodsDetail = new JSONArray();
        JSONObject goods1 = new JSONObject();
        goods1.put("goods_id", "1001");
        goods1.put("goods_name", "阿萨姆奶茶");
        //goods1.put("quantity", 10);
        goods1.put("price", 5);
        goodsDetail.add(goods1);
        bizContent.put("goods_detail", goodsDetail);
         扩展信息,按需传入
        //JSONObject extendParams = new JSONObject();
        //extendParams.put("sys_service_provider_id", "2088511833207846");
        //bizContent.put("extend_params", extendParams);
        request.setBizContent(bizContent.toString());
        AlipayTradeWapPayResponse response = alipayClient.pageExecute(request);
        if(response.isSuccess()){
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
        }
        String form = response.getBody();
        System.out.println("*********************\n返回结果为:"+form);
        return form;
    }
    //支付结果,异步通知
    @RequestMapping(value = "/notify_payResult",method = RequestMethod.POST)
    public void notify_payResult(HttpServletResponse response, HttpServletRequest request) throws AlipayApiException, IOException {
        //将异步通知中收到的所有参数都存放到map中
        Map paramsMap =new HashMap<>();
        paramsMap= AlipayUtil.getParameterMap(request);
        //调用SDK验证签名
        boolean signVerified = AlipaySignature.rsaCheckV1(paramsMap, staticAliPayProperties.ALIPUBLIC_KEY, staticAliPayProperties.CHARSET, staticAliPayProperties.SIGN_TYPE);
        if(signVerified){
        // TODO 验签成功后,按照支付结果异步通知中的描述,对支付结果中的业务内容进行二次校验,校验成功后在response中返回success并继续商户自身业务处理,校验失败返回failure
            response.getWriter().write("success");
            response.getWriter().close();
            //处理业务逻辑,待续
        }else{
        // TODO 验签失败则记录异常日志,并在response中返回failure.
            response.getWriter().write("success");
            response.getWriter().close();
        }
    }
    //通过商家网站唯一订单号 out_trade_no 或支付宝交易号 trade_no 查询对应订单支付情况。
    @GetMapping("/queryOrder/{out_trade_no}")
    @ResponseBody
    public String queryOrder(@PathVariable String out_trade_no) throws AlipayApiException {
        AlipayClient alipayClient= AlipayUtil.alipayClient;
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", out_trade_no);
//bizContent.put("trade_no", "2014112611001004680073956707");
        request.setBizContent(bizContent.toString());
        AlipayTradeQueryResponse response = alipayClient.execute(request);
        if(response.isSuccess()){
            System.out.println("查询订单--->调用成功");
        } else {
            System.out.println("查询订单--->调用失败");
        }
        return response.getBody();
    }
    //退款,待续
    @GetMapping("/createRefund/{out_trade_no}")
    @ResponseBody
    public String createRefund(@PathVariable String out_trade_no){
        return "";
    }
}

util.AlipayUtil

package com.spring.util;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.service.schema.util.StringUtil;
import com.spring.config.AlipayProperties;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@Component
public class AlipayUtil {
    @Autowired
    private AlipayProperties aliPayProperties ;
    /*
    @Autowired 注解不能作用于静态变量,所以借助静态变量 staticAliPayProperties 作为过渡,
    并在初始化的方法里面,让 staticAliPayProperties = aliPayProperties;
    */
    public static AlipayProperties staticAliPayProperties;
    //alipayClient只需要初始化一次,后续调用不同的API都可以使用同一个alipayClient对象。
    public static AlipayClient alipayClient;
    /**
     * 初始化
     */
    @PostConstruct
    public void init() {
        staticAliPayProperties = aliPayProperties;
        alipayClient = new DefaultAlipayClient(staticAliPayProperties.getGATEWAY(), staticAliPayProperties.getAPPID(), staticAliPayProperties.getPRIVATE_KEY(), "json", staticAliPayProperties.getCHARSET(), staticAliPayProperties.getALIPUBLIC_KEY(), staticAliPayProperties.getSIGN_TYPE());
    }
    /**
     * 生成商户订单号(25位):时间(精确到毫秒)+3位随机数+5位用户id
     */
    public static synchronized  String getOut_trade_no() {
        //暂时以appid代替
        String userId=staticAliPayProperties.APPID;
        //时间(精确到毫秒)
        DateTimeFormatter ofPattern = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
        String localDate = LocalDateTime.now().format(ofPattern);
        //3位随机数
        String randomNumeric = RandomStringUtils.randomNumeric(3);
        //5位用户id
        int subStrLength = 5;
        int length = userId.length();
        String str;
        if (length >= subStrLength) {
            str = userId.substring(length - subStrLength, length);
        } else {
            str = String.format("%0" + subStrLength + "d", userId);
        }
        String orderNum = localDate + randomNumeric + str;
        System.out.println("订单号:{"+orderNum+"}");
        return orderNum;
    }
    /**
     * 从request中获得参数Map,并返回可读的Map
     *
     * @param request
     * @return
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static Map getParameterMap(HttpServletRequest request) {
        // 参数Map
        Map properties = request.getParameterMap();
        // 返回值Map
        Map returnMap = new HashMap();
        Iterator entries = properties.entrySet().iterator();
        Map.Entry entry;
        String name = "";
        String value = "";
        while (entries.hasNext()) {
            entry = (Map.Entry) entries.next();
            name = (String) entry.getKey();
            Object valueObj = entry.getValue();
            if(null == valueObj){
                value = "";
            }else if(valueObj instanceof String[]){
                String[] values = (String[])valueObj;
                for(int i=0;i<values.length;i++){
                    value = values[i] + ",";
                }
                value = value.substring(0, value.length()-1);
            }else{
                value = valueObj.toString();
            }
            returnMap.put(name, value);
        }
        return returnMap;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值