JSAPI实现H5页面微信支付

news2024/9/22 1:03:28

进入官网文档:> 微信支付官网文档 根据官网文档能够很详细的需要做的事

接下来,采用的是JSAPI的方式小程序嵌入H5页面中实现微信支付,直接拉起支付页面

一:需要在微信公众号平台和微信支付商家平台获取的配置的关键参数如下:

1,openid:需要实现微信登录才能获取

2,微信公众号绑定的appid

3,微信商家号绑定对应的appid的商家号id

4,商家号密钥

5,商家号拉起支付的授权目录

6,支付完成通知的回调地址:这个地址是后端自定义的回调接口地址

准备以上参数之后,开始写代码:根据官网文档编写

二:简单总结需要做的事儿

1,创建sdk客户端
.
2,构造请求的参数
.
3,封装前端需要的响应参数
.
4,前端获取参数,直接拉起支付界面
.
5,支付完成完成后,请求回调地址,处理结果
.
注意:这里签名的类型有两种md5和HMACSHA256需要注意一下这个地方,出错概率大

controller层如下 :
在这里插入图片描述

请求实体

@Data
@ApiModel("微信下单请求实体")
public class WxPayOrderDTO {

    @ApiModelProperty(value = "用户openid")
    @NotBlank(message = "openid不能未空")
    private String openId;

    @ApiModelProperty(value = "收费类型")
    @NotNull(message = "商品标识标识不能未空")
    private Integer type;

}

常量封装

public class WxPayConstant {

     // 回调地址
    public static final String  NOTIFY_URL = "https://gpt.xiaomon.com/api2/base/wx/callback";

    // 商家号密钥
    public static final String  API_KEY = "Tunda123Tunda123Tunda123Tunda123";

    // appid
    public static final String  APP_ID = "wx27599519b337b629";

    // 商家号id
    public static final String  PAY_MCH_ID = "1618043632";

}

serviceImpl层:

   /**
     * 微信JSAPI支付
     * @param payDTO
     * @return
     */
    public Map<String, String> wxPayForJSAPI(WxPayOrderDTO payDTO) {

            // 创建订单
            SaveOrderVO order = orderService.createOrder(payDTO);
        try {
            //创建sdk客户端
            WXPay wxPay = new WXPay(new WXPayConfigCustom());

            //构造请求的参数
            Map<String, String> data = new HashMap<>();
            data.put("openid",payDTO.getOpenId());
            data.put("body",order.getRemark()); // 商品描述
            // 金额处理一下
            BigDecimal fee = order.getFee().multiply(new BigDecimal(100));
            log.info("金额:{}",fee.setScale(0, BigDecimal.ROUND_DOWN).toString());
            data.put("total_fee", fee.setScale(0, BigDecimal.ROUND_DOWN).toString()); // 订单金额, 单位分
            data.put("nonce_str",WXPayUtil.generateNonceStr());// 随机字符串
            data.put("spbill_create_ip", AddressUtils.getIp()); // 下单ip
            log.info("微信下单ip->{}",AddressUtils.getIp());
            data.put("notify_url", WxPayConstant.NOTIFY_URL); // 订单结果通知, 微信主动回调此接口
            data.put("out_trade_no", order.getOrderNo()); // 订单唯一编号, 不允许重复
            data.put("trade_type", "JSAPI");  // 交易类型 MWEB--H5支付、JSAPI--小程序支付-类型不同则参数不同
            String sign = WXPayUtil.generateSignature(data, WxPayConstant.API_KEY, WXPayConstants.SignType.HMACSHA256);
            data.put("sign",sign);

            Map<String, String> map = wxPay.unifiedOrder(data);
            log.info("微信平台下订单情况->{}",map);
            String prepayId = map.get("prepay_id");
            if(null==prepayId){
                orderService.updateOrder(order.getOrderNo(),"", OrderStatusEnum.FAIL_PAY);
                throw new BusinessException("获取预支付id异常");
            }

            // 封装前端需要的响应参数
            Map<String, String> resultMap = new HashMap<String, String>();
            resultMap.put("appId", WxPayConstant.APP_ID);
            resultMap.put("timeStamp", String.valueOf(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli() / 1000));
            resultMap.put("nonceStr", WXPayUtil.generateNonceStr());
            resultMap.put("package", "prepay_id=" + prepayId);
            // 注意:下单默认的是h256方式,校验默认是MD5方式,前端默认采用MD5校验
            resultMap.put("signType", "MD5");

            // 将map按照ASCILL码排序
            Map<String, String> sortMap = new TreeMap<String,String>(resultMap);
            log.info("排序之后:{}",sortMap);

             sign = WXPayUtil.generateSignature(sortMap, WxPayConstant.API_KEY,WXPayConstants.SignType.HMACSHA256);

            resultMap.put("paySign", sign);
            resultMap.put("orderNo",order.getOrderNo());
            return resultMap;
        }catch (Exception e){
            orderService.updateOrder(order.getOrderNo(),"", OrderStatusEnum.FAIL_PAY);
            throw new BusinessException("微信支付下单异常,请重试");
        }
    }

