springboot集成微信app支付

一、准备工作(以下信息需要自行开通和申请):

    public static final String APP_ID = "";//app的id 需要app应用
    public static final String KEY = "";//api密钥 商户账户信息里面去获取
    public static final String MCH_ID = "";//商户的id,需要开通商户

maven项目添加依赖:

        <!-- 微信支付 -->
        <dependency>
            <groupId>com.github.wxpay</groupId>
            <artifactId>wxpay-sdk</artifactId>
            <version>0.0.3</version>
        </dependency>

 二、开发流程:

整个流程我们只需要两个接口即可:

1.微信支付的统一下单接口(本地项目请求微信):

URL地址:https://api.mch.weixin.qq.com/pay/unifiedorder

2.微信支付后的通知接口,是我们向外提供的(微信请求本地项目):接口地址自行定义

三、代码:我使用的springboot restful接口方式,详解请看注释

service层:

 
import java.util.Map;
 
public interface WeixinService {
    /**
     * 
     * @方法名称 payBack
     * @功能描述 <pre>回调接口</pre>
     * @创建时间 2020年5月22日 下午12:50:15
     * @param resXml
     * @return
     */
    String payBack(String resXml);
    /**
     * 
     * @param order 
     * @方法名称 doUnifiedOrder
     * @功能描述 <pre>统一下单</pre>
     * @创建时间 2020年5月22日 下午12:50:26
     * @return
     * @throws Exception
     */
    Map<String, String> doUnifiedOrder(Order order) throws Exception;
    
}

service层实现(以下代码已删除了业务处理部分,需要自己添加自己项目的业务处理):

 
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
 
import lombok.extern.slf4j.Slf4j;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import java.util.HashMap;
import java.util.Map;
 
/**
 * 
 * @类名称 WeixinServiceImpl.java
 * @类描述 <pre>微信 支付</pre>
 * @创建时间 2020年5月22日 下午12:51:13
 * @版本 5.0.0
 * @修改记录
 * <pre>
 *     版本                       修改人         修改日期          修改内容描述
 *     ----------------------------------------------
 *     5.0.0     yw     2020年5月22日             
 *     ----------------------------------------------
 * </pre>
 */
@Service
@Slf4j
public class WeixinServiceImpl implements WeixinService {
    
    public static final String HOST_IP = "";//回调的服务器ip
    public static final String NOTIFY_URL = "";//回调的地址,注意:外网可以访问
    public static final String TRADE_TYPE_APP = "APP";
 
    @Autowired
    OrderService orderService;//自己业务的处理服务
   
