您的位置:首页 > 移动开发

微信支付APP支付完全攻略

2015-12-14 14:55 369 查看

微信支付接入应用

最近项目中要接入微信支付,所以就去研究了下,发现坑还真不少啊。也就有了这篇博客。

接入前准备

在开始接入微信支付前你的去微信的开发平台上面注册你自己的应用。具体的链接是微信开发平台

当然你也可以从APIStore里面找到微信的开发平台。在开放平台注册应用并申请微信支付功能。

默认在开放平台注册的应用只有分享基本功能,要开通微信支付的需要以下流程。

微信开发平台开通微信支付流程

移动应用微信支付

- 注册并通过开放平台开发者资质审核

- 填写申请资料

- 验证账户并签署协议

反正接入微信支付挺坑的,认证开发者还有300大洋每年,穷啊~~~

具体可以参考申请接入微信支付或者这里

接下来说下注册app要注意的事项

注册应用的AppId和AppSecret就不说啦,官方说明:商户在微信开放平台申请开发应用后,微信开放平台会生成APP的唯一标识APPID。由于需要保证支付安全,需要在开放平台绑定商户应用包名和应用签名,设置好后才能正常发起支付。设置界面在【开放平台】中的栏目【管理中心 / 修改应用 / 修改开发信息】里面,如图红框内所示。



如果你想自己的应用在debug就能调起微信支付的话,你就需要使用微信提供的签名工具来生成

应用包名:是在APP项目配置文件AndroidManifest.xml中声明的package值,例如DEMO中的package=”net.sourceforge.simcpux”。

应用签名:根据项目的应用包名和编译使用的keystore,可由签名工具生成一个32位的md5串,在调试的手机上安装签名工具后,运行可生成应用签名串,如图所示,绿色串即应用签名。签名工具下载地址

https://open.weixin.qq.com/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android.apk



注意事项:在获取签名时,这个应用签名工具生成的签名对应的就是我们安装在测试手机带keystore的debug或者relese包,所以要调起微信支付需要对应应用签名的包才能正常调起微信支付。

开始开发

由于实际测试需要配置自己的开放平台账号,商户号等,故使用微信官方的支付例子.

获取预支付订单

a.请求预支付订单的参数

/**
* 配置请求预支付订单的 参数
*/
private String genProductArgs() {
StringBuffer xml = new StringBuffer();

try {
String  nonceStr = genNonceStr();
xml.append("</xml>");
List<NameValuePair> packageParams = new LinkedList<NameValuePair>();
//APPID 即微信开放平台生成的唯一标识
packageParams.add(new BasicNameValuePair("appid", Constants.APP_ID));
//商品或支付单简要描述
packageParams.add(new BasicNameValuePair("body", "weixin"));
//微信支付分配的商户号
packageParams.add(new BasicNameValuePair("mch_id", Constants.MCH_ID));
//随机字符串,不长于32位。推荐随机数生成算法
packageParams.add(new BasicNameValuePair("nonce_str", nonceStr));
//接收微信支付异步通知回调地址
packageParams.add(new BasicNameValuePair("notify_url", "http://121.40.35.3/test"));
//商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号
packageParams.add(new BasicNameValuePair("out_trade_no",genOutTradNo()));
//APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP。
packageParams.add(new BasicNameValuePair("spbill_create_ip","127.0.0.1"));
//订单总金额,单位为分,详见支付金额
packageParams.add(new BasicNameValuePair("total_fee", "1"));
//交易类型 取值如下:JSAPI,NATIVE,APP,详细说明见参数规定
packageParams.add(new BasicNameValuePair("trade_type", "APP"));
String sign = genPackageSign(packageParams);
//签名,详见签名生成算法
packageParams.add(new BasicNameValuePair("sign", sign));

String xmlstring =toXml(packageParams);

return xmlstring;

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

}


b.请求生成预支付订单

/**
* 请求预支付订单
*/
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 void onPostExecute(Map<String,String> result) {
if (dialog != null) {
dialog.dismiss();
}
sb.append("prepay_id\n"+result.get("prepay_id")+"\n\n");
show.setText(sb.toString());

resultunifiedorder=result;

}

@Override
protected void onCancelled() {
super.onCancelled();
}

@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);

String content = new String(buf);
Log.e("orion", content);
//解析返回的xml数据
Map<String,String> xml=decodeXml(content);

return xml;
}
}


c.解析返回的xml数据


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;

}


请求预支付订单这个过程,实际开发过程中为了提高数据的安全性,建议放在服务端操作,客户端只有获取到调起支付的参数即可。

2.调起支付

a. 将自己的应用注册到微信

final IWXAPI msgApi = WXAPIFactory.createWXAPI(this, null);
msgApi.registerApp(Constants.APP_ID);


b.配置调起参数PayReq

/**
* 配置调起支付参数
*/
private void genPayReq() {

req.appId = Constants.APP_ID;
req.partnerId = Constants.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");

show.setText(sb.toString());

Log.e("orion", signParams.toString());

}


c.调起支付

/**
* 调起支付
*/
private void sendPayReq() {

msgApi.registerApp(Constants.APP_ID);
msgApi.sendReq(req);
Log.e("orion", "req.checkArgs() = "+req.checkArgs());
}


3.获取支付结果

a.设置获取支付结果的返回界面 **注意:**WXPayEntryActivity一定要在包名的.wxapi.WXPayEntryActivity下面,


b.在Manifest中注册响应的Activity和receiver

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >

<activity
android:name=".PayActivity"
android:label="@string/app_name"
android:exported="true"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="wxf2f565574a968187"/>
</intent-filter>
</activity>

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

<receiver
android:name="net.sourceforge.simcpux.AppRegister">
<intent-filter>
<action android:name="com.tencent.mm.plugin.openapi.Intent.ACTION_REFRESH_WXAPP" />
</intent-filter>
</receiver>

</application>


c.在WXPayEntryActivity中处理支付返回结果

package com.weixin.paydemo.wxapi;

import com.weixin.paydemo.R;
import net.sourceforge.simcpux.Constants;

import com.tencent.mm.sdk.constants.ConstantsAPI;
import com.tencent.mm.sdk.modelbase.BaseReq;
import com.tencent.mm.sdk.modelbase.BaseResp;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.sdk.openapi.WXAPIFactory;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler{

private static final String TAG = "MicroMsg.SDKSample.WXPayEntryActivity";

private IWXAPI api;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pay_result);

api = WXAPIFactory.createWXAPI(this, Constants.APP_ID);

api.handleIntent(getIntent(), this);
}

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

@Override
public void onReq(BaseReq req) {
}

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

if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.app_tip);
builder.setMessage(getString(R.string.pay_result_callback_msg, resp.errStr +";code=" + String.valueOf(resp.errCode)));
builder.show();
}
}
}


最后需要微信demo的同学可以点击这里下载,如有疑问,欢迎QQ咨询 670463616 或者邮件 fj25822@qq.com

##
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: