文章目录

  • 环境介绍
    • 开发环境
    • 前期准备工作:
  • 支付宝支付Controller
  • 支付宝管理Service实现类(Service没啥看的,就不贴了)

环境介绍

开发环境

实际生产环境,每次测试需要0.01元的巨资;使用的为前端为uiapp 后端为spring boot框架

前期准备工作:

通过支付宝平台注册获取商户appid,使用密钥工具(Windows,ios)生成商家的公私密钥,通过用户的公钥在支付宝端进行注册,形成支付宝公钥

支付宝密钥支付流程

###在pom中导入maven依赖

<!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-sdk-java --><dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-sdk-java</artifactId><version>4.10.97.ALL</version></dependency>

以下为配置类

import org.springframework.context.annotation.Configuration;
@Configuration
public class AliPayConfig {// 商户appidpublic static String APPID = "保密";// 私钥 pkcs8格式的public static String RSA_PRIVATE_KEY = "保密";// 服务器异步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问public static String notify_url = "http://保密:8085/Alipay/notify";// 页面跳转同步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 商户可以自定义同步跳转地址public static String return_url = "http://商户网关地址/alipay.trade.wap.pay-JAVA-UTF-8/return_url.jsp";// 请求网关地址public static String gatewayUrl = "https://openapi.alipay.com/gateway.do";// 编码public static String CHARSET = "UTF-8";// 返回格式public static String FORMAT = "json";// 支付宝公钥public static String ALIPAY_PUBLIC_KEY = "保密";// 日志记录目录public static String log_path = "/log";// RSA2public static String SIGNTYPE = "RSA2";
}

还是配置类,主要是通过Bean来管理了创建DefaultAlipayClient,避免之后每次调用都要写一堆参数去new


import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;@Slf4j
@Component
@Configuration
public class AliPayClientConfig {@Resourceprivate AliPayConfig alipayConfig;/*** 支付宝gatewayUrl*/private String gatewayUrl = alipayConfig.gatewayUrl;/*** 商户应用id*/private String appid = alipayConfig.APPID;/*** RSA私钥,用于对商户请求报文加签*/private String appPrivateKey = alipayConfig.RSA_PRIVATE_KEY;/*** 支付宝RSA公钥,用于验签支付宝应答*/private String alipayPublicKey = alipayConfig.ALIPAY_PUBLIC_KEY;/*** 签名类型*/private String signType = alipayConfig.SIGNTYPE;/*** 格式*/private String formate = alipayConfig.FORMAT;/*** 编码*/private String charset = alipayConfig.CHARSET;/*** 同步地址*/private String returnUrl = alipayConfig.return_url;/*** 异步地址*/private String notifyUrl = alipayConfig.notify_url;/*** 最大查询次数*/private static int maxQueryRetry = 5;/*** 查询间隔(毫秒)*/private static long queryDuration = 5000;/*** 最大撤销次数*/private static int maxCancelRetry = 3;/*** 撤销间隔(毫秒)*/private static long cancelDuration = 3000;public String getAppid() {return appid;}public void setAppid(String appid) {this.appid = appid;}public String getAppPrivateKey() {return appPrivateKey;}public void setAppPrivateKey(String appPrivateKey) {this.appPrivateKey = appPrivateKey;}public String getAlipayPublicKey() {return alipayPublicKey;}public void setAlipayPublicKey(String alipayPublicKey) {this.alipayPublicKey = alipayPublicKey;}public String getSignType() {return signType;}public void setSignType(String signType) {this.signType = signType;}public String getFormate() {return formate;}public void setFormate(String formate) {this.formate = formate;}public String getCharset() {return charset;}public void setCharset(String charset) {this.charset = charset;}public String getGatewayUrl() {return gatewayUrl;}public void setGatewayUrl(String gatewayUrl) {this.gatewayUrl = gatewayUrl;}public String getReturnUrl() {return returnUrl;}public void setReturnUrl(String returnUrl) {this.returnUrl = returnUrl;}public String getNotifyUrl() {return notifyUrl;}public void setNotifyUrl(String notifyUrl) {this.notifyUrl = notifyUrl;}@Beanpublic AlipayClient alipayClient(){return new DefaultAlipayClient(this.getGatewayUrl(),this.getAppid(),this.getAppPrivateKey(),this.getFormate(),this.getCharset(),this.getAlipayPublicKey(),this.getSignType());}
}

支付宝支付Controller

