1.先去微信开放平台 跟 公众平台申请各种需要的key ,总共是要得到appid,mchid,apikey这三个东西
微信开放平台能获取到的是appid跟mchid,首先要创建一个应用 填写包名跟签名 签名必须是正式打包之后的那个 把正式签名打包完的应用安装在手机上面 用这个工具获取
https://open.weixin.qq.com/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android.apk
等应用审核通过之后就是要申请微信支付的功能了 麻烦了一通之后 会得到商户单号 即 mchid
apikey是微信支付审核通过之后 在商户平台之上创建的api密钥
2.接着就是创建一个项目 在工程里面集成微信支付的sdk
compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
在工程根目录下创建一个wxapi 的目录 com.xxx.xxx.wxapi 在底下新建一个名为WXPayEntryActivity 的类,代码一般是这样的
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
private IWXAPI api;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
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) {
if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
if (resp.errCode == 0) {
Toast.makeText(this, "微信支付成功", Toast.LENGTH_SHORT).show();
} else if (resp.errCode == -1) {
Toast.makeText(this, "微信支付失败:" + resp.errStr, Toast.LENGTH_SHORT).show();
} else if (resp.errCode == -2) {
Toast.makeText(this, "取消支付", Toast.LENGTH_SHORT).show();
}
finish();
}
}
在清单文件里面添加如下字段
<activity
android:name=".wxapi.WXPayEntryActivity"
android:exported="true"
android:launchMode="singleTop">
</activity>
一切完毕 就可以开始支付操作了 (要是不确定签名什么的是否正确 可以试着先集成一下微信分享 要是微信分享可以成功 那往后出现支付调用不出 就不是签名的问题了)
3.一个MD5类:
public final static String getMessageDigest(byte[] buffer) {
char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
try {
MessageDigest mdTemp = MessageDigest.getInstance("MD5");
mdTemp.update(buffer);
byte[] md = mdTemp.digest();
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
} catch (Exception e) {
return null;
}
}
微信官方统一下单的接口 :
https://api.mch.weixin.qq.com/pay/unifiedorder
要求将所需要的参数组装成xml格式返回给下单接口,根据返回回来的数据 进行签名 生成签名之后 就可以进行微信支付的调用了:
public class MainActivity extends Activity implements OnClickListener {
private Button submitButton;
private Button confirmButton;
private TextView textView;
private StringBuffer sb;
private Map<String, String> resultunifiedorder;
private PayReq req;
private final IWXAPI msgApi = WXAPIFactory.createWXAPI(this, null);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
submitButton = (Button) findViewById(R.id.bt_submit_order);
confirmButton = (Button) findViewById(R.id.bt_corfirm);
textView = (TextView) findViewById(R.id.tv_prepay_id);
submitButton.setOnClickListener(this);
confirmButton.setOnClickListener(this);
sb = new StringBuffer();
req = new PayReq();
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.bt_submit_order:
String urlString = "https://api.mch.weixin.qq.com/pay/unifiedorder";
PrePayIdAsyncTask prePayIdAsyncTask = new PrePayIdAsyncTask();
prePayIdAsyncTask.execute(urlString);
break;
case R.id.bt_corfirm:
genPayReq();//生成签名参数
sendPayReq();
break;
default:
break;
}
}
/*
* 调起微信支付
*/
private void sendPayReq() {
msgApi.registerApp(Constants.APP_ID);
msgApi.sendReq(req);
}
private long genTimeStamp() {
return System.currentTimeMillis() / 1000;
}
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(Constants.API_KEY);
this.sb.append("sign str\n" + sb.toString() + "\n\n");
String appSign = MD5.getMessageDigest(sb.toString().getBytes());
return appSign;
}
private void genPayReq() {
req.appId = Constants.APP_ID;
req.partnerId = Constants.MCH_ID;
if (resultunifiedorder != null) {
req.prepayId = resultunifiedorder.get("prepay_id");
req.packageValue = "prepay_id=" + resultunifiedorder.get("prepay_id");
} else {
Toast.makeText(MainActivity.this, "prepayid为空", Toast.LENGTH_SHORT).show();
}
req.nonceStr = getNonceStr();
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");
textView.setText(sb.toString());
}
private class PrePayIdAsyncTask extends AsyncTask<String, Void, Map<String, String>> {
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
/**
* 生成prepayid
*
* @param params
* @return
*/
@Override
protected Map<String, String> doInBackground(String... params) {
// TODO Auto-generated method stub
String url = String.format(params[0]);
String entity = getProductArgs();
byte[] buf = Util.httpPost(url, entity);
String content = new String(buf);
Map<String, String> xml = decodeXml(content);
return xml;
}
@Override
protected void onPostExecute(Map<String, String> result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if (dialog != null) {
dialog.dismiss();
}
sb.append("prepay_id\n" + result.get("prepay_id") + "\n\n");
textView.setText(sb.toString());
resultunifiedorder = result;
}
}
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("Simon", "----" + e.toString());
}
return null;
}
private String getProductArgs() {
// TODO Auto-generated method stub
StringBuffer xml = new StringBuffer();
try {
String nonceStr = getNonceStr();
xml.append("<xml>");
List<NameValuePair> packageParams = new LinkedList<NameValuePair>();
packageParams.add(new BasicNameValuePair("appid", Constants.APP_ID));
packageParams.add(new BasicNameValuePair("body", "APP pay test"));
packageParams.add(new BasicNameValuePair("mch_id", Constants.MCH_ID));
packageParams.add(new BasicNameValuePair("nonce_str", nonceStr));
packageParams.add(new BasicNameValuePair("notify_url", "https://www.baidu.com"));//回调地址
packageParams.add(new BasicNameValuePair("out_trade_no", genOutTradNo()));
packageParams.add(new BasicNameValuePair("total_fee", "1"));
packageParams.add(new BasicNameValuePair("trade_type", "APP"));
String sign = getPackageSign(packageParams);
packageParams.add(new BasicNameValuePair("sign", sign));
String xmlString = toXml(packageParams);
return xmlString;
} catch (Exception e) {
// TODO: handle exception
return null;
}
}
private String genOutTradNo() {
Random random = new Random();
return MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());
}
private String getNonceStr() {
Random random = new Random();
return MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());
}
private String getPackageSign(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(Constants.API_KEY);
String packageSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
return packageSign;
}
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>");
return sb.toString();
}