微信回调

 /**
     * 微信回调
     * @param request
     * @return
     */
    @Override
    public String wxPayCallBack(HttpServletRequest request) {
        log.info("微信支付-成功回调");
        // 校验结果、XML
        Map<String, String> back = new HashMap();
        String result = "";
        try {
            InputStream inStream = request.getInputStream();
            ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
            }
            outSteam.close();
            inStream.close();
            result = new String(outSteam.toByteArray());
            //xml转map 微信SDK自带
            Map<String, String> map = WXPayUtil.xmlToMap(result);
            // 判断签名是否正确、记得指定加密方式,因为下单默认的是h256方式,校验默认是MD5方式
            if (WXPayUtil.isSignatureValid(map, WxPayConstant.API_KEY, WXPayConstants.SignType.HMACSHA256)) {
                back.put("return_code", "SUCCESS");
                if ("SUCCESS".equalsIgnoreCase(map.get("result_code")));{
                    log.info("支付成功,回调成功");
                    // 拿到订单号,修改订单状态
                    String orderNo = map.get("out_trade_no");
                    String  payTime = map.get("time_end");
                    orderService.updateOrder(orderNo, payTime,OrderStatusEnum.SUCESS_PAY);
                }
            } else {
                back.put("return_code", "FAIL");
                back.put("return_msg", "参数格式校验错误");
            }
            // WX响应格式是xml的字符串
            result  = WXPayUtil.mapToXml(back);
        } catch (Exception e) {
           throw new BusinessException("支付回调用异常");
        }finally {
            // 必须响应给WX服务器
            return result;
        }
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1080426.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MidJourney | AI绘画也有艺术

免费绘画&#xff0c;体验更多AI可关&注公&众&号&#xff1a;AI研究工厂

ICPC 2019-2020 North-Western Russia Regional Contest

A (codeforces.com) 这题在移动不被挡板挡住以及不超过边界的情况下&#xff0c;每次走的越多那么次数就越少 只要两个每次都走b-a步&#xff08;已经是不被挡板挡住走的最多了&#xff09;&#xff0c;就不用考虑被挡板挡住的情况&#xff0c;只用单独考虑了&#xff0c;如果…

算法通过村第十三关-术数|黄金笔记|数论问题

文章目录 前言辗转相除法素数和合数埃氏筛选法丑数问题总结 前言 提示&#xff1a;难过的人伤心的人、在生活里面对困境的人、即将抑郁的人、从外面很难看出异样&#xff0c;人的心里却可能有一些裂痕。只是人不会再表面裂开。 --栾颖新《那个苹果也很好》 数论是一个很重要的学…

Stable diffusion 用DeOldify给黑白照片、视频上色

老照片常常因为当时的技术限制而只有黑白版本。然而现代的 AI 技术,如 DeOldify,可以让这些照片重现色彩。 本教程将详细介绍如何使用 DeOldify 来给老照片上色。. 之前介绍过基于虚拟环境的 基于DeOldify的给黑白照片、视频上色,本次介绍对于新手比较友好的在Stable diff…

2023年中国非血管介入手术无源耗材发展现状、竞争格局及行业市场规模[图]

非血管介入手术是指通过人体自然腔道或通过人体的小切口接近病灶而无需进入血管系统的微创手术&#xff0c;内窥镜、有源医疗器械及无源耗材则是该手术中最常用的医疗器械。非血管介入手术无源耗材主要包括导丝、球囊导管、取石网篮、封堵导管及鞘管。 非血管介入手术无源耗材…

LeetCode【739】每日温度

题目&#xff1a; 思路&#xff1a; https://www.bilibili.com/video/BV1PJ411H7P7/?spm_id_from333.337.search-card.all.click&vd_source2f682a60feabf0f730ad09e0f980ce83 单调栈 思考&#xff1a; 解决栈类问题&#xff0c;思考入栈&#xff0c;出栈条件&#xff1b;…

vue设置页面超时15分钟自动退出登录

需求&#xff1a;用户登录后&#xff0c;如果长时间未操作页面这个时候需要自动退出登录回到登录页面。 注意点&#xff1a;这里我们如果把超时的时间放到浏览器里面存储&#xff0c;我们要放到本地存储里面localStorage里面 Vue设置长时间未操作登录以后自动到期返回登录页 …

重生奇迹MU玛雅宝石的获取方法

在打斗游戏中重生奇迹MU游戏最好玩&#xff0c;并且游戏里面有很多的宝石&#xff0c;比如玛雅宝石、灵魂宝石以及创造宝石等等&#xff0c;这些宝石的作用非常强大&#xff0c;玩家必须要懂得如何利用这些宝石。 那么是否了解玛雅宝石呢&#xff0c;玛雅宝石应该算是最经典的…

