转载声明:原文链接:https://blog.csdn.net/magic_guo/article/details/120816658
支付模块是电商项目的核心,毕竟电商是属于B2C的,最终的盈利才是最重要的,第三方支付平台有很多,而且第三方支付平台对于商家接入都会有一些开发文档和demo作为指引,因此这部分虽然重要,但是开发相对简单;
下面我们来了解一下对接支付宝的一些流程:
1、首先我们对接支付宝需要到支付宝开放平台
2、然后选择自己的支付能力,我这里选择的是“电脑网站支付”;
点击电脑网站支付的基础功能,便可以看到一些基础的参数和接口描述以及代码示例、流程图:
然后登陆进行秘钥操作:
秘钥操作
1、生成秘钥并上传
2、生成秘钥请求签名
3、使用生成秘钥验签
下面看代码:
maven:
使用feign来调用order模块,最重要的依赖是支付宝sdk的依赖;
<dependencies>
<dependency>
<groupId>com.guo</groupId>
<artifactId>shop-common</artifactId>
</dependency>
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.12.4.ALL</version>
</dependency>
<dependency>
<groupId>com.guo</groupId>
<artifactId>shop-feign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
controller接口:@Controller
@RequestMapping("/aliPay")
public class AliPayController {
// 支付宝提供的网关
private String serverUrl = "https://openapi.alipaydev.com/gateway.do";
// 支付宝分配给开发者的应用ID
private String APP_ID = "2021000117670024";
// 加签配置的时候,支付宝分配的应用私钥
private String APP_PRIVATE_KEY = "";
// 仅支持JSON
private String FORMAT = "JSON";
// 请求使用的编码格式,如utf-8,gbk,gb2312等
private String CHARSET = "utf-8";
// 加签配置时,上传应用公钥到支付宝,会生成一个支付宝公钥;这样才算加签内容完成
private String ALIPAY_PUBLIC_KEY = "";
// 商户生成签名字符串所使用的签名算法类型,目前支持RSA2和RSA,推荐使用RSA2
private String SIGN_TYPE = "RSA2";
@Autowired
private IOrderService orderService;
public void pay (String orderId, HttpServletResponse httpResponse) throws ServletException, IOException {
//获得初始化的AlipayClient
AlipayClient alipayClient = new DefaultAlipayClient(
serverUrl,
APP_ID,
APP_PRIVATE_KEY,
FORMAT,
CHARSET,
ALIPAY_PUBLIC_KEY,
SIGN_TYPE
);
//创建API对应的request
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
// 用户付款之后同步跳转的地址
alipayRequest.setReturnUrl("https://www.baidu.com/");
// 异步返回通知商家的地址, 支付之后就更新数据库订单的状态
alipayRequest.setNotifyUrl("http://domain.com/CallBack/notify_url.jsp");
// 根据订单Id,通过feign查询此订单
Order order = orderService.getOrderByOrderId(orderId);
//填充业务参数
alipayRequest.setBizContent( "{" +
" \"out_trade_no\":" + orderId + "," + // 订单号
" \"product_code\":\"FAST_INSTANT_TRADE_PAY\"," + // 商品/产品编号 必填项
" \"total_amount\":" + order.getTotalPrice() + "," + // 订单总金额 必填项
" \"subject\":\"电商平台商品支付\"," + // 订单的主题/标题 必填项
" \"body\":\"具体商品的信息\"," + // 订单的描述
// passback_params 公用回传参数:如果请求时传递了该参数,则返回给商户时会回传该参数。支付宝只会在异步通知时将该参数原样返回。
// 本参数必须进行UrlEncode之后才可以发送给支付宝
" \"passback_params\":\"merchantBizType%3d3C%26merchantBizNo%3d2016010101111\"," +
" \"extend_params\":{" + // 业务扩展参数
" \"sys_service_provider_id\":\"2088511833207846\"" +
" }" +
" }" );
String form= "" ;
try {
// 获取一个登陆页面
form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单
} catch (AlipayApiException e) {
e.printStackTrace();
}
// 把登录页面响应给用户
httpResponse.setContentType( "text/html;charset=" + CHARSET);
httpResponse.getWriter().write(form); //直接将完整的表单html输出到页面
httpResponse.getWriter().flush();
httpResponse.getWriter().close();
}
/**
* 此过程需要对异步返回结果进行验签
* @param request 异步返回通知商家的请求
* @return
* @throws AlipayApiException
*/
@RequestMapping("/updateOrderStatus")
public ResultEntity updateOrderStatus(HttpServletRequest request) throws AlipayApiException {
// 异步返回通知商家的请求参数
Map<String, String[]> parameterMap = request.getParameterMap();
// 将异步通知中收到的所有参数都存放到 map 中
Map<String, String> paramsMap = new HashMap<>();
Set<Map.Entry<String, String[]>> entries = parameterMap.entrySet();
for (Map.Entry<String, String[]> entry : entries) {
paramsMap.put(entry.getKey(), entry.getValue()[0]);
}
// 调用SDK验证签名
boolean signVerified = AlipaySignature.rsaCheckV1(paramsMap, ALIPAY_PUBLIC_KEY, CHARSET, SIGN_TYPE);
if (signVerified){
String orderId = paramsMap.get("out_trade_no");
String orderStatus = paramsMap.get("trade_status");
HashMap<String, Object> map = new HashMap<>();
map.put("orderId", orderId);
map.put("orderStatus", 2);
if ("TRADE_SUCCESS".equals(orderStatus)) {
// 更改订单状态为已支付
orderService.updateOrderStatus(map);
return ResultEntity.success("更改订单状态为已支付!");
}
return ResultEntity.error("订单状态异常!");
// TODO 验签成功后,按照支付结果异步通知中的描述,对支付结果中的业务内容进行二次校验,校验成功后在response中返回success并继续商户自身业务处理,校验失败返回failure
} else {
// TODO 验签失败则记录异常日志,并在response中返回failure.
System.out.println("此请求是非法的;");
return ResultEntity.error("此请求是非法的;");
}
}
/**
* 退款接口
*/
public void refund() {
}
/**
* 商家主动退款接口
* 若用户一直未支付,商户可以调用该接口关闭指定交易;成功关闭交易后该交易不可支付
*/
public void closeTransaction(){
}
/**
* 下载账单接口
*/
public void downloadBill() {
}
}
这些接口的调试可以去支付宝提供的沙箱环境,登录支付宝,在沙箱环境中想充多少Money就冲多少,享受一下有钱人的滋味!
根据文档指引,所有的接口开发并不太难,因此只写了一个支付接口和验签的接口(即更改订单状态),其它接口可以根据翁当之后自行补充;其中最重要的是一些细节上的操作,毕竟此模块是关于Money的,刚入职的同学肯定不会负责这一模块。
帖子还没人回复快来抢沙发