APP支付宝提现和微信提现之服务端接入

支付宝充值弄完了之后,接下来就讲一下支付宝的提现和微信提现的服务端集成的大概逻辑。

一:支付宝提现

首先申请appid,生成应用公私钥并上传支付宝后台就不说了,然后写一个配置信息类将appid,privateKey和alipay_publicKey封装进去,集成SDK等有不清楚的可以看我的:APP接入支付宝支付之服务端实现 这篇文章。

国际惯例先附上官方API文档https://docs.open.alipay.com/api_28/alipay.fund.trans.toaccount.transfer,这里说明已经很详细了接下来就是调用代码了

AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.ALIPAY_URL, AlipayConfig.APP_ID,
				AlipayConfig.PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY,
				AlipayConfig.SIGN_TYPE);
		AlipayFundTransToaccountTransferRequest request = new AlipayFundTransToaccountTransferRequest();
		Map<String, String> map = new LinkedHashMap<String, String>();
		map.put("out_biz_no", "本地订单编号");
		map.put("payee_type", "ALIPAY_LOGONID");
		map.put("payee_account","收款支付宝账户");
		map.put("amount", "金额");
		map.put("payer_show_name", "XX平台用户提现");
		map.put("payee_real_name","收款人真实姓名");
		map.put("remark", "您的提现已转出请查收。");
		request.setBizContent(map.toString());
		AlipayFundTransToaccountTransferResponse response = alipayClient.execute(request);
        if ("10000".equals(response.getCode())) { //提现成功,本地业务逻辑略
					
					} else { // 支付宝提现失败,本地业务逻辑略
						logger.info("调用支付宝提现接口成功,但提现失败");
					}

这个不像APP支付那样需要异步回调的URL而是直接响应,然后可以根据响应码判断商户是否将资金转出到用户所对应的支付宝账户里并执行业务逻辑了。

二:微信提现

一开始老板说要做APP的微信提现功能的时候其实我是有点懵的,因为自己生活中用了那么多APP还从来没有见过app可以直接提现到用户的微信零钱里面的。然后老板很自信的说有的,发了一个微信企业付款的链接给我,如下https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_1但是这个功能需要商户入驻90天才能开通这个功能。

接下来先封装一个微信配置信息类

package link.nuggets.utils;

public class WeChatConfig {
	 /**
     * 商户id
     */
    public static String MCH_ID = "11111"; // 商户号 
    /**
     * 应用id,appId
     */
    public static String APP_ID = "11111"; // 微信开发平台应用id
    /**
     * APP_SECRET
     */
    public static String APP_SECRET = "111111"; // 应用对应的凭证
    /**
     * 秘钥
     */
    public static String APP_KEY = "111111"; // 商户号对应的密钥
    /**
     * 扩展字段
     */
    public static String PACKAGE = "Sign=WXPay"; // 扩展字段 暂填写固定值Sign=WXPay
    /**
     * 设备号
     */
    public static String DEVICE_INFO = "WEB";// 设备号 终端设备号(门店号或收银设备ID),默认请传"WEB"
    /**
     * 通知回调接口路径
     */
    public static String NOTIFY_URL = "https://WeChatPlaceOrder";
    /**
     * 钞票类型 人民币
     */
    public static String FEE_TYPE = "CNY";
    /**
     * 交易类型
     */
    public static String TRADE_TYPE = "APP";//交易类型
    /**
     * 固定的,统一下单后调用的生成预付单接口
     */
    public static String PAY_ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    /**
     * 企业付款接口
     */
    public static String TRANSFERS_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
}

然后很蛋疼的就是调用微信的接口都是传XML格式的数据的,而且调用微信接口的时候金额的默认单位是分,比如你传100到微信那边其实就是1元。微信返回给你的金额数字100其实相当于100分也就是1元。

接下来要写一个Map和Xml之间相互转换的工具类

public class XmlUtils {

	/**
	 * <P>
	 * map集合转化成xml字符串
	 * </P>
	 * 
	 * @param map
	 * @param rootName
	 * @return
	 */
	public static String mapToXml(Map<String, String> map, String rootName) {
		Element root = new Element(rootName);
		if (map == null)
			return xmlToString(root);
		for (String str : map.keySet())
			root.addContent(new Element(str).setText((map.get(str) == null ? "" : map.get(str) + "")));
		return xmlToString(root);
	}

	/**
	 * <P>
	 * xml字符串转化成map集合
	 * </P>
	 * 
	 * @param xmlStr字符串
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, String> xmlToMap(String xmlStr) {

		SAXBuilder builder = new SAXBuilder();
		Map<String, String> map = new HashMap<String, String>();
		try {
			xmlStr = URLDecoder.decode(xmlStr, "UTF-8");
			Reader in = new StringReader(xmlStr);
			Document doc = builder.build(in);
			Element root = doc.getRootElement();
			List<Element> list = root.getChildren();
			for (Element e : list)
				map.put(e.getName(), e.getText());
			return map;
		} catch (JDOMException e) {
		} catch (UnsupportedEncodingException e) {
		} catch (IOException e) {
		} catch (Exception e) {
		}
		return map;

	}

	
}

然后就是封装参数调用微信企业付款接口了,其中需要传入用户的openid,这个可以在用户调用微信付款接口的时候有个异步回调通知,会返回用户的openid,另外也可以申请个公众号,然后关注的微信用户也会有一个openid。

SortedMap<String, String> map = new TreeMap<String, String>();
		map.put("mch_appid",WeChatConfig.APP_ID);
		map.put("mchid",WeChatConfig.MCH_ID);
		map.put("nonce_str",OrderReqDataUtil.getNonceStr());//随机字符串
		map.put("partner_trade_no",orderNumber);//本地订单编号
		map.put("openid",openid);//openid
		
		map.put("check_name","FORCE_CHECK");
		map.put("re_user_name",realName);//收款人真实姓名
		map.put("amount",amount+"");//金额
		map.put("desc","XX平台提现!");
		map.put("spbill_create_ip",ipAddress);//IP
		map.put("sign",TenpayUtil.genServerSign(map));
		String orderInfo = XmlUtils.mapToXml(map,"xml");
		//生成交易记录,这一步才调用微信提现接口,上面的是封装参数
		String returnXml = restTemplate.postForEntity(WeChatConfig.TRANSFERS_URL, orderInfo,String.class).getBody();
		Map<String, String> returnInfo=new HashMap<String, String>();
		returnInfo= XmlUtils.xmlToMap(returnXml);
if ("SUCCESS".equals(returnInfo.get("return_code"))
			&& "SUCCESS".equals(returnInfo.get("result_code"))) {
		// 提现成功,修改记录
					
		} else {
		// 提现失败,更新记录
						
		logger.info("微信提现过程出错,userId:" + userId + ",错误代码:" + returnInfo.get("err_code") + ",错误信息:"
				+ returnInfo.get("err_code_des"));
			
					}

自此,支付宝和微信的提现就写完了,第一次接肯定有很多不足,希望各位大佬们能指点指点一起进步。

猜你喜欢

转载自blog.csdn.net/King__Jack/article/details/83038196