沙箱支付实现扫码支付教程(前后端分离版) |
您所在的位置:网站首页 › 支付宝怎么搞行程码二维码扫描 › 沙箱支付实现扫码支付教程(前后端分离版) |
利用沙箱支付实现电脑扫码支付
一、准备工作二、效果展示三、实现代码3.1 后台代码(我这里利用的是SpringBoot集成的SSM,当然不使用SpringBoot也可以)3.2 前台代码 (前台是利用脚手架搭建的Vue项目)
一、准备工作
1、注册支付宝开放平台账号,成为开发者。 地址:https://open.alipay.com/platform/home.htm 4.后面需要使用的参数 APPID商户私钥(使用系统默认密钥的公钥模式,点击查看获取)支付宝公钥支付宝网关5、手机上下载沙箱支付宝 (到时候支付用这个支付宝支付) 1、随手写的一个前台vue界面 3.1.1 pom.xml文件 不用全部的,重点是 :支付宝sdk包、fastjson 4.0.0 com.zking springboot02 0.0.1-SNAPSHOT springboot02 Demo project for Spring Boot 1.8 UTF-8 UTF-8 2.1.18.RELEASE org.springframework.boot spring-boot-starter-jdbc org.springframework.boot spring-boot-starter-web org.mybatis.spring.boot mybatis-spring-boot-starter 2.1.4 mysql mysql-connector-java 5.1.44 runtime org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test org.junit.jupiter junit-jupiter RELEASE test com.github.pagehelper pagehelper-spring-boot-starter 1.4.1 org.springframework.boot spring-boot-starter-aop 2.6.2 com.alipay.sdk alipay-sdk-java 3.1.0 com.alibaba fastjson 1.2.48 org.springframework.boot spring-boot-starter-data-redis com.alibaba druid 1.2.6 log4j log4j 1.2.17 org.springframework.boot spring-boot-dependencies ${spring-boot.version} pom import org.apache.maven.plugins maven-compiler-plugin 3.8.1 1.8 1.8 UTF-8 org.mybatis.generator mybatis-generator-maven-plugin 1.3.2 true true src/main/resources/generatorConfig.xml org.springframework.boot spring-boot-maven-plugin 2.1.18.RELEASE com.zking.springboot02.Springboot02Application repackage repackage3.1.2 model包 package com.zking.springboot02.model; import lombok.Data; /** * 支付实体对象 * 根据支付宝接口协议,其中的属性名,必须使用下划线,不能修改 * * @author 借我丹青妙笔 */ @Data public class AlipayBean { private static final long serialVersionUID = 1L; /** * 商户订单号,必填 * */ 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; } }3.1.3 utils包 AlipayConfig类(请配置好该类,防止报错) appId:APPID,沙箱应用提供的privateKey: 商户私钥,点击公钥证书查看returnUrl : 支付完成后跳转的页面,例如我填的是:http://localhost:8088/ package com.zking.springboot02.utils; import lombok.Data; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; /** * 配置文件读取 * */ @Configuration @Data @Component public class AlipayConfig { /** * 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号 */ private String appId = ""; /** * 商户私钥,您的PKCS8格式RSA2私钥 */ private String privateKey = ""; /** * 支付宝公钥, */ private String publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyqAN9WzWigim0/3fBK97RFZ7Juu31+DfXMVHTHSTP+4WPvr80zTiIQmT9xTFVGBgD8BBX0XELxqLQxsYQm/MgEgccHTnCKPP7Ci979YuwZyjOysdTc6BNO/6RqPZruih6wSYDJNuJUgY/hwuWi+owUDbHL7NvZ8r/TaIJvEzzhJVrTMsIBQBe66LRE7gE2avwEV8Qck9e4yexsDUD7ja1+2T1ltfHAP2u/SBOD+7PkkPgVkINPDHt4bXZ9DIhPhosiw8IidEEniXj/Ku1wtgETll/btJljhhXq98JHBlw94+yx+BQ+9s2S2CjXkxfdZDB9s+jFy80e6UIV76xxfB0QIDAQAB"; /** * 服务器异步通知页面路径需http://格式的完整路径,不能加?id=123这类自定义参数 */ private String notifyUrl = "https://www.duan33f.top"; /** * 页面跳转同步通知页面路径 需http://格式的完整路径. * 支付完成后返回的地址 */ private String returnUrl = ""; /** * 签名方式 */ private String signType = "RSA2"; /** * 字符编码格式 */ private String charset = "utf-8"; /** * 支付宝网关 */ private String gatewayUrl = "https://openapi.alipaydev.com/gateway.do"; /** * 支付宝网关 */ private String logPath = "C:\\"; }Alipay类 package com.zking.springboot02.utils; 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; import com.zking.springboot02.model.AlipayBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.annotation.Resource; /** * 支付宝支付接口 * @author 借我丹青妙笔 */ @Component public class Alipay { @Autowired private AlipayConfig alipayConfig; /** * 支付接口 * @param alipayBean * @return * @throws AlipayApiException */ public String pay(AlipayBean alipayBean) throws AlipayApiException { // 1、获得初始化的AlipayClient String 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(); //System.out.println(appId); 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(); // 返回付款信息 return result; } }3.1.4 Service包 PayService接口 package com.zking.springboot02.service; import com.alipay.api.AlipayApiException; import com.zking.springboot02.model.AlipayBean; /** * 支付服务 * @author 借我丹青妙笔 * @date Dec 12, 2018 */ public interface PayService { /** * 支付宝支付接口 * @param alipayBean * @return * @throws AlipayApiException */ String aliPay(AlipayBean alipayBean) throws AlipayApiException; }PayServiceImpl类 package com.zking.springboot02.service.impl; import com.alipay.api.AlipayApiException; import com.zking.springboot02.model.AlipayBean; import com.zking.springboot02.service.PayService; import com.zking.springboot02.utils.Alipay; import org.springframework.stereotype.Service; import javax.annotation.Resource; @Service public class PayServiceImpl implements PayService { @Resource private Alipay alipay; @Override public String aliPay(AlipayBean alipayBean) throws AlipayApiException { return alipay.pay(alipayBean); } }3.1.5 contorller包 payController类 package com.zking.springboot02.contorller; import com.alipay.api.AlipayApiException; import com.zking.springboot02.model.AlipayBean; import com.zking.springboot02.service.PayService; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.HashMap; import java.util.Map; @RestController @RequestMapping("/pay") @CrossOrigin public class PayController { @Resource private PayService payService; /** * 阿里支付 * @param alipayBean * @return * @throws AlipayApiException */ @PostMapping("/alipay") public Map alipay(AlipayBean alipayBean) throws AlipayApiException { System.out.println(alipayBean); Map map = new HashMap(); String str = payService.aliPay(alipayBean); System.out.println(str); map.put("msg",str); map.put("code",0); // return map; } }3.1.6 application.yml文件 server: port: 8080 #端口号 servlet: context-path: /s02 #项目名 3.2 前台代码 (前台是利用脚手架搭建的Vue项目)3.2.1 src下api包下action.js文件 /** * 对后台请求的地址的封装,URL格式如下: * 模块名_实体名_操作 */ export default { //服务器 'SERVER': 'http://localhost:8080/s02', 'alipay' : 'http://localhost:8080/s02/pay/alipay', //获得请求的完整地址,用于mockjs测试时使用 'getFullPath': k => { return this.SERVER + this[k]; } }3.2.2 src下api包下http.js文件 /** * vue项目对axios的全局配置 */ import axios from 'axios' import qs from 'qs' //引入action模块,并添加至axios的类属性urls上 import action from '@/api/action' axios.urls = action // axios默认配置 axios.defaults.timeout = 10000; // 超时时间 // axios.defaults.baseURL = 'http://localhost:8080/crm'; // 默认地址 axios.defaults.baseURL = action.SERVER; //整理数据 // 只适用于 POST,PUT,PATCH,transformRequest` 允许在向服务器发送前,修改请求数据 axios.defaults.transformRequest = function(data) { data = qs.stringify(data); return data; }; // 请求拦截器 axios.interceptors.request.use(function(config) { // let jwt = sessionStorage.getItem('jwt'); // if (jwt) { // config.headers['jwt'] = jwt; // } return config; }, function(error) { return Promise.reject(error); }); // 响应拦截器 axios.interceptors.response.use(function(response) { return response; }, function(error) { return Promise.reject(error); }); export default axios;3.2.3 src下router下index.js文件 import Vue from 'vue' import Router from 'vue-router' import Shop from '@/views/Shop' import buy from '@/views/buy' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'Shop', component: Shop }, { path: '/buy', name: 'buy', component: buy } ] })3.2.4 src下views下Shop.vue文件 去支付 export default { name: "Shop", data: function() { return { tableData: [{ out_trade_no: '101', subject: 'Java从入门到入土', total_amount: 33 }, { out_trade_no: '202', subject: 'Mysql删库跑路指南', total_amount: 44 }, { out_trade_no: '303', subject: 'Java编程思想', total_amount: 89 }, { out_trade_no: '404', subject: 'Java设计模式', total_amount: 56 }] }; }, methods: { toBuy(row){ console.log(row); //利用$router.push进行跳转 this.$router.push({ //path后面跟跳转的路由地址 path: '/buy', //name后面跟跳转的路由名字(必须有亲测,不使用命名路由会传参失败) name: 'buy', params: { //imgsListsUrl2是自己定义的名字,this.imgsListsUrl是要被传递的值 payInfo: row } }) } }, created: function() { } }3.2.5 src下views下buy.vue文件 确定订单 付款 //import axios from 'axios' export default { name: "buy", data() { return { payInfo: { out_trade_no: '', subject: '', total_amount: null, body: '' } } }, mounted() { //this.$route.params.imgsListsUrl2是传过来的参数 var time = new Date(); this.payInfo = this.$route.params.payInfo this.payInfo.out_trade_no = time.getTime(); }, methods: { submit() { var url = this.axios.urls.alipay;//得到api下action.js中的alipay this.axios.post(url, this.payInfo).then(resp => {//调用后台方法 console.log(resp); const divForm = document.getElementsByTagName('div') if (divForm.length) { document.body.removeChild(divForm[0]) } const div = document.createElement('div') div.innerHTML = resp.data.msg // data就是接口返回的form 表单字符串 document.body.appendChild(div) document.forms[0].setAttribute('target', '_blank') // 新开窗口跳转 document.forms[0].submit() }).catch(resp => { console.log(resp); }); } } } .box { width: 800px; } .left { width: 85px; padding-top: 5px; font-size: 15px; } .right { width: 400px; }3.2.6 src下main.js文件 import Vue from 'vue' import ElementUI from 'element-ui' //新添加1 import 'element-ui/lib/theme-chalk/index.css' //新添加2,避免后期打包样式不同,要放在import App from './App';之前 import axios from '@/api/http' //vue项目对axios的全局配置 import App from './App' import router from './router' import VueAxios from 'vue-axios' Vue.use(VueAxios,axios) Vue.use(ElementUI) //新添加3 Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', router, components: { App }, template: '' })END OK,重要的代码已经完全提供了。 声明:实现沙箱支付可以让我们了解如何调用如支付宝的接口,让我们理解接口的调用。 对业务开发有极大的帮助与提升。也希望每个看完这篇博客的小伙伴都能实现沙箱支付的扫码支付功能,若有问题,请留下你的评论,欢迎互相探讨。 作者:借我丹青妙笔 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |