微信支付集成

微信支付

1:去微信开放平台注册应用
https://open.weixin.qq.com/cgi-bin/index?t=home/index&lang=zh_CN&token=2c0fee9c43e1eb8f9febcc7cb73abf598e2d4011

这里需要注意的是:

包名正确(重要)
签名正确(重要)
温馨提示:如果你发布的正式版本,需要用官方app重新生成签名,然后在开放平台重新设置sign,因为测试版本的keystore与正式版的keystore不一样。总之,就是你用的keystore生成的sign要和微信开放平台的时刻保持一致。

微信提供的签名生成工具
把包名添加上去就可以获取签名
注意:把要获取签名的应用安装在手机上
https://res.wx.qq.com/open/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android2.apk

创建移动应用并成功之后会收到腾讯发来的邮件:


Paste_Image.png

通过邮件你能获得重要的参数:
(1):AppID
(2):微信支付商户号
(4):前往商户平台完成入驻
(4):API秘钥(自己设置即可,注意一定要32位字母加数字的组合)记得保存好秘钥,以后要使用

开发前的准备

先了解下交互时序图,统一下单API、支付结果通知API和查询订单API等都涉及签名过程,调用都必须在商户服务器端完成。如图8.6所示。

APP支付时序图

图8.6 APP支付时序图

安卓sdk下载
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=11_1
微信开放平台
https://open.weixin.qq.com/
微信android开发手册
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317784&token=&lang=zh_CN
微信app开发步骤
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_5

下载开发工具包
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419319167&lang=zh_CN


开始接入微信支付

1.在项目中引入微信开发包


引入jar

2.在AndroidManifest.xml中添加相应的权限

<uses-permission android:name="android.permission.INTERNET"/> 
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> 
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> 
<uses-permission android:name="android.permission.READ_PHONE_STATE"/> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

3.在MainActivity中注册到为微信

配置debug签名

创建应用需要填写应用签名,配置在debug下直接用的正式的key,这样就不用每次打包才能调起微信客户端

signingConfigs {
        debug {
            storeFile file("你的keystore路径")
            storePassword "xxx"
            keyAlias "xxx"
            keyPassword "xxx"
        }

        release {
            storeFile file("你的keystore路径")
            storePassword "xxx"
            keyAlias "xxx"
            keyPassword "xxx"
        }
}

3.在MainActivity中注册到为微信


注册微信
api= WXAPIFactory.createWXAPI(this,ConfigUtil.Wechat_Appid,true);
api.registerApp(ConfigUtil.Wechat_Appid);

4.在点击的时候向微信发送请求


发送请求
case R.id.wechat_pay:
    PayReq request = new PayReq();
    request.appId = ConfigUtil.Wechat_Appid;
    request.partnerId = "1327244301";
    request.prepayId= "wx2016092009564343e737275f0904349502";
    request.packageValue = "Sign=WXPay";
    request.nonceStr= "70vhVHnJj6ph7mf9";
    request.timeStamp= "1474336603";
    request.sign= "815BC8D5508FD90F7A978856B2174E21";
    api.sendReq(request);
    break;

5.配置回调
[1]在微信管理后台中配置的包名下新建wxapi包
[2]在wxapi包下新建WXPayEntryActivity的类(注意这个类的位置和名称不能改变)


新建WXPayEntryActivity类

[3]WXPayEntryActivity类实现IWXAPIEventHandler继承Activity,该布局文件自己定义即可


WXPayEntryActivity类实现


[4]在AndroidManifest.xml中注册activity

<activity
    android:name=".wxapi.WXPayEntryActivity"
    android:exported="true"
    android:launchMode="singleTop"/>

[5]在WXPayEntryActivity类中onCreate中注册微信


注册微信
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    api = WXAPIFactory.createWXAPI(this, ConfigUtil.Wechat_Appid);
    api.handleIntent(getIntent(), this);
}

 @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        api.handleIntent(intent, this);
    }

