支付服务实现逻辑

简单概况一下支付服务的实现逻辑

通过支付宝的沙箱环境来模拟支付功能,用户点击支付宝的链接后给后端发/aliPayOrder请求,封装支付宝需要payVo对象,并且调用 String pay = alipayTemplate.pay(payVo)和 return pay;来调用支付宝沙箱环境提供的支付页面(这里返回的pay是一个html页面,直接给浏览器渲染后就是支付宝提供的支付页面),这是支付宝官方写好了的,模拟支付宝支付的过程,专门用来给开发人员测试用的,用户输入自己的支付宝账号密码成功支付后就会发请求memberOrder.html,这其实就是支付成功后跳转到用户的订单页面,这个页面会呈现用户的所有订单记录,所以这个请求会把用户的订单数据都封装好,并且把这些数据渲染到订单页面,但是刚支付成功的订单的状态还是待支付,这就有问题了,最后通过支付宝支付成功后的异步回调来修改刚支付成功的订单状态为已支付(异步回调其实就是支付成功后支付宝会给一个地址发送一个请求来告诉你支付成功了)

1、支付使用的是支付宝的沙箱环境来模拟测试的

官网:登录 - 支付宝

2、在订单服务的config文件里配置下面的支付宝支付沙箱环境(常量)

package com.saodai.saodaimall.order.config;import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.saodai.saodaimall.order.vo.PayVo;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;/*** 支付宝支付沙箱环境配置*/
@ConfigurationProperties(prefix = "alipay")
@Component
@Data
public class AlipayTemplate {// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号public String app_id;// 商户私钥,您的PKCS8格式RSA2私钥public String merchant_private_key;// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。public String alipay_public_key;// 服务器[异步通知]页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问// 支付宝会悄悄的给我们发送一个请求,告诉我们支付成功的信息public String notify_url;// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问//同步通知,支付成功,一般跳转到成功页public String return_url;// 签名方式private  String sign_type;// 字符编码格式private  String charset;//订单超时时间(用于收单,防止用户支付很慢,导致订单过期自动关了后再支付订单的情况)private String timeout = "1m";// 支付宝网关; https://openapi.alipaydev.com/gateway.dopublic String gatewayUrl;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;}
}

3、在application.properties配置真正自己的沙箱环境配置

#支付宝相关的配置
#应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
alipay.app_id=2021000119644301
#商户私钥,用的是RSA2私钥
alipay.merchant_private_key=MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCNO1TNy1L65dxxrcmYwo452ClW8rpJsshk9fiToCDSC3Fz0SZQlGYwqGxXr0NzzLvf0sHmIK49CXwXfPgYZPSxaCQSJVm7r87sAEoDi75w0gH0dt+m4viN0GzSGYXVdAfO2J/1BqJoNlpVah3vb3UwLIYpVmNRY6TNdDxnZbpB2Hcosjo8PXvEwqU5MS1W16VkRSkEwPUw/gkKLFUrDqbes5JgJeneAkCPuGa18rNMHxugibVKutfj7MFdomLaNMB2hNOapH3matKJ6JZi/uSqBNLWxfr8kUCw4t8tjJjNaisSfqYwjM9EeWTkkbcba02VUvziB6DqFCue9nV0MVkDAgMBAAECggEAYbHHCcw6DGBwyxoiN89tPsouXnztLAnF4UDcwJGl4mYUBr+It3jP75yxxT3xdOsMktlhU2UL4iDre/vwSj+bnBSjzwGTPudwRYQ1rpo+FCDRRV/tea3LrZ2diQAquerXc9gZXg9GzLu8ZRVQu83nzHkgHPwrG6PH3m8nUYbm/qBM2Fq6nH6AyybXdUk8iwNpLvy/wQkfxPIfZglQqHlEW9x96hs+n/GUx/S4mKFxT6L8MNd7K/rez/xPSGzjPcG1+UkI8VeWQLSnBmfFrCVFrl87rXk6x/6gnY5nogFmKafAvip6hR0/+50vGtWqU/HgeyDc9q/xyLwYy4pulgeRkQKBgQDJqiJjx9WRlC5tfUuwGf2puuwCgu+vqofbE0RuSZtBvb92M65yR+ZtuFkZADOu/ldf5+dITtc1+QpUXCxCvyO+l+w2f0S9oHkfhTmIx6A+jH0spvXfVuZOe97kh2YF3wkAJMd2XBUOEN2xLSeqf62aQxAtfB0zGGZ5iCnoWGbPRwKBgQCzSNPg2XsBb0YVLHtfSOQfuIn7NRHyjznya/9d5cP2HTXgQYMVoJDTKP8ZOwmDFWkRf/DRJEmUGaV5+nJpXa8fyBTkHCCzAEzu8CK2zVQuLPPG9TQXh3t8STEruAu3Sq99LtF8kDhA/8MrmgXmMyhqJGN+jBhwGLq7RekUOg7eZQKBgHLUGpLgZd5oFuunTaKvmf28fsiLT/mhy4vV88Asz2fmqI+gq/NMt4vATZNrxwIctxnYDZzhr69+5//TICy9c5gCH7GEVFr5dh6ZmIIm0TrsehYj15rde3QzGl7cLh6nuhNH3f+qPR7uQZ2yTYTLAMn2585Ofr3qZedLvjkbpSbfAoGBAJZOWFQKALYTNA5MXKJl2ds+O2//7iwNJ+e140I1fzS3CJQaWGupUcG2fSgJ9s+PA6dIO/0bDxS666B397Oed1ONyvXzHvbzKYyohnH7crfDuBz1NdcEHuLz+eVNR4VDeBzbQ4XK416bDmVfm9KC0T8rgr51dYeFNAgNdHsgsZaBAoGAF4sYuVYF2iv9ZTmYMbf9DNv5Px25v2j2RD0pyW+haR2Jq6NqLlGwV/wnFDNAR1BTnFh3vNM1loaw897qORW8bNnAhDGH91jz+pSiCfV4mu9CXDoIw/ZxBfgdxGX7FI7EWPtSG3qb029Vtezks0OW9VROC3I0qePqVeLF8rV6tuE=
#支付宝公钥
alipay.alipay_public_key=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAh3IVA56nyTr1Gt33gC5RAbtIVh+pMg1z9ad3VC5h0QPyU0dHYS+j4PbDjeR7kA/Gz3Q7gcp1vo+H4NTBeaQ3m0vG/+UW2wuT6GNeNT8g59gDElE9LtSpqZzsHZMFHKzsvY5n/2v8ADrF16t/TfNnsKvkSCO7Rtcc2mJZtBvZF/APXLn4mbdSs8v5f4o4/RU/iKyKjIUiWfl58JCLD0JYVMxGUcv1Sh9q+1irv4KrP+J/L77eaJ6FiXHX7aXxhsPZQnHy+4KUsjgst1vuYlhpTX9h9GSKiBlFvjTamQhrPtfPfkqa0bsHHmOjToE6gatwDFER0f0kH5gxgo1x1HK0+QIDAQAB
#异步回调地址(支付宝会悄悄的给我们发送一个请求,告诉我们支付成功的信息)
alipay.notify_url=http://vtyk0jgqvh.51xd.pub/payed/notify
#同步通知地址(支付成功后跳转到指定的地址,这里是跳到最终的订单页面)
alipay.return_url=http://member.saodaimall.com/memberOrder.html
#签名方式
alipay.sign_type=RSA2
alipay.charset=utf-8
#支付宝网关
alipay.gatewayUrl=https://openapi.alipaydev.com/gateway.do
spring.mvc.date-format=yyyy-MM-dd HH:mm:ss

上面要配置的内容有应用ID、商户私钥、支付宝公钥、异步回调地址、同步通知地址即可,然后再沙箱中配置好商户的公钥即可

