利用沙箱支付实现电脑扫码支付

  • 一、准备工作
  • 二、效果展示
    • 三、实现代码
      • 3.1 后台代码(我这里利用的是SpringBoot集成的SSM,当然不使用SpringBoot也可以)
      • 3.2 前台代码 (前台是利用脚手架搭建的Vue项目)

一、准备工作

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"?>
<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><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包

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类(请配置好该类,防止报错)

  1. appId:APPID,沙箱应用提供的
  2. privateKey: 商户私钥,点击公钥证书查看
  3. 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 {@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();//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 {@Resourceprivate Alipay alipay;@Overridepublic 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 {@Resourceprivate PayService payService;/*** 阿里支付* @param alipayBean* @return* @throws AlipayApiException*/@PostMapping("/alipay")public Map alipay(AlipayBean alipayBean) throws AlipayApiException {System.out.println(alipayBean);Map<String,Object> map = new HashMap<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格式如下:* 模块名_实体名_操作*/
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文件

<template><el-table :data="tableData" style="width: 100%"><el-table-column prop="out_trade_no" label="编号"></el-table-column><el-table-column prop="subject" label="订单名称" ></el-table-column><el-table-column prop="total_amount" label="付款金额"></el-table-column><el-table-column  label="操作"><template slot-scope="scope"><el-button @click="toBuy(scope.row)" type="text" size="small">去支付</el-button></template></el-table-column></el-table></template><script>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() {}}
</script><style>
</style>

3.2.5 src下views下buy.vue文件

<template><div class="main"><center><div class="box"><h2>确定订单</h2><el-form :model="payInfo" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm"><el-form-item label="订单号" prop="out_trade_no"><el-input v-model="payInfo.out_trade_no" readonly="true"></el-input></el-form-item><el-form-item label="商品名称" prop="subject"><el-input v-model="payInfo.subject" readonly="true"></el-input></el-form-item><el-form-item label="商品价格" prop="total_amount"><el-input v-model="payInfo.total_amount" readonly="true"></el-input></el-form-item><el-form-item label="商品描述" prop="body"><el-input v-model="payInfo.body"></el-input></el-form-item><el-button type="primary" plain @click="submit" style="width: 100%;" round>付款</el-button></el-form></div></center></div>
</template>
<script>//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.payInfothis.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>
<style scoped>.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' //新添加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: '<App/>'
})

END

OK,重要的代码已经完全提供了。

声明:实现沙箱支付可以让我们了解如何调用如支付宝的接口,让我们理解接口的调用。
对业务开发有极大的帮助与提升。也希望每个看完这篇博客的小伙伴都能实现沙箱支付的扫码支付功能,若有问题,请留下你的评论,欢迎互相探讨。
作者:借我丹青妙笔

沙箱支付实现扫码支付教程(前后端分离版)相关推荐

  1. 微信支付之扫码支付与小程序支付

    微信支付之扫码支付与小程序支付 前言:最近的需求中,频繁出现微信支付功能的开发,于是研读了微信官方开发文档以及相关代码做了以下总结,并记录在此,以备不时之需.如有不足之处,欢迎批评指正. 微信官方开发 ...

  2. php接入微信支付,扫码支付和H5支付(非微信浏览器),基于thinkPHP框架 WeChatDeveloper支付类包 踩坑指南

    此文章入选<PHP领域内容榜>第4名 文章介绍 本文主要介绍通过thinkPHP5和第三方支付类包(WeChatDeveloper)实现快速接入微信扫码支付和微信H5手机网站支付(非微信浏 ...

  3. 支付宝支付之扫码支付(电脑网站支付)、H5支付(手机网站支付)相关业务流程分析总结

    前言 在上一篇文章<微信支付之扫码支付.公众号支付.H5支付.小程序支付相关业务流程分析总结>中,分析和总结了微信支付相关支付类型的业务流程,这里作为与微信支付平起平坐不相伯仲的支付宝支付 ...

  4. 手机H5支付和扫码支付的区别是什么?

    H5支付就是网页发起的微信.支付宝唤醒,通过微信自带的微信浏览器内jssdk发起的微信支付.支付宝也可以拉起手机浏览器唤醒支付宝发起支付宝支付. 扫码支付即通过手机app进行扫码付款,最常用的软件如微 ...

  5. 支付宝支付开发—当面付条码支付和扫码支付

    关键字:支付宝 当面付 条码支付 扫码支付 二维码支付 订单查询 退款 作者:方倍工作室 原文:https://www.cnblogs.com/txw1958/p/alipay-f2fpay.html ...

  6. 支付宝支付开发——当面付条码支付和扫码支付

    原文: http://www.cnblogs.com/txw1958/p/alipay-f2fpay.html 本文介绍支付宝中当面付下属的条码支付.扫码支付.订单查询.退款申请的集成开发过程. 本文 ...

  7. 第三篇、记录微信统一支付、扫码支付开发

    项目中使用了微信的统一支付以及扫码支付,记录下学习记录 目录 项目中使用了微信的统一支付以及扫码支付,记录下学习记录 1.配置wechat4j.properties 文件 2.编写支付工具类 3.统一 ...

  8. 若依前后端分离版手把手教你本地搭建环境并运行项目

    场景 RuoYi-Vue是一款基于SpringBoot+Vue的前后端分离极速后台开发框架. RuoYi 官网地址:http://ruoyi.vip RuoYi 在线文档:http://doc.ruo ...

  9. 若依管理系统前后端分离版基于ElementUI和SpringBoot怎样实现Excel导入和导出

    场景 使用若依前后端分离版实现Excel的导入和导出. 前端:Vue+ElementUI 后端:SpringBoot+POI+Mysql 注: 博客: https://blog.csdn.net/ba ...

最新文章

  1. mysql 日志管理
  2. flask 读取 csv
  3. Boost:字符串分割Split的测试程序
  4. xshell连接虚拟机里的linux系统
  5. python 文本处理2
  6. json.stringfy()和json.parse()
  7. linux 系统忘记数据库root密码
  8. java中userservice是什么,【图片】求助大神~~我在Reaml中注入userService对象启动tomcat就报错【java吧】_百度贴吧...
  9. C#:foreach语句,yield语句
  10. 百度编辑器ueditor 字符限制
  11. Solaris下设置nfs与nfs挂载
  12. android动画效果 translate,详解Android 动画之TranslateAnimation应用的参数说明
  13. Electron 打包时下载 xxx-electron-v1.6.8-arch-x64.zip 文件出错
  14. Numpy创建正态分布和均匀分布
  15. feign+hystrix相关超时时间配置问题
  16. 微信小程序仿打卡小程序
  17. Android 百度文字识别(详细步骤+源码)
  18. java实现生成纯色图片代码实例
  19. gdb打印errno显示cant find thread-local storage xxxx
  20. 交换机工作原理及端口安全配置

热门文章

  1. 玩 ChatGPT 的正确姿势「GitHub 热点速览 v.22.49」
  2. cve-2019-0192一把梭
  3. 程序设计天梯赛——T1(15分)java版
  4. linux安装ie浏览器吗,Ubuntu上安装IE浏览器的方法有哪些 安装方法分享
  5. 从0到1,反距离加权IDW(Inverse Distance Weighted Interpolation) 插值变形算法
  6. 【html+css+js】用前端做一个视频播放器页面
  7. Java实战之继承与多态
  8. poi获取excel打印标题行与表头,itext生成pdf设置打印标题行与表头
  9. 2021-01-3 VBA利用企业邮箱自动发送邮件
  10. 2019-07-12 函数递归、二分法、匿名函数、三元表达式、内置函数