[6]实现onResp

public void onResp(BaseResp baseResp) {
    Log.d(TAG, "onPayFinish, errCode = " + baseResp.errCode);

    if (baseResp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("标题");
        builder.setMessage(String.valueOf(baseResp.errCode));
        builder.show();
    }
}

baseResp.errCode是返回的错误码


错误码

注意:WXPayEntryActivity类必须叫这个名必须在wxapi包下


微信调不起来:
检查签名是否正确
包名是否与微信后台配置的一致
检查是否添加权限
检查代码 是否在初始化时注册微信 是否正确发送请求
微信支付调用起来没有回调:
查看包名是否正确
类名是否正确
在AndroidManifest.xml是否注册activity

解决方法:
实在掉不起来微信(包名正确签名正确)就重新安装微信客户端 和重新安装 测试项目

预支付订单和sign最好在服务器中完成,但若是就想在客户端做怎么弄呢?为方便,那么我这里就直接给出代码,可供大家参考:

/**
 *该类用于在客户端处理吊起微信支付前,生成prepay_id和sign的方式举例,
 * 但建议在服务器端处理prepay_id和sign
 **/
public class PayActivity extends Activity {
	// appid
	// 请同时修改 androidmanifest.xml里面,.PayActivity里的属性<data
	// android:scheme=""/>为新设置的appid
	public  static  String APP_ID;

	// 商户号
	public  static String MCH_ID ;
	// API密钥,在商户平台设置
	public static String API_KEY ;
	private String body;
	private  String total;
	PayReq req;
	final IWXAPI msgApi = WXAPIFactory.createWXAPI(this, null);
	Map<String, String> resultunifiedorder;
	StringBuffer sb;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		 APP_ID= getIntent().getStringExtra("appid");
		 MCH_ID=getIntent().getStringExtra("partnerid");
		 API_KEY=getIntent().getStringExtra("apikey");
		 body=getIntent().getStringExtra("body");

		req = new PayReq();
		sb = new StringBuffer();
		msgApi.registerApp(APP_ID);

