UniApp + SpringBoot 实现支付宝支付和退款功能

网友投稿 439 2022-07-26


目录开发准备支付宝支付开发后端部分前端部分支付宝退款开发后端部分

上篇介绍了UniApp + SpringBoot 实现微信支付和退款功能,喜欢的朋友可以点击查看。

开发准备

一台用于支付的测试机用于编写的后端框架接口的 IDE (IDEA 或者 Eclipse 都可以)HBuilder X 用来编辑 UniApp 项目的编辑器和编译器基本的 SpringBoot 的脚手架,可以去 https://start.spring.io/ 或者 IDEA 自带的快速生成脚手架插件。Jdk 11

支付宝支付开发

后端部分

在 SpringBoot 中添加以下坐标

org.springframework.boot

spring-boot-starter-web

com.alipay.sdk

alipay-sdk-java

4.22.32.ALL

org.springframework.boot

spring-boot-configuration-processor

true

org.projectlombok

lombok

true

在 resources 目录下添加 application.yml 我们不去用默认的 application.properties 文件,毕竟 yml 更好看点。并在 yml 中添加以下内容

# 服务启动端口

server:

port: 8080

# 支付宝支付

alipay:

server_url: https://openapi.alipay.com/gateway.do

app_id: 企业支付的 APPID

private_key: 申请的私钥

format: json

charset: utf-8

alipay_public_key: 申请的公钥

sign_type: RSA2

notifyUrl: 回调地址

创建一个 AlipayConfig.java 继承 com.alipay.api.AlipayConfig

@Getter

@Setter

@ToString

@Component

@ConfigurationProperties(prefix = "alipay")

public class AlipayConfig extends com.alipay.api.AlipayConfig {

private String serverUrl;

private String appId;

private String privateKey;

private String format;

private String charset;

private String alipayPublicKey;

private String signType;

private String notifyUrl;

}

创建一个 BizAlipayService.java

import com.alipay.api.AlipayApiException;

import com.alipay.api.DefaultAlipayClient;

import com.alipay.api.domain.AlipayTradeAppPayModel;

import com.alipay.api.request.AlipayTradeAppPayRequest;

import com.alipay.api.response.AlipayTradeAppPayResponse;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

/**

* 阿里云支付类

*/

@Service

public class BizAlipayService {

private static Logger logger = LoggerFactory.getLogger(BizAlipayService.class);

@Autowired

AlipayConfig alipayConfig;

private DefaultAlipayClient client() throws AlipayApiException {

return new DefaultAlipayClient(alipayConfig);

}

/**

* 预下单

*

* @param subject 订单标题

* @param outTradeNo 商家生成的订单号

* @param totalAmount 订单总价值

* @return

*/

public String appPay(String subject, String outTradeNo, String totalAmount) {

String source = "";

try {

DefaultAlipayClient client = client();

AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();

model.setSubject(subject);

model.setOutTradeNo(outTradeNo);

model.setTotalAmount(totalAmount);

// alipay 封装的接口调用

AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();

request.setBizModel(model);

request.setNotifyUrl(alipayConfig.getNotifyUrl());

AlipayTradeAppPayResponse response = client.sdkExecute(request);

source = response.getBody();

} catch (AlipayApiException e) {

logger.error("支付出现问题,详情:{}", e.getErrMsg());

e.printStackTrace();

}

return source;

}

}

创建一个 AlipayController.java 来实现接口给前端调用时使用

import com.alipay.api.AlipayApiException;

import com.alipay.api.internal.util.AlipaySignature;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.http://Autowired;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

import java.math.BigDecimal;

import java.util.HashMap;

import java.util.Map;

@RestController

public class AlipayController {

private static Logger logger = LoggerFactory.getLogger(AlipayController.class);

@Autowired

AlipayConfig alipayConfig;

@Autowired

BizAlipayService alipayService;

/**

* 支付接口

*

* @return

*/

@GetMapping("/pay")

public String orderPay() {

String s = alipayService.appPay("测试支付", String.valueOf(System.currentTimeMillis()), new BigDecimal("0.01").toString());

logger.info("支付生成信息:{}", s);

return s;

}

/**

* 订单回调

*

* @return

*/

@RequestMapping(method = RequestMethod.POST, value = "/notify")

public String orderNotify(HttpServletRequest request) {

Map params = new HashMap<>();

Map requestParams = request.getParameterMap();

for (String name : requestParams.keySet()) {

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);

}

try {

boolean flag = AlipaySignature.rsaCheckV1(params, alipayConfig.getAlipayPublicKey(), alipayConfig.getCharset(), alipayConfig.getSignType());

if (flag) {

logger.info("支付回调信息:{}", params);

return "success";

} else {

return "error";

}

} catch (AlipayApiException e) {

logger.error("支付宝错误回调:{}", e.getErrMsg());

e.printStackTrace();

return "error";

}

}

}

上面的 controller 写了两个接口一个用来 app端的调用,一个给支付用来回调。回调接口的地址要放到刚才配置中的 notifyUrl 属性里。

由于支付宝回调要使用线上的地址作为回调地址,这里我推荐两个解决办法使用一台服务器+备案的域名搭建上面的后台地址使用 花生壳 来实现本地内网穿透

我使用的是 花生壳 作为本次的开发环境,启动 springboot 的服务,配置好花生壳。后台部分到目前为止已经结束了。

前端部分

UniApp 是一个使用vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台。牛啊,UniApp 能打这么多的端呢,不过这次我只使用 APP 端的功能。

在 HBuilder X 中新建一个项目,我目前使用的版本 3.3.10.20220124

创建好项目之后,在 manifest.json 中勾选以下内容

在 index.vue 添加支付相关功能

{{title}}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:一个依赖搞定 Spring Boot 接口防盗刷的流程分析
下一篇:解决Netty解码http请求获取URL乱码问题
相关文章

 发表评论

暂时没有评论,来抢沙发吧~