目录
[Nuxt.js IP 启动](#Nuxt.js IP 启动)
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; //回调路径
步骤三:修改工具类

java
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 [email protected]
*/
@Component
@EnableConfigurationProperties(PayProperties.class)
public class PayHelper {
private WXPay wxPay;
private PayProperties payProperties;
@Bean
public 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;
}
}
}
后端实现
- 步骤一:修改PayController,添加callback方法
- 步骤二:检查网关,放行callback方法
- 步骤三:修改花生壳,访问10010端口

java
https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_7&index=8
步骤一:修改PayController,添加callback方法
java
@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端口

查看控制台结果
java
<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
查看支付状态
后端实现
- 步骤一:修改PayService,查询订单支付状态
- 步骤二:编写PayService实现类
- 步骤三:修改PayController

步骤一:修改PayService,查询订单支付状态
java
package com.czxy.changgou4.service;
import com.czxy.changgou4.utils.PayState;
import com.czxy.changgou4.vo.PayRequest;
/**
* @author 桐叔
* @email [email protected]
*/
public interface PayService {
/**
* 查看支付状态
* @param sn
* @return
*/
public PayState query(Long sn);
}
步骤二:编写PayService实现类
java
@Override
public PayState query(Long sn) {
//查询微信支付状态
PayState payState = payHelper.queryOrder(sn);
return payState;
}
步骤三:修改PayController
java
@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());
}
前端实现
如果订单已经支付,跳转到支付成功页面。

- 步骤一:修改api.js,查询订单支付状态
- 步骤二:修改flow3,"查询订单状态"绑定事件
- 步骤三:修改flow3,编写事件,如果是成功,调到到flow4
- 步骤四:编写flow4,与flow3基本内容一致,提示信息为"支付成功,货物即将送出!"
步骤一:修改api.js,查询订单支付状态
java
findPayStatus : ( sn ) => {
return axios.get("/order-service/pay/"+sn )
}
步骤二:修改flow3,"查询订单状态"绑定事件

步骤三:修改flow3,编写事件,如果是成功,调到到flow4
java
methods: {
async findPayStatusFn() {
let { data } = await this.$request.findPayStatus( this.sn );
if( data.code == 20000) {
location.href = 'flow4'
} else {
alert( data.message );
}
}
},
步骤四:编写flow4,与flow3基本内容一致,提示信息为"支付成功,货物即将送出!"
java
<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配置类
java
ackage com.czxy.changgou4.config;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
/**
* @author 桐叔
* @email [email protected]
*/
@Component
public class OrderPayQueue {
private static final String ORDER_PAY_QUEUE = "order_pay";
@Bean
public Queue queue() {
return new Queue(ORDER_PAY_QUEUE);
}
}

添加依赖
java
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
添加yml配置
java
spring:
rabbitmq:
host: 127.0.0.1
username: guest
password: guest
步骤二:修改回调函数,将sn存放到rabbit中

rabbitTemplate.convertAndSend("", "order_pay", sn);
步骤三:编写监听器(消费者),更新订单状态
java
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 [email protected]
*/
@Component
@RabbitListener(queues = "order_pay")
public class OrderPayListener {
@Autowired
private OrderService orderService;
/**
* 更新支付状态
* @param message
*/
@RabbitHandler
public void updatePayStatus(String message){
orderService.updatePayStatus( message , "1" );
}
}
步骤四:修改OrderService,完成修改功能
java
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);
}
java
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 {
@Override
public void updatePayStatus(String sn, String status) {
//更新状态
baseMapper.updateStatus(sn,status);
}
}
步骤五:修改OrderMapper,完成修改功能
java
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控制台,可以手动发布消息