		// 生成prepay_id
		GetPrepayIdTask getPrepayId = new GetPrepayIdTask();
		getPrepayId.execute();
	}

	private class GetPrepayIdTask extends AsyncTask<Void, Void, Map<String, String>> {
		private ProgressDialog dialog;
		@Override
		protected void onPreExecute() {
			dialog = ProgressDialog.show(PayActivity.this, getString(R.string.app_tip), getString(R.string.getting_prepayid));
		}

		@Override
		protected Map<String, String> doInBackground(Void... params) {

			String url = String.format("https://api.mch.weixin.qq.com/pay/unifiedorder");
			String entity = genProductArgs();

			Log.e("orion", entity);

			byte[] buf = Util.httpPost(url, entity);  //执行与获取预付款订单请求,并获得订单byte

			String content = new String(buf);
			Log.e("orion", content);
			Map<String, String> map = decodeXml(content);
			return map;
		}

		@Override
		protected void onPostExecute(Map<String, String> result) {
			if (dialog != null) {
				dialog.dismiss();
			}
			sb.append("prepay_id\n" + result.get("prepay_id") + "\n\n");

			resultunifiedorder = result;

			if (result.get("prepay_id") != null) {
				genPayReq();  //吊起支付请求
			} else {
				Toast.makeText(getApplicationContext(), "调用微信支付失败!", Toast.LENGTH_SHORT).show();
			}
		}
	}

	public Map<String, String> decodeXml(String content) {
		try {
			Map<String, String> xml = new HashMap<String, String>();
			XmlPullParser parser = Xml.newPullParser();
			parser.setInput(new StringReader(content));
			int event = parser.getEventType();
			while (event != XmlPullParser.END_DOCUMENT) {

				String nodeName = parser.getName();
				switch (event) {
				case XmlPullParser.START_DOCUMENT:

					break;
				case XmlPullParser.START_TAG:

					if ("xml".equals(nodeName) == false) {
						// 实例化student对象
						xml.put(nodeName, parser.nextText());
					}
					break;
				case XmlPullParser.END_TAG:
					break;
				}
				event = parser.next();
			}

			return xml;
		} catch (Exception e) {
			Log.e("orion", e.toString());
		}
		return null;

	}

	private String genNonceStr() {
		Random random = new Random();
		return MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());
	}

	private long genTimeStamp() {
		return System.currentTimeMillis() / 1000;
	}

	private String genOutTradNo() {
		Random random = new Random();
		String out_trade_no = MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());
		return out_trade_no;
	}
	private String genProductArgs() {
		StringBuffer xml = new StringBuffer();

		try {
			String nonceStr = genNonceStr();
			xml.append("</xml>");
			List<NameValuePair> packageParams = new LinkedList<NameValuePair>();
			packageParams.add(new BasicNameValuePair("appid", APP_ID));
			packageParams.add(new BasicNameValuePair("body", body));//物品
			packageParams.add(new BasicNameValuePair("mch_id", MCH_ID));
			packageParams.add(new BasicNameValuePair("nonce_str", nonceStr));
			packageParams.add(new BasicNameValuePair("notify_url", "http://baidu.com"));
			packageParams.add(new BasicNameValuePair("out_trade_no", genOutTradNo()));
			packageParams.add(new BasicNameValuePair("spbill_create_ip", getPhoneIp()));
			packageParams.add(new BasicNameValuePair("total_fee", getIntent().getStringExtra("total_fee")));//金额
			packageParams.add(new BasicNameValuePair("trade_type", "APP"));
			String sign = genPackageSign(packageParams);
			packageParams.add(new BasicNameValuePair("sign", sign));
			String xmlstring = toXml(packageParams);
			return new String(xmlstring.getBytes(), "ISO8859-1");
			// return xmlstring;

		} catch (Exception e) {
		//	Log.e(TAG, "genProductArgs fail, ex = " + e.getMessage());
			return null;
		}

	}
	private void genPayReq() {
		req.appId = APP_ID;
		req.partnerId = MCH_ID;
		req.prepayId = resultunifiedorder.get("prepay_id");
		req.packageValue = "Sign=WXPay";
		req.nonceStr = genNonceStr();
		req.timeStamp = String.valueOf(genTimeStamp());
		List<NameValuePair> signParams = new LinkedList<NameValuePair>();
		signParams.add(new BasicNameValuePair("appid", req.appId));
		signParams.add(new BasicNameValuePair("noncestr", req.nonceStr));
		signParams.add(new BasicNameValuePair("package", req.packageValue));
		signParams.add(new BasicNameValuePair("partnerid", req.partnerId));
		signParams.add(new BasicNameValuePair("prepayid", req.prepayId));
		signParams.add(new BasicNameValuePair("timestamp", req.timeStamp));
		req.sign = genAppSign(signParams);
		sb.append("sign\n" + req.sign + "\n\n");
		sendPayReq();
		Log.e("orion", signParams.toString());

	}

	/**
	 * 获取预支付订单时需要生成的PackageSign签名
	 */

	private String genPackageSign(List<NameValuePair> params) {
		StringBuilder sb = new StringBuilder();

		for (int i = 0; i < params.size(); i++) {
			sb.append(params.get(i).getName());
			sb.append('=');
			sb.append(params.get(i).getValue());
			sb.append('&');
		}
		sb.append("key=");
		sb.append(API_KEY);
		String packageSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
		Log.e("orion", packageSign);
		return packageSign;
	}

	//吊起支付时需要生成的AppSign签名
	private String genAppSign(List<NameValuePair> params) {
		StringBuilder sb = new StringBuilder();

		for (int i = 0; i < params.size(); i++) {
			sb.append(params.get(i).getName());
			sb.append('=');
			sb.append(params.get(i).getValue());
			sb.append('&');
		}
		sb.append("key=");
		sb.append(API_KEY);

		this.sb.append("sign str\n" + sb.toString() + "\n\n");
		String appSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
		Log.e("orion", appSign);
		return appSign;
	}

	private String toXml(List<NameValuePair> params) {
		StringBuilder sb = new StringBuilder();
		sb.append("<xml>");
		for (int i = 0; i < params.size(); i++) {
			sb.append("<" + params.get(i).getName() + ">");

			sb.append(params.get(i).getValue());
			sb.append("</" + params.get(i).getName() + ">");
		}
		sb.append("</xml>");

		Log.e("orion", sb.toString());
		return sb.toString();
	}

	// 发起微信支付
	private void sendPayReq() {

		msgApi.registerApp(APP_ID);
		msgApi.sendReq(req);
	}

	public static String getPhoneIp() {
		try {
			for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
				NetworkInterface intf = en.nextElement();
				for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
					InetAddress inetAddress = enumIpAddr.nextElement();
					if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
						return inetAddress.getHostAddress().toString();
					}
				}
			}
		} catch (Exception e) {
		}
		return "127.0.0.1";
	}
}