(1)在上面的官网查看APPID

(2)选择支付加密方式为RSA2(非对称加密方式)

RSA2(非对称加密方式)图解

在这里也就是商户和支付宝两者之间有两对密钥,每一对都是一把公钥一把私钥,其中支付宝的私钥是只有支付宝官方核心人员才知道的

点击上图的查看就可以更换密钥

下载支付宝密钥生成器生成密钥

生成的应用私钥是要配置到支付宝的组件配置中去的,应用公钥给支付宝的沙箱后支付宝也会告诉你一个支付宝的公钥,这个要配置到支付宝的组件配置中。

图解:上面的配置商户私钥(自己的私钥)alipay.merchant_private_key的值就是上面生成密钥的应用私钥,把上面应用公钥(商户公钥)复制到下面公钥字符的区域(其实就是把你自己的公钥(商户公钥)告诉支付宝),点击保存设置后支付宝就知道了你的公钥,然后它会告诉你它的公钥是什么,直接复制并配置到application.properties配置文件里的支付宝公钥alipay.alipay_public_key的值(只需要在配置文件中配置两把钥匙,还有一把是商户公钥,这把不需要配置,因为点击保持后支付宝已经知道了你的公钥)

4、前台设置点击支付宝支付跳转的链接(发请求/aliPayOrder给后端)

<li><img src="/static/order/pay/img/zhifubao.png" style="weight:auto;height:30px;" alt=""><a th:href="'http://order.saodaimall.com/aliPayOrder?orderSn='+${submitOrderResp.order.orderSn}">支付宝</a>
</li>

5、在订单服务的web文件的PayWebController控制器处理前面的发的请求/aliPayOrder

package com.saodai.saodaimall.order.web;import com.alipay.api.AlipayApiException;
import com.saodai.saodaimall.order.config.AlipayTemplate;
import com.saodai.saodaimall.order.service.OrderService;
import com.saodai.saodaimall.order.vo.PayVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;/**
* 支付宝控制器
**/@Slf4j
@Controller
public class PayWebController {@Autowiredprivate AlipayTemplate alipayTemplate;@Autowiredprivate OrderService orderService;/*** 用户下单:支付宝支付* 1、让支付页让浏览器展示* 2、支付成功以后,跳转到用户的订单列表页* @param orderSn* @return* @throws AlipayApiException*/@ResponseBody@GetMapping(value = "/aliPayOrder",produces = "text/html")//produces = "text/html"表示返回的类型是htmlpublic String aliPayOrder(@RequestParam("orderSn") String orderSn) throws AlipayApiException {//getOrderPay方法是为了封装PayVo对象PayVo payVo = orderService.getOrderPay(orderSn);//这里返回的pay是一个html页面,直接给浏览器渲染就行了String pay = alipayTemplate.pay(payVo);//        System.out.println(pay);return pay;}}

getOrderPay方法是为了封装PayVo对象,分流程:

1、根据订单号查询到订单

2、格式化付款金额并封装到PayVo

3、获取订单的第一个订单项,把商品销售属性组合(JSON)作为商品描述

