大家好,我是大史兄弟,一个不断摸索爬行的程序员。看CSND文章已经有好多年了,但是写文章还是第一次。我不是行业的大牛,只是一个希望不断进步成为大牛的小白程序员。
  不知道有没有和我一样情况的,学习过很多的技术但是从来没有细致的整理过,当需要使用的时候总要去“问百度”,花时间去搜索,不仅浪费时间还对“百度”产生依赖。因此我写文章的首要目的就是要把自己学习过的东西整理下来自己看,如果有的小伙伴需要也可以拿去参考。

支付宝之电脑网站支付(保姆版)-编程之家

  他喵的,可爱中带着霸气,继续学起来。gogogo…😁

文章目录

  • 前言
  • 一、准备工作
  • 二、代码编写
    • 1.开发环境
    • 2.前端
    • 3.后端接口
    • 4.测试
  • 注意
  • 小结
  • 废话一下

前言

  本次我分享的是支付宝支付中最简单的网页支付,在PC端完成消费。网页支付的界面大家肯定见过,我们上学时在学校网站上报名英语四级或者全国计算机等级考试的时候就使用的这种支付形式。
  我的项目需求:项目设置捐款专栏,打开捐款专栏,卡片式列表展示需要捐款事件,用户自主选择事件完成捐款,系统记录捐款记录。
  整体流程:申请注册(登录)应用—配置应用—前端集成页面搭建—后端配置—测试


一、准备工作

  项目中接入支付功能,首先我们要去支付宝开发平台注册自己支付环境,然后才能成功的接入支付功能。下面我一步一步的演示如何开启支付服务。

1.百度搜索–支付宝开放平台

  https://open.alipay.com/
手机支付宝扫码登录
支付宝之电脑网站支付(保姆版)-编程之家
扫码后成功跳转到
支付宝之电脑网站支付(保姆版)-编程之家

2.点击研发服务
  这里我简单的说一下,因为是个人开发,我们只能使用支付宝的沙箱环境(测试版),真实支付需要企业资质才行,咋们玩不了。但是这个沙箱支付也够咋们玩了,一般都是测试环境弄好把一些配置参数一改就能线上使用了,你会这个也就够了。
支付宝之电脑网站支付(保姆版)-编程之家
进入到沙箱环境页面,系统已经自动为你创建一个应用,你可以看到如下信息。
注意:我们实现基本的支付功能需要如下参数信息:
1)APPID
2)支付宝公钥
3)商户私钥
4)支付宝网关
5)签名方式(RSA2)
6)字符编码格式(utf-8)
支付宝之电脑网站支付(保姆版)-编程之家
注意:
(1)按支付宝的提示点击沙箱环境,进入沙箱环境页面,如果你是第一次使用蚂蚁金服开放平台,那么会进入入驻页面,需要加入蚂蚁金服开放平台,成为一名开发者。傻瓜式的填写信息就行,
(2)APPID:上见图
(3)支付宝网关:见上图

2.获取“支付宝公钥”和“商户私钥”
  获取支付宝公钥和商户私钥需要借助——支付宝开放平台开发助手进行生成,支付宝开放平台开发助手我放到百度云中大家自行提取。(里面还包含一个官方给的Demo)
链接:https://pan.baidu.com/s/1xEQ82br_J3G3kqQgMyajmg
提取码:4j3z
  (1)傻瓜式安装完毕之后如下图:
支付宝之电脑网站支付(保姆版)-编程之家
  (2)点击生成密钥用应用公钥换取支付宝公钥,具体如图:
支付宝之电脑网站支付(保姆版)-编程之家
支付宝之电脑网站支付(保姆版)-编程之家
  填写完毕之后如下图:到这里基本上我们需要的参数就全部露面。
支付宝之电脑网站支付(保姆版)-编程之家
总结一下需要的所有配置参数
1)APPID:支付宝沙箱应用网页直接复制
2)支付宝公钥:使用支付宝助手生成应用公钥换取支付宝公钥
3)商户私钥:点击支付宝助手文件位置RSA密钥中的应用私钥
4)支付宝网关:支付宝沙箱应用网页直接复制
5)签名方式(RSA2)
6)字符编码格式(utf-8)