    @Override
    public String payBack(String resXml) {
        WXConfigUtil config = null;
        try {
            config = new WXConfigUtil();
        } catch (Exception e) {
            e.printStackTrace();
        }
        WXPay wxpay = new WXPay(config);
        String xmlBack = "";
        Map<String, String> notifyMap = null;
        try {
            notifyMap = WXPayUtil.xmlToMap(resXml);         // 调用官方SDK转换成map类型数据
            if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {//验证签名是否有效,有效则进一步处理
 
                String return_code = notifyMap.get("return_code");//状态
                String out_trade_no = notifyMap.get("out_trade_no");//商户订单号
                if (return_code.equals("SUCCESS")) {
                    if (out_trade_no != null) {
                        // 注意特殊情况:订单已经退款,但收到了支付结果成功的通知,不应把商户的订单状态从退款改成支付成功
                        // 注意特殊情况:微信服务端同样的通知可能会多次发送给商户系统,所以数据持久化之前需要检查是否已经处理过了,处理了直接返回成功标志
                        //业务处理 以下进行业务处理(比如修改订单状态信息等)
                        log.info("微信手机支付回调成功订单号:{}", out_trade_no);
                        xmlBack = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                    } else {
                        log.info("微信手机支付回调失败订单号:{}", out_trade_no);
                        xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
                    }
                }
                return xmlBack;
            } else {
                // 签名错误,如果数据里没有sign字段,也认为是签名错误
                //失败的数据要不要存储?
                log.error("手机支付回调通知签名错误");
                xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
                return xmlBack;
            }
        } catch (Exception e) {
            log.error("手机支付回调通知失败", e);
            xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
        return xmlBack;
    }
 
    /**
     * 
     * @方法名称 doUnifiedOrder
     * @功能描述 <pre>统一下单接口具体实现</pre>
     * @创建时间 2020年5月22日 下午4:30:44
     * @param order 参数可以根据自己定义
     * @return
     * @throws Exception
     */
    @Override
    public Map<String, String> doUnifiedOrder(Order order) throws Exception {
        try {
            WXConfigUtil config = new WXConfigUtil();
            WXPay wxpay = new WXPay(config);
            Map<String, String> data = new HashMap<>();
            //生成商户订单号,不可重复
            data.put("appid", WXConfigUtil.APP_ID);
            data.put("mch_id", WXConfigUtil.MCH_ID);
            data.put("nonce_str", WXPayUtil.generateNonceStr());
            String body = "手机支付";
            data.put("body", body);
            data.put("out_trade_no", order.getOrderNo());//订单号
            data.put("total_fee", "1");//设置金额1分
            //自己的服务器IP地址
            data.put("spbill_create_ip", HOST_IP);
            //异步通知地址(请注意必须是外网)
            data.put("notify_url", NOTIFY_URL);
            //交易类型
            data.put("trade_type", TRADE_TYPE_APP);
            //附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据
            data.put("attach", "");
            data.put("sign", WXPayUtil.generateSignature(data, WXConfigUtil.KEY,
                    WXPayConstants.SignType.MD5));
            //使用官方API请求预付订单
            Map<String, String> response = wxpay.unifiedOrder(data);
            if ("SUCCESS".equals(response.get("return_code"))) {//主要返回以下5个参数
                Map<String, String> param = new HashMap<>();
                param.put("appid", WXConfigUtil.APP_ID);
                param.put("partnerid",response.get("mch_id"));
                param.put("prepayid",response.get("prepay_id"));
                param.put("package","Sign=WXPay");
                param.put("noncestr",WXPayUtil.generateNonceStr());
                param.put("timestamp",System.currentTimeMillis()/1000+"");
                param.put("sign",WXPayUtil.generateSignature(param, WXConfigUtil.KEY,
                        WXPayConstants.SignType.MD5));
                return param;
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("下单失败");
        }
        throw new Exception("下单失败");
    }
}

controller层:

 
 
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
 
 
 
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
 
/**
 * 
 * @类名称 WeixinRestController.java
 * @类描述 <pre>微信app支付</pre>
 * @作者  yw  xingsfdz@163.com
 * @创建时间 2020年5月22日 下午4:04:19
 * @版本 5.0.0
 *
 * @修改记录
 * <pre>
 *     版本                       修改人         修改日期          修改内容描述
 *     ----------------------------------------------
 *     5.0.0     yw     2020年5月22日             
 *     ----------------------------------------------
 * </pre>
 */
@Slf4j
@Api(value="微信",tags={"微信"})
@RequestMapping("/weixin/")
@RestController
public class WeixinRestController{
    
    @Autowired
    WeixinService weixinService;
    
    /**
     * 
     * @方法名称 wxAdd
     * @功能描述 <pre>微信统一下单- 前端发起下单 比如web ios android</pre>
     * @作者    yw
     * @创建时间 2020年5月22日 下午12:56:59
     * @return
     * @throws Exception
     */
    @RequestMapping(value={"app/wxpay"}, method={RequestMethod.POST})
    public ResponseMsg wxpay(HttpServletRequest request, Order order) throws Exception {
        return new ResponseMsg(weixinService.doUnifiedOrder(order));
    }
    
    /**
     * 
     * @方法名称 wxPayNotify
     * @功能描述 <pre>给微信回调的接口</pre>
     * @作者    yw
     * @创建时间 2020年5月22日 下午4:04:55
     * @param request
     * @return
     */
    @PostMapping("order/wxnotify")
    @ApiOperation("微信回调")
    public String wxPayNotify(HttpServletRequest request) {
        String resXml = "";
        try {
            InputStream inputStream = request.getInputStream();
            //将InputStream转换成xmlString
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            StringBuilder sb = new StringBuilder();
            String line = null;
            try {
                while ((line = reader.readLine()) != null) {
                    sb.append(line + "\n");
                }
            } catch (IOException e) {
                log.info(e.getMessage());
            } finally {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            resXml = sb.toString();
            String result = weixinService.payBack(resXml);
            return result;
        } catch (Exception e) {
            log.info("微信手机支付失败:" + e.getMessage());
            String result = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
            return result;
        }
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
虽然我是AI语言模型,但我仍然尽力为您提供一个springboot集成微信支付功能代码的参考。这里是一个简单的示例: ``` // 微信支付配置信息 @Configuration public class WeChatPayConfig { @Value("${wechat.pay.appid}") private String appId; @Value("${wechat.pay.mchid}") private String mchId; @Value("${wechat.pay.key}") private String key; @Value("${wechat.pay.cert}") private String certPath; @Bean public WxPayConfig wxPayConfig() throws Exception { WxPayConfig payConfig = new WxPayConfig(); payConfig.setAppId(appId); payConfig.setMchId(mchId); payConfig.setMchKey(key); payConfig.setCertPath(certPath); return payConfig; } @Bean public WxPayService wxPayService() throws Exception { WxPayService payService = new WxPayServiceImpl(); payService.setConfig(wxPayConfig()); return payService; } } // 微信支付控制器 @RestController @RequestMapping("/wechat/pay") public class WeChatPayController { @Autowired private WxPayService wxPayService; @PostMapping("/unifiedOrder") public Map<String, String> unifiedOrder(@RequestBody Map<String, String> requestMap) throws Exception { WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest(); orderRequest.setOutTradeNo(requestMap.get("outTradeNo")); // 商户订单号 orderRequest.setTotalFee(Integer.valueOf(requestMap.get("totalFee"))); // 总金额 orderRequest.setBody(requestMap.get("body")); // 商品描述 orderRequest.setSpbillCreateIp(requestMap.get("spbillCreateIp")); // 终端IP orderRequest.setNotifyUrl(requestMap.get("notifyUrl")); // 回调地址 orderRequest.setTradeType(WxPayTradeType.APP); // 交易类型 return wxPayService.unifiedOrder(orderRequest); } @PostMapping("/notify") public String notify(@RequestBody String xmlData) throws Exception { WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData); // 处理回调信息 return WxPayNotifyResponse.success("处理成功"); } } ``` 在这个示例中,我们使用`WxPayConfig`和`WxPayService`来配置和调用微信支付功能。在`WeChatPayController`中,我们定义了两个方法:`unifiedOrder`和`notify`,分别用于发起微信支付订单和处理微信支付回调通知。 请注意,这里的代码只是一个基本的示例,您需要根据自己的实际需求进行修改和定制。同时,您还需要自行处理微信支付回调信息,包括验签、更新订单状态等操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值