微信公众号支付——预支付订单

  1.需要一个可以登陆微信商户平台的账号,此账号是服务号并开通了微信支付,商户在申请开通时,客服会发送邮件到你的邮箱,

上图中有几个重要信息:商户号和appid,务必记住商户号和appid。其中登陆账号和密码用于登陆微信支付首页点击打开链接

2.点击上图中的下载api证书,设置api密码。这个证书主要在微信支付api中需要证书的地方使用中的退款等功能提示需要证书。


:什么时候加载使用该证书?当要实现微信退款时,发起退款请求前,需要先加载安全证书

package com.jy.common.pay.weixinpay;

import java.io.File;
import java.io.FileInputStream;
import java.net.URL;
import java.security.KeyStore;

import javax.net.ssl.SSLContext;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

/*
 * 加载安全证书、退款等需要证书的请求使用此类中的方法
 * */
public class ClientCustomSSL {
	public static String doRefund(String url, String data) throws Exception {
		KeyStore keyStore = KeyStore.getInstance("PKCS12");
		URL luj = Thread.currentThread().getContextClassLoader().getResource("apiclient_cert.p12");//src目录下的证书文件
		FileInputStream is = new FileInputStream(new File(luj.toURI()));
		try {
		keyStore.load(is, "这个是你设置的安全证书的密码".toCharArray());// 这里写密码..默认是你的mchid,也就是前面发送给你的
				邮件中的商户号
		} finally {
		is.close();
		}

		// Trust own CA and all self-signed certs
		SSLContext sslcontext = SSLContexts.custom()
		.loadKeyMaterial(keyStore, "商户号".toCharArray())// 这里也是写密码的
		.build();
		// Allow TLSv1 protocol only
		SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null,
		SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
		CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
		try {
		HttpPost httpost = new HttpPost(url); // 设置响应头信息
		httpost.addHeader("Connection", "keep-alive");
		httpost.addHeader("Accept", "*/*");
		httpost.addHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
		httpost.addHeader("Host", "api.mch.weixin.qq.com");
		httpost.addHeader("X-Requested-With", "XMLHttpRequest");
		httpost.addHeader("Cache-Control", "max-age=0");
		httpost.addHeader("User-Agent","Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
		httpost.setEntity(new StringEntity(data, "UTF-8"));
		CloseableHttpResponse response = httpclient.execute(httpost);
		try {
		HttpEntity entity = response.getEntity();

		String jsonStr = EntityUtils.toString(response.getEntity(),
		"UTF-8");
		EntityUtils.consume(entity);
		return jsonStr;
		} finally {
		response.close();
		}
		} finally {
		httpclient.close();
		}
	}
}
上面返回的jsonStr则是:你发起退款时返回的一些json信息,这里一般将其转为map方便使用。

其中上面调用的方法需要2个参数:url,data

url:微信支付提供的退款接口https://api.mch.weixin.qq.com/secapi/pay/refund

data:这个参数微信支付官方推荐使用xml格式,所以一般都是用String字符串构造一个xml,这个xml和官方文档一样

<xml>
<appid>wx2421b1c4370ec43b</appid>
<mch_id>10000100</mch_id>
<nonce_str>6cefdb308e1e2e8aabd48cf79e546a02</nonce_str>
<out_refund_no>1415701182</out_refund_no>
<out_trade_no>1415757673</out_trade_no>
<refund_fee>1</refund_fee>
<total_fee>1</total_fee>
<transaction_id></transaction_id>
<sign>FE56DD4AA85C0EECA82C35595A69E153</sign>
</xml> 

data就是上面这个xml的字符串,一般先将退款接口需要的参数放入到map中,在将map转为xml字符串。


3.在实现预支付订单前应先获取到开发需要的一些参数:如openid、随机字符串、签名、

1.openid获取:

String url="https://api.weixin.qq.com/sns/oauth2/access_token?"
        + "appid="
+你的appid

+ "&secret="+你的secret
        + "&code="+code
        + "&grant_type=authorization_code";
JSONObject jsonObject=HttpGet.getRes(url);
String usersWeixinId=jsonObject.getString("openid");

      secret是公众号的appsecret,这个在微信支付平台中的开发者中心可以找到

code是应用授权作用域,官方提供两个,任选一个:snsapi_base(不弹出授权窗口,只获取openid),snsapi_userinfo(弹出授权窗口.....)

2.随机字符串获取:这个参数一般是32位以内的大写字母和0-9数字的随机组合,不能超出32位

3.签名获取:签名详细算法地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3

获取签名步骤:

根据上图中的参数生成字符串

stringA="appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&nonce_str=ibuaiVcKdpRxkhJA";

再接着串联:

stringSignTemp=stringA+"&key=192006250b4c09247ec02edce69f6a2d" //注:key为商户平台设置的密钥key

sign=MD5(stringSignTemp).toUpperCase()="9A0A8659F005D6984697E2CA0A9CF3B7" //注:MD5签名方式

sign=hash_hmac("sha256",stringSignTemp,key) //注:HMAC-SHA256签名方式

两种签名方式任选,sign这就是我们需要的签名

4.简单地说:实现微信支付中的各种功能只需要3个大步骤:1.微信公众号支付的各个接口。2.生成发起订单等功能的XML字符串。3.发送http请求,输出返回的结果

1.预支付订单接口:https://api.mch.weixin.qq.com/pay/unifiedorder

预支付订单的通知地址:http://www.weixin.qq.com/wxpay/pay.php(即发起订单后的回调接口),此接口不能携带参数

2.查询预支付订单的接口:https://api.mch.weixin.qq.com/pay/orderquery

查询预支付订单时需要一个参数:微信订单号或者商户订单号任选一个,一般优先微信订单号,商户订单号的详细算法地址:

https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_2,就是拼接各个参数

这两个订单号的详细资料地址:http://www.tuicool.com/articles/vIFR7rJ

3.关闭订单接口:https://api.mch.weixin.qq.com/pay/closeorder

4.申请退款接口:https://api.mch.weixin.qq.com/secapi/pay/refund 此功能需要安全证书,自己去开发者中心下载

退款接口中需要的商户订单号与商户退款订单号是一致的,主要实现:

public  static  String getRandomStringByLength( int  length) {
       String base =  "0123456789" ;
       Random random =  new  Random();
       StringBuffer sb =  new  StringBuffer();
       for  ( int  i =  0 ; i < length; i++) {
           int  number = random.nextInt(base.length());
           sb.append(base.charAt(number));
       }
       return  sb.toString();
   }
 
 
   /**
    * @function 生成商户订单号/退款单号
    * @date 2015-12-17
    * @return String
    */
   public  static  String getOrderNo(){
       SimpleDateFormat sdf =  new  SimpleDateFormat( "yyyyMMddHHmmssSSS" );
       Date date =  new  Date();
       return  sdf.format(date) + getRandomStringByLength( 4 );
   }


5.查询退款接口:https://api.mch.weixin.qq.com/pay/refundquery

6.下载对账单:https://api.mch.weixin.qq.com/pay/downloadbill

7.支付结果通知:https://pay.weixin.qq.com/wxpay/pay.action或者http://www.weixin.qq.com/wxpay/pay.php

8.获取openid接口:https://api.weixin.qq.com/sns/oauth2/access_token需要部分参数,上面有例子


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值