其中Util中涉及的代码如下:

public static byte[] httpPost(String url, String entity) {
		if (url == null || url.length() == 0) {
			Log.e(TAG, "httpPost, url is null");
			return null;
		}

		HttpClient httpClient = getNewHttpClient();

		HttpPost httpPost = new HttpPost(url);

		try {
			httpPost.setEntity(new StringEntity(entity));
			httpPost.setHeader("Accept", "application/json");
			httpPost.setHeader("Content-type", "application/json");

			HttpResponse resp = httpClient.execute(httpPost);
			if (resp.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				Log.e(TAG, "httpGet fail, status code = " + resp.getStatusLine().getStatusCode());
				return null;
			}

			return EntityUtils.toByteArray(resp.getEntity());
		} catch (Exception e) {
			Log.e(TAG, "httpPost exception, e = " + e.getMessage());
			e.printStackTrace();
			return null;
		}
	}

其他文档:

微信开发平台官网:申请流业务流程 订单签名算法及验证

微信支付集成及爬坑:代码详谈

集成微信登录 :http://www.jianshu.com/p/d95e4343e231

Android实现点击支付按钮,弹起自定义输入法进行密码输入: 点我哦!

微信扫一扫揭秘:  猛戳这里!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
最新最全微信支付集成SDK是一种用于开发者在自己的应用程序中集成微信支付功能的软件开发工具包。它提供了丰富的支付接口和功能,方便开发者快速集成微信支付功能,并且可以有效地处理支付过程中的各种逻辑。 这个最新版本的微信支付集成SDK具有以下特点: 1. 高度可定制化:开发者可以根据自己的需求,自定义支付页面的样式、布局和交互效果,以满足用户的个性化支付需求。 2. 安全可靠:该SDK采用了先进的加密算法和安全传输协议,确保支付过程中的数据传输和用户信息的安全性。 3. 多种支付方式支持:除了常见的扫码支付和H5支付外,该SDK还支持一键支付、小程序支付、APP支付等多种支付方式,满足不同场景的支付需求。 4. 丰富的支付接口:该SDK提供了丰富的支付接口,开发者可以根据自己的业务需求,调用不同的支付接口实现不同的功能,如查询订单状态、退款操作等。 5. 强大的后台管理功能:该SDK还提供了后台管理系统,开发者可以通过后台管理系统实时查看支付数据、统计分析、配置支付参数等,便于对支付业务进行管理和优化。 总之,这个最新最全的微信支付集成SDK为开发者提供了一个方便、快捷的集成微信支付功能的工具包,开发者可以根据自己的需求选择适合的接口和功能,实现灵活多样的支付方式和支付场景。无论是电商平台、移动应用还是其他支付场景,该SDK都能够满足开发者的需求,提升用户体验和支付安全性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值