购物网站补货提醒软件怎么做,织梦源码怎样做单页网站,网站项目建设申请汇报大纲,人人建站网目录 支付模块需求分析表设计支付单表支付宝账号信息表-商家账号微信支付账号信息表-商家账号银行账号表-商家资金账号表支付流水表 流程分析支付基础模块继承加密算法沙箱环境准备支付宝支付-流程分析根据demo封装工具类导入依赖AlipayConfigAlipayInfoAlipayUtil 内网穿透 领… 目录 支付模块需求分析表设计支付单表支付宝账号信息表-商家账号微信支付账号信息表-商家账号银行账号表-商家资金账号表支付流水表 流程分析支付基础模块继承加密算法沙箱环境准备支付宝支付-流程分析根据demo封装工具类导入依赖AlipayConfigAlipayInfoAlipayUtil 内网穿透 领养订单-支付流程后端生成支付单和进行支付AdoptOrderServiceImplPayConstantsPayBillPayBillServiceImpl测试 前台显示支付form表单前台完成支付异步回调通知后完成后续逻辑 订单与支付汇总流程图 每种订单都有对应类型的支付 支付模块
需求分析 资金账号支付账号 支付方式 支付单 支付流水
表设计 三种类型支付单表支付流水表支付方式表
支付单表
CREATE TABLE t_pay_bill (id bigint(20) NOT NULL AUTO_INCREMENT,digest varchar(100) DEFAULT NULL COMMENT 交易摘要,money decimal(11,2) NOT NULL COMMENT 金额,state tinyint(4) NOT NULL DEFAULT 0 COMMENT 支付状态 0待支付1 已支付-1 取消,lastPayTime datetime DEFAULT NULL,payChannel tinyint(4) NOT NULL COMMENT 支付方式 余额 三方支付支付宝微信银联,createTime datetime DEFAULT NULL,updateTime datetime DEFAULT NULL,unionPaySn char(15) DEFAULT NULL COMMENT 统一支付单号,businessType varchar(255) NOT NULL COMMENT 业务类型,businessKey bigint(20) NOT NULL COMMENT 关联业务键,user_id bigint(20) DEFAULT NULL,nickName varchar(255) DEFAULT ,shopName varchar(255) DEFAULT NULL,shop_id bigint(11) DEFAULT NULL,PRIMARY KEY (id)
) ENGINEInnoDB AUTO_INCREMENT30 DEFAULT CHARSETutf8 COMMENT支付单;1.订单模块生成订单 2.支付模块生成支付单 3.支付模块生成统一支付单号调三方接口进行支付 4.支付成功返回统一支付单号给支付模块支付模块根据统一支付单号找到订单修改状态 5.订单模块根据支付模块的订单类型和订单号找到订单修改订单状态
支付宝账号信息表-商家账号
CREATE TABLE t_pay_alipay_info (id bigint(20) NOT NULL AUTO_INCREMENT,shop_id bigint(20) DEFAULT NULL,shopName varchar(255) DEFAULT NULL,appid varchar(255) DEFAULT NULL COMMENT 应用id,merchant_private_key varchar(2500) DEFAULT NULL COMMENT 商家私钥,alipay_public_key varchar(2500) DEFAULT NULL COMMENT 支付宝公钥,PRIMARY KEY (id)
) ENGINEInnoDB AUTO_INCREMENT2 DEFAULT CHARSETutf8;微信支付账号信息表-商家账号
CREATE TABLE t_pay_wechat_info (merchant_private_key varchar(2500) DEFAULT NULL,appid varchar(255) DEFAULT NULL,id bigint(20) NOT NULL AUTO_INCREMENT,alipay_public_key varchar(2500) DEFAULT NULL,shop_id bigint(20) DEFAULT NULL,shopName varchar(255) DEFAULT NULL,PRIMARY KEY (id)
) ENGINEInnoDB AUTO_INCREMENT2 DEFAULT CHARSETutf8;银行账号表-商家
CREATE TABLE t_pay_bank_info (merchant_private_key varchar(2500) DEFAULT NULL,appid varchar(255) DEFAULT NULL,id bigint(20) NOT NULL AUTO_INCREMENT,alipay_public_key varchar(2500) DEFAULT NULL,shop_id bigint(20) DEFAULT NULL,shopName varchar(255) DEFAULT NULL,PRIMARY KEY (id)
) ENGINEInnoDB AUTO_INCREMENT2 DEFAULT CHARSETutf8;资金账号表
CREATE TABLE t_pay_account (id bigint(20) NOT NULL AUTO_INCREMENT,createTime datetime DEFAULT NULL,updateTime datetime DEFAULT NULL,user_id bigint(20) NOT NULL COMMENT 用户ID,useableBalance int(11) NOT NULL DEFAULT 0 COMMENT 可用金额,frozenBalance int(11) NOT NULL DEFAULT 0 COMMENT 冻结金额,creditBanance int(11) NOT NULL DEFAULT 0 COMMENT 积分,salt varchar(255) DEFAULT NULL,payPassword varchar(32) NOT NULL COMMENT 支付密码 md5加密加盐,PRIMARY KEY (id)
) ENGINEInnoDB DEFAULT CHARSETutf8 COMMENT用户账户;支付流水表
CREATE TABLE t_pay_account_flow (id bigint(20) NOT NULL AUTO_INCREMENT,createTime bigint(20) DEFAULT NULL,user_id bigint(20) NOT NULL COMMENT 用户ID,nickName varchar(20) DEFAULT NULL COMMENT 用户姓名,money decimal(11,2) NOT NULL COMMENT 金额,type tinyint(4) NOT NULL COMMENT 支付方式,businessType varchar(4) NOT NULL COMMENT 业务类型,businessName varchar(20) NOT NULL COMMENT 业务名,businessKey bigint(20) NOT NULL COMMENT 关联业务键,payChannel tinyint(4) NOT NULL,payChannelName varchar(20) NOT NULL,note varchar(50) DEFAULT NULL COMMENT 备注,digest varchar(100) DEFAULT NULL,unionPaySeq char(15) DEFAULT NULL COMMENT 统一支付单号,PRIMARY KEY (id)
) ENGINEInnoDB DEFAULT CHARSETutf8 COMMENT用户支付流水;流程分析
结合上面内容 https://opendocs.alipay.com/open/00a0ut 电脑网站支付 - 产品介绍 - 流程介绍
支付基础模块继承
拷贝java和xml代码配置yml扫描别名
加密算法 沙箱环境准备
在线加密生成自己的公钥和私钥 把自己的公钥告诉支付宝并得到支付宝的公钥 保存自己的 appid 私钥 和支付宝的公钥到数据库表里
支付宝支付-流程分析
https://opendocs.alipay.com/open/00a0ut 电脑网站支付 - 接入指南 - 电脑网站支付快速接入 - 流程介绍 根据订单生成支付单后调支付接口要传同步通知地址和异步通知地址
支付平台返回string(内容是一个支付表单)给后端后端将这个String交给前端到浏览器显示
中间的步骤由用户与支付宝他们自己完成
支付完成后三重返回保证 1.同步通知只做重定向页面通知 2.异步通知以此为准收到后分别去更改支付单和订单的状态 3.主动用统一支付单号去支付宝查询状态
根据demo封装工具类
导入依赖
!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-sdk-java --
dependencygroupIdcom.alipay.sdk/groupIdartifactIdalipay-sdk-java/artifactIdversion3.7.4.ALL/version
/dependencyAlipayConfig
public class AlipayConfig {// 服务器异步通知路径 需http://格式的完整路径不能加?id123这类自定义参数必须外网可以正常访问public static String notify_url http://c84pns.natappfree.cc/notify;// 页面跳转同步通知页面路径 需http://格式的完整路径不能加?id123这类自定义参数必须外网可以正常访问public static String return_url http://localhost/success.html;// 签名方式public static String sign_type RSA2;// 字符编码格式public static String charset utf-8;// 测试环境支付宝网关public static String gatewayUrl https://openapi.alipaydev.com/gateway.do;
}AlipayInfo
Data
public class AlipayInfo extends BaseDomain {private String merchant_private_key;//我的私钥private String appid;//我的AppIDprivate String alipay_public_key;//支付宝公钥private Long shop_id;private String shopName;}AlipayUtil
public class AlipayUtil {public static String pay(AlipayInfo info, PayBill payBill){try {//获得初始化的AlipayClientAlipayClient alipayClient new DefaultAlipayClient(cn.ming.pay.utils.AlipayConfig.gatewayUrl,info.getAppid(),info.getMerchant_private_key(),json,cn.ming.pay.utils.AlipayConfig.charset,info.getAlipay_public_key(),cn.ming.pay.utils.AlipayConfig.sign_type);//设置请求参数AlipayTradePagePayRequest alipayRequest new AlipayTradePagePayRequest();alipayRequest.setReturnUrl(cn.ming.pay.utils.AlipayConfig.return_url);alipayRequest.setNotifyUrl(cn.ming.pay.utils.AlipayConfig.notify_url);//商户订单号商户网站订单系统中唯一订单号必填String out_trade_no payBill.getUnionPaySn();//付款金额必填String total_amount payBill.getMoney().toString();//订单名称必填String subject payBill.getDigest();//商品描述可空String body payBill.getDigest();alipayRequest.setBizContent({\out_trade_no\:\ out_trade_no \, \total_amount\:\ total_amount \, \subject\:\ subject \, \body\:\ body \, \product_code\:\FAST_INSTANT_TRADE_PAY\});//请求String result alipayClient.pageExecute(alipayRequest).getBody();return result;} catch (AlipayApiException e) {e.printStackTrace();}return null;}}内网穿透
使用内网穿透将本地的异步通知地址暴露到公网上供外网访问
官网首页https://natapp.cn/ NATAPP1分钟快速新手图文教程https://natapp.cn/article/natapp_newbie
购买隧道 - 免费 名称pethome隧道协议web本地端口8080 - 免费购买 查看我的隧道得到authtoken
下载客户端解压至任意目录得到natapp.exe
同文件夹下新建config.ini文件输入authtokenxxx保存
双击natapp.exe得到公网可用域名
配置以下两个回调地址
// 服务器异步通知路径 需http://格式的完整路径不能加?id123这类自定义参数必须外网可以正常访问
public static String notify_url http://254fde.natappfree.cc/notify;
// 页面跳转同步通知页面路径 需http://格式的完整路径不能加?id123这类自定义参数必须外网可以正常访问
public static String return_url http://localhost/success.html;ph-web拷贝success.html到根目录编码异步回调notify接口
AlipayController PostMapping(/notify)public void notify(HttpServletRequest request){System.out.println(支付宝异步回调);}领养订单-支付流程
后端生成支付单和进行支付
AdoptOrderServiceImpl /*** 领养订单结算*/OverrideTransactionalpublic String submit(MapString, Object params, Logininfo loginIn) {Long petId Long.valueOf(params.get(pet_id).toString());Long addressId Long.valueOf(params.get(address_id).toString());//收货地址t_user_address的idInteger payMethod Integer.valueOf(params.get(pay_method).toString());//1 支付宝 2 微信 3 银联 0 余额Integer serviceMethod Integer.valueOf(params.get(service_method).toString());//送货方式//1.修改状态 准备下架Pet pet petMapper.loadById(petId);pet.setState(0);pet.setOffsaletime(new Date());//2.绑定用户User user userMapper.loadByloginInfoId(loginIn.getId());pet.setUser(user);pet.setUser_id(user.getId());pet.setShop_id(pet.getShop().getId());petMapper.update(pet);//3.生成订单 一次性AdoptOrder order initAdoptOrder(pet, user);//骚操作为了后边操作支付单不用再来修改订单先生成统一的支付单号String unionPaySn CodeGenerateUtils.generateUnionPaySn();order.setPaySn(unionPaySn);adoptOrderMapper.save(order);// 3.1 生成订单地址UserAddress userAddress userAddressMapper.loadById(addressId);OrderAddress orderAddress userAddress2OrderAddress(order, userAddress);orderAddressMapper.save(orderAddress);// 4.支付单PayBill payBill initPayBill(payMethod, pet, user, order);payBillMapper.save(payBill);//调用统一支付接口老杨定义的return payBillService.pay(payBill);// 5.订单定时取消任务 TODO}private AdoptOrder initAdoptOrder(Pet pet, User user) {AdoptOrder order new AdoptOrder();order.setDigest(【摘要】 pet.getName());order.setPrice(pet.getSaleprice());order.setOrderSn(CodeGenerateUtils.generateOrderSn(user.getId()));order.setLastConfirmTime(new Date(System.currentTimeMillis() 15*60*1000));//最后确认时间order.setPet_id(pet.getId());order.setUser_id(user.getId());order.setShop_id(pet.getShop().getId());return order;}private OrderAddress userAddress2OrderAddress(AdoptOrder order, UserAddress userAddress) {OrderAddress orderAddress new OrderAddress();BeanUtils.copyProperties(userAddress, orderAddress);orderAddress.setId(null);orderAddress.setOrder_id(order.getId());orderAddress.setOrderSn(order.getOrderSn());return orderAddress;}Overridepublic PageListAdoptOrder queryAdmin(AdoptOrderQuery query, Long loginInfoId) {//1.通过loginInfoID查询出EmployeeEmployee employee employeeMapper.loadByLoginInfoId(loginInfoId);//2.如果employee中的shopID不为null,就是店铺。否则就是平台员工if (employee.getShop_id() ! null) {query.setShopId(employee.getShop_id());}return super.queryPage(query);}Overridepublic PageListAdoptOrder queryUser(AdoptOrderQuery query, Long loginInfoId) {User user userMapper.loadByloginInfoId(loginInfoId);query.setUserId(user.getId());return super.queryPage(query);}private PayBill initPayBill(Integer payMethod, Pet pet, User user, AdoptOrder order) {PayBill payBill new PayBill();payBill.setDigest(order.getDigest()支付单);payBill.setMoney(order.getPrice());//重点支付唯一表示payBill.setUnionPaySn(order.getPaySn());payBill.setLastPayTime(new Date(System.currentTimeMillis() PayConstants.LAST_TIME));payBill.setPayChannel(Long.valueOf(payMethod));//0 余额 1 支付宝 2 微信 3 银联payBill.setBusinessType(PayConstants.BUSINESS_TYPE_ADOPT);payBill.setBusinessKey(order.getId());payBill.setUser_id(user.getId());payBill.setShop_id(pet.getShop().getId());payBill.setNickName(user.getUsername());return payBill;}PayConstants
public class PayConstants {public static final Integer LAST_TIME 15*60*1000;//领养订单public static final String BUSINESS_TYPE_ADOPT business_type_adopt;//服务订单public static final String BUSINESS_TYPE_PRODUCT business_type_product;//收购订单public static final String BUSINESS_TYPE_ACQUISITION business_type_acquisition;//商品订单public static final String BUSINESS_TYPE_GOODS business_type_goods;//充值订单public static final String BUSINESS_TYPE_RECHARGE business_type_recharge;}PayBill
Data
public class PayBill extends BaseDomain {private String digest;private BigDecimal money;private String unionPaySn;private Integer state 0;//0待支付1 已支付-1 取消private Date lastPayTime;private Long payChannel; //0 余额 1 支付宝 2 微信 3 银联private String businessType;private Long businessKey;private Date updateTime;private Date createTime new Date();private Long user_id;private Long shop_id;private String nickName;
}PayBillServiceImpl Overridepublic String pay(PayBill payBill) {if(payBill null){throw new BusinessException(请生成支付单后在进行支付);}PayBill payBill1 payBillMapper.loadByUnionPaySn(payBill.getUnionPaySn());if(payBill1 null){throw new BusinessException(请生成支付单后在进行支付);}Long payChannel payBill1.getPayChannel();String resultData ;switch(payChannel.intValue()){case 1 ://支付宝AlipayInfo info alipayInfoMapper.loadByShopId(payBill1.getShop_id());resultData AlipayUtil.pay(info, payBill1);break;case 2 ://微信//TODObreak;case 3 ://银联//TODObreak;default : //0 余额//TODO}return resultData;}测试
adoptOrder.html methods: {orderSubmit() {this.$http.post(/adopt/submit, this.order).then(result {console.log(result.data);// $(#alipayForm).html(result.data.resultObj);// location.href personCenter.html;}).catch(result {alert(系统错误);})}},前台显示支付form表单
div idalipayForm/divmethods: {orderSubmit() {this.$http.post(/adopt/submit, this.order).then(result {console.log(result.data);$(#alipayForm).html(result.data.resultObj);// location.href personCenter.html;}).catch(result {alert(系统错误);})}},前台完成支付
form表单显示后会展示支付宝扫码或登录页面完成支付后跳转到success回调页面可从url取到unionPaySn查询数据显示到success页面。
异步回调通知后完成后续逻辑
AlipayController PostMapping(/notify)public void notify(HttpServletRequest request){System.out.println(支付宝异步回调);//获取支付宝POST过来反馈信息try {MapString,String params new HashMapString,String();MapString,String[] requestParams request.getParameterMap();for (IteratorString iter requestParams.keySet().iterator(); iter.hasNext();) {String name (String) iter.next();String[] values (String[]) requestParams.get(name);String valueStr ;for (int i 0; i values.length; i) {valueStr (i values.length - 1) ? valueStr values[i]: valueStr values[i] ,;}valueStr new String(valueStr);params.put(name, valueStr);}String unionPaySn params.get(out_trade_no);PayBill payBill payBillService.loadByUnionPaySn(unionPaySn);if(payBill ! null){AlipayInfo info alipayInfoService.getByShopId(payBill.getShop_id());boolean signVerified AlipaySignature.rsaCheckV1(params,info.getAlipay_public_key(),AlipayConfig.charset,AlipayConfig.sign_type); //调用SDK验证签名if(signVerified) {//验证成功//商户订单号String out_trade_no unionPaySn;//支付宝交易号String trade_no request.getParameter(trade_no);//交易状态String trade_status request.getParameter(trade_status);if(trade_status.equals(TRADE_FINISHED)){//用户确认}else if (trade_status.equals(TRADE_SUCCESS)){//1. 改支付单状态payBill.setState(1);payBill.setUpdateTime(new Date());payBillService.update(payBill);String businessType payBill.getBusinessType();//2.再修改对应领养的订单状态 businessType businessKey 订单if(PayConstants.BUSINESS_TYPE_ADOPT.equals(businessType)){//领养订单Long orderId payBill.getBusinessKey();AdoptOrder order adoptOrderService.getById(orderId);order.setState(1);adoptOrderService.update(order);}}}else {//验证失败System.out.println(老宋不要搞事);//调试用写文本函数记录程序运行情况是否正常//String sWord AlipaySignature.getSignCheckContentV1(params);//AlipayConfig.logResult(sWord);}}} catch (AlipayApiException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}订单与支付汇总流程图