二、代码编写

1.开发环境

  我没有新建项目,我是直接在项目中接入,使用的VUE+SpringBoot前后端分离的。使用什么技术实现无所谓,主要是让我们感受整个支付的流程为未来工作打下基础。(我感觉哈,作为小白的简历上出现支付、安全、优化等字眼的介绍,无形中就给自己加分)

2.前端

  纠结半天要不要复制全部前端代码上去,因为太长了影响观感,但是我想到我以前看别的博主分享的时候只截取部分代码的时候总忍不住的咒骂一下,最后我还是全部复制下来给大家参考。(有需要的话直接复制)

<template><!--    捐款组件--><div><div style="width: 500px;height: 400px;"><el-form ref="form" :model="AliPayPojo" label-width="200px"><el-form-item label="商户订单号 :"><el-input v-model="AliPayPojo.widout_trade_no"></el-input></el-form-item><el-form-item label="订单名称 :"><el-input v-model="AliPayPojo.widsubject"></el-input></el-form-item><el-form-item label="付款金额 :"><el-input v-model="AliPayPojo.widtotal_amount"></el-input></el-form-item><el-form-item label="商品描述:"><el-input v-model="AliPayPojo.widbody"></el-input></el-form-item></el-form><span style="display: flex;justify-content: center;"><el-button type="primary" @click="pay" style="width: 200px;text-align: center">支付</el-button></span></div><!--接口返回的html代码渲染在页面上--><div id="payDiv" v-html="payCont"><!--肯定有很多同学这样进行渲染,这样页面无法解析,咋们要用上面标签进行渲染才ok--><!--{{payCont}}--></div></div>
</template><script>export default {name: "DepMana",data() {return {//需要传到接口的必要参数AliPayPojo: {widbody: '',widout_trade_no: '',widsubject: '',widtotal_amount: ''},payCont: ''}}, methods: {//支付请求方法pay() {this.postRequest('/system/admin/aliPay/', this.AliPayPojo).then(resp => {if (resp) {this.payCont = resp;/*** this.$nextTick稍微解释一下:this.payCont 进行赋值的时候是异步的* (1)如果不加this.$nextTick:有可能出现this.payCont还没有渲染完毕,我这边就submit了,这个时候控制台就会报找不到这个submit* (2)加this.$nextTick:就是确保我已经渲染完成了,你去获取这个class完成提交。* */this.$nextTick(() => {//使用原生js去获取到渲染在页面上的from表单,我们手动的提交请求,转到支付页面let payId = document.getElementsByName('punchout_form')[0];//提交payId.submit();});}})},//生成订单编号---根据日期生成getWidoutTradeNo() {let vNow = new Date();let sNow = "";sNow += String(vNow.getFullYear());sNow += String(vNow.getMonth() + 1);sNow += String(vNow.getDate());sNow += String(vNow.getHours());sNow += String(vNow.getMinutes());sNow += String(vNow.getSeconds());sNow += String(vNow.getMilliseconds());this.AliPayPojo.widout_trade_no = sNow;}}, mounted() {this.getWidoutTradeNo()}}
</script><style scoped></style>

  说实话我是为了你们才去找**//生成订单编号—根据日期生成**代码,我自己玩的话我直接就随机数了…
  前端需要说明的我都注释了。

3.后端接口

  后端接口四步走:添加依赖——》添加配置类——》验证参数–跳转支付界面——》业务…(这个根据自己需要来)
  比如:商城系统在验证配置参数的时候生成订单信息入库(标注是否付款),支付完成回调(修改订单转态还是其他业务需求根据具体需要来吧…)

(1)添加依赖

    <dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-sdk-java</artifactId><version>4.8.73.ALL</version></dependency>

(2)添加配置类
  我也是直接复制过来的哈哈,上面需要填写的参数上面都介绍了,直接copy好了。

package com.sbw.server.config.alipay;import org.springframework.context.annotation.Configuration;import java.io.FileWriter;
import java.io.IOException;/* **类名:AlipayConfig*功能:基础配置类*详细:设置帐户有关信息及返回路径*修改日期:2017-04-05*说明:*以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。*该代码仅供学习和研究支付宝接口使用,只是提供一个参考。*/
@Configuration
public class AlipayConfig {//↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号public static String app_id = "";// 商户私钥,您的PKCS8格式RSA2私钥public static String merchant_private_key = "";// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。public static String alipay_public_key = "";// 服务器"异步通知"页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问public static String notify_url = "http://工程公网访问地址/alipay.trade.page.pay-JAVA-UTF-8/notify_url.jsp";// 页面跳转"同步通知"页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问public static String return_url = "http://www.baidu.com";// 签名方式public static String sign_type = "";// 字符编码格式public static String charset = "";// 支付宝网关public static String gatewayUrl = "";// 支付宝网关public static String log_path = "D:\\aliPay";//↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑/*** 写日志,方便测试(看网站需求,也可以改成把记录存入数据库)** @param sWord 要写入日志里的文本内容*/public static void logResult(String sWord) {FileWriter writer = null;try {writer = new FileWriter(log_path + "alipay_log_" + System.currentTimeMillis() + ".txt");writer.write(sWord);} catch (Exception e) {e.printStackTrace();} finally {if (writer != null) {try {writer.close();} catch (IOException e) {e.printStackTrace();}}}}
}

(3)验证参数–跳转支付界面
  代码我也是直接copy,上面百度网盘里面有一个官方demo,这里的代码就是从一个jsp页面文件中copy下来的。代码我没有全部在controller里面写,感觉太长了,我给封装起来了。————路径、包你没有或者对不上的你就删掉:例如:swagger、logger、lombok等等,要是嫌弃加依赖麻烦,你就删掉或者注释就好了。

package com.sbw.server.utils;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.sbw.server.config.alipay.AlipayConfig;
import com.sbw.server.pojo.AliPayPojo;
import org.slf4j.LoggerFactory;/*** 沙箱支付工具类*/
public class PayUtil {private static final org.slf4j.Logger logger = LoggerFactory.getLogger(PayUtil.class);public static String aliPay(AliPayPojo aliPayPojo) {//获得初始化的AlipayClientAlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);//设置请求参数AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();alipayRequest.setReturnUrl(AlipayConfig.return_url);alipayRequest.setNotifyUrl(AlipayConfig.notify_url);商户订单号,商户网站订单系统中唯一订单号,必填//String out_trade_no = new String(request.getParameter("WIDout_trade_no").getBytes("ISO-8859-1"),"UTF-8");付款金额,必填//String total_amount = new String(request.getParameter("WIDtotal_amount").getBytes("ISO-8859-1"),"UTF-8");订单名称,必填//String subject = new String(request.getParameter("WIDsubject").getBytes("ISO-8859-1"),"UTF-8");商品描述,可空//String body = new String(request.getParameter("WIDbody").getBytes("ISO-8859-1"),"UTF-8");alipayRequest.setBizContent("{\"out_trade_no\":\"" + aliPayPojo.getWIDout_trade_no() + "\","+ "\"total_amount\":\"" + aliPayPojo.getWIDtotal_amount() + "\","+ "\"subject\":\"" + aliPayPojo.getWIDsubject() + "\","+ "\"body\":\"" + aliPayPojo.getWIDbody() + "\","+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");//若想给BizContent增加其他可选请求参数,以增加自定义超时时间参数timeout_express来举例说明//alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","//		+ "\"total_amount\":\""+ total_amount +"\","//		+ "\"subject\":\""+ subject +"\","//		+ "\"body\":\""+ body +"\","//		+ "\"timeout_express\":\"10m\","//		+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");//请求参数可查阅【电脑网站支付的API文档-alipay.trade.page.pay-请求参数】章节//请求String result = null;try {result = alipayClient.pageExecute(alipayRequest).getBody();AlipayConfig.logResult(result);} catch (AlipayApiException e) {e.printStackTrace();logger.error("=====================支付宝支付验证信息有误,还没有到支付界面======================");}//结果返回logger.info(result);logger.error("=====================支付宝支付验证信息正确,跳转到支付界面======================");return result;}
}

接收参数的实体:AliPayPojo

package com.sbw.server.pojo;import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class AliPayPojo {//商户订单号,商户网站订单系统中唯一订单号,必填private String WIDout_trade_no;//付款金额,必填private String WIDtotal_amount;//订单名称,必填private String WIDsubject;//商品描述,可空private String WIDbody;
}

controller:

package com.sbw.server.controller;
import com.sbw.server.pojo.AliPayPojo;
import com.sbw.server.utils.PayUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;@Api(tags = "操作员支付宝支付")
@RestController
@RequestMapping("/system/admin")
public class AliPay {@ApiOperation(value = "捐款支付宝支付")@PostMapping("/aliPay")public String getAllAdmin(@RequestBody AliPayPojo aliPayPojo){//支付封装结果返回String result = PayUtil.aliPay(aliPayPojo);//...写你的业务逻辑:健壮性的判断、生成某某东西入库等等//我这里简单粗暴,直接返回字符串,前端解析.....return result;}
}

4.测试

  测一下,测一下。我给自己冲了100W,虚拟的世界让人陶醉呀。😜,我写好才发现,我测试的时候只填了1块钱,拉胯呀,骨子里还是穷人啊。😭

前端页面:
支付宝之电脑网站支付(保姆版)-编程之家
如果你验证那一步没问题的话就会自动的跳转到支付页面,如下图:(如果你要问卖家和买家信息在哪里—–支付宝开发平台-沙箱环境-沙箱账号里面)
支付宝之电脑网站支付(保姆版)-编程之家
输入的账号密码正确跳转到真正的付款页
支付宝之电脑网站支付(保姆版)-编程之家
支付宝之电脑网站支付(保姆版)-编程之家
支付宝之电脑网站支付(保姆版)-编程之家

注意

(1)验签异常:仔细检查,如果公/私实在没问题的话,你去官方有个专门处理这个错误的地方,一步一步教你如何检查。
(2)前端接到跳转支付也的from表单的html代码,渲染和跳转的方法很多中,你们自己去百度一大推,我用的是最low的那种


小结

  总体下来大家应该也感觉的出来,全程代码都是复制过来了,基本上把官方给的demo看明白直接copy过来就好了,到了真实的项目中你知道大概个流程,找个老员工带你一次,可能都省你去API的时间,下次有新的需求就直接上手搞了。还有其他的支付形式,也都大差不差,主要要明白流程吧。(关于安全和效率性能的话那就另说了)。

废话一下

  以前老师总告诉我们最好的放松的方式就是安静的看一本书、跑个步,当时真的觉得躺在床上比什么放松方式都好,但是我现在真的认同这个观点。一天工作回到家不是直接躺在床上,而是看看书写点自己觉得有意义的文章真的是一件很放松的事情,比如说写文章,写着写着你会精神百倍,你会把所有工作中的烦恼和疲惫感抛之脑后。(如果你有女朋友那就两说了,和女朋友一起躺床上那…😈😈😈)
  我蛮想知道那些优质博主一篇文章五六万字还有更多,真的是一个一个字敲的嘛,他们是真的伟大的呀,我敲着1.4万字都感觉要好长时间呀,还要反复的改。

  如果有企业资质就爽了,个人开发限制太多了。我想搞个短信验证码登录,代码敲好了申请还没通过,好像目前阿里不给个人申请,要申请必须要求备案的网站,难顶。我果断去申请了一个腾讯云的短信服务,分分钟通过,这一点还是要表扬一下腾讯滴,虽然在我儿时骗了我不少钱,但是今天我要praise 一下。💞

  如果你也是菜鸡,那么咋们就菜鸡互啄一下,交流交流学习经验。如果您是行业大牛,路过一定要给我留下点您宝贵的指导意见,对您感激不尽。❤️💛💜

如果有错误,欢迎评论区讨论,谢谢大家。😉😉😉