当前位置: 首页 > news >正文

【畅购商城】微信支付之支付回调和支付状态

目录

Nuxt.js IP 启动

支付回调

回调接口

后端实现

查看支付状态

后端实现

前端实现

​​​​​​​前置技术:RabbitMQ

​​​​​​​更新订单状态

​​​​​​​Nuxt.js IP 启动

  "config": {"nuxt": {"host": "0.0.0.0","port": "3000"}},

​​​​​​​支付回调

​​​​​​​回调接口

步骤一:修改yml文件,添加notifyUrl配置

步骤二:修改配置文件

步骤三:修改工具类

步骤一:修改yml文件,添加notifyUrl配置

sc:pay:notifyUrl: http://40m459492i.wicp.vip/order-service/pay/callback

步骤二:修改配置文件

private String notifyUrl;           //回调路径

步骤三:修改工具类

package com.czxy.changgou4.utils;import com.czxy.changgou4.config.PayProperties;
import com.github.wxpay.sdk.WXPay;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;import java.util.HashMap;
import java.util.Map;/*** @author 桐叔* @email liangtong@itcast.cn*/
@Component
@EnableConfigurationProperties(PayProperties.class)
public class PayHelper {private WXPay wxPay;private PayProperties payProperties;@Beanpublic WXPay wxPay(PayProperties payProperties){if(wxPay == null){this.payProperties = payProperties;wxPay = new WXPay(payProperties);}return wxPay;}private static final Logger logger = LoggerFactory.getLogger(PayHelper.class);public PayHelper() {}public PayHelper(PayProperties payProperties) {wxPay = new WXPay(payProperties);}public String createPayUrl(Long sn) {String key = "pay.url." + sn;try {Map<String, String> data = new HashMap<>();// 商品描述data.put("body", "商城测试");// 订单号data.put("out_trade_no", sn.toString());//货币data.put("fee_type", "CNY");//金额,单位是分data.put("total_fee", "1");//调用微信支付的终端IP(商城的IP)data.put("spbill_create_ip", "127.0.0.1");//回调地址data.put("notify_url", this.payProperties.getNotifyUrl());// 交易类型为扫码支付data.put("trade_type", "NATIVE");//商品id,使用假数据data.put("product_id", "1234567");Map<String, String> result = this.wxPay.unifiedOrder(data);if ("SUCCESS".equals(result.get("return_code"))) {if("SUCCESS".equals(result.get("result_code"))){String url = result.get("code_url");return url;} else {logger.error("创建预交易订单失败,错误信息:{}", result.get("err_code_des"));return null;}} else {logger.error("创建预交易订单失败,错误信息:{}", result.get("return_msg"));return null;}} catch (Exception e) {logger.error("创建预交易订单异常", e);return null;}}/*** 查询订单状态* 交易状态参考:(trade_state)SUCCESS—支付成功REFUND—转入退款NOTPAY—未支付CLOSED—已关闭REVOKED—已撤销(付款码支付)USERPAYING--用户支付中(付款码支付)PAYERROR--支付失败(其他原因,如银行返回失败)* @param sn* @return*/public PayState queryOrder(Long sn) {Map<String, String> data = new HashMap<>();// 订单号data.put("out_trade_no", sn.toString());try {Map<String, String> result = this.wxPay.orderQuery(data);if("SUCCESS".equals(result.get("return_code"))){if("SUCCESS".equals(result.get("result_code"))) {String tradeState = result.get("trade_state");if ("SUCCESS".equals(tradeState)) {return PayState.SUCCESS;}if ("NOTPAY".equals(tradeState)) {return PayState.NOT_PAY;}if ("CLOSED".equals(tradeState)) {return PayState.CLOSED;}}}return PayState.PAY_ERROR;} catch (Exception e) {logger.error("查询订单状态异常", e);return PayState.PAY_ERROR;}}
}

​​​​​​​后端实现