C层本来不该写业务逻辑的,那时为了测试方便就没改回来,见谅,我还是个小菜。
请求参数之后我会封装一下,大家勉强看看吧,支付部分都通了

import com.commerce.mall.common.api.CommonResult;
import com.commerce.mall.mapper.OmsOrderMapper;
import com.commerce.mall.model.OmsOrder;
import com.commerce.mall.model.OmsOrderExample;
import com.commerce.mall.portal.service.AlipayOrderService;
import io.micrometer.core.instrument.util.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;/*** 支付宝支付Controller*/
@Api(tags = "AlipayOrderController", description = "支付宝支付相关接口 测试中")
@RestController
@SpringBootApplication
@RequestMapping("/Alipay")
public class AliPayOrderController {@Autowiredprivate AlipayOrderService alipayOrderService;@Autowiredprivate OmsOrderMapper omsOrderMapper;/*** 创建订单*/@ApiOperation(value = "创建订单", notes = "支付宝支付创建订单")@PostMapping("/createOrder")public CommonResult createOrder(@ApiParam(value = "说明:商户网站唯一订单号") @RequestParam String orderSn,@ApiParam(value = "说明:订单总金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000]") @RequestParam Double total_amount,@ApiParam(value = "说明:商品的标题/交易标题/订单标题/订单关键字等") @RequestParam String subject,@ApiParam(value = "商品描述") @RequestParam String body) {try {// 1、验证订单是否存在OmsOrderExample omsOrder = new OmsOrderExample();omsOrder.createCriteria().andOrderSnEqualTo(orderSn);long count = omsOrderMapper.countByExample(omsOrder);int newcount = (int)count;if(newcount < 1){return CommonResult.failed("订单不存在,订单生成失败");}// 2、创建支付宝订单String orderStr = alipayOrderService.createOrder(orderSn, total_amount, subject,body);return CommonResult.success("data", orderStr);} catch (Exception e) {return CommonResult.failed("订单生成失败"+e);}}/*** 支付异步通知* 接收到异步通知并验签通过后,一定要检查通知内容,* 包括通知中的app_id、out_trade_no、total_amount是否与请求中的一致,并根据trade_status进行后续业务处理。* https://docs.open.alipay.com/194/103296*/@ApiOperation(value = "支付异步通知", notes = "接收到异步通知并验签通过后,一定要检查通知内容")@PostMapping("/notify")public String notify(HttpServletRequest request) {// 验证签名,确保是支付宝返回的boolean flag = alipayOrderService.rsaCheckV1(request);if (flag) {String tradeStatus = request.getParameter("trade_status"); // 交易状态String outTradeNo = request.getParameter("out_trade_no"); // 商户订单号String tradeNo = request.getParameter("trade_no"); // 支付宝订单号String totalAmount = request.getParameter("total_amount"); // 本次交易支付的订单金额String sellerId = request.getParameter("seller_id"); // 收款支付宝账号对应的支付宝唯一用户号String notify_time = request.getParameter("notify_time"); // 通知的发送时间。格式为yyyy-MM-dd HH:mm:ssString trade_status = request.getParameter("trade_status"); // 交易目前所处的状态/*** 还可以从request中获取更多有用的参数,自己尝试*/boolean notify = alipayOrderService.notify(tradeStatus, outTradeNo, tradeNo,totalAmount,sellerId,notify_time,trade_status);if(notify){return "success";}}return "fail";}@ApiOperation(value = "查询订单", notes = "查询订单,半成品,禁止调用")@PostMapping("/cheak")public CommonResult checkAlipay(@ApiParam(value = "订单号") @RequestParam String orderNo) {if(StringUtils.isBlank(orderNo)){return CommonResult.failed("订单编号不能为空");}String aByte = alipayOrderService.checkAlipay(orderNo);return CommonResult.success("data",aByte);}@ApiOperation(value = "退款", notes = "退款,半成品")@PostMapping("/refund")public CommonResult refund(@ApiParam(value = "订单号") @RequestParam String orderNo,@ApiParam(value = "退款金额") @RequestParam double amount,@ApiParam(value = "退款原因") @RequestParam(required = false) String refundReason) {if(StringUtils.isBlank(orderNo)){return CommonResult.failed("订单编号不能为空");}if(amount <= 0){return CommonResult.failed("退款金额必须大于0");}String refund = alipayOrderService.refund(orderNo, amount, refundReason);if (StringUtils.isBlank(refund)){return CommonResult.failed("失败");}return CommonResult.success("退款成功");}}

支付宝管理Service实现类(Service没啥看的,就不贴了)

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.commerce.mall.mapper.OmsAlipayFlowMapper;
import com.commerce.mall.mapper.OmsOrderMapper;
import com.commerce.mall.model.*;
import com.commerce.mall.portal.config.AliPayClientConfig;
import com.commerce.mall.portal.service.AlipayOrderService;
import io.micrometer.core.instrument.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;/*** 支付宝管理Service实现类*/
@Service
public class AlipayOrderServiceImpl implements AlipayOrderService {private final Logger logger = LoggerFactory.getLogger(AlipayOrderServiceImpl.class);@Autowiredprivate AliPayClientConfig alipayClientConfig;@Autowiredprivate OmsOrderMapper omsOrderMapper;@Autowiredprivate OmsAlipayFlowMapper omsAlipayFlowMapper;@Overridepublic String createOrder(String orderSn, Double total_amount, String subject, String body) throws AlipayApiException {//SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();model.setOutTradeNo(orderSn);model.setSubject(subject);model.setTotalAmount(String.valueOf(total_amount));model.setBody(body);//model.setPassbackParams("公用回传参数,如果请求时传递了该参数,则返回给商户时会回传该参数");model.setProductCode("QUICK_MSECURITY_PAY");// 该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天 (屁股后面的字母一定要带,不然报错)model.setTimeoutExpress("30m");    ////实例化具体API对应的request类,类名称和接口名称对应,app支付接口2.0//https://opendocs.alipay.com/apis/api_1/alipay.trade.app.payAlipayTradeAppPayRequest ali_request = new AlipayTradeAppPayRequest();ali_request.setBizModel(model);ali_request.setNotifyUrl(alipayClientConfig.getNotifyUrl());// 回调地址//就是orderString 可以直接给客户端请求,无需再做处理。try {// 注意这里是sdkExecute方法, 如果是网页支付的话调用pageExecute方法return alipayClientConfig.alipayClient().sdkExecute(ali_request).getBody();} catch (AlipayApiException e) {e.printStackTrace();throw new RuntimeException("支付异常");}}@Overridepublic boolean notify(String tradeStatus, String orderNo, String tradeNo,String totalAmount,String sellerId,String notify_time,String trade_status)   {if ("TRADE_FINISHED".equals(tradeStatus)|| "TRADE_SUCCESS".equals(tradeStatus)) {// 支付成功,根据业务逻辑修改相应数据的状态//修改订单表状态OmsOrder omsOrder = new OmsOrder();omsOrder.setId(Long.parseLong(orderNo));//支付方式:0->未支付;1->支付宝;2->微信omsOrder.setPayType(1);//订单状态:0->待付款;1->待发货;2->已发货;3->已完成;4->已关闭;5->无效订单;6->售后omsOrder.setStatus(1);int i = omsOrderMapper.updateByPrimaryKeySelective(omsOrder);//创建支付宝流水记录OmsAlipayFlow alipayFlow = new OmsAlipayFlow();alipayFlow.setOrderSn(orderNo);alipayFlow.setTradeNo(tradeNo);alipayFlow.setTotalAmount(new BigDecimal(totalAmount));alipayFlow.setSellerId(Long.parseLong(sellerId));//把string转化为datetry {alipayFlow.setNotifyTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(notify_time));} catch (ParseException e) {e.printStackTrace();return false;}alipayFlow.setTradeStatus(trade_status);int insert = omsAlipayFlowMapper.insert(alipayFlow);if (i>0 && insert>0) {return true;}}return false;}
//开放平台 SDK 提供了 AlipaySignature.rsaCertCheckV1 方法,可以使用该方法对通知报文验签。
//生活号异步通知需要使用 AlipaySignature.rsaCertCheckV2 方法,会保留 sign_type 参数参与验签。@Overridepublic boolean rsaCheckV1(HttpServletRequest request){try {Map<String, String> params = new HashMap<>();Map<String, String[]> requestParams = request.getParameterMap();for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {String name = (String) iter.next();String[] values = requestParams.get(name);String valueStr = "";for (int i = 0; i < values.length; i++) {valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";}params.put(name, valueStr);}boolean verifyResult = AlipaySignature.rsaCheckV1(params, alipayClientConfig.getAlipayPublicKey(), alipayClientConfig.getCharset(), alipayClientConfig.getSignType());return verifyResult;} catch (AlipayApiException e) {logger.debug("verify sigin error, exception is:{}", e);return false;}}@Overridepublic String checkAlipay(String outTradeNo) {logger.info("==================向支付宝发起查询,查询商户订单号为:"+outTradeNo);try {AlipayTradeQueryRequest alipayTradeQueryRequest = new AlipayTradeQueryRequest();alipayTradeQueryRequest.setBizContent("{" +"\"out_trade_no\":\""+outTradeNo+"\"" +"}");AlipayTradeQueryResponse alipayTradeQueryResponse = alipayClientConfig.alipayClient().execute(alipayTradeQueryRequest);if(alipayTradeQueryResponse.isSuccess()){//业务逻辑具体看个人 这不展示了switch (alipayTradeQueryResponse.getTradeStatus()) // 判断交易结果{case "TRADE_FINISHED": // 交易结束并不可退款//            修改订单状态的代码return "TRADE_FINISHED 交易结束并不可退款";//   break;case "TRADE_SUCCESS": // 交易支付成功//         修改订单状态的代码return "TRADE_SUCCESS 交易支付成功";//    break;case "TRADE_CLOSED": // 未付款交易超时关闭或支付完成后全额退款//            修改订单状态的代码return "TRADE_CLOSED 未付款交易超时关闭或支付完成后全额退款";//   break;case "WAIT_BUYER_PAY": // 交易创建并等待买家付款//          修改订单状态的代码return "WAIT_BUYER_PAY 交易创建并等待买家付款";//    break;default:break;}
//                 更新表记录
//                return alipaymentOrder.getTradeStatus();return (alipayTradeQueryResponse).toString();} else {logger.info("==================调用支付宝查询接口失败!");return "调用支付宝查询接口失败";}} catch (AlipayApiException e) {// TODO Auto-generated catch blocke.printStackTrace();}return null;}@Overridepublic String refund(String orderNo, double amount, String refundReason) {AlipayTradeRefundModel model=new AlipayTradeRefundModel();// 商户订单号model.setOutTradeNo(orderNo);// 退款金额model.setRefundAmount(String.valueOf(amount));// 退款原因model.setRefundReason(refundReason);// 退款订单号(同一个订单可以分多次部分退款,当分多次时必传)// model.setOutRequestNo(UUID.randomUUID().toString());AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();alipayRequest.setBizModel(model);AlipayTradeRefundResponse alipayResponse = null;try {alipayResponse = alipayClientConfig.alipayClient().execute(alipayRequest);} catch (AlipayApiException e) {logger.error("订单退款失败,异常原因:{}", e);}if(alipayResponse != null){String code = alipayResponse.getCode();String subCode = alipayResponse.getSubCode();String subMsg = alipayResponse.getSubMsg();if("10000".equals(code)&& StringUtils.isBlank(subCode)&& StringUtils.isBlank(subMsg)){// 表示退款申请接受成功,结果通过退款查询接口查询// 修改用户订单状态为退款OmsOrder omsOrder = new OmsOrder();omsOrder.setId(Long.parseLong(orderNo));//订单状态:0->待付款;1->待发货;2->已发货;3->已完成;4->已关闭;5->无效订单;6->售后omsOrder.setStatus(4);int i = omsOrderMapper.updateByPrimaryKeySelective(omsOrder);//创建支付宝流水记录OmsAlipayFlow alipayFlow = new OmsAlipayFlow();//TRADE_CLOSED 未付款交易超时关闭,或支付完成后全额退款alipayFlow.setTradeStatus("TRADE_CLOSED");OmsAlipayFlowExample example = new OmsAlipayFlowExample();example.createCriteria().andOrderSnNotEqualTo(orderNo);int insert = omsAlipayFlowMapper.updateByExampleSelective(alipayFlow,example);if (i>0 && insert>0) {return "订单退款成功";}}return null;}return null;}
}

Africa项目之支付部分(一、对接支付宝)相关推荐

