地址簿
产品原型

业务功能:
- 查询地址列表。
- 新增地址。
- 修改地址。
- 删除地址。
- 设置默认地址。
- 查询默认地址。
接口设计
新增地址。

查询当前登录用户的所有地址信息。

查询默认地址。

根据id修改地址。

根据id删除地址。

根据id查询地址。

设置默认地址。

数据库设计(address_book表)
| 字段名 |
数据类型 |
说明 |
备注 |
| id |
bigint |
主键 |
自增 |
| user_id |
bigint |
用户id |
逻辑外键 |
| consignee |
varchar(50) |
收货人 |
|
| sex |
varchar(2) |
性别 |
|
| phone |
varchar(11) |
手机号 |
|
| province_code |
varchar(12) |
省份编码 |
|
| province_name |
varchar(32) |
省份名称 |
|
| city_code |
varchar(12) |
城市编码 |
|
| city_name |
varchar(32) |
城市名称 |
|
| district_code |
varchar(12) |
区县编码 |
|
| district_name |
varchar(32) |
区县名称 |
|
| detail |
varchar(200) |
详细地址信息 |
具体到门牌号 |
| label |
varchar(100) |
标签 |
公司、家、学校 |
| is_default |
tinyint(1) |
是否默认地址 |
1是 0否 |
代码开发
1.AddressBookController。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| package com.sky.controller.user;
@RestController @RequestMapping("/user/addressBook") @Api(tags = "C端地址簿接口") public class AddressBookController {
@Autowired private AddressBookService addressBookService;
@GetMapping("/list") @ApiOperation("查询当前登录用户的所有地址信息") public Result<List<AddressBook>> list() { AddressBook addressBook = new AddressBook(); addressBook.setUserId(BaseContext.getCurrentId()); List<AddressBook> list = addressBookService.list(addressBook); return Result.success(list); }
@PostMapping @ApiOperation("新增地址") public Result save(@RequestBody AddressBook addressBook) { addressBookService.save(addressBook); return Result.success(); }
@GetMapping("/{id}") @ApiOperation("根据id查询地址") public Result<AddressBook> getById(@PathVariable Long id) { AddressBook addressBook = addressBookService.getById(id); return Result.success(addressBook); }
@PutMapping @ApiOperation("根据id修改地址") public Result update(@RequestBody AddressBook addressBook) { addressBookService.update(addressBook); return Result.success(); }
@PutMapping("/default") @ApiOperation("设置默认地址") public Result setDefault(@RequestBody AddressBook addressBook) { addressBookService.setDefault(addressBook); return Result.success(); }
@DeleteMapping @ApiOperation("根据id删除地址") public Result deleteById(Long id) { addressBookService.deleteById(id); return Result.success(); }
@GetMapping("default") @ApiOperation("查询默认地址") public Result<AddressBook> getDefault() { AddressBook addressBook = new AddressBook(); addressBook.setIsDefault(1); addressBook.setUserId(BaseContext.getCurrentId()); List<AddressBook> list = addressBookService.list(addressBook);
if (list != null && list.size() == 1) { return Result.success(list.get(0)); }
return Result.error("没有查询到默认地址"); }
}
|
2.AddressBookService。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package com.sky.service;
public interface AddressBookService {
List<AddressBook> list(AddressBook addressBook);
void save(AddressBook addressBook);
AddressBook getById(Long id);
void update(AddressBook addressBook);
void setDefault(AddressBook addressBook);
void deleteById(Long id);
}
|
3.AddressBookServiceImpl。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| package com.sky.service.impl;
@Service @Slf4j public class AddressBookServiceImpl implements AddressBookService { @Autowired private AddressBookMapper addressBookMapper;
public List<AddressBook> list(AddressBook addressBook) { return addressBookMapper.list(addressBook); }
public void save(AddressBook addressBook) { addressBook.setUserId(BaseContext.getCurrentId()); addressBook.setIsDefault(0); addressBookMapper.insert(addressBook); }
public AddressBook getById(Long id) { AddressBook addressBook = addressBookMapper.getById(id); return addressBook; }
public void update(AddressBook addressBook) { addressBookMapper.update(addressBook); }
@Transactional public void setDefault(AddressBook addressBook) { addressBook.setIsDefault(0); addressBook.setUserId(BaseContext.getCurrentId()); addressBookMapper.updateIsDefaultByUserId(addressBook);
addressBook.setIsDefault(1); addressBookMapper.update(addressBook); }
public void deleteById(Long id) { addressBookMapper.deleteById(id); } }
|
4.AddressBookMapper.java。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| package com.sky.mapper;
import com.sky.entity.AddressBook; import org.apache.ibatis.annotations.*; import java.util.List;
@Mapper public interface AddressBookMapper {
List<AddressBook> list(AddressBook addressBook);
@Insert("insert into address_book" + " (user_id, consignee, phone, sex, province_code, province_name, city_code, city_name, district_code," + " district_name, detail, label, is_default)" + " values (#{userId}, #{consignee}, #{phone}, #{sex}, #{provinceCode}, #{provinceName}, #{cityCode}, #{cityName}," + " #{districtCode}, #{districtName}, #{detail}, #{label}, #{isDefault})") void insert(AddressBook addressBook);
@Select("select * from address_book where id = #{id}") AddressBook getById(Long id);
void update(AddressBook addressBook);
@Update("update address_book set is_default = #{isDefault} where user_id = #{userId}") void updateIsDefaultByUserId(AddressBook addressBook);
@Delete("delete from address_book where id = #{id}") void deleteById(Long id); }
|
5.AddressBookMapper.xml。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.sky.mapper.AddressBookMapper">
<select id="list" parameterType="AddressBook" resultType="AddressBook"> select * from address_book <where> <if test="userId != null"> and user_id = #{userId} </if> <if test="phone != null"> and phone = #{phone} </if> <if test="isDefault != null"> and is_default = #{isDefault} </if> </where> </select>
<update id="update" parameterType="addressBook"> update address_book <set> <if test="consignee != null"> consignee = #{consignee}, </if> <if test="sex != null"> sex = #{sex}, </if> <if test="phone != null"> phone = #{phone}, </if> <if test="detail != null"> detail = #{detail}, </if> <if test="label != null"> label = #{label}, </if> <if test="isDefault != null"> is_default = #{isDefault}, </if> </set> where id = #{id} </update>
</mapper>
|
用户下单
用户点餐业务流程