  1. 步骤一:修改PayController,添加callback方法
  2. 步骤二:检查网关,放行callback方法
  3. 步骤三:修改花生壳,访问10010端口

https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_7&index=8

步骤一:修改PayController,添加callback方法

@PostMapping("/callback")
public void callback(HttpServletRequest request, HttpServletResponse response) throws IOException {try {//1 获得响应内容String xml = IOUtils.toString(request.getInputStream(), "UTF-8");System.out.println(xml);//解析Map<String, String> map = WXPayUtil.xmlToMap( xml );// 查询成功if("SUCCESS".equals(map.get( "result_code" )  )){// 获得订单号String sn = map.get("out_trade_no");//TODO  更新订单状态System.out.println(sn);//如果成功,给微信支付一个成功的响应response.setContentType("text/xml");String data = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";response.getWriter().write(data);}} catch (Exception e) {e.printStackTrace();response.setContentType("text/xml");String data = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA["+e.getMessage()+"]]></return_msg></xml>";response.getWriter().write(data);}
}

步骤二:检查网关,放行callback方法

步骤三:修改花生壳,访问10010端口

 

查看控制台结果

<xml><appid><![CDATA[wx8397f8696b538317]]></appid>
<bank_type><![CDATA[COMM_CREDIT]]></bank_type>
<cash_fee><![CDATA[1]]></cash_fee>
<fee_type><![CDATA[CNY]]></fee_type>
<is_subscribe><![CDATA[N]]></is_subscribe>
<mch_id><![CDATA[1473426802]]></mch_id>
<nonce_str><![CDATA[47e529ea929e4c9e847ee9699751a648]]></nonce_str>
<openid><![CDATA[oNpSGwZaaw_0uBEMwFpkwIwFsttw]]></openid>
<out_trade_no><![CDATA[1259484402174529500]]></out_trade_no>
<result_code><![CDATA[SUCCESS]]></result_code>
<return_code><![CDATA[SUCCESS]]></return_code>
<sign><![CDATA[2D4BC610795C1DC303B0B26092D6C6E3]]></sign>
<time_end><![CDATA[20200510220429]]></time_end>
<total_fee>1</total_fee>
<trade_type><![CDATA[NATIVE]]></trade_type>
<transaction_id><![CDATA[4200000568202005108477965385]]></transaction_id>
</xml>
1259484402174529500

​​​​​​​查看支付状态

​​​​​​​后端实现

  1. 步骤一:修改PayService,查询订单支付状态
  2. 步骤二:编写PayService实现类
  3. 步骤三:修改PayController

步骤一:修改PayService,查询订单支付状态

package com.czxy.changgou4.service;import com.czxy.changgou4.utils.PayState;
import com.czxy.changgou4.vo.PayRequest;/*** @author 桐叔* @email liangtong@itcast.cn*/
public interface PayService {/*** 查看支付状态* @param sn* @return*/public PayState query(Long sn);
}

步骤二:编写PayService实现类

@Override
public PayState query(Long sn) {//查询微信支付状态PayState payState = payHelper.queryOrder(sn);return payState;}

步骤三:修改PayController

@GetMapping("/{sn}")
public BaseResult query(@PathVariable("sn") Long sn){//查询PayState payState = payService.query(sn);//返回if(payState.getCode() == 1) {return BaseResult.ok(payState.getDesc());}return BaseResult.error(payState.getDesc());
}

​​​​​​​前端实现

如果订单已经支付,跳转到支付成功页面。

  1. 步骤一:修改api.js,查询订单支付状态
  2. 步骤二:修改flow3,“查询订单状态”绑定事件
  3. 步骤三:修改flow3,编写事件,如果是成功,调到到flow4
  4. 步骤四:编写flow4,与flow3基本内容一致,提示信息为“支付成功,货物即将送出!”

步骤一:修改api.js,查询订单支付状态

  findPayStatus : ( sn ) => {return axios.get("/order-service/pay/"+sn )}

步骤二:修改flow3,“查询订单状态”绑定事件

步骤三:修改flow3,编写事件,如果是成功,调到到flow4

  methods: {async findPayStatusFn() {let { data } = await this.$request.findPayStatus( this.sn );if( data.code == 20000) {location.href = 'flow4'} else {alert( data.message );}}},

步骤四:编写flow4,与flow3基本内容一致,提示信息为“支付成功,货物即将送出!”

<template><div><!-- 顶部导航 start --><div class="topnav"><div class="topnav_bd w990 bc"><div class="topnav_left"></div><div class="topnav_right fr"><ul><li>您好,欢迎来到畅购![<a href="login.html">登录</a>] [<a href="register.html">免费注册</a>] </li><li class="line">|</li><li>我的订单</li><li class="line">|</li><li>客户服务</li></ul></div></div></div><!-- 顶部导航 end --><div style="clear:both;"></div><!-- 页面头部 start --><div class="header w990 bc mt15"><div class="logo w990"><h2 class="fl"><a href="index.html"><img src="images/logo.png" alt="畅购商城"></a></h2><div class="flow fr flow3"><ul><li>1.我的购物车</li><li>2.填写核对订单信息</li><li class="cur">3.成功提交订单</li></ul></div></div></div><!-- 页面头部 end --><div style="clear:both;"></div><!-- 主体部分 start --><div class="success w990 bc mt15"><div class="success_hd"><h2>订单支付成功</h2></div><div class="success_bd"><p><span></span>支付成功,货物即将送出!</p></div></div><!-- 主体部分 end --><div style="clear:both;"></div><!-- 底部版权 start --><Footer></Footer><!-- 底部版权 end --></div>
</template><script>
import TopNav from '../components/TopNav'
import Footer from '../components/Footer'export default {head: {title: '首页',link: [{rel:'stylesheet',href: '/style/success.css'},],script: []},components: {TopNav,Footer,}}
</script><style></style>

​​​​​​​前置技术:RabbitMQ

​​​​​​​更新订单状态

步骤一:配置环境,

rabbitmq中添加order_pay队列

添加依赖

添加yml配置

步骤二:修改回调函数,将sn存放到rabbit中

步骤三:编写监听器(消费者),更新订单状态

步骤四:修改OrderService,完成修改功能

步骤五:修改OrderMapper,完成修改功能

步骤一:配置环境,

rabbitmq中添加order_pay队列,添加rabbit配置类

ackage com.czxy.changgou4.config;import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;/*** @author 桐叔* @email liangtong@itcast.cn*/
@Component
public class OrderPayQueue {private static final String ORDER_PAY_QUEUE = "order_pay";@Beanpublic Queue queue() {return new Queue(ORDER_PAY_QUEUE);}
}

添加依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

 ​​​​​​​

添加yml配置

spring:rabbitmq:host: 127.0.0.1username: guestpassword: guest

步骤二:修改回调函数,将sn存放到rabbit中

rabbitTemplate.convertAndSend("", "order_pay", sn); 

步骤三:编写监听器(消费者),更新订单状态

package com.czxy.changgou4.listener;import com.czxy.changgou4.service.OrderService;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;/*** @author 桐叔* @email liangtong@itcast.cn*/
@Component
@RabbitListener(queues = "order_pay")
public class OrderPayListener {@Autowiredprivate OrderService orderService;/*** 更新支付状态* @param message*/@RabbitHandlerpublic void updatePayStatus(String message){orderService.updatePayStatus( message , "1" );}
}

步骤四:修改OrderService,完成修改功能

package com.czxy.changgou4.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.czxy.changgou4.pojo.Order;
import com.czxy.changgou4.pojo.User;
import com.czxy.changgou4.vo.CartVo;
import com.czxy.changgou4.vo.OrderVo;import java.util.List;public interface OrderService extends IService<Order> {void updatePayStatus(String sn, String status);
}
package com.czxy.changgou4.service.impl;import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.czxy.changgou4.pojo.Order;
import com.czxy.changgou4.pojo.OrderGoods;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import javax.annotation.Resource;
import java.util.*;@Service
@Transactional
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {@Overridepublic void updatePayStatus(String sn, String status) {//更新状态baseMapper.updateStatus(sn,status);}
}

步骤五:修改OrderMapper,完成修改功能  

package com.czxy.changgou4.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.czxy.changgou4.pojo.Order;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;@Mapper
public interface OrderMapper extends BaseMapper<Order> {/*** 更加sn修改状态* @param sn* @param status*/@Update("UPDATE tb_order SET STATUS = #{status} WHERE sn = #{sn}")void updateStatus(@Param("sn") String sn, @Param("status") String status);
}

测试:在rabbitMQ web控制台,可以手动发布消息

http://www.lryc.cn/news/512032.html

相关文章:

  • 【Compose multiplatform教程18】多平台资源的设置和配置
  • MT6765核心板_MTK6765安卓核心板规格参数_联发科MTK模块开发
  • conda常用维护命令
  • Html——10 关键字和描述
  • Mysql(MGR)和ProxySQL搭建部署-Docker版本
  • QML学习(一) Qt Quick和QML介绍以及适用场景说明
  • 深入理解 PyTorch 的 view() 函数:以多头注意力机制(Multi-Head Attention)为例 (中英双语)
  • 使用PHP函数 “setcookie“ 设置cookie
  • redis优化
  • 数据分析的革命——解读云数据库 SelectDB 版的力量
  • Ngnix介绍、安装、实战及用法!!!
  • 算法基础一:冒泡排序
  • 云开发实战教程:手把手教你高效开发应用
  • Git基本操作快速入门(30min)
  • VS Code AI开发之Copilot配置和使用详解
  • QT中使用OpenGL function
  • STM32-笔记16-定时器中断点灯
  • Live555、FFmpeg、GStreamer介绍
  • oracle基础:理解 Oracle SQL 中的 WHERE 后的 (+) 用法
  • 【linux】进程间通信(IPC)——匿名管道,命名管道与System V内核方案的共享内存,以及消息队列和信号量的原理概述
  • 【深度学习】卷积网络代码实战ResNet
  • org.apache.zookeeper.server.quorum.QuorumPeerMain
  • oscp学习之路,Kioptix Level2靶场通关教程
  • SkyWalking java-agent 是如何工作的,自己实现一个监控sql执行耗时的agent
  • 每天40分玩转Django:Django表单集
  • 查看vue的所有版本号和已安装的版本
  • 钉钉h5微应用,鉴权提示dd.config错误说明,提示“jsapi ticket读取失败
  • 【openGauss】正则表达式次数符号“{}“在ORACLE和openGauss中的差异
  • 宏任务和微任务的区别
  • 数据库系统原理复习汇总