项目场景:

需求:VUE + SpringMVC前后端分离项目使用支付宝API接口实现付款。


问题描述

提示为:验签出错,建议检查签名字符串或签名私钥与应用公钥是否匹配

解决方案:

1.密钥真的不匹配,检查是否输出错误或者出现了空格。
2.确认密钥无误,可能是数据传输回前端的时候出现了问题,编码格式不对,出现了中文,解析出现问题,导致失败!!建议在填写订单信息的时候不要出现中文。
3.如果真的需要中文信息,可将返回的结果转换为 utf-8的编码格式,如下:

@PostMapping(value = "pay/alipay" , produces = "text/html;charset=utf-8")

实现过程

获取私钥、公钥、APPID

打开支付宝开放平台:https://open.alipay.com/develop/sandbox/tool

打开沙箱工具,后使用自定义密钥:

建议使用密钥生成器来生成密钥:

按照要求安装下载:

默认即可,点击生成密钥,生成后这个程序先不要关闭,记录下生成的密钥,之后会用到。

SpringMVC后端代码编写

如果你是使用SSM或SpringBoot + Mybatis plus写的后端,那么可以直接复制到你的项目,代码进行少量修改即可。

引入支付宝Api的Maven依赖

    <!--支付宝Api--><!-- fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.48</version></dependency><!-- 支付宝支付jar包 --><dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-sdk-java</artifactId><version>4.22.57.ALL</version></dependency><!--支付宝Api end-->

需要的文件如下,其他内容不相关可以不看,只需要关注红框内的文件


支付宝订单实体类

package cn.edu.nchu.bookstore.entity;/*** 支付实体对象* 根据支付宝接口协议,其中的属性名,必须使用下划线,不能修改*/
public class AlipayBean {/*** 商户订单号,必填**/private String out_trade_no;/*** 订单名称,必填*/private String subject;/*** 付款金额,必填* 根据支付宝接口协议,必须使用下划线*/private String total_amount;/*** 商品描述,可空*/private String body;/*** 超时时间参数*/private String timeout_express= "10m";/*** 产品编号*/private String product_code= "FAST_INSTANT_TRADE_PAY";public String getOut_trade_no() {return out_trade_no;}public void setOut_trade_no(String out_trade_no) {this.out_trade_no = out_trade_no;}public String getSubject() {return subject;}public void setSubject(String subject) {this.subject = subject;}public String getTotal_amount() {return total_amount;}public void setTotal_amount(String total_amount) {this.total_amount = total_amount;}public String getBody() {return body;}public void setBody(String body) {this.body = body;}public String getTimeout_express() {return timeout_express;}public void setTimeout_express(String timeout_express) {this.timeout_express = timeout_express;}public String getProduct_code() {return product_code;}public void setProduct_code(String product_code) {this.product_code = product_code;}}

支付宝订单工具类:

package cn.edu.nchu.bookstore.utils.alipay.config;import cn.edu.nchu.bookstore.dao.OrderDao;
import cn.edu.nchu.bookstore.entity.AlipayBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;@Component
public class Alipay {@Autowiredprivate AlipayConfig alipayConfig;/*** 支付接口* @param alipayBean* @return* @throws AlipayApiException*/public String pay(AlipayBean alipayBean) throws AlipayApiException {// 1、获得初始化的AlipayClientString serverUrl = alipayConfig.getGatewayUrl();String appId = alipayConfig.getAppId();String privateKey = alipayConfig.getPrivateKey();String format = "json";String charset = alipayConfig.getCharset();String alipayPublicKey = alipayConfig.getPublicKey();String signType = alipayConfig.getSignType();String returnUrl = alipayConfig.getReturnUrl();String notifyUrl = alipayConfig.getNotifyUrl();AlipayClient alipayClient = new DefaultAlipayClient(serverUrl, appId, privateKey, format, charset, alipayPublicKey, signType);// 2、设置请求参数AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();// 页面跳转同步通知页面路径alipayRequest.setReturnUrl(returnUrl);// 服务器异步通知页面路径alipayRequest.setNotifyUrl(notifyUrl);// 封装参数alipayRequest.setBizContent(JSON.toJSONString(alipayBean));// 3、请求支付宝进行付款,并获取支付结果String result = alipayClient.pageExecute(alipayRequest).getBody();System.out.println(result);// 返回付款信息return result;}
}

支付宝参数类

注意在这个页面内填入你的APPID,商户私钥,支付宝公钥:

package cn.edu.nchu.bookstore.utils.alipay.config;import org.springframework.context.annotation.Configuration;import org.springframework.stereotype.Component;@Configuration
@Component
public class AlipayConfig {/*** 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号*/private String appId = "";/*** 商户私钥,您的PKCS8格式RSA2私钥*/private String privateKey ="";/*** 支付宝公钥,*/private String publicKey = "";/*** 服务器异步通知页面路径需http://格式的完整路径,不能加?id=123这类自定义参数*/private String notifyUrl = "http://localhost:8081/#/success";/*** 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数*/private String returnUrl = "http://localhost:8081/#/success";/*** 签名方式*/private String signType = "RSA2";/*** 字符编码格式*/private String charset = "utf-8";/*** 支付宝网关*/private String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";/*** 支付宝网关*/private String logPath = "C:\\";public String getAppId() {return appId;}public void setAppId(String appId) {this.appId = appId;}public String getPrivateKey() {return privateKey;}public void setPrivateKey(String privateKey) {this.privateKey = privateKey;}public String getPublicKey() {return publicKey;}public void setPublicKey(String publicKey) {this.publicKey = publicKey;}public String getNotifyUrl() {return notifyUrl;}public void setNotifyUrl(String notifyUrl) {this.notifyUrl = notifyUrl;}public String getReturnUrl() {return returnUrl;}public void setReturnUrl(String returnUrl) {this.returnUrl = returnUrl;}public String getSignType() {return signType;}public void setSignType(String signType) {this.signType = signType;}public String getCharset() {return charset;}public void setCharset(String charset) {this.charset = charset;}public String getGatewayUrl() {return gatewayUrl;}public void setGatewayUrl(String gatewayUrl) {this.gatewayUrl = gatewayUrl;}public String getLogPath() {return logPath;}public void setLogPath(String logPath) {this.logPath = logPath;}
}

支付服务接口:

package cn.edu.nchu.bookstore.service;import cn.edu.nchu.bookstore.entity.AlipayBean;
import com.alipay.api.AlipayApiException;public interface PayService {/*** 支付宝支付接口* @param alipayBean* @return* @throws AlipayApiException*/String aliPay(AlipayBean alipayBean) throws AlipayApiException;}

支付实体服务类实现类

package cn.edu.nchu.bookstore.service.impl;import cn.edu.nchu.bookstore.entity.AlipayBean;
import cn.edu.nchu.bookstore.service.PayService;
import cn.edu.nchu.bookstore.utils.alipay.config.Alipay;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import com.alipay.api.AlipayApiException;@Service("payService")
public class PayServiceImpl implements PayService {@Autowiredprivate Alipay alipay;@Overridepublic String aliPay(AlipayBean alipayBean) throws AlipayApiException {return alipay.pay(alipayBean);}
}

支付控制器类

package cn.edu.nchu.bookstore.controller;import cn.edu.nchu.bookstore.entity.AlipayBean;
import cn.edu.nchu.bookstore.service.PayService;
import cn.edu.nchu.bookstore.utils.JsonResult;
import com.alipay.api.AlipayApiException;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;import java.io.UnsupportedEncodingException;@RestController
//可修改为Controller
public class PayController {@Autowiredprivate PayService payService;/*** 阿里支付* @param outTradeNo* @param subject* @param totalAmount* @param body* @return* @throws AlipayApiException*/@PostMapping(value = "pay/alipay" , produces = "text/html;charset=utf-8")/*可替换为:@RequestMapping(value = "pay/alipay" , produces = "text/html;charset=utf-8")@ResponseBody*/public String alipay(String outTradeNo, String subject, String totalAmount, String body) throws AlipayApiException, UnsupportedEncodingException {AlipayBean alipayBean = new AlipayBean();alipayBean.setOut_trade_no(outTradeNo);alipayBean.setSubject(subject);alipayBean.setTotal_amount(totalAmount);alipayBean.setBody(body);System.out.println(outTradeNo);System.out.println(subject);System.out.println(totalAmount);System.out.println(body);return payService.aliPay(alipayBean);}
}

前端开发

该部分使用vue实现,通过点击支付按钮点击实现跳转到支付界面吗,将订单填写在params里面
         submitOrder() {//   修改为你自己的地址var url = "/pay/alipay";this.axios({method: 'post',url: url,params: {outTradeNo: ,//订单的唯一IDsubject: ,//订单名称totalAmount: ,//订单总价,即付款的钱body: ,//订单主题内容},}).then(response => {// 添加之前先删除一下,如果单页面,页面不刷新,添加进去的内容会一直保留在页面中,二次调用form表单会出错const divForm = document.getElementsByTagName('div')if (divForm.length) {document.body.removeChild(divForm[0])}const div = document.createElement('div')console.log(response.data);div.innerHTML = response.data // data就是接口返回的form 表单字符串document.body.appendChild(div)document.forms[0].setAttribute('target', '_blank') // 新开窗口跳转document.forms[0].submit()}).catch(err => {console.log(err)})

支付成功后的操作——success.vue

这个success界面需要在前面的AlipayConfig 类里面定义,你也可以设置为跳转到其他页面。
我是在这个页面实现了支付后的对数据更新的操作,你也可以直接在后端实现业务,而不必在前端再发一次请求。
以下代码仅供参考,你需要自己写post/get请求的方式,界面自行美化
<template><div>支付成功!!</div>
</template><script>export default {mounted() {console.log(this.$route.query.out_trade_no);// 获取订单号//你也可以通过this.$route.query.xxx 获取订单价格,等信息,//在支付之前,通过F12查看“network” ,支付后,你会看到带有订单信息的请求,找到请求的内容// 以下代码是支付成功之后的操作,请在这修改你自己的处理方式// 以下代码是经过封装的请求,不能直接使用// 我这里的意思是支付后,根据订单ID对订单状态进行修改this.$post("order/payForOrderByGen", {orderGeneratedId: this.$route.query.out_trade_no,}).then(res => {this.$message({message: res.data ? '支付成功!' : "支付失败",type: res.data ? 'success' : 'error'});// 跳转到订单页面this.$router.push("/customer/order");}).catch(err => {console.log(err);});}}
</script><style>
</style>

参考文章

https://blog.csdn.net/weixin_51324855/article/details/124097792


如文章中有侵权,请及时联系删除。
本文用于记录作者本人的学习,其中遇到的问题,欢迎大家在讨论区交流。

实现SpringMVC + Vue 前后端分离 支付宝API付款相关推荐

  1. React / Vue 前后端分离项目实现微信分享教程

    小编推荐:Fundebug专注于JavaScript.微信小程序.微信小游戏,Node.js和Java实时BUG监控.真的是一个很好用的bug监控费服务,众多大佬公司都在使用. 网上非常多的微信分享例 ...

  2. 视频教程-SpringBoot+Security+Vue前后端分离开发权限管理系统-Java

    SpringBoot+Security+Vue前后端分离开发权限管理系统 10多年互联网一线实战经验,现就职于大型知名互联网企业,架构师, 有丰富实战经验和企业面试经验:曾就职于某上市培训机构数年,独 ...

  3. 基于SpringBoot+SpringCloud+Vue前后端分离项目实战 --开篇

    本文目录 前言 做项目的三大好处 强强联手(天狗组合) 专栏作者简介 专栏的优势 后端规划 1. SpringBoot 和 SpringCloud 的选择 2. Mybatis 和 MybatisPl ...

  4. ssm vue架构图_ssm+vue前后端分离框架整合实现(附源码)

    前言 本文针对Spring+SpringMVC+Mybatis后台开发框架(基于maven构建)与vue前端框架(基于webpack构建)的项目整合进行介绍,对于ssm和vue单独项目的搭建不作为本文 ...

  5. laravel + Vue 前后端分离 之 项目配置- 生产环境部署

    几日之后,开始部署 生产环境, 有兴趣的同学可以先看一下laravel + Vue 前后端分离 项目配置 开发环境,好了,废话少说,开始总结 部署过程中的问题:https://blog.csdn.ne ...

  6. laravel + Vue 前后端分离 之 项目配置 - 开发环境

    既然你来到查看这篇文章,那么你应该知道PHP 版本 >=7. 接着看一下目录 |-blog |-- api |-- front 目录外部很简单,,不多说了,赶紧看重点 配置Laravel 作为前 ...

  7. 基于SpringBoot+Vue前后端分离的在线教育平台项目

    基于SpringBoot+Vue前后端分离的在线教育平台项目 赠给有缘人,希望能帮助到你!也请不要吝惜你的大拇指,你的Star.点赞将是对我最大的鼓励与支持! 开源传送门: 后台:Gitee | Gi ...

  8. Spring Boot+Vue/前后端分离/高并发/秒杀实战课程之spring Security快速搭建oauth2 内存版身份认证

    Springboot快速搭建oauth2 内存版身份认证 环境准备 点击[Create New Project]创建一个新的项目 项目环境配置 配置Thymeleaf 搭建oauth2认证,加入两个依 ...

  9. 基于SSM+SpringBoot+MySQL+Vue前后端分离的博客论坛系统

    项目运行截图 系统首页 技术描述 开发工具: idea/eclipse 数据库: mysql Jar包仓库: Maven 前段框架: vue/ElementUI/echart 后端框架: spring ...

最新文章

  1. 充电 | 打开机器学习的大门,需要了解哪些知识?
  2. 别再叫我 Sql boy!
  3. 随机取6位数字或字母方法
  4. 自定义LocaleResolver实现页面中英文切换
  5. 图的两种存储形式(邻接矩阵、邻接表)
  6. linux驱动 自旋锁
  7. 函数声明和函数表达式
  8. python虚拟人脸生成_Python-OpenCV人脸识别之数据集生成
  9. 生日python十种日期格式_Python可视化-二十四节气与生日间隔天数统计
  10. 毕业两年程序员Java学习路线
  11. IntelliJ IDEA 配置svn
  12. CUX:固定资产台账报表源代码(信息较全)
  13. echarts 北京公交线路-线路效应
  14. 显卡T600和RTX3050哪个好
  15. python 爬虫 快看漫画整站爬取(解决动态加载漫画图片地址、漫画图片合成长图、图片文件排序等问题)
  16. PDF工具Adobe Arcrobat Pro DC下载安装教程
  17. python importlib bootstrap_python - importlib._bootstrap和Python解释器初始化 - SO中文参考 - www.soinside.com...
  18. GitHub 上值得收藏的 100 个精选前端项目!
  19. Thinkpad 蓝牙键盘 Fn 键处于锁定状态的解决方法
  20. Hbase教程(二) Hbase数据库Shell命令

热门文章

  1. 耿明雨调研生态漓江宜居凤凰.山水尚境
  2. 由Babel理解前端编译原理
  3. 焦作大学计算机应用技术代码,焦作大学专业代码
  4. 使用chatgpt写6.5分作文范文
  5. Python 偏函数 将函数固定部分参数
  6. 分块传输的请求次数与客户端/服务端工作过程
  7. 上周热点回顾(6.25-7.1)
  8. 第三方ipad电容笔哪个品牌好用?平板电容笔推荐
  9. 微前端框架乾坤配置记录
  10. css左侧投影_css3投影讲解、投影