为什么选择虚拟展会展览?了解虚拟展会展览的应用领域

引言&#xff1a; 相较于传统的实体展览&#xff0c;虚拟展会展览具有吸引力和便捷性&#xff0c;能够在全球范围内进行宣传活动。这种创新形式不仅能够降低成本、扩大受众范围&#xff0c;还能够提供没有过的互动性和数据分析。 一&#xff0e;虚拟展会展览简介 虚拟展会展览…

TikTok变现的5个高效策略:打造成功创作者之路

短视频平台TikTok已经成为全球范围内最受欢迎的社交媒体之一&#xff0c;吸引了数亿用户。对于创作者而言&#xff0c;TikTok不仅是一个分享创意和娱乐的平台&#xff0c;还是一个潜在的收入来源。本文Nox聚星将和大家探讨TikTok的变现策略&#xff0c;揭示其中的关键秘诀和策略…

京东数据平台:2023年京东营养保健品市场销售数据分析

随着十一长假结束&#xff0c;市场端也开始了一系列的消费数据回顾和复盘。从现有数据表现来看&#xff0c;营养保健品市场的增长备受关注。 近日&#xff0c;京东消费及产业发展研究院与《经济日报》联合整合了相关数据。数据显示&#xff0c;2023年中秋福利采购季期间&#…

class类实现Serializable接口生成serialVersionUID

前言 我在class类实现了Serializable接口&#xff0c;发现把鼠标放在这个类名上&#xff0c;然后键盘输入altenter键没有生成serialVersionUID的提示 解决 找到Editor下边的Inspections&#xff0c;然后搜索UID&#xff0c;把如下截图中的勾选即可 效果 鼠标光标放在类名上&am…

C/C++之自定义类型(结构体,位段,联合体,枚举)详解

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言程序设计————KTV C语言小游戏 C语言进阶 C语言刷题 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力&#xff0c;一起奔赴大厂。 目录 个人主页&#xff1a;点我进入主页 …

使用 KubeSkoop exporter 监测和定位容器网络抖动问题

作者&#xff1a;遐宇、溪恒 本文是 8 月 17 日直播的文字稿整理&#xff0c;文末可观看直播回放。除去文章内容外&#xff0c;还包括针对实际网络问题的实战环节。 容器网络抖动问题发生频率低&#xff0c;时间短&#xff0c;是网络问题中最难定位和解决的问题之一。 不仅如…

Java基于SpringBoot的学生就业管理信息系统

文章目录 1. 简介2. 技术栈3. 总体设计4 系统设计4.1前台功能模块4.2后台功能模块4.2.1管理员功能 六 源码咨询 1. 简介 Java基于SpringBoot的学生就业管理信息系统&#xff0c;本次设计任务是要设计一个就业信息管理系统&#xff0c;通过这个系统能够满足就业信息管理功能。系…

【接口测试】如何在 Eolink Apilkit 中使用 cookie ?

什么是 Cookie &#xff1f; Cookie是一种在网站之间传递的小型文本文件&#xff0c;用于存储用户的个人信息和偏好设置。当您访问一个网站时&#xff0c;网站会将Cookie存储在您的浏览器中&#xff0c;并在您下次访问该网站时读取该Cookie。这样&#xff0c;网站可以记住您的…

【Spring AOP】Spring AOP 详解

Spring AOP 详解 一. 什么是 AOP二. AOP 组成切面&#xff08;Aspect&#xff09;连接点&#xff08;Join Point&#xff09;切点&#xff08;Pointcut&#xff09;通知&#xff08;Advice&#xff09; 三. Spring AOP 实现1. 添加 AOP 框架⽀持2. 定义切面和切点3. 定义相关通…

nginx windows安装部署,代理转发配置

一、安装 1、nginx官网下载 windows版本 nginx官网 下载后解压到本地 2、在nginx的配置文件是conf目录下的nginx.conf&#xff0c;默认配置的nginx监听的端口为80&#xff0c;如果本地电脑的80端口有被占用&#xff0c;如果本地80端口已经被使用则修改成其他端口。如下&…

【吴恩达深度学习】

第一周 1、修正线性单元ReLU 第二周、Logistic回归 1、样本矩阵X&#xff1a; 是一个m*nx的矩阵&#xff0c;表示m个样本&#xff08;一个竖列代表一个样本&#xff09;&#xff0c;每个样本有nx个特征。 2、标签矩阵Y&#xff1a;[y1,y2,y3,ym] m个训练样本分别对应的标签…

C++程序员必修第一课【C++基础课程】01:安装C++开发环境

1 本课主要内容&#xff1a; 了解 C 开发相关基础概念学会在 Windows10 上安装 Visual Studio 2019免费社区版新建第一个 "Hello World" C 程序&#xff0c;验证 C 开发环境 2 主要知识点&#xff1a; C 开发环境是同时指操作系统和C开发工具操作系统主要有 Window…