  /*** 获取当前订单的支付信息(支付宝支付)* @param orderSn* @return*/@Overridepublic PayVo getOrderPay(String orderSn) {PayVo payVo = new PayVo();//根据订单号查询到订单OrderEntity orderInfo = this.getOrderByOrderSn(orderSn);//因为数据库保存的是小数点后四位,这里要转为2位(setScale(2, BigDecimal.ROUND_UP)表示保留两位小数点,向上取值)BigDecimal payAmount = orderInfo.getPayAmount().setScale(2, BigDecimal.ROUND_UP);//设置付款金额payVo.setTotal_amount(payAmount.toString());//商户订单号payVo.setOut_trade_no(orderInfo.getOrderSn());//查询订单项的数据List<OrderItemEntity> orderItemInfo = orderItemService.list(new QueryWrapper<OrderItemEntity>().eq("order_sn", orderSn));//获取订单的第一个订单项OrderItemEntity orderItemEntity = orderItemInfo.get(0);//把商品销售属性组合(JSON)作为商品描述payVo.setBody(orderItemEntity.getSkuAttrsVals());//把商品sku名字作为设置订单名称payVo.setSubject(orderItemEntity.getSkuName());return payVo;}
package com.saodai.saodaimall.order.vo;import lombok.Data;/*** 支付宝支付需要用到的数据封装类*/
@Data
public class PayVo {private String out_trade_no; // 商户订单号 必填private String subject; // 订单名称 必填private String total_amount;  // 付款金额 必填private String body; // 商品描述 可空
}

6、第五步处理成功后会执行下面链接的跳转

这个memberOrder.html其实就是订单服务的所有订单界面(用户的所有订单)

#同步通知,支付成功,一般跳转到成功页
alipay.return_url=http://member.saodaimall.com/memberOrder.html

7、在会员服务的web包的MemberWebController控制器来处理请求/memberOrder.html(这里进行了分页处理)

package com.saodai.saodaimall.member.web;import com.alibaba.fastjson.JSON;
import com.saodai.common.utils.R;
import com.saodai.saodaimall.member.feign.OrderFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;/***支付宝支付成功后回调页面处理器**/@Controller
public class MemberWebController {@Autowiredprivate OrderFeignService orderFeignService;@GetMapping(value = "/memberOrder.html")public String memberOrderPage(@RequestParam(value = "pageNum",required = false,defaultValue = "0") Integer pageNum,Model model, HttpServletRequest request) {//获取到支付宝给我们转来的所有请求数据//request,验证签名//查出当前登录用户的所有订单列表数据Map<String,Object> page = new HashMap<>();page.put("page",pageNum.toString());//远程查询订单服务订单数据R orderInfo = orderFeignService.listWithItem(page);System.out.println(JSON.toJSONString(orderInfo));model.addAttribute("orders",orderInfo);return "orderList";}}

(1)远程调用订单服务来查询所有订单信息

 /*** 分页查询当前登录用户的所有订单信息(用于前台我的订单里的数据回显)* @param params* @return*/@PostMapping("/listWithItem")//@RequiresPermissions("order:order:list")public R listWithItem(@RequestBody Map<String, Object> params){PageUtils page = orderService.queryPageWithItem(params);return R.ok().put("page", page);}

(2)OrderServiceImpl的queryPageWithItem方法具体实现

分流程:

1、按会员id去查询所有订单,然后按创建时间做降序排列(也就是最新的订单会在第一个显示)

2、遍历所有订单集合(封装List<OrderEntity>中的订单项的数据)

 /*** 分页查询当前登录用户的所有订单信息(用于前台我的订单里的数据回显)*/@Overridepublic PageUtils queryPageWithItem(Map<String, Object> params) {MemberResponseVo memberResponseVo = LoginUserInterceptor.loginUser.get();//按会员id去查询所有订单,然后按创建时间做降序排列(也就是最新的订单会在第一个显示)IPage<OrderEntity> page = this.page(new Query<OrderEntity>().getPage(params),new QueryWrapper<OrderEntity>().eq("member_id",memberResponseVo.getId()).orderByDesc("create_time"));//遍历所有订单集合(封装订单项)List<OrderEntity> orderEntityList = page.getRecords().stream().map(order -> {//根据订单号查询订单项里的数据List<OrderItemEntity> orderItemEntities = orderItemService.list(new QueryWrapper<OrderItemEntity>().eq("order_sn", order.getOrderSn()));order.setOrderItemEntityList(orderItemEntities);return order;}).collect(Collectors.toList());page.setRecords(orderEntityList);return new PageUtils(page);}

8、通过支付宝支付成功后的异步回调来修改支付成功后订单页面的订单项的状态

(1)在支付宝沙箱环境配置中有以下配置

这个配置就是表示支付宝支付成功后会有一个支付成功的异步消息发送到这个url地址(特别注意的是这个地址必须是外网能够访问的到得道地址,vtyk0jgqvh.51xd.pub是买了内网穿透后给的地址,外网可以访问到的地址,它和本机的order.saodaimall.com地址是对应的),告诉我们支付成功了,这里就可以通过这个地址来修改订单的状态(也就是把支付宝支付成功后的订单状态由待付款自动修改成已支付状态),这个请求会按固定的时间间隔来发送请求,直到返回“success”才会停止发送请求(发完固定次数也会停止)

#支付宝会悄悄的给我们发送一个请求,告诉我们支付成功的信息
alipay.notify_url=http://vtyk0jgqvh.51xd.pub/payed/notify

(2)上面的/payed/notify请求由订单服务的listener包的OrderPayedListener控制器来处理

package com.saodai.saodaimall.order.listener;import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.saodai.saodaimall.order.config.AlipayTemplate;
import com.saodai.saodaimall.order.service.OrderService;
import com.saodai.saodaimall.order.vo.PayAsyncVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;/**
* 订单支付成功控制器(支付宝支付成功后的异步通知)
* 支付宝会悄悄的给我们发送一个请求,告诉我们支付成功的信息
* 只要收到支付宝的异步通知,返回 success 支付宝便不再通知(在通知之前需要验签)
*/
@RestController
public class OrderPayedListener {@Autowiredprivate OrderService orderService;@Autowiredprivate AlipayTemplate alipayTemplate;@PostMapping(value = "/payed/notify")public String handleAlipayed(PayAsyncVo asyncVo, HttpServletRequest request) throws AlipayApiException, UnsupportedEncodingException {// 获取支付宝POST过来反馈信息//TODO 需要验签Map<String, String> params = new HashMap<>();Map<String, String[]> 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] + ",";}//乱码解决,这段代码在出现乱码时使用// valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");params.put(name, valueStr);}//alipayTemplate.getAlipay_public_key()是支付宝公钥 alipayTemplate.getCharset()字符编码格式 alipayTemplate.getSign_type()签名方式boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayTemplate.getAlipay_public_key(),alipayTemplate.getCharset(), alipayTemplate.getSign_type()); //调用SDK验证签名if (signVerified) {System.out.println("签名验证成功...");//去修改订单状态String result = orderService.handlePayResult(asyncVo);return result;} else {System.out.println("签名验证失败...");return "error";}}//        for (String key:requestParams.keySet()){//            String value = request.getParameter(key);//            System.out.println("key: "+key+"=======>value"+value);//        }//        System.out.println("asyncVo:"+asyncVo);//        System.out.println("----------------------------");//        System.out.println("requestParams"+requestParams);//        return "success";}
package com.saodai.saodaimall.order.vo;import lombok.Data;
import lombok.ToString;import java.util.Date;/*** 支付的异步vo(用于下单付款后修改订单的状态为已付款)*/
@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;//支付者的idprivate String body;//订单的信息private String invoice_amount;//支付金额private String version;private String notify_id;//通知idprivate String fund_bill_list;private String notify_type;//通知类型; trade_status_syncprivate String out_trade_no;//订单号private String total_amount;//支付的总额private String trade_status;//交易状态  TRADE_SUCCESSprivate String trade_no;//流水号private String auth_app_id;//private String receipt_amount;//商家收到的款private String point_amount;//private String app_id;//应用idprivate String buyer_pay_amount;//最终支付的金额private String sign_type;//签名类型private String seller_id;//商家的id}

(3)上面控制器的代码都是固定的,唯一是自己业务处理的代码就一句

唯一是自己业务处理:String result = orderService.handlePayResult(asyncVo);

  /*** 处理支付宝的支付结果(支付宝异步通知)* @param asyncVo* @return*/@Transactional(rollbackFor = Exception.class)@Overridepublic String handlePayResult(PayAsyncVo asyncVo) {//保存交易流水信息PaymentInfoEntity paymentInfo = new PaymentInfoEntity();//订单号(对外业务号)paymentInfo.setOrderSn(asyncVo.getOut_trade_no());//支付宝交易流水号paymentInfo.setAlipayTradeNo(asyncVo.getTrade_no());//支付总金额paymentInfo.setTotalAmount(new BigDecimal(asyncVo.getBuyer_pay_amount()));//交易内容paymentInfo.setSubject(asyncVo.getBody());//支付状态paymentInfo.setPaymentStatus(asyncVo.getTrade_status());//创建时间paymentInfo.setCreateTime(new Date());//回调时间paymentInfo.setCallbackTime(asyncVo.getNotify_time());//添加到数据库中this.paymentInfoService.save(paymentInfo);//修改订单状态//获取当前状态 TRADE_SUCCESSString tradeStatus = asyncVo.getTrade_status();//TRADE_SUCCESS是支付宝提供的表示订单状态的常量(表示商家支持的可以退款的支付成功)TRADE_FINISHED表示商家不支持退款的支付成功if (tradeStatus.equals("TRADE_SUCCESS") || tradeStatus.equals("TRADE_FINISHED")) {//获取订单号(订单号是自己系统生成的订单号)String orderSn = asyncVo.getOut_trade_no();//orderSn是订单号 OrderStatusEnum.PAYED.getCode()是PAYED(1,"已付款")  PayConstant.ALIPAY支付类型this.updateOrderStatus(orderSn,OrderStatusEnum.PAYED.getCode(), PayConstant.ALIPAY);}return "success";}/*** 修改订单状态(其实就是把订单状态改成已付款)* @param orderSn  订单号* @param code  订单状态* @param payType  支付类型*/private void updateOrderStatus(String orderSn, Integer code,Integer payType) {this.baseMapper.updateOrderStatus(orderSn,code,payType);}
<!--    修改订单状态-->
<update id="updateOrderStatus">UPDATE oms_orderSET `status` = #{code},modify_time = NOW(),pay_type = #{payType},payment_time = NOW()WHERE order_sn = #{orderSn}
</update>
package com.saodai.saodaimall.order.entity;import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;/*** 保存交易流水信息*/
@Data
@TableName("oms_payment_info")
public class PaymentInfoEntity implements Serializable {private static final long serialVersionUID = 1L;/*** id*/@TableIdprivate Long id;/*** 订单号(对外业务号)*/private String orderSn;/*** 订单id*/private Long orderId;/*** 支付宝交易流水号*/private String alipayTradeNo;/*** 支付总金额*/private BigDecimal totalAmount;/*** 交易内容*/private String subject;/*** 支付状态*/private String paymentStatus;/*** 创建时间*/private Date createTime;/*** 确认时间*/private Date confirmTime;/*** 回调内容*/private String callbackContent;/*** 回调时间*/private Date callbackTime;}

支付服务-----功能实现逻辑相关推荐

  1. 关于12306网站新增支付宝支付服务功能的公告

    自11月30日起,中国铁路客户服务中心12306网站支付宝账户支付服务功能上线试运行,旅客网购火车票新增一种支付方式.旅客在12306网站购买火车票时,可选择工行.农行.中行.建行.招行.银联.中铁银 ...

  2. 订单服务-----功能实现逻辑

    订单服务的实现流程(确认订单->提交订单->支付) 1.整合SpringSession 使用SpringSession的目的是来解决分布式session不同步不共享的问题,其实就是为了让登 ...

  3. 秒杀服务-----功能实现逻辑

    管理员上架秒杀商品的流程 1.去后台管理系统添加新的秒杀场次(注意这里不能把之前的秒杀场次给修改后再次使用,还有时间必须要三天内) 2.在秒杀服务中的定时任务修改一下每5s上架一次(这样是为了更快上架 ...

  4. 精讲23种设计模式-策略模式~聚合短信服务和聚合支付服务

    文章目录 一.设计模式 1. 为什么需要使用设计模式 2. 设计模式的分类 3. 什么是策略模式 4. 为什么叫做策略模式 5. 策略模式优缺点 6. 策略模式应用场景 7. Spring框架中使用的 ...

  5. 支付服务代码设计(策略模式,可扩展,接入方便)

    最近一直在深入学习一些知识,整理出一些东西一直没有时间写出来,后续会慢慢总结一下写在博客上,对于博客还是不想专门写知识点,总结和提升终究是为了自己,写出来的博客为了让别人看的好,更为了自己的成长和记录 ...

  6. 微信支付-App支付服务端详解

    微信App支付服务端详解 引言 主要实现app支付统一下单.异步通知.调起支付接口.支付订单查询.申请退款.查询退款功能:封装了https对发起退款的证书校验.签名.xml解析等. 支付流程 具体支付 ...

  7. 微信支付服务端自动对账

    微信支付服务端自动对账 支付及对账流程链接 自动对账说明 微信支付后每天的商户系统的自动对账还是比较繁琐的,所谓自动对账实际上就是将商户某天交易成功的订单信息与微信某天的账单进行逐一匹配的过程.其涉及 ...

  8. 微信APP支付服务端和Android 端详解及其demo

    最近在开发APP微信支付和支付宝支付,Android 端和后端都是我自己开发的,发现两家公司的文档都不是很友好,特别是微信,接触过或者开发过的人都应该有所体会.因此我特意把开发的过程梳理了,做下记录, ...

  9. 在线部分:werobot服务、主要逻辑服务、句子相关模型服务、BERT中文预训练模型+微调模型(目的:比较两句话text1和text2之间是否有关联)、模型在Flask部署

    日萌社 人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新) 智能对话系统:Unit对话API 在线聊天的总体架构与工具介绍 ...

最新文章

  1. 权威解释IDEA的“Include in project build”打钩或者不打勾有啥区别?
  2. 算法------二叉树的层序遍历
  3. C/C++中单井号与双井号的使用
  4. 关于Kingfisher--备用
  5. 用C#快速往Excel写数据
  6. matlab中矩阵怎么敲_Ansys刚度(质量、阻尼)矩阵的提取(part 1)
  7. SQL Server数据库字段类型详解
  8. 利用jQuery和css实现的模仿百度搜索列表页面的分页的足迹效果
  9. python监控linux运行程序_如何在linux/tcl/python中监控正在打开或启动的应用程序?...
  10. 中国微流体系统市场趋势报告、技术动态创新及市场预测
  11. ARTS打卡10-抓住海森堡Bug
  12. sessionid java_java如何获取sessionid
  13. 视频工厂分享vlog拍摄技巧
  14. 二元logistic模型案例_基于Logistic回归的二元分类应用(含公式推导)
  15. 从零开始学版图(一)——反相器版图
  16. TSC TTP-244 Pro打印机QT版本开发
  17. python 谱聚类
  18. #教计算机学画卡通人物#生成式对抗神经网络GAN原理、Tensorflow搭建网络生成卡通人脸
  19. threeJs设置控制器的阻尼效果,拖拽起来不生硬
  20. 第三次电信重组大局初定(图)

热门文章

  1. Flutter 制霸全平台?这事儿我看有戏。
  2. put请求带body
  3. 1008:美元和人民币
  4. YII模板(前台显示)详细分析
  5. c语言定义寄存器中的两位,汇编语言:编写一个程序,显示AL寄存器中的两位十六进制数...
  6. 关于节日文化的HTML网页设计-----二十四节气
  7. 2023首届大学生算法大赛 - 村庄
  8. OCR身份证识别SDK
  9. 小丸子学Redis系列之——Data types(一)
  10. 基于opencv的图片模板匹配及其简单应用