接口设计
请求方式:POST
请求路径:/user/order/submit
参数:
- 地址簿
id
- 配送状态(立即送出、选择送出时间)
- 打包费
- 总金额
- 备注
- 餐具数量
返回数据:

数据库设计
订单表和订单明细表的关系:一对多。
订单表orders
| 字段名 |
数据类型 |
说明 |
备注 |
| id |
bigint |
主键 |
自增 |
| number |
varchar(50) |
订单号 |
|
| status |
int |
订单状态 |
1待付款 2待接单 3已接单 4派送中 5已完成 6已取消 |
| user_id |
bigint |
用户id |
逻辑外键 |
| address_book_id |
bigint |
地址id |
逻辑外键 |
| order_time |
datetime |
下单时间 |
|
| checkout_time |
datetime |
付款时间 |
|
| pay_method |
int |
支付方式 |
1微信支付 2支付宝支付 |
| pay_status |
tinyint |
支付状态 |
0未支付 1已支付 2退款 |
| amount |
decimal(10,2) |
订单金额 |
|
| remark |
varchar(100) |
备注信息 |
|
| phone |
varchar(11) |
手机号 |
冗余字段 |
| address |
varchar(255) |
详细地址信息 |
冗余字段 |
| consignee |
varchar(32) |
收货人 |
冗余字段 |
| cancel_reason |
varchar(255) |
订单取消原因 |
|
| rejection_reason |
varchar(255) |
拒单原因 |
|
| cancel_time |
datetime |
订单取消时间 |
|
| estimated_delivery_time |
datetime |
预计送达时间 |
|
| delivery_status |
tinyint |
配送状态 |
1立即送出 0选择具体时间 |
| delivery_time |
datetime |
送达时间 |
|
| pack_amount |
int |
打包费 |
|
| tableware_number |
int |
餐具数量 |
|
| tableware_status |
tinyint |
餐具数量状态 |
1按餐量提供 0选择具体数量 |
订单明细表order_detail
| 字段名 |
数据类型 |
说明 |
备注 |
| id |
bigint |
主键 |
自增 |
| name |
varchar(32) |
商品名称 |
冗余字段 |
| image |
varchar(255) |
商品图片路径 |
冗余字段 |
| order_id |
bigint |
订单id |
逻辑外键 |
| dish_id |
bigint |
菜品id |
逻辑外键 |
| setmeal_id |
bigint |
套餐id |
逻辑外键 |
| dish_flavor |
varchar(50) |
菜品口味 |
|
| number |
int |
商品数量 |
|
| amount |
decimal(10,2) |
商品单价 |
|
代码开发
根据用户下单接口的参数设计DTO。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package com.sky.dto;
@Data public class OrdersSubmitDTO implements Serializable { private Long addressBookId; private int payMethod; private String remark; @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime estimatedDeliveryTime; private Integer deliveryStatus; private Integer tablewareNumber; private Integer tablewareStatus; private Integer packAmount; private BigDecimal amount; }
|
根据用户下单接口的返回结果设计VO。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| package com.sky.vo;
@Data @Builder @NoArgsConstructor @AllArgsConstructor public class OrderSubmitVO implements Serializable { private Long id; private String orderNumber; private BigDecimal orderAmount; private LocalDateTime orderTime; }
|
创建OrderController并提供用户下单方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package com.sky.controller.user;
@RestController("userOrderController") @RequestMapping("user/order") @Api(tags = "用户端订单相关接口") @Slf4j public class OrderController { @Autowired private OrderService orderService;
@PostMapping("/submit") @ApiOperation("用户下单") public Result<OrderSubmitVO> submit(@RequestBody OrdersSubmitDTO ordersSubmitDTO) { log.info("用户下单,参数为{}", ordersSubmitDTO); OrderSubmitVO orderSubmitVO = orderService.submitOrder(ordersSubmitDTO); return Result.success(orderSubmitVO); } }
|
创建OrderService接口,并声明用户下单方法。
1 2 3 4 5 6 7
| package com.sky.service;
@Service public interface OrderService { OrderSubmitVO submitOrder(OrdersSubmitDTO ordersSubmitDTO); }
|
创建OrderServiceImpl实现OrderService接口。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| package com.sky.service.impl;
@Service public class OrderServiceImpl implements OrderService { @Autowired private OrderMapper orderMapper; @Autowired private OrderDetailMapper orderDetailMapper; @Autowired private AddressBookMapper addressBookMapper; @Autowired private ShoppingCartMapper shoppingCartMapper;
@Override @Transactional public OrderSubmitVO submitOrder(OrdersSubmitDTO ordersSubmitDTO) { AddressBook addressBook = addressBookMapper.getById(ordersSubmitDTO.getAddressBookId()); if(addressBook == null){ throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL); }
Long userId = BaseContext.getCurrentId(); ShoppingCart shoppingCart = new ShoppingCart(); shoppingCart.setUserId(userId); List<ShoppingCart> shoppingCartList = shoppingCartMapper.list(shoppingCart); if(shoppingCartList == null || shoppingCartList.size() == 0){ throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL); }
Orders orders = new Orders(); BeanUtils.copyProperties(ordersSubmitDTO, orders); orders.setOrderTime(LocalDateTime.now()); orders.setPayStatus(Orders.UN_PAID); orders.setStatus(Orders.PENDING_PAYMENT); orders.setNumber(String.valueOf(System.currentTimeMillis())); orders.setPhone(addressBook.getPhone()); orders.setConsignee(addressBook.getConsignee()); orders.setUserId(userId);
orderMapper.insert(orders);
List<OrderDetail> orderDetailList = new ArrayList<>(); for(ShoppingCart cart : shoppingCartList){ OrderDetail orderDetail = new OrderDetail(); BeanUtils.copyProperties(cart, orderDetail); orderDetail.setOrderId(orders.getId()); orderDetailList.add(orderDetail); }
orderDetailMapper.insertBatch(orderDetailList);
shoppingCartMapper.deleteById(userId);
OrderSubmitVO orderSubmitVO = OrderSubmitVO.builder() .id(orders.getId()) .orderTime(orders.getOrderTime()) .orderNumber(orders.getNumber()) .orderAmount(orders.getAmount()) .build();
return orderSubmitVO; } }
|
创建OrderMapper接口和对应的xml映射文件。
1 2 3 4 5 6 7
| package com.sky.mapper;
@Mapper public interface OrderMapper { void insert(Orders orders); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.sky.mapper.OrderMapper">
<insert id="insert" parameterType="Orders" useGeneratedKeys="true" keyProperty="id"> insert into orders (number, status, user_id, address_book_id, order_time, checkout_time, pay_method, pay_status, amount, remark, phone, address, consignee, estimated_delivery_time, delivery_status, pack_amount, tableware_number, tableware_status) values (#{number}, #{status}, #{userId}, #{addressBookId}, #{orderTime}, #{checkoutTime}, #{payMethod}, #{payMethod}, #{amount}, #{remark}, #{phone}, #{address}, #{consignee}, #{estimatedDeliveryTime}, #{deliveryStatus}, #{packAmount}, #{tablewareNumber}, #{tablewareStatus}) </insert> </mapper>
|
创建OrderDetailMapper接口和对应的xml映射文件。
1 2 3 4 5 6 7
| package com.sky.mapper;
@Mapper public interface OrderDetailMapper { void insertBatch(List<OrderDetail> orderDetailList); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.sky.mapper.OrderDetailMapper">
<insert id="insertBatch"> insert into order_detail (name, image, order_id, dish_id, setmeal_id, dish_flavor, number, amount) values <foreach collection="orderDetailList" item="od" separator=","> (#{od.name}, #{od.image}, #{od.orderId}, #{od.dishId}, #{od.setmealId}, #{od.dishFlavor}, #{od.number}, #{od.amount}) </foreach> </insert> </mapper>
|
订单支付
微信支付介绍
微信支付产品

参考:https://pay.weixin.qq.com/static/product/product_index.shtml
微信支付接入流程

微信小程序支付时序图

JSAPI下单:商户系统调用该接口在微信支付服务后台生成预支付交易单。
链接:微信支付-开发者文档

微信小程序调起支付:通过JSAPI下单接口获取到发起支付的必要参数prepay_id,然后使用微信支付提供的小程序方法调起小程序支付。
链接:微信支付-开发者文档

微信支付准备工作
1.获取微信支付平台证书、商户私钥文件:两个pem文件。
2.获取临时域名:支付成功后微信服务通过该域名回调我们的程序。
链接:https://dashboard.cpolar.com/

注意:使用cpolar.exe http 8080命令如果不出现Forwarding这个选项,把命令换成cpolar.exe http -region=cn_vip 8080即可。
代码开发
不跳过微信支付
1.微信支付相关配置。

application.yml。
1 2 3 4 5 6 7 8 9 10 11
| sky: wechat: appid: ${sky.wechat.appid} secret: ${sky.wechat.secret} mchid: ${sky.wechat.mchid} mchSerialNo: ${sky.wechat.mchSerialNo} privateKeyFilePath: ${sky.wechat.privateKeyFilePath} apiV3Key: ${sky.wechat.apiV3Key} weChatPayCertFilePath: ${sky.wechat.weChatPayCertFilePath} notifyUrl: ${sky.wechat.notifyUrl} refundNotifyUrl: ${sky.wechat.refundNotifyUrl}
|
application-dev.yml(实现微信支付需要填写如下内容)
1 2 3 4 5 6 7 8 9 10 11
| sky: wechat: appid: secret: mchid: mchSerialNo: privateKeyFilePath: apiV3Key: weChatPayCertFilePath: notifyUrl: refundNotifyUrl:
|
2.user/OrderController。
1 2 3 4 5 6 7 8 9
| @PutMapping("/payment") @ApiOperation("订单支付") public Result<OrderPaymentVO> payment(@RequestBody OrdersPaymentDTO ordersPaymentDTO) throws Exception { log.info("订单支付:{}", ordersPaymentDTO); OrderPaymentVO orderPaymentVO = orderService.payment(ordersPaymentDTO); log.info("生成预支付交易单:{}", orderPaymentVO); return Result.success(orderPaymentVO); }
|
3.OrderService。
1 2 3 4 5
| OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception;
void paySuccess(String outTradeNo);
|
4.OrderServiceImpl。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| @Autowired private WeChatPayUtil weChatPayUtil; @Autowired private UserMapper userMapper;
public OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception { Long userId = BaseContext.getCurrentId(); User user = userMapper.getById(userId);
JSONObject jsonObject = weChatPayUtil.pay( ordersPaymentDTO.getOrderNumber(), new BigDecimal(0.01), "苍穹外卖订单", user.getOpenid() );
if (jsonObject.getString("code") != null && jsonObject.getString("code").equals("ORDERPAID")) { throw new OrderBusinessException("该订单已支付"); }
OrderPaymentVO vo = jsonObject.toJavaObject(OrderPaymentVO.class); vo.setPackageStr(jsonObject.getString("package"));
return vo; }
public void paySuccess(String outTradeNo) {
Orders ordersDB = orderMapper.getByNumber(outTradeNo);
Orders orders = Orders.builder() .id(ordersDB.getId()) .status(Orders.TO_BE_CONFIRMED) .payStatus(Orders.PAID) .checkoutTime(LocalDateTime.now()) .build();
orderMapper.update(orders); }
|
5.OrderMapper。
1 2 3 4 5 6
| @Select("select * from orders where number = #{orderNumber}") Orders getByNumber(String orderNumber);
void update(Orders orders);
|
6.OrderMapper.xml。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <update id="update" parameterType="com.sky.entity.Orders"> update orders <set> <if test="cancelReason != null and cancelReason!='' "> cancel_reason=#{cancelReason}, </if> <if test="rejectionReason != null and rejectionReason!='' "> rejection_reason=#{rejectionReason}, </if> <if test="cancelTime != null"> cancel_time=#{cancelTime}, </if> <if test="payStatus != null"> pay_status=#{payStatus}, </if> <if test="payMethod != null"> pay_method=#{payMethod}, </if> <if test="checkoutTime != null"> checkout_time=#{checkoutTime}, </if> <if test="status != null"> status = #{status}, </if> <if test="deliveryTime != null"> delivery_time = #{deliveryTime} </if> </set> where id = #{id} </update>
|
7.UserMapper。
1 2 3
| @Select("select * from user where id = #{id}") User getById(Long userId);
|
8.PayNotifyController。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
| package com.sky.controller.notify;
import com.alibaba.druid.support.json.JSONUtils; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.sky.properties.WeChatProperties; import com.sky.service.OrderService; import com.wechat.pay.contrib.apache.httpclient.util.AesUtil; import lombok.extern.slf4j.Slf4j; import org.apache.http.entity.ContentType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.nio.charset.StandardCharsets; import java.util.HashMap;
@RestController @RequestMapping("/notify") @Slf4j public class PayNotifyController { @Autowired private OrderService orderService; @Autowired private WeChatProperties weChatProperties;
@RequestMapping("/paySuccess") public void paySuccessNotify(HttpServletRequest request, HttpServletResponse response) throws Exception { String body = readData(request); log.info("支付成功回调:{}", body);
String plainText = decryptData(body); log.info("解密后的文本:{}", plainText);
JSONObject jsonObject = JSON.parseObject(plainText); String outTradeNo = jsonObject.getString("out_trade_no"); String transactionId = jsonObject.getString("transaction_id");
log.info("商户平台订单号:{}", outTradeNo); log.info("微信支付交易号:{}", transactionId);
orderService.paySuccess(outTradeNo);
responseToWeixin(response); }
private String readData(HttpServletRequest request) throws Exception { BufferedReader reader = request.getReader(); StringBuilder result = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { if (result.length() > 0) { result.append("\n"); } result.append(line); } return result.toString(); }
private String decryptData(String body) throws Exception { JSONObject resultObject = JSON.parseObject(body); JSONObject resource = resultObject.getJSONObject("resource"); String ciphertext = resource.getString("ciphertext"); String nonce = resource.getString("nonce"); String associatedData = resource.getString("associated_data");
AesUtil aesUtil = new AesUtil(weChatProperties.getApiV3Key().getBytes(StandardCharsets.UTF_8)); String plainText = aesUtil.decryptToString(associatedData.getBytes(StandardCharsets.UTF_8), nonce.getBytes(StandardCharsets.UTF_8), ciphertext);
return plainText; }
private void responseToWeixin(HttpServletResponse response) throws Exception{ response.setStatus(200); HashMap<Object, Object> map = new HashMap<>(); map.put("code", "SUCCESS"); map.put("message", "SUCCESS"); response.setHeader("Content-type", ContentType.APPLICATION_JSON.toString()); response.getOutputStream().write(JSONUtils.toJSONString(map).getBytes(StandardCharsets.UTF_8)); response.flushBuffer(); } }
|
跳过微信支付
参考链接:
只试过下面这个:
苍穹外卖跳过微信支付(全网最强,最详细,最容易理解)_跳过网页微信付费-CSDN博客
其他的方法(没试过):
苍穹外卖项目微信支付(没有商户号)的解决方法,超详细!!!_没有微信商户号怎么实现支付-CSDN博客
苍穹外卖按照别的博主修改vx支付后商家订单不通知问题-CSDN博客
苍穹外卖遇到问题(包括跳过微信支付、nodejs不兼容等)_怎么跳过exe的支付界面设置-CSDN博客
1.OrderServiceImpl。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| @Override public OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception{ Long userId = BaseContext.getCurrentId(); User user = userMapper.getById(userId);
JSONObject jsonObject = new JSONObject(); jsonObject.put("code", "ORDERPAID"); OrderPaymentVO vo = jsonObject.toJavaObject(OrderPaymentVO.class); vo.setPackageStr(jsonObject.getString("package"));
Integer OrderPaidStatus = Orders.PAID; Integer OrderStatus = Orders.TO_BE_CONFIRMED;
LocalDateTime check_out_time = LocalDateTime.now();
String orderNumber = ordersPaymentDTO.getOrderNumber();
log.info("调用updateStatus,用于替换微信支付更新数据库状态的问题"); orderMapper.updateStatus(OrderStatus, OrderPaidStatus, check_out_time, orderNumber);
return vo; }
|
2.OrderMapper。
1 2 3 4 5 6 7 8
|
@Update("update orders set status = #{orderStatus},pay_status = #{orderPaidStatus} ,checkout_time = #{check_out_time} " + "where number = #{orderNumber}") void updateStatus(Integer orderStatus, Integer orderPaidStatus, LocalDateTime check_out_time, String orderNumber);
|