Android APP統合微信支払い
最近プロジェクトの中で支払い機能が必要で、bossは一致して微信で支払うことを決定して、だからネット上で多くの資料を調べて、言うのが全部ではありませんて、終わったら前の同僚を探して指導します.統合に成功した.ここで総括記録をします.
1、アプリに微信決済を統合し、まずもちろん公式サイトに登録して支払い機能を取得する.これらは開発には関係なく、公式サイトで詳しく説明されていますが、ここではあまり文章を作っていません.これらの能力を得ることは開発に条件を提供した.開発で使われるのは、プラットフォームから与えられたAPPID、APPsercet、およびビジネスプラットフォームに設置されたAPP_key.
2、支払い能力などの前提条件が整ったら、開発プロセスです.コードの中でどのようにようやくつり上げて支払うことができて、公式サイトのDEMO自身を参照してもいくつか総括と各方面の大神の指導をしました.次のステップに分けて演奏します.
(1)、まずはもちろんsdkを工事環境に配置し、公式サイトでAndroid端末SDKをダウンロードし、解凍後libmmsdkをダウンロードする.JArはプロジェクトを導入し、DEMOのConstant.JAva(ここでは公式demoの様式を参照して書くが、もちろん他の方式も採用できる)、MD 5.java、Util.JAvaはプロジェクト(私がここで使った)に入れて、これらの前提条件があれば次のコード操作を書くことができます.
(2)、注文情報の生成
受注情報を生成するには以下の方法で生成し,受注情報を生成するには署名ファイルが必要であるため,生成署名が含まれている.微信はすべての要求にXMLパラメータ形式を採用することを要求し、すべての生産注文情報の後、xmlに変換する必要がある.注文情報に必要な要求パラメータは公式サイトで照合できますが、ここには必要なパラメータがいくつか入っています.
受注情報の生成方法:
このxmlリクエストパラメータを構築するにはhttpclientが生成したので,いくつかのパケットが導入された.他の方法で支払い注文を生成することもできます.最後の形式が公式サイトの形式と同じであればいいです.
いくつかのパラメータの生成に関連しています.ここには、私たちのプロジェクトのビジネスロジックがリストされています.もちろん、プロジェクトによって異なります.
(3)、微信バックグラウンド指定インタフェースにアクセスし、perpay_を取得するid.
前のはこのperpayを得るためだと言える.idが用意されており、公式サイトで指定されたインタフェースは「https://api.mch.weixin.qq.com/pay/unifiedorder」リクエストは公式サイトdemoでutilが提供するリクエスト方式を採用
ここでは非同期処理方式を採用し,要求指定インタフェースにperapy_を得る.idの後に直接支払いを吊り上げる方法.
要求が正常に返されたデータももちろんxml形式であり、perpay_に解析して取り出す必要がある.id(返された結果はperpay_idだけでなく、他の情報も含まれており、個人的には支払いを吊るすにはperpay_idだけでいいと感じています).ここでもdemoを参照して取得した情報をxmlで解析する.
これが正常に実行された後、bookオブジェクトのperpay_idはすでに割り当てられている.非同期で取り出して使用するだけです.
前の非同期操作方法をボタンクリックイベントに割り当て、すべてのステップが正しい場合、支払いインタフェースに入ることができます.以下の図です.
コールバックでダイアログ・ボックスがポップアップされ、ユーザーに支払いに成功し、他のロジックを処理するように要求されます.
これですべてのステップがほぼ完全になり、公式の例とドキュメントを組み合わせると、プロジェクトに支払い機能を迅速に追加できるはずです.
もちろん、ここで触れた手順はすべてappクライアントで行われていますが、公式サイトでは署名取得などの操作をサービスバックグラウンドで行うことをお勧めしています.安全のためでしょう.つまり、カスタマーサービス側が注文情報をサービス側に伝えることです.サービス側は、支払いを吊り上げるために必要な情報を返します.
(perpay_id、商家id、署名などを含む)その後、クライアントが微信を吊り上げて支払う.
1、アプリに微信決済を統合し、まずもちろん公式サイトに登録して支払い機能を取得する.これらは開発には関係なく、公式サイトで詳しく説明されていますが、ここではあまり文章を作っていません.これらの能力を得ることは開発に条件を提供した.開発で使われるのは、プラットフォームから与えられたAPPID、APPsercet、およびビジネスプラットフォームに設置されたAPP_key.
2、支払い能力などの前提条件が整ったら、開発プロセスです.コードの中でどのようにようやくつり上げて支払うことができて、公式サイトのDEMO自身を参照してもいくつか総括と各方面の大神の指導をしました.次のステップに分けて演奏します.
(1)、まずはもちろんsdkを工事環境に配置し、公式サイトでAndroid端末SDKをダウンロードし、解凍後libmmsdkをダウンロードする.JArはプロジェクトを導入し、DEMOのConstant.JAva(ここでは公式demoの様式を参照して書くが、もちろん他の方式も採用できる)、MD 5.java、Util.JAvaはプロジェクト(私がここで使った)に入れて、これらの前提条件があれば次のコード操作を書くことができます.
(2)、注文情報の生成
受注情報を生成するには以下の方法で生成し,受注情報を生成するには署名ファイルが必要であるため,生成署名が含まれている.微信はすべての要求にXMLパラメータ形式を採用することを要求し、すべての生産注文情報の後、xmlに変換する必要がある.注文情報に必要な要求パラメータは公式サイトで照合できますが、ここには必要なパラメータがいくつか入っています.
受注情報の生成方法:
//
private String genProductArgs() {
StringBuffer xml = new StringBuffer();
try {
String nonceStr = genNonceStr();
xml.append("");
List packageParams = new LinkedList();
packageParams.add(new BasicNameValuePair("appid", Constants.APP_ID)); //APPID
packageParams.add(new BasicNameValuePair("body", " :" + singlePrice + " x " + payment_num.getText().toString() + " ")); //
packageParams.add(new BasicNameValuePair("mch_id", Constants.MCH_ID)); // ID
packageParams.add(new BasicNameValuePair("nonce_str", nonceStr)); //
packageParams.add(new BasicNameValuePair("notify_url","http://www.weixin.qq.com/wxpay/pay.php")); //
packageParams.add(new BasicNameValuePair("out_trade_no",getTrade())); //
packageParams.add(new BasicNameValuePair("spbill_create_ip",getLocalHostIp())); // IP
//double price = Double.parseDouble(payment_num.getText().toString()) * (Integer.parseInt(singlePrice) * 100);
double price = Double.parseDouble(singlePrice) * 100 * n;
int priceInt = (int) price;
packageParams.add(new BasicNameValuePair("total_fee", priceInt+"")); // int
packageParams.add(new BasicNameValuePair("trade_type", "APP")); //
String sign = genAppSign(packageParams);
packageParams.add(new BasicNameValuePair("sign", sign)); //
String xmlstring = parseNodeToXML(packageParams); // xml
return xmlstring;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
このxmlリクエストパラメータを構築するにはhttpclientが生成したので,いくつかのパケットが導入された.他の方法で支払い注文を生成することもできます.最後の形式が公式サイトの形式と同じであればいいです.
いくつかのパラメータの生成に関連しています.ここには、私たちのプロジェクトのビジネスロジックがリストされています.もちろん、プロジェクトによって異なります.
//
private String getTrade(){
long nowTime = System.currentTimeMillis();
SimpleDateFormat format = new SimpleDateFormat("yyMMddHHmmss");
return format.format(new Date(nowTime));
}
// Sign
StringBuilder sb = new StringBuilder();
private String genAppSign(List 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
" + sb.toString() + "
");
String appSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
return appSign;
}
//
private String genNonceStr() {
Random random = new Random();
return MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());
}
/**
* xml
* @param treeNodes
* @return
*/
public String parseNodeToXML(List treeNodes) {
StringBuffer xmlnodes = new StringBuffer();
if (treeNodes != null && treeNodes.size() > 0) {
xmlnodes.append("");
for (int i = 0; i < treeNodes.size(); i++) {
NameValuePair node = treeNodes.get(i);
xmlnodes.append("").append(node.getValue()).append(""+node.getName()+">");
}
xmlnodes.append(" ");
}
//return xmlnodes.toString();
String xml = xmlnodes.toString();
try {
xml = new String(xml.toString().getBytes(), "ISO8859-1"); // , , perpred_id
return xml;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
// IP
public String getLocalHostIp() {
String ipaddress = "";
try {
Enumeration en = NetworkInterface.getNetworkInterfaces();
//
while (en.hasMoreElements()) {
NetworkInterface nif = en.nextElement();// ip
Enumeration inet = nif.getInetAddresses();
// ip
while (inet.hasMoreElements()) {
InetAddress ip = inet.nextElement();
if (!ip.isLoopbackAddress() && InetAddressUtils.isIPv4Address(ip.getHostAddress())) {
return ip.getHostAddress();
}
}
}
}
catch (SocketException e) {
Log.e("feige", " ip ");
e.printStackTrace();
}
return ipaddress;
}
(3)、微信バックグラウンド指定インタフェースにアクセスし、perpay_を取得するid.
前のはこのperpayを得るためだと言える.idが用意されており、公式サイトで指定されたインタフェースは「https://api.mch.weixin.qq.com/pay/unifiedorder」リクエストは公式サイトdemoでutilが提供するリクエスト方式を採用
ここでは非同期処理方式を採用し,要求指定インタフェースにperapy_を得る.idの後に直接支払いを吊り上げる方法.
// id
public void gotoWechat() {
new AsyncTask() {
@Override
protected Object doInBackground(Object[] objects) { // Prepay_id
String url = String.format("https://api.mch.weixin.qq.com/pay/unifiedorder");
String entity = genProductArgs(); //
byte[] buf = Util.httpPost(url, entity);
String content = new String(buf); //
//Log.e("orion", content);
try {
xmlParseTest(content); //
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
wechatPay();
}
}.execute();
}
要求が正常に返されたデータももちろんxml形式であり、perpay_に解析して取り出す必要がある.id(返された結果はperpay_idだけでなく、他の情報も含まれており、個人的には支払いを吊るすにはperpay_idだけでいいと感じています).ここでもdemoを参照して取得した情報をxmlで解析する.
WeixinParentId 。
/**
* xml
* prepay_id
* Books
*/
WeixinParentId book = null; // Books
public void xmlParseTest(String str) throws IOException, XmlPullParserException {
XmlPullParser pullParser = Xml.newPullParser(); // XmlPullParser
//InputStream is = getContext().getAssets().open("parse.xml"); //
ByteArrayInputStream is = new ByteArrayInputStream(str.getBytes("UTF-8"));
ArrayList books = null ;
pullParser.setInput(is, "UTF-8");
int type = pullParser.getEventType(); //
while (type != pullParser.END_DOCUMENT) { //
switch(type){
case XmlPullParser.START_DOCUMENT: //
books = new ArrayList();
break;
case XmlPullParser.START_TAG: //
if (pullParser.getName().equals("xml")) {
book = new WeixinParentId();
}else if (pullParser.getName().equals("return_msg")) {
type = pullParser.next(); // ,
book.setReturn_msg(pullParser.getText());
}else if (pullParser.getName().equals("appid")) {
type = pullParser.next();
book.setAppid(pullParser.getText());
}else if (pullParser.getName().equals("prepay_id")) {
type = pullParser.next();
book.setPrepay_id(pullParser.getText());
}
break;
case XmlPullParser.END_TAG: //
if (pullParser.getName().equals("book")) {
books.add(book);
book = null; //
}
break;
}
type = pullParser.next(); //
}
//Log.e("test", "book------id----" + book.getPrepay_id());
}
これが正常に実行された後、bookオブジェクトのperpay_idはすでに割り当てられている.非同期で取り出して使用するだけです.
// perpay_id
protected void wechatPay() {
PayReq req = new PayReq();
req.appId = Constants.APP_ID;
req.partnerId = Constants.MCH_ID;
req.prepayId = book.getPrepay_id();
req.packageValue = "Sign=WXPay";
req.nonceStr = genNonceStr();
req.timeStamp = String.valueOf(genTimeStamp());
List signParams = new LinkedList();
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
" + req.sign + "
");
// , , IWXMsg.registerApp
//Log.e("test","book.getPrepay_id()----------"+book.getPrepay_id()+"-------genNonceStr()-------"+genNonceStr()+"--------genTimeStamp()-------"+genTimeStamp()+"---genAppSign(signParams)--"+genAppSign(signParams));
api.sendReq(req);
// dialog.dismiss();
}
//
private long genTimeStamp() {
return System.currentTimeMillis() / 1000;
}
前の非同期操作方法をボタンクリックイベントに割り当て、すべてのステップが正しい場合、支払いインタフェースに入ることができます.以下の図です.
, :
, APP , 。 wxapi
WXPayEntryActivity Onresp() , 。
コールバックでダイアログ・ボックスがポップアップされ、ユーザーに支払いに成功し、他のロジックを処理するように要求されます.
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.activity_main2);
api = WXAPIFactory.createWXAPI(this, Constants.APP_ID);
api.handleIntent(getIntent(), this);
api.registerApp(Constants.APP_ID);
}
@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) {
int errCode = resp.errCode;
if (errCode == 0) {
// 0
// Intent intent = new Intent("name");
// sendBroadcast(intent);
// Log.e("test"," --onResp--");
// Toast.makeText(this," ",Toast.LENGTH_SHORT).show();
new AlertDialog.Builder(this).setMessage(" ").setPositiveButton(" ", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
finish();
PaymentActivity.instance.finish();
Intent intent = new Intent(WXPayEntryActivity.this, PuzzGameActivity.class);
intent.putExtra("ISPLAY",true);
startActivity(intent);
}
}).setTitle(" ").create().show();
Toast.makeText(this," ",Toast.LENGTH_LONG).show();
}
else if (errCode == -1) {
//-1 : 、 APPID、 APPID 、 APPID 、 。
new AlertDialog.Builder(this).setMessage(" ").setPositiveButton(" ", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
finish();
}
}).setTitle(" ").create().show();
finish();
}
else if (errCode == -2) {
//-2 。 : , , APP。
finish();
}
}
}
これですべてのステップがほぼ完全になり、公式の例とドキュメントを組み合わせると、プロジェクトに支払い機能を迅速に追加できるはずです.
もちろん、ここで触れた手順はすべてappクライアントで行われていますが、公式サイトでは署名取得などの操作をサービスバックグラウンドで行うことをお勧めしています.安全のためでしょう.つまり、カスタマーサービス側が注文情報をサービス側に伝えることです.サービス側は、支払いを吊り上げるために必要な情報を返します.
(perpay_id、商家id、署名などを含む)その後、クライアントが微信を吊り上げて支払う.