利用沙箱支付实现电脑扫码支付
一、准备工作
1、注册支付宝开放平台账号,成为开发者。
地址:https://open.alipay.com/platform/home.htm
2、进入沙箱,进行配置。
3.我们可以看到这个界面
4.后面需要使用的参数
- APPID
- 商户私钥(使用系统默认密钥的公钥模式,点击查看获取)
- 支付宝公钥
- 支付宝网关
5、手机上下载沙箱支付宝 (到时候支付用这个支付宝支付)
6、下载好支付宝沙箱版后,登录支付宝提供的账号
二、效果展示
1、随手写的一个前台vue界面
2、进入确定订单界面,可以添加商品描述
3、跳转支付界面,利用沙箱支付宝完成支付
4、完成支付
5、跳回自己设置的界面
END…
三、实现代码
3.1 后台代码(我这里利用的是SpringBoot集成的SSM,当然不使用SpringBoot也可以)
3.1.1 pom.xml文件
不用全部的,重点是 :支付宝sdk包、fastjson
<?xml version="1.0" encoding="UTF-8"?><projectxmlns="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><groupId>com.zking</groupId><artifactId>springboot02</artifactId><version>0.0.1-SNAPSHOT</version><name>springboot02</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>2.1.18.RELEASE</spring-boot.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.4</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.44</version><scope>runtime</scope></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.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>RELEASE</version><scope>test</scope></dependency><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.4.1</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId><version>2.6.2</version></dependency><!-- 支付宝sdk包 --><dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-sdk-java</artifactId><version>3.1.0</version></dependency><!-- fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.48</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- https://mvnrepository.com/artifact/com.alibaba/druid --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.6</version></dependency><!-- https://mvnrepository.com/artifact/log4j/log4j --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin><!-- mvn mybatis-generator:generate --><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.3.2</version><configuration><verbose>true</verbose><overwrite>true</overwrite><!--配置文件的位置--><configurationFile>src/main/resources/generatorConfig.xml</configurationFile></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.1.18.RELEASE</version><configuration><mainClass>com.zking.springboot02.Springboot02Application</mainClass></configuration><executions><execution><id>repackage</id><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build></project>
3.1.2 model包
packagecom.zking.springboot02.model;importlombok.Data;/**
* 支付实体对象
* 根据支付宝接口协议,其中的属性名,必须使用下划线,不能修改
*
* @author 借我丹青妙笔
*/@DatapublicclassAlipayBean{privatestaticfinallong serialVersionUID =1L;/**
* 商户订单号,必填
*
*/privateString out_trade_no;/**
* 订单名称,必填
*/privateString subject;/**
* 付款金额,必填
* 根据支付宝接口协议,必须使用下划线
*/privateString total_amount;/**
* 商品描述,可空
*/privateString body;/**
* 超时时间参数
*/privateString timeout_express="10m";/**
* 产品编号
*/privateString product_code="FAST_INSTANT_TRADE_PAY";publicStringgetOut_trade_no(){return out_trade_no;}publicvoidsetOut_trade_no(String out_trade_no){this.out_trade_no = out_trade_no;}publicStringgetSubject(){return subject;}publicvoidsetSubject(String subject){this.subject = subject;}publicStringgetTotal_amount(){return total_amount;}publicvoidsetTotal_amount(String total_amount){this.total_amount = total_amount;}publicStringgetBody(){return body;}publicvoidsetBody(String body){this.body = body;}}
3.1.3 utils包
AlipayConfig类(请配置好该类,防止报错)
- appId:APPID,沙箱应用提供的
- privateKey: 商户私钥,点击公钥证书查看
- returnUrl : 支付完成后跳转的页面,例如我填的是:http://localhost:8088/
packagecom.zking.springboot02.utils;importlombok.Data;importorg.springframework.context.annotation.Configuration;importorg.springframework.context.annotation.PropertySource;importorg.springframework.stereotype.Component;/**
* 配置文件读取
*
*/@Configuration@Data@ComponentpublicclassAlipayConfig{/**
* 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
*/privateString appId ="";/**
* 商户私钥,您的PKCS8格式RSA2私钥
*/privateString privateKey ="";/**
* 支付宝公钥,
*/privateString publicKey ="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyqAN9WzWigim0/3fBK97RFZ7Juu31+DfXMVHTHSTP+4WPvr80zTiIQmT9xTFVGBgD8BBX0XELxqLQxsYQm/MgEgccHTnCKPP7Ci979YuwZyjOysdTc6BNO/6RqPZruih6wSYDJNuJUgY/hwuWi+owUDbHL7NvZ8r/TaIJvEzzhJVrTMsIBQBe66LRE7gE2avwEV8Qck9e4yexsDUD7ja1+2T1ltfHAP2u/SBOD+7PkkPgVkINPDHt4bXZ9DIhPhosiw8IidEEniXj/Ku1wtgETll/btJljhhXq98JHBlw94+yx+BQ+9s2S2CjXkxfdZDB9s+jFy80e6UIV76xxfB0QIDAQAB";/**
* 服务器异步通知页面路径需http://格式的完整路径,不能加?id=123这类自定义参数
*/privateString notifyUrl ="https://www.duan33f.top";/**
* 页面跳转同步通知页面路径 需http://格式的完整路径.
* 支付完成后返回的地址
*/privateString returnUrl ="";/**
* 签名方式
*/privateString signType ="RSA2";/**
* 字符编码格式
*/privateString charset ="utf-8";/**
* 支付宝网关
*/privateString gatewayUrl ="https://openapi.alipaydev.com/gateway.do";/**
* 支付宝网关
*/privateString logPath ="C:\\";}
Alipay类
packagecom.zking.springboot02.utils;importcom.alibaba.fastjson.JSON;importcom.alipay.api.AlipayApiException;importcom.alipay.api.AlipayClient;importcom.alipay.api.DefaultAlipayClient;importcom.alipay.api.request.AlipayTradePagePayRequest;importcom.zking.springboot02.model.AlipayBean;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Component;importjavax.annotation.Resource;/**
* 支付宝支付接口
* @author 借我丹青妙笔
*/@ComponentpublicclassAlipay{@AutowiredprivateAlipayConfig alipayConfig;/**
* 支付接口
* @param alipayBean
* @return
* @throws AlipayApiException
*/publicStringpay(AlipayBean alipayBean)throwsAlipayApiException{// 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();//System.out.println(appId);AlipayClient alipayClient =newDefaultAlipayClient(serverUrl, appId, privateKey, format, charset, alipayPublicKey, signType);// 2、设置请求参数AlipayTradePagePayRequest alipayRequest =newAlipayTradePagePayRequest();// 页面跳转同步通知页面路径
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接口
packagecom.zking.springboot02.service;importcom.alipay.api.AlipayApiException;importcom.zking.springboot02.model.AlipayBean;/**
* 支付服务
* @author 借我丹青妙笔
* @date Dec 12, 2018
*/publicinterfacePayService{/**
* 支付宝支付接口
* @param alipayBean
* @return
* @throws AlipayApiException
*/StringaliPay(AlipayBean alipayBean)throwsAlipayApiException;}
PayServiceImpl类
packagecom.zking.springboot02.service.impl;importcom.alipay.api.AlipayApiException;importcom.zking.springboot02.model.AlipayBean;importcom.zking.springboot02.service.PayService;importcom.zking.springboot02.utils.Alipay;importorg.springframework.stereotype.Service;importjavax.annotation.Resource;@ServicepublicclassPayServiceImplimplementsPayService{@ResourceprivateAlipay alipay;@OverridepublicStringaliPay(AlipayBean alipayBean)throwsAlipayApiException{return alipay.pay(alipayBean);}}
3.1.5 contorller包
payController类
packagecom.zking.springboot02.contorller;importcom.alipay.api.AlipayApiException;importcom.zking.springboot02.model.AlipayBean;importcom.zking.springboot02.service.PayService;importorg.springframework.web.bind.annotation.CrossOrigin;importorg.springframework.web.bind.annotation.PostMapping;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RestController;importjavax.annotation.Resource;importjava.util.HashMap;importjava.util.Map;@RestController@RequestMapping("/pay")@CrossOriginpublicclassPayController{@ResourceprivatePayService payService;/**
* 阿里支付
* @param alipayBean
* @return
* @throws AlipayApiException
*/@PostMapping("/alipay")publicMapalipay(AlipayBean alipayBean)throwsAlipayApiException{System.out.println(alipayBean);Map<String,Object> map =newHashMap<String,Object>();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格式如下:
* 模块名_实体名_操作
*/exportdefault{//服务器'SERVER':'http://localhost:8080/s02','alipay':'http://localhost:8080/s02/pay/alipay',//获得请求的完整地址,用于mockjs测试时使用'getFullPath':k=>{returnthis.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);});exportdefault 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)exportdefaultnewRouter({
routes:[{
path:'/',
name:'Shop',
component: Shop
},{
path:'/buy',
name:'buy',
component: buy
}]})
3.2.4 src下views下Shop.vue文件
<template><el-table:data="tableData"style="width: 100%"><el-table-columnprop="out_trade_no"label="编号"></el-table-column><el-table-columnprop="subject"label="订单名称"></el-table-column><el-table-columnprop="total_amount"label="付款金额"></el-table-column><el-table-columnlabel="操作"><templateslot-scope="scope"><el-button@click="toBuy(scope.row)"type="text"size="small">去支付</el-button></template></el-table-column></el-table></template><script>exportdefault{
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(){}}</script><style></style>
3.2.5 src下views下buy.vue文件
<template><divclass="main"><center><divclass="box"><h2>确定订单</h2><el-form:model="payInfo":rules="rules"ref="ruleForm"label-width="100px"class="demo-ruleForm"><el-form-itemlabel="订单号"prop="out_trade_no"><el-inputv-model="payInfo.out_trade_no"readonly="true"></el-input></el-form-item><el-form-itemlabel="商品名称"prop="subject"><el-inputv-model="payInfo.subject"readonly="true"></el-input></el-form-item><el-form-itemlabel="商品价格"prop="total_amount"><el-inputv-model="payInfo.total_amount"readonly="true"></el-input></el-form-item><el-form-itemlabel="商品描述"prop="body"><el-inputv-model="payInfo.body"></el-input></el-form-item><el-buttontype="primary"plain@click="submit"style="width: 100%;"round>付款</el-button></el-form></div></center></div></template><script>//import axios from 'axios'exportdefault{
name:"buy",data(){return{
payInfo:{
out_trade_no:'',
subject:'',
total_amount:null,
body:''}}},mounted(){//this.$route.params.imgsListsUrl2是传过来的参数var time =newDate();this.payInfo =this.$route.params.payInfo
this.payInfo.out_trade_no = time.getTime();},
methods:{submit(){var url =this.axios.urls.alipay;//得到api下action.js中的alipaythis.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);});}}}</script><stylescoped>.box{width: 800px;}.left{width: 85px;padding-top: 5px;font-size: 15px;}.right{width: 400px;}</style>
3.2.6 src下main.js文件
import Vue from'vue'import ElementUI from'element-ui'//新添加1import'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 */newVue({
el:'#app',
router,
components:{ App },
template:'<App/>'})
END
OK,重要的代码已经完全提供了。
声明:实现沙箱支付可以让我们了解如何调用如支付宝的接口,让我们理解接口的调用。
对业务开发有极大的帮助与提升。也希望每个看完这篇博客的小伙伴都能实现沙箱支付的扫码支付功能,若有问题,请留下你的评论,欢迎互相探讨。
作者:借我丹青妙笔
版权归原作者 借我丹青妙笔 所有, 如有侵权,请联系我们删除。