微信回调 java_详解APP微信支付(java后台_统一下单和回调)

本文详细介绍了如何在Java后台实现APP微信支付的统一下单和回调处理。首先,讲解了配置微信支付所需信息,接着展示了生成预支付订单信息的方法`wxpay`,包括生成随机字符串、设置回调地址等。然后,重点讨论了支付成功的回调函数`notifyWeiXinPay`,强调了回调函数在公网环境的重要性以及如何处理重复回调。最后,提到了一些关键工具类和方法,如`ConfigManager`用于读取配置文件,以及`PayCommonUtil`工具类中的签名验证和HTTP请求处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.微信配置信息 global.properties

73de20fff4a9f70c1925acf10d63764f.png

2.方法wxpay用于生成预支付订单信息

方法notifyWeiXinPay用于微信支付成功后的回调, 注意: 在手机端使用微信支付成功后,微信服务器会根据提供的回调地址进行回调, parameterMap.put("notify_url", wxnotify); (见下面代码)

在局域网是无法进行回调的,必须将你的服务端放在公网上进行测试, 回调函数会被多次调用,如果第一次成功后,你可以将业务数据状态标志为已处理, 对于相同订单的其它回调就不需要再次处理了;

package com.main.controller;

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.UnsupportedEncodingException;

import java.math.BigDecimal;

import java.util.Date;

import java.util.HashMap;

import java.util.Map;

import java.util.SortedMap;

import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.jdom.JDOMException;

import org.springframework.http.MediaType;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.bind.annotation.ResponseBody;

import com.main.model.WeiXinPrePay;

import com.main.util.ConfigManager;

import com.main.util.DateUtil;

import com.main.util.GeneralConstant;

import com.main.util.PayCommonUtil;

import com.main.util.Result;

import com.main.util.StringUtil;

@Controller

@RequestMapping("/pay")