  1. android支付功能开发,对接支付宝支付接口开发详细步骤

    对接支付宝支付接口,官方文档已经写的很清楚了,但是也有很多像我一样的小白,第一次对接支付宝支付接口,会有些迷茫,所以我在此写下这篇文章,给我和我一样的同学,一点思路吧. 第一步:(先要在支付宝进行操做 ...

  2. 网站对接支付宝进行支付

    本文介绍PC网页对接支付宝,完成批量向支付宝账户转账的功能(使用Java实现),首先我的水平是这样的:接到这个工作任务后,可以说我是大白,之前我做过银行的项目,懂签名和验签是怎么一回事,但是对接支付宝 ...

  3. 项目场景:对接支付宝支付,沙箱环境提示:支付存在钓鱼风险!防钓鱼网站的方法

    项目场景:对接支付宝支付,沙箱环境提示:支付存在钓鱼风险!防钓鱼网站的方法 问题描述: 对接中遇到的问题: 原因分析: 提示:浏览器的锅 解决方案: 关闭所有窗口,只打开那个支付页面窗口就可以 转载h ...

  4. django手机访问_Django对接支付宝电脑网站、App支付步骤详解!这个框架是真强!...

    一.前言 本文主要针对 Python for Django 在对接支付宝电脑网站.手机网站.App支付过程中具体实现步骤进行详解: 相信大家支付功能也写了不少,但时间一长,再次用到的时候有些细节难免会 ...

  5. java 对接支付宝支付

    2019独角兽企业重金招聘Python工程师标准>>> 对接支付宝支付的前提: 1,商户开通支付能力 登录蚂蚁金服 开放平台:https://open.alipay.com/plat ...

  6. JAVA对接支付宝支付(超详细,一看就懂)

    Java对接支付宝支付 更多内容 冷文博客: 传送门 引入 为什么要发这篇帖子呢?原因很简单,就是因为在一个稍稍正规一点的应用上都会有支付这个环节,我们日常的在线支付如今包括支付宝,微信钱包,QQ钱包 ...

  7. java SpringBoot 对接支付宝 APP支付 证书模式及非证书模式

    一. 添加maven依赖 sdk <dependency><groupId>com.alipay.sdk</groupId><artifactId>al ...

  8. 对接支付宝App支付和网页支付接口详解

    之前在项目中使用过支付宝的沙箱测试支付和实际开发支付,是关于App对接支付宝接口的,由于前段时间有朋友询问怎么对接网页支付,通过研究支付包的开发文档,在这里总结一下对接支付宝的App支付接口和网页支付 ...

  9. java对接支付宝支付

    java对接支付宝支付演示 现在有不少的项目都需要对接支付,这里主要是进行讲解对接支付宝H5支付 废话不多说 上代码 引入支付宝官方的sdk <!-- https://mvnrepository ...

最新文章

  1. 联邦学习fate笔记小结
  2. C语言语句单选题,C语言练习题
  3. 前端和后端开发人员比例_前端开发人员vs后端开发人员–实践中的定义和含义
  4. 纪念数学家、系统与控制学家关肇直院士《泛函分析》
  5. 可以用JAVA编程的物联网开发板,了解一下?
  6. 20140923 cin.get() getline cin
  7. 数据结构——图-有向带权图的邻接表基础
  8. 检测电脑硬件的软件_【软件分享】PowerDVD | PotPlayer | AIDA64
  9. RDS关系型数据库服务
  10. 迁移Exchange Server 2003
  11. MS SQL 数据库状态为SUSPECT的处理方法
  12. python基础-文件处理与函数
  13. cacti linux io,【cacti】Linux磁盘I/O监控
  14. dell linux 无线网卡驱动,DELL D630安装CentOS6的无线网卡驱动
  15. eclipse运行不了jsp代码,错误代码:couldn't create the java virtual machine. a fatal exception has occurred.
  16. 英语单词词性顺口溜_英语十大词性口诀
  17. Dataset的用法简析
  18. 36 | 职业发展:应聘安全工程师,我需要注意什么?
  19. java学习笔记-基础篇
  20. vue 生命周期(详解)

热门文章

  1. 盘点:2016年度WiFi行业十大事件
  2. 【_ 記 】Java Calendar类详解(今年 本月 今日 去年 上月 昨日)
  3. 对翁大师C的一点想法
  4. 《认知觉醒》心得记录
  5. Spring对事务的操作
  6. 黑白激光打印机打印时出现黑道,怎么办?
  7. API接口名称(item_search - 京东按关键字搜索商品)[item_search,item_get,item_search_shop等]
  8. fcrackzip暴力破解zip密码
  9. Android A4尺寸 canvas,HTML5 canvas 计算显示文字宽度的方法(measureText)
  10. 开通微信公众号流程所需资料及时间