第三方支付(服务商模式)

  1. 必读 ,第三方服务商申请自己的服务号appid,并通过该服务号appid申请服务商mch_id,以此获得微信支付服务商能力。再通过服务商mch_id为所服务的特约商户申请创建微信支付sub_mch_id,创建好的sub_mch_id默认和服务商的mch_id建立父子授权关系。以此来使用微信支付提供的开放接口,对特约商户及用户提供服务。同时,微信支付为服务商模式下的每一条“mch_id-sub_mch_id父子授权关系”上,都开放了一些开发配置能力供服务商配置,包括不限于支付授权目录、推荐关注的appid、sub_appid等。拿小程序支付举例,服务商订单由哪个小程序调用js拉起支付,则需要在特约商户开发配置中将该小程序appid配置成sub_appid。每条父子关系上的sub_appid可以为多,用以满足不同的场景需求,但每笔交易只能使用1个;
  2. 注意,sub_appid使用说明:sub_appid可为公众号,APP或小程序的appid,服务商在服务商商户平台可手动为每个特约商户绑定与渠道商主体或特约商户主体一致的公众号,APP或小程序的appid;针对小程序,还支持绑定服务商主体的小程序appid。目前最多配置5个. 手工配置路径:”服务商商户平台-服务商功能-子商户管理-开发配置-特约商户APPID配置”

小结
1、问题:sub_appid与sub_mch_id不一致,
解决办法:在服务商功能对特约商户进行小程序授权sub_appid.
2、问题:微信公众号支付支付验证签名失败,
解决办法:在生成prepay_id的时候传入的APPID必须是小程序的。

小程序发起支付

 wx.request({
      url: 'wxUnifiedOrder',//后台请求获取支付请求参数
      method: 'POST',
      data: data,
      header: {
        'Accept': 'application/json'
      },
      success: function (obj) {
        wx.requestPayment({
          'timeStamp': ''+obj.data.obj.timeStamp,
          'nonceStr': obj.data.obj.nonceStr,
          'package': obj.data.obj.packageStr,
          'signType': obj.data.obj.signType,
          'paySign': obj.data.obj.paySign,
         'success': function (res) {
            console.info('success ' + JSON.stringify(res));
          },
          'fail': function (res) {
            console.info('fail ' + JSON.stringify(res));
          },
          'complete': function (res) {
            console.info('complete ' + JSON.stringify(res));
          }
        })
      }
    })

后台获取微信签名返回数据

		WxMerchant wxMerchant=wxMerchantMapper.getByEntId(entId);
		AbsWxPayConfig config = WXPayConfigImpl.getInstance();
		if(isMiniApp) {
			config = WXMiniPayConfigImpl.getInstance();
		}
		WXPay wxpay = new WXPay(config, false, config.getUseSandbox());

		logger.info("wx.body=" + ResourceUtil.getConfig("wx.body"));

		HashMap data = new HashMap();
		if (tradeMode==TradeMode.PLAT.value()) { 
			//平台模式
			data.put("sub_openid", openid);
			//商户为特约商户ID
			data.put("sub_mch_id", wxMerchant.getMerId());
		}else {
			//企业公众号模式
			WxOfficialAccount wxOfficialAccount = wxOfficialAccountMapper.getByEntId(entId);
			data.put("sub_appid", wxOfficialAccount.getAppid());
			data.put("sub_openid", openid);
			//普通商户ID
			data.put("mch_id", wxMerchant.getMerId());
		}

		data.put("body", ResourceUtil.getConfig("wx.body"));
		data.put("out_trade_no", payment.getPaymentNo());
		data.put("device_info", "");
		data.put("fee_type", "CNY");
		data.put("total_fee", amt.toString());
		data.put("spbill_create_ip", clientIP);
		data.put("notify_url", ResourceUtil.getConfig("wx.notify_url"));
		data.put("trade_type", "JSAPI");
		// data.put("openid", openid);
		

		Map r = wxpay.unifiedOrder(data);
		logger.info(r.toString());

		Map retMap = new HashMap();

		if (r.get("return_code").equals("FAIL")) {
			Payment p = new Payment();
			p.setPaymentId(payment.getPaymentId());
			p.setStatus(Status.FAIL.value());
			p.setRemark(r.get("return_msg"));
			paymentMapper.updateByPrimaryKeySelective(p);

			retMap.put("success", "false");
			retMap.put("msg", p.getRemark());
			return retMap;
		} else {
			if (r.get("result_code").equals("FAIL")) {
				Payment p = new Payment();
				p.setPaymentId(payment.getPaymentId());
				p.setStatus(Status.FAIL.value());
				p.setRemark(r.get("err_code") + r.get("err_code_des"));
				paymentMapper.updateByPrimaryKeySelective(p);

				retMap.put("success", "false");
				retMap.put("msg", p.getRemark());
				return retMap;
			} else {
				Payment p = new Payment();
				p.setPaymentId(payment.getPaymentId());
				p.setStatus(Status.RET.value());
				p.setRemark("prepay_id=" + r.get("prepay_id"));
				paymentMapper.updateByPrimaryKeySelective(p);

				// String timeStamp=String.valueOf(System.currentTimeMillis()/1000);
				Long timeStamp = System.currentTimeMillis() / 1000;
				String nonceStr = WXPayUtil.generateNonceStr();

				logger.info("appid=" + config.getAppID());
				logger.info("r.appid=" + r.get("appid"));

				retMap.put("success", "true");
				retMap.put("appId", "小程序appId");
				retMap.put("timeStamp", String.valueOf(timeStamp));
				retMap.put("nonceStr", nonceStr);
				retMap.put("package", "prepay_id=" + r.get("prepay_id"));
				retMap.put("signType", config.getSignTypeStr());
			
				//生成prepay_id的时候传入的APPID是小程序自身的APPID,不然会报出“支付验证签名错误”
				Map retData = new HashMap();
				retData.put("appId", "这里传入小程序APPID");
				retData.put("timeStamp", retMap.get("timeStamp"));
				retData.put("nonceStr", retMap.get("nonceStr"));
				retData.put("package", retMap.get("package"));
				retData.put("signType", retMap.get("signType"));
				logger.info(retData.toString());
				String paySign = WXPayUtil.generateSignature(retData, config.getKey(), SignType.HMACSHA256);
				retMap.put("paySign", paySign);
				return retMap;

			}
		}

你可能感兴趣的:(小程序,第三方支付,特约商户)