public class PayController {

String randomString = PayCommonUtil.getRandomString(32);

//支付成功后的回调函数

public static String wxnotify = "http://com.zhuohuicalss/pay/notifyWeiXinPay";

public PayController() {

System.out.println("MainController构造函数");

}

/**

* @param totalAmount 支付金额

* @param description 描述

* @param request

* @return

*/

@RequestMapping(value = "/wxpay", produces = MediaType.APPLICATION_JSON_VALUE)

@ResponseBody

public Result wxpay(HttpServletRequest request) {

Result result = new Result();

Long userId = new Long(1);//baseController.getUserId();

BigDecimal totalAmount = new BigDecimal(request.getParameter("totalPrice"));

String trade_no = "";

String description="";

try {

trade_no = new String(request.getParameter("orderNum").getBytes("ISO-8859-1"),"UTF-8");

description = request.getParameter("description");

} catch (UnsupportedEncodingException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

String openId = "";

Map map = weixinPrePay(trade_no,totalAmount,description,openId,request);

SortedMap finalpackage = new TreeMap();

//应用ID

finalpackage.put("appid", ConfigManager.getInstance().getConfigItem("WXAppID")/*PayCommonUtil.APPID*/);

//商户号

finalpackage.put("partnerid", ConfigManager.getInstance().getConfigItem("MCH_ID"));

Long time = (System.currentTimeMillis() / 1000);

//时间戳

finalpackage.put("timestamp", time.toString());

//随机字符串

finalpackage.put("noncestr", map.get("nonce_str"));

//预支付交易会话ID

finalpackage.put("prepayid", map.get("prepay_id"));

//扩展字段

finalpackage.put("package", "Sign=WXPay");

WeiXinPrePay prePay = new WeiXinPrePay();

prePay.setAppId(ConfigManager.getInstance().getConfigItem("WXAppID"));

prePay.setMchId(ConfigManager.getInstance().getConfigItem("MCH_ID"));

prePay.setTimeStamp(time.toString());

prePay.setNonceStr(map.get("nonce_str"));

prePay.setPrepayId(map.get("prepay_id"));

prePay.setSignType("MD5");

prePay.setPaySign(sign);

result.setData(prePay);

result.setStateCode(GeneralConstant.SUCCESS);

result.setDesc("微信支付加载成功");

return result;

}

/**

* 统一下单

* 应用场景:商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易回话标识后再在APP里面调起支付。

* @param trade_no

* @param totalAmount

* @param description

* @param openid

* @param sym

* @param request

* @return

*/

@SuppressWarnings("unchecked")

public Map weixinPrePay(String trade_no,BigDecimal totalAmount,

String description, String openid, HttpServletRequest request) {

SortedMap parameterMap = new TreeMap();

parameterMap.put("appid", ConfigManager.getInstance().getConfigItem("WXAppID")); //应用appid

parameterMap.put("mch_id", ConfigManager.getInstance().getConfigItem("MCH_ID")/*PayCommonUtil.MCH_ID*/); //商户号

//parameterMap.put("device_info", "WEB");

parameterMap.put("nonce_str", randomString);

parameterMap.put("body", description);

parameterMap.put("out_trade_no", trade_no);

parameterMap.put("fee_type", "CNY");

System.out.println("jiner");

BigDecimal total = totalAmount.multiply(new BigDecimal(100)); //接口中参数支付金额单位为【分】,参数值不能带小数,所以乘以100

java.text.DecimalFormat df=new java.text.DecimalFormat("0");

parameterMap.put("total_fee", df.format(total));

System.out.println("jiner2");

parameterMap.put("spbill_create_ip", PayCommonUtil.getRemoteHost(request));

parameterMap.put("notify_url", wxnotify);

parameterMap.put("trade_type", "APP");//"JSAPI"

//trade_type为JSAPI是 openid为必填项

//parameterMap.put("openid", openid);

System.out.println("");

String sign = PayCommonUtil.createSign("UTF-8", parameterMap);

System.out.println("jiner2");

parameterMap.put("sign", sign);

String requestXML = PayCommonUtil.getRequestXml(parameterMap);

System.out.println(requestXML);

String result = PayCommonUtil.httpsRequest(

"https://api.mch.weixin.qq.com/pay/unifiedorder", "POST",

requestXML);

System.out.println(result);

Map map = null;

try {

map = PayCommonUtil.doXMLParse(result);

} catch (JDOMException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return map;

}

/**

* 此函数会被执行多次,如果支付状态已经修改为已支付,则下次再调的时候判断是否已经支付,如果已经支付了,则什么也执行

* @param request

* @param response

* @return

* @throws IOException

* @throws JDOMException

*/

@RequestMapping(value = "notifyWeiXinPay", produces = MediaType.APPLICATION_JSON_VALUE)

// @RequestDescription("支付回调地址")

@ResponseBody

public String notifyWeiXinPay(HttpServletRequest request, HttpServletResponse response) throws IOException, JDOMException {

System.out.println("微信支付回调");

InputStream inStream = request.getInputStream();

ByteArrayOutputStream outSteam = new ByteArrayOutputStream();

byte[] buffer = new byte[1024];

int len = 0;

while ((len = inStream.read(buffer)) != -1) {

outSteam.write(buffer, 0, len);

}

String resultxml = new String(outSteam.toByteArray(), "utf-8");

Map params = PayCommonUtil.doXMLParse(resultxml);

outSteam.close();

inStream.close();

Map return_data = new HashMap();

if (!PayCommonUtil.isTenpaySign(params)) {

// 支付失败

return_data.put("return_code", "FAIL");

return_data.put("return_msg", "return_code不正确");

return StringUtil.GetMapToXML(return_data);

} else {

System.out.println("===============付款成功==============");

// ------------------------------

// 处理业务开始

// ------------------------------

// 此处处理订单状态,结合自己的订单数据完成订单状态的更新

// ------------------------------

String total_fee = params.get("to

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值