I. Preparations
1. Development Platform and SDK Download
Wechat Open Platform
Download SDK
Wechat Payment Demo Download
http://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=11_1
2. Creating Applications
Creating Mobile Applications to Get AppID AppSecret
To obtain payment function, it also needs developer qualification certification, 300 RMB / year fee, which seems to be the only fee in the open platform.
3. Android Mainfest File Modification
Jurisdiction
<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"/>
II. Business processes
Interaction between merchant system and Wechat payment system
Step 1: User chooses goods in APP, submits orders, and chooses Wechat to pay.
Step 2: The merchant receives the user's payment form in the background and invokes the unified order interface of Wechat payment. See also[ Unified Order API].
Step 3: Unified single interface returns normal prepay_id, and then regenerates the signature according to the signature specification, then transfers the data to APP. The fields participating in the signature are appId, partnerId, prepayId, nonceStr, timeStamp, package. Note: The value format of package is Sign=WXPay
Step 4: Merchant APP calls Wechat Payment. See this chapter for api[ Description of development steps on app side]
Step 5: Business background receives payment notification. api see[ Payment Result Notification API]
Step 6: Business background query payment results. api[ Query Order API]
III. Development
1. Registration Application
final IWXAPI msgApi = WXAPIFactory.createWXAPI(this, null); msgApi.registerApp(Constants.APP_ID);
2. Call Unified Payment Single Interface and Return PrepayID
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); Map<String,String> xml=decodeXml(content); return xml; } }
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", 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", "http://121.40.35.3/test")); packageParams.add(new BasicNameValuePair("out_trade_no",genOutTradNo())); packageParams.add(new BasicNameValuePair("spbill_create_ip","127.0.0.1")); packageParams.add(new BasicNameValuePair("total_fee", "1")); 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; } }
3. Setting parameters of PayReq request and sending payment request
//Setting parameters for PayReq requests private void genPayReq() { req.appId = Constants.APP_ID; req.partnerId = Constants.MCH_ID; req.prepayId = resultunifiedorder.get("prepay_id"); req.packageValue = "prepay_id="+resultunifiedorder.get("prepay_id"); 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()); }
//Send requests msgApi.sendReq(req);
4. Processing Result Callback
IWXAPIEventHandler Interface for Implementing Wechat API
api.handleIntent(getIntent(), new IWXAPIEventHandler);
Processing request callbacks in onResp(BaseResp resp) of IWXAPIEventHandler
@Override public void onResp(BaseResp resp) { Log.d(TAG, "onPayFinish, errCode = " + resp.errCode); if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) { //Handling PayReq callbacks 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(); } }