一、一些名词解释:
1.1 对称加密:
1.2 非对称加密:
1.3 内网穿透:
1.4 内网穿透配置:
listen 80;
server_name zeyigou.com *.zeyigou.com 497n86m7k7.52http.net;
#charset koi8-r;
#access_log /var/log/nginx/log/host.access.log main;
location /static/ {
root /usr/share/nginx/html;
}
location /payed/ {
proxy_set_header Host order.zeyigou.com;
proxy_pass http://zeyigou;
}
1.5 加签与验签:
1.6 收单:
1、订单在支付页,不支付,一直刷新,订单过期了才支付,订单状态改为已支付了,但是库存解锁了。
使用支付宝自动收单功能解决。只要一段时间不支付,就不能支付了。
2、由于时延等问题。订单解锁完成,正在解锁库存的时候,异步通知才到
- 订单解锁,手动调用收单
3、网络阻塞问题,订单支付成功的异步通知一直不到达
- 查询订单列表时,ajax获取当前未支付的订单状态,查询订单状态时,再获取一下支付宝此订单的状态
4、其他各种问题
- 每天晚上闲时下载支付宝对账单,一一进行对账
二、支付宝沙箱使用:
2.0 支付宝支付时序图:
2.1 使用沙箱开发一般步骤:
2.1.1 进入支付宝开发平台:
2.1.2 进入[研发服务]
2.1.3 看到如下沙箱应用:
2.1.4 点击”设置/查看”:
2.1.5 进入下载页面下载并安装:
2.2.6 打开密钥生成工具如下:
2.2.7 复制应用私钥与支付宝公钥,后面开发中会用到。
2.2 下载官方SDK,并使用idea或Eclipse打开它
2.2.1 下载官方SDK:
2.2.2 打开后的目录结构:[Eclipse目录结构]
说明: 如果是Idea打开,需要经过处理,以Eclipse导入后,指定Facets中的web文件件位置,删除原来的Eclipse的jar包,添加tomcat及当前项目中的jar包(WEB-INF/lib目录).
2.2.3 打开后的目录结构:[Idea目录结构]
引入的依赖:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.0</version>
</parent>
<dependencies>
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.16.2.ALL</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
AlipayTemplate.java
@Component
@Data
public class AlipayTemplate {
//在支付宝创建的应用的id
private String app_id = "2016110200786382";
// 商户私钥,您的PKCS8格式RSA2私钥
private String merchant_private_key = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCLNeHUbXVv6LRgV4NRyx4yH3dCBuXQLh/kzJmYlXjwkqXMNssDOvvQlT2Y5Pdws936IJSveNK9ViGurn9a8PwLyRTVazZFyDmb3v99E1qsGG9dCeZxL+ofPSsH8uS+E3det7MkAjQc3mxvL1bkoan/9N5zaxkqAn25Yy0sMTDdPE4Db1Y8u0p9WZQ0TniH5EW7vRCJHxV3SRBvCqiNoEOgIDAcmnIymD8OaSeUVAuj+Uiq1C15F270UxCPYzcME9Klbl53ifweBhSGUBDsHI12v7QOw6n1pVmX4OagNfLoALnM/MwZrpEnfUip/CD9UDrHMpN/oJpphzVd63sqclJjAgMBAAECggEAHAarAmNPA0qsFcFIlMz5tUmUbtyIo9LFZQCz434kLPq5GlXlpS7Yx3NkRUXDcxMjG1o31OPUOX3/pfVHen2NoKnI4faFpKLcxj6s3Pdqh78bnHWDyUHGNqfP4/fIiWPN4mnFTPiMmUtGNVQogDrzyK35ou7q0ARUX2BSFdWJauCNRA6LEap4LUWtF0N0vCryPeBcElUAYd3J/VhQM5NkBKBkCbvLE1S9cElBURLxJtus2KZvxWnryDxN3Pm3+YWRm9J/zXe6zBy1VHqXYRey4rtxWJWSzz7aZ8lPRZbwSedVr2cte3+CeQejYF744wDbyaHaiQ+6sU3ixmke4ACegQKBgQDr5cu8TWNfmslHTuDrcUgn5FkTSB5UuJJ58+EvpiEfVj9BK9nvniNFHAVEwLclhbAlAlLlDzu9U1Gx50E858G3YX11ETnBNV7sv/JjXZnMhOHy2IM5sm/hFobvqgqyPqTDDV6uVEhOutO1TLnIAMv21mQ77o067xezwP03WS1TIQKBgQCXEtDngMujfOVk0it3IbbiagZkMQh2GultA8pUd9KA/qB26Z1z95vORU3aKqYNeJHxtY69fh7hvqat6V93JjE3X1XuBKYj8GKE7INmUN3elXbDbF4ZAwf1aGeuaqi2kz9VV5A07MSOtKT9G/FWCaNLYbyuqtZgHi8CjtiqAmg5AwKBgGkL663uyFHKm9clSQOPbpJVHVV4yAjyKEgmUiDl2doajhB3dpU91nbwA2iaaPRMlCPm5QMbxX6Jm9edI2/7xEflIfj/srhXC+5hi460H8jzY6rAv67xxuB1J6GSFzFItBYn3gHDhm+Iwr35bMGjmTBSSFBn6nxT/DoPtrLvA0ABAoGANGV4QvKurjNBNGiYXqc40OpI8TL4Zk4LK54m7IjqX4bwjI2V6IS2ayIqUEJ+eSmaJKT9rscxWsZO9P5998stQrE0EmtWXByhbszA/hmJ+gsIt9q8ABzHA9yEKUAg58HGM4k9IL4FpiENICQy3c5V7m0ljcb+tzOAxnhYuQ5Aq5UCgYAooWmzBRcn/dajfawzZ9WOcAcJlq2+7TtL1SCU/wMg+LDhAuktXaVF7ZTuT8VUwYXX2pj12by/B0bWBCAhzlqUYQCII4wwbZq2f8nC/lbQfEisYVfcPQBYJA3pcAH+FCWUtIZMPhekniywNW2s+Ibrm2Sr6HIQA4dPFc27uH4N0g==";
// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
private String alipay_public_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr1mPk6rIzSaYkaOthD0zsivN4pln2o66yP1DdIuauV6ggAC6jkO7kfZHJmBYXY/oGXPSbWqdn2g8s6FHJzLAjT9XMOqhFtQh5mMCTr5/gdgN6oc9O/zYCD1xEV9pAXZ1rBufzXixjmlnA8lCNiLsRUcYjoAcUyDBPUP3iLTvFJm1XhmA3ogR5U2CR56wynIa+toaCLxEav9S6gkjALmLwFSkimySEUZB361f+kXCcO+riZwsO65uquXEH8p7z44hezkqT09kaEIQDAHXH6f/RhOzmAuNQHSD93DbzvjrWPyW2vYA/eQnPLNc+ctka/Nf6CH5X4XMfmp9q+4p19URcQIDAQAB";
// 服务器[异步通知]页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
// 支付宝会悄悄的给我们发送一个请求,告诉我们支付成功的信息
private String notify_url = "http://localhost:8000/payed/notify";
// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
//同步通知,支付成功,一般跳转到成功页
private String return_url = "http://localhost:8000/memberOrder.html";
// 签名方式
private String sign_type = "RSA2";
// 字符编码格式
private String charset = "utf-8";
private String timeout = "30m";
// 支付宝网关; https://openapi.alipaydev.com/gateway.do
private String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";
public String pay(PayVo vo) throws AlipayApiException {
//AlipayClient alipayClient = new DefaultAlipayClient(AlipayTemplate.gatewayUrl, AlipayTemplate.app_id, AlipayTemplate.merchant_private_key, "json", AlipayTemplate.charset, AlipayTemplate.alipay_public_key, AlipayTemplate.sign_type);
//1、根据支付宝的配置生成一个支付客户端
AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl,
app_id, merchant_private_key, "json",
charset, alipay_public_key, sign_type);
//2、创建一个支付请求 //设置请求参数
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
alipayRequest.setReturnUrl(return_url);
alipayRequest.setNotifyUrl(notify_url);
//商户订单号,商户网站订单系统中唯一订单号,必填
String out_trade_no = vo.getOut_trade_no();
//付款金额,必填
String total_amount = vo.getTotal_amount();
//订单名称,必填
String subject = vo.getSubject();
//商品描述,可空
String body = vo.getBody();
alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
+ "\"total_amount\":\""+ total_amount +"\","
+ "\"subject\":\""+ subject +"\","
+ "\"body\":\""+ body +"\","
+ "\"timeout_express\":\""+timeout+"\","
+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
String result = alipayClient.pageExecute(alipayRequest).getBody();
//会收到支付宝的响应,响应的是一个页面,只要浏览器显示这个页面,就会自动来到支付宝的收银台页面
System.out.println("支付宝的响应:"+result);
return result;
}
}
PayVo.java(同步请求类)
/**
* ------------------------------
* 功能:
* 作者:WF
* 微信:hbxfwf13590332912
* 创建时间:2021/8/16-16:34
* ------------------------------
*/
@Data
public class PayVo {
private String out_trade_no; // 商户订单号 必填
private String subject; // 订单名称 必填
private String total_amount; // 付款金额 必填
private String body; // 商品描述 可空
}
PayAsyncVo.java (异步回调类)
@ToString
@Data
public class PayAsyncVo {
private String gmt_create;
private String charset;
private String gmt_payment;
private Date notify_time;
private String subject;
private String sign;
private String buyer_id;//支付者的id
private String body;//订单的信息
private String invoice_amount;//支付金额
private String version;
private String notify_id;//通知id
private String fund_bill_list;
private String notify_type;//通知类型; trade_status_sync
private String out_trade_no;//订单号
private String total_amount;//支付的总额
private String trade_status;//交易状态 TRADE_SUCCESS
private String trade_no;//流水号
private String auth_app_id;//
private String receipt_amount;//商家收到的款
private String point_amount;//
private String app_id;//应用id
private String buyer_pay_amount;//最终支付的金额
private String sign_type;//签名类型
private String seller_id;//商家的id
}
三、在项目中整合支付宝开发:
3.1 定义zyg-pay-interface工程,依赖如下:
<dependencies>
<dependency>
<groupId>com.zelin</groupId>
<artifactId>zyg-pojo</artifactId>
<version>2.0</version>
</dependency>
</dependencies>
3.2 定义zyg-pay-service工程,依赖如下:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.zelin</groupId>
<artifactId>zyg-pay-interface</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>com.zelin</groupId>
<artifactId>zyg-dao</artifactId>
<version>2.0</version>
</dependency>
<!--1. 引入thymeleaf-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--3.引入redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.16.2.ALL</version>
</dependency>
</dependencies>
3.3 zyg-pay-service的application.yml文件配置如下:
server:
port: 7008
logging:
level:
com.zelin: debug
spring:
dubbo:
application:
name: zyg-pay-service
registry:
address: zookeeper://192.168.56.10:2181
base-package: com.zelin.pay.service
protocol:
name: dubbo
port: 21888
thymeleaf:
cache: false
redis:
host: 192.168.56.10
alipay:
app_id: 2016110200786382
merchant_private_key: MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC5gxoY+/itsKQtamxVo5cgXS5qTrIYcEHv/vZ/hb3/B7+22HpcaYbD8JNoR2HXpzAYm9wizKPSup51u9JyUI6eEi2MfLxVI/FgwH/4rjM+U4Teq80WPeZFLqoimkOcwYV4ukwmOI8wBl3Tm5T243JlKSZYoB1o3g048aNRfv4/gS0zKOlpT+AFTbD8ceyhipamm48meZAg0s+MlgEGh+LABG53by1WI8V1VLZywUlhj20YdT6Hfdhg4t6cJUpjIxXOVi+K5UTeTy/KhSJqQ6Gp2b1rCuZ0/9WOCIvUKCCnMmcm52Z/IeTZZR5Im8Vwqm2S1AM2t4TFQQ+ZKUFQQRerAgMBAAECggEAKETPG3FGr91SJhGd5pEWMw5HDwh6HFfx2DjOJSxQ69Uwxm4DUaAOguXr+YzVLky6Yf0jMeKeBRZBY2kb63iVHLbxcDd7YjflI41lugOGWBclFnjQke1p2MaiY9R8rMBNSsGV2g4Y9uHK6C4zjcwdftwJ2N8YwzTARgYd34jjg8EV3mmkL8Qp+lK3q3kNdMm93WejlXbKBt4Adrr+LZHe8j+0gjp3vcRTeu8FBu+FiAXvLkNEIsg4jexwPrcPrHt2v761I4/EegLZqaYSyMFvfB72IsRaTaHeTjqBHuf0Dc6U1Kv5CV9R1rLgUdNC5bYix9xyPhtCV43QOmr1NEuNUQKBgQDmeqRMnYmRLbhEsS7MT7ql94hor+w7ekDSMUrjYlj/e8BBlVFf6KMza2yo3hp3nlZEOxo1HiNhCP2EZMIneO/Dy7aepQp5aQRKzzxy9ZcG6oJlaJlSdcCoB+d68h2HPAC6qg7VolLTNZYPHEfMYX+gX2X8EmcobmxJiidMMDIMBwKBgQDODcnGe8wt1IMRaio9eYYvG06WsoqaxCdl5UphL23l0eCBEOwi3WUx/lgzMQUti+EtZVr+XJIC6WMsBRXJMuqrY4T0Ar0aGezJC0S3+HefSkrQgqs3LZA6uw54eVyj5XEveGeY3Tv9fCJuSIQdds0S16sHosHd0XKhtEEgpq92PQKBgCXCeAJ5WN1pISRX5vPgKBMiz71e/RPtfosxOjSwmyYYLzJPdUqCQaKd+epcoPdyAG4jRLLpIiC2qVo0a76tyJJKYLvzDBlCBEsBUsT+yWR/rSdSELR6yDp/OQRigEX0paXvUIjdlDY4NEJ7fqPUYWVz27CFj1MHbERMFw4bY0enAoGAZGc3kK22GgbZLt0qY/YZOk72BlxNSYiXIgGOMrjntfqEiJ90ULDMpIWo+JjESyNDv9kJc7QruZt7pXF84iMbUhQWLsg+2L8VMAl7nKFHuKh8uAlT4HklNFj9fhq012/vrQ/gew4iMywPoulW5vyChNHuFrRp/uoWD1FEAuL10IkCgYABUXkMImvD3/xLUq75+rCHSr9TgVCC4CF+jEYqoy62ZNMUKvBXyjotAFQdJk4DfcmlBZQ7+EBZXW8cVt8i7xobvuOOzl93HAcnqnMNmw0UxWK9IX70/+9JdxYxHSLmRHWlBYf5gS9xlorhnBh+QLhaMeaNdUMeyCF/gTGUM6xJ2g==
alipay_public_key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr1mPk6rIzSaYkaOthD0zsivN4pln2o66yP1DdIuauV6ggAC6jkO7kfZHJmBYXY/oGXPSbWqdn2g8s6FHJzLAjT9XMOqhFtQh5mMCTr5/gdgN6oc9O/zYCD1xEV9pAXZ1rBufzXixjmlnA8lCNiLsRUcYjoAcUyDBPUP3iLTvFJm1XhmA3ogR5U2CR56wynIa+toaCLxEav9S6gkjALmLwFSkimySEUZB361f+kXCcO+riZwsO65uquXEH8p7z44hezkqT09kaEIQDAHXH6f/RhOzmAuNQHSD93DbzvjrWPyW2vYA/eQnPLNc+ctka/Nf6CH5X4XMfmp9q+4p19URcQIDAQAB
notify_url: http://42d323h910.qicp.vip/payed/notify
return_url: http://cart.zeyigou.com/orderlist
sign_type: RSA2
charset: utf-8
timeout: 30m
gatewayUrl: https://openapi.alipaydev.com/gateway.do
说明: app_id: 商户id merchant_private_key: 商户私钥 alipay_public_key: 支付宝公钥 notify_url: 支付成功后支付宝后台发送请求的异步回调地址,不要定义在cas这类单点登录的工程中。 return_url: 支付成功后立即跳转的地址。 sign_type:加密认证方式 timeout:代表关单时间,如:30m 即30分钟 gatewayUrl: 支付宝网关,固定值
3.4 在zyg-cart-web与zyg-page-web中分别引入zyg-pay-service:
<!--引入支付服务-->
<dependency>
<groupId>com.zelin</groupId>
<artifactId>zyg-pay-interface</artifactId>
<version>2.0</version>
</dependency>
注意: 最后,要进行异步调用,所以,我们不要把异步调用的方法写在zyg-cart-web这种有cas认证的模块中,否则,支付宝后台不能访问它。最后,异步调用会失败,所以,我们只需要定义一个没有cas认证的工程即可。
3.5 在zyg-cart-web中定义控制器如下:
/**
* ------------------------------
* 功能:
* 作者:WF
* 微信:hbxfwf13590332912
* 创建时间:2021/8/17-14:58
* ------------------------------
*/
@Controller
public class PayController {
@Reference(timeout = 5000)
private PayService payService;
@Reference(timeout = 5000)
private OrderService orderService;
/**
* 功能: 点击支付页面中的支付宝按钮时行支付
* 参数:
* 返回值: java.lang.String
* 时间: 2021/8/17 15:09
*/
@RequestMapping("pay")
@ResponseBody
public String payOrder(String outTradeNo){
//0. 得到登录id
String name = SecurityContextHolder.getContext().getAuthentication().getName();
//1. 根据支付订单号查询出payVo对象
PayVo payVo = payService.findPayVoFromRedis(name,outTradeNo);
//2. 调用支付方法
String result = payService.pay(payVo);
//3. 返回
return result;
}
/**
* 功能: 支付成功后跳转到的页面
* 参数:
* 返回值: java.lang.String
* 时间: 2021/8/17 20:46
*/
@RequestMapping("/orderlist")
public String orderlist(Model model){
//0. 得到登录id
String name = SecurityContextHolder.getContext().getAuthentication().getName();
//1. 根据登录用户id得到订单及订单项列表
List<OrderEntity> orderEntities = orderService.findOrdersByUserId(name);
//2. 放到model中到
model.addAttribute("orderList",orderEntities);
return "orderlist";
}
}
3.6 在zyg-page-web中定义回调监听器:
/**
* ------------------------------
* 功能:
* 作者:WF
* 微信:hbxfwf13590332912
* 创建时间:2021/8/17-16:44
* ------------------------------
*/
@RestController
public class PaySyncController {
@Reference(timeout = 5000)
private PayService payService;
/**
* 功能: 支付宝发送异步通知
* 参数:
* 返回值: java.lang.String
* 时间: 2021/8/17 16:46
*/
@PostMapping("/payed/notify")
public String payed(PayAsyncVo vo, HttpServletRequest request){
System.out.println("vo = " + vo);
//1. 得到登录用户
//String userId = SecurityContextHolder.getContext().getAuthentication().getName();
//2. 得支支付宝后台传入的数据
Map<String,String> params = new HashMap<>();
Map<String,String[]> requestParams = request.getParameterMap();
for (Iterator<String> 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.getBytes("ISO-8859-1"), "utf-8");
params.put(name, valueStr);
}
//boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); //调用SDK验证签名
String result = payService.payNotify(vo,params);
System.out.println("result = " + result);
return result;
}
}
zyg-page-web的application.yml文件中配置关于日期的格式, 不配置会报错!
spring:
mvc:
date-format: yyyy-MM-dd HH:mm:ss
3.7 在zyg-order-service中添加方法的最后添加支付日志处理:
/**
* 功能: 提交订单
* 参数:
* 返回值: void
* 时间: 2021/8/14 16:44
*/
@Transactional
@Override
public void add(OrderEntity order) {
//1. 得到购物车列表的字符串
String cartStr = redisTemplate.opsForValue().get(order.getUserId());
//2. 转换为List<Cart>对象并返回
List<Cart> cartList = null;
if(StringUtils.isNotBlank(cartStr)){
cartList = JSON.parseArray(cartStr,Cart.class);
}
//2.1 定义代表所有订单的总金额
double total = 0;
//2.2 定义代表订单号的字符串
String orderIds = "";
//3. 添加订单(一个购物车对应一个订单)
for (Cart cart : cartList) {
//3.1 定义订单对象
OrderEntity orderEntity = new OrderEntity();
//3.2 生成订单id主键
long id = idWorker.nextId();
//累加订单和
orderIds += id + ",";
orderEntity.setOrderId(id);
//3.3 设置订单的其它相关属性
orderEntity.setCreateTime(new Date());
orderEntity.setPaymentType(order.getPaymentType());
orderEntity.setReceiver(order.getReceiver());
orderEntity.setReceiverAreaName(order.getReceiverAreaName());
orderEntity.setReceiverMobile(order.getReceiverMobile());
orderEntity.setSellerId(cart.getSellerId());
orderEntity.setUserId(order.getUserId());
orderEntity.setSourceType(order.getSourceType());
orderEntity.setStatus("1"); //未支付
double sum = 0; //定义订单的总金额
//3.4 得到购物车的购物项数据,向订单项表中添加此数据
for (OrderItemEntity item : cart.getOrderItemList()) {
//3.4.1 计算小计
BigDecimal totalFee = new BigDecimal(item.getNum() * item.getPrice().doubleValue());
item.setTotalFee(totalFee);
//3.4.2 累加总金额
sum += totalFee.doubleValue();
//3.4.3 设置订单的id
item.setOrderId(id);
//3.4.4 设置订单项的id
item.setId(idWorker.nextId());
//3.4.5 设置商家id
item.setSellerId(cart.getSellerId());
//3.4.6 添加订单项到tb_ordeItem表
orderItemDao.insert(item);
}
//3.5 计算此订单的总金额
orderEntity.setPayment(new BigDecimal(sum));
//3.6 添加订单
this.save(orderEntity);
//3.7 累加总金额
total += sum;
}
//4. 保存支付日志到数据库
if(order.getPaymentType().equals("1")){ //1:代表网上支付
//4.1 定义支付日志
PayLogEntity payLog = new PayLogEntity();
payLog.setCreateTime(new Date());
payLog.setPayType("2"); //代表支付宝
payLog.setTradeState("0"); //代表未支付 0:未支付 1:己支付
payLog.setUserId(order.getUserId()); //设置登录用户
payLog.setOutTradeNo(idWorker.nextId()); //设置支付的订单号
payLog.setTotalFee((long) (total)); //计算总金额
payLog.setSubject("泽易购商城支付订单");
payLog.setBody("一个良好的网上交易平台...");
//4.2 去掉多余的订单id后的逗号
orderIds = orderIds.substring(0, orderIds.length() - 1);
//4.3 设置订单号
payLog.setOrderList(orderIds);
//4.4 添加支付日志到数据库中
payLogDao.insert(payLog) ;
//5. 保存到redis中一份(key:登录userid value:订单日志对象)
redisTemplate.opsForValue().set(order.getUserId() + ":paylog",JSON.toJSONString(payLog),10, TimeUnit.DAYS);
}
//6. 清空redis中的购物车
//todo...
}
3.8 在zyg-pay-service中添加支付成功后对支付日志及订单的修改:
/**
* ------------------------------
* 功能:
* 作者:WF
* 微信:hbxfwf13590332912
* 创建时间:2021/8/17-15:05
* ------------------------------
*/
@Service
public class PayServiceImpl extends ServiceImpl<PayLogDao, PayLogEntity> implements PayService {
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private AlipayTemplate alipayTemplate;
@Autowired
private OrderDao orderDao;
//1. 从redis中查询出订单日志
@Override
public PayLogEntity findPayLogByUserId(String name) {
String s = redisTemplate.opsForValue().get(name + ":paylog");
PayLogEntity payLogEntity = JSON.parseObject(s, PayLogEntity.class);
return payLogEntity;
}
//2. 从redis中根据订单号查询payVo对象
@Override
public PayVo findPayVoFromRedis(String name, String tradeNo) {
//2.1 查询出支付日志对象
String s = redisTemplate.opsForValue().get(name + ":paylog");
//2.2 转换为payLog
PayLogEntity payLogEntity = JSON.parseObject(s, PayLogEntity.class);
//2.3 定义payVo对象
PayVo payVo = new PayVo();
payVo.setBody(payLogEntity.getBody());
payVo.setOut_trade_no(payLogEntity.getOutTradeNo() + "");
payVo.setSubject(payLogEntity.getSubject());
payVo.setTotal_amount(payLogEntity.getTotalFee() + "");
//2.4 返回
return payVo;
}
/**
* 功能: 返回的是支付的表单 页面
* 参数:
* 返回值: java.lang.String
* 时间: 2021/8/17 15:26
*/
@Override
public String pay(PayVo payVo) {
try {
return alipayTemplate.pay(payVo);
} catch (AlipayApiException e) {
e.printStackTrace();
}
return "hello";
}
/**
* 功能: 验签并返回字符串,如果是success,就代表成功,否则,失败
* 参数:
* 返回值: java.lang.String
* 时间: 2021/8/17 16:52
*/
@Override
public String payNotify(PayAsyncVo vo, Map<String, String> params) {
try {
//1. 进行验签
boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayTemplate.getAlipay_public_key(),
alipayTemplate.getCharset(), alipayTemplate.getSign_type()); //调用SDK验证签名
//2. 判断是否验签成功
if(signVerified){
//第一部分:修改支付日志
//2.1 更新支付日志与订单
//String s = redisTemplate.opsForValue().get(userId + ":paylog");
//PayLogEntity payLogEntity = JSON.parseObject(s, PayLogEntity.class);
String out_trade_no = vo.getOut_trade_no();
PayLogEntity payLogEntity = this.getById(out_trade_no);
payLogEntity.setTransactionId(vo.getTrade_no());
payLogEntity.setTradeState("1"); //代表己支付
//2.2 修改到数据库中
this.updateById(payLogEntity);
//第二部分:修改订单的状态
//2.1 得到订单id列表
String orderList = payLogEntity.getOrderList();
//2.2 使用,使用,号进行拆分
String[] split = orderList.split(",");
//2.3 遍历出每一个订单id
for (String orderId : split) {
//2.3.1 根据订单id查询出订单
OrderEntity orderEntity = orderDao.selectById(orderId);
//2.3.2 修改订单状态值
orderEntity.setStatus("2"); //2:代表己付款
//2.3.3 保存订单
orderDao.updateById(orderEntity);
}
System.out.println("支付成功");
return "success";
}
} catch (AlipayApiException e) {
e.printStackTrace();
}
System.out.println("支付失败!");
return "fail";
}
}