一、支付宝支付流程回顾
支付流程:这个支付流程是一种分布式事务的一种解决方案。异步通知,重试机制。
1、点击支付后,网站会接受到一个请求表单,再封装好以post方式提交参数给支付宝。
同步通知:使用本地浏览器重定向到本网站,不会实现任何的订单状态的更改
异步通知:支付宝使用http技术发送到本网站,进行订单状态的更改。
如果网站没有及时响应的时候,支付宝会进行再发,进行重试,补偿机制。
二、项目整合支付接口流程
1、SpringCloud分布式与微服务项目 区别?分项目和分服务的区别。
答:分布式是单独跟项目去拆分,还没划分具体的服务上去。
传统的MVC-->分布式服务-->SOA面向接口--->微服务
支付服务
二、项目整合接口流程
流程:
1、先下单,然后会生成一个订单ID
2、使用订单id调用支付接口,生成form提交元素
3、直接返回页面执行html元素。
下单支付,库存减去1 订单支付流程,都是有时间限制的。存redis
详细支付流程() 首先生成支付令牌。有效期是15分钟。
1、首先请求支付的之附表创建一条支付信息
2、生成支付token, 使用redis , key为支付token,value为支付表的id.
3、返回支付token给客户端。
4、使用支付的token,向redis查找对应支付表的id。
如果在redis中找不到说明支付已经失效了。
5、使用支付表的id,获取支付信息
6、封装支付包from的提交参数。
三、创建支付token接口
支付服务需要提供两个接口
1、创建token接口。
2、使用token进行支付。
四、支付宝对接步骤:
查找支付信息(这个是整个流程的重点)
/**
* 查找支付信息
*/
@Override
public ResponseBase findPayToken(@RequestParam("payToken") String payToken) {
//1.参数验证
if(StringUtils.isEmpty(payToken)) {
return setResultError("token不能为空");
}
//2.判断token有效期
//3.使用token,查找支付信息,通过token在redis中查找对应的支付id
String payIdStr = (String) baseRedisService.getString(payToken);
if(StringUtils.isEmpty(payIdStr)) {
return setResultError("支付请求已经超时");
}
//4.使用支付id进行下单。
Long payId = Long.valueOf(payIdStr);
//5.使用支付id查询支付信息
PaymentInfo paymentInfo = paymenInfoDao.getPaymentInfo(payId);
if(paymentInfo == null) {
return setResultError("未找到支付信息");
}
//6.对接支付代码。返回支付form表单给客户端 这个直接copy支付宝中的
//alipay.trade.page.pay.jsp 中的是实现方法
//获得初始化的AlipayClient
AlipayClient 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 = paymentInfo.getOrderId();
//付款金额,必填
String total_amount = String.valueOf(paymentInfo.getPrice());
//订单名称,必填
String subject = "腾讯视频VIP会员充值";
//商品描述,可空
String body = "腾讯视频VIP会员100年充值";
//封装json
alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
+ "\"total_amount\":\""+ total_amount +"\","
+ "\"subject\":\""+ subject +"\","
+ "\"body\":\""+ body +"\","
+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
//请求
String result;
try {
result = alipayClient.pageExecute(alipayRequest).getBody();
JSONObject data = new JSONObject();
data.put("payHtml", result);
return setResultSuccess(data);
} catch (AlipayApiException e) {
return setResultError("请求表单错误信息"+e);
}
}
五、将支付项目服务,整合到pc-web上(页面上集成)
PayController:
package com.leeue.controller;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.LinkedHashMap;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import com.leeue.base.ResponseBase;
import com.leeue.constants.Constants;
import com.leeue.fegin.PayServiceFegin;
import lombok.extern.slf4j.Slf4j;
/**
* @classDesc: 功能描述:()
* @author:李月
* @Version:v1.0
* @createTime:2019年1月25日 上午10:22:21
*/
@Slf4j
@Controller
public class PayController {
//fegin进行远程调用
@Autowired
PayServiceFegin payServiceFegin;
/**
* 使用token进行支付
* @param payToken
* @throws IOException
*/
@RequestMapping("/aliPay")
public void aliPay(String payToken,HttpServletResponse response) throws IOException {
//这个写到客户端的流
response.setHeader("Content-type", "text/html;charset=UTF-8");
response.setCharacterEncoding("utf-8");
PrintWriter writer = response.getWriter();
// response.setContentType();
//1.验证参数
if(StringUtils.isEmpty(payToken)) {
writer.println("token参数不能为空");
return ;
}
//2.调用服务接口
ResponseBase payTokenResult = payServiceFegin.findPayToken(payToken);
if(!payTokenResult.getRtnCode().equals(Constants.HTTP_RES_CODE_200)) {
String msg = payTokenResult.getMsg();
writer.println(msg);
return ;
}
//3.返回可以执行的html元素给客户端。
LinkedHashMap data = (LinkedHashMap) payTokenResult.getData();
String patHtml = (String) data.get("payHtml");
log.info("####PayController####payHtml:{}",patHtml);
//4.页面上进行渲染出来
writer.println(patHtml);
writer.close();
}
}