一个app里面肯定会有支付,而绝大多数会集成微信支付,当然也不是很难,我只是将我踩过的坑填补,然后提供比较好的工具出来,方便大家使用。
GetPrepayIdTask getPrepayIdTask = new GetPrepayIdTask(this, price + "", "" + tuanbi_info, logid);
getPrepayIdTask.execute();
这个就是开始,但是在这里那个price很关键,微信是以分为最小单位,但是不可以出现10.0这样的情况,而且最好不要使用double的数据类型,应该使用float,double数据类型会有精度丢失的问题,所以经常会看到9.99999的情况。这个是不合理的。然后我粘贴处GetPrePayIdTask:
import java.io.StringReader;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.xmlpull.v1.XmlPullParser;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.provider.DocumentsContract.Root;
import android.util.Log;
import android.util.Xml;
import com.tencent.mm.opensdk.modelpay.PayReq;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
/**
* Created by Administrator on 2017/4/12.
* 微信支付
*/
public class GetPrepayIdTask extends AsyncTask> {
/**
* 微信支付业务:入参app_id
*/
public static final String WXAPPID = "";
public static final String MCH_ID = "";
public static final String API_KEY = "";
private StringBuffer sb = new StringBuffer();
private Map resultunifiedorder;
private PayReq req = new PayReq();
private IWXAPI msgApi;
private Context c;
private String price;
/**
* 订单号
*/
private String orderNo;
/*商品描述交易字段格式根据不同的应用场景按照以下格式:
APP——需传入应用市场上的APP名字-实际商品名称,天天爱消除-游戏充值。*/
/**
* 多个订单
*/
private String orderNos;
public GetPrepayIdTask(Context c, String price, String orderNo, String orderNos) {
msgApi = WXAPIFactory.createWXAPI(c, null);
this.c = c;
this.price = price;
this.orderNo = orderNo;
this.orderNos = orderNos;
}
private ProgressDialog dialog;
@Override
protected void onPreExecute() {
dialog = ProgressDialog.show(c, "弹窗提示", "正在加载");
}
@Override
protected void onPostExecute(Map result) {
if (dialog != null) {
dialog.dismiss();
}
sb.append("prepay_id\n" + result.get("prepay_id") + "\n\n");
resultunifiedorder = result;
genPayReq();
msgApi.registerApp(WXAPPID);
msgApi.sendReq(req);
}
@Override
protected void onCancelled() {
super.onCancelled();
}
@Override
protected Map doInBackground(Void... params) {
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);
Map xml = decodeXml(content);
return xml;
}
private void genPayReq() {
req.appId = WXAPPID;
req.partnerId = MCH_ID;
//req.prepayId=Constants.API_KEY;
req.prepayId = resultunifiedorder.get("prepay_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("appkey", Constants.API_KEY));
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");
Log.e("orion", signParams.toString());
// req.appId = Constants.APP_ID;
// req.partnerId = Constants.MCH_ID;
// req.prepayId="wx20150928191247ec2bfe36120916857122";
// req.packageValue = "Sign=WXPay";
// req.nonceStr="lPLaOjotrEy9MYx3";
// req.sign="10DD9C41A6857B4C4AEA98E24605925C";
// req.timeStamp="1443437278";
}
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(API_KEY);
this.sb.append("sign str\n" + sb.toString() + "\n\n");
String appSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
Log.e("orionAppSign", appSign);
return appSign;
}
private String genProductArgs() {
StringBuffer xml = new StringBuffer();
try {
String nonceStr = genNonceStr();
xml.append("");
List packageParams = new LinkedList();
packageParams.add(new BasicNameValuePair("appid", WXAPPID));
packageParams.add(new BasicNameValuePair("body", orderNo));
packageParams.add(new BasicNameValuePair("mch_id", MCH_ID));
packageParams.add(new BasicNameValuePair("nonce_str", nonceStr));
packageParams.add(new BasicNameValuePair("notify_url", "http://agent.quygt.com/tenpay/tenpaynotify"));
// packageParams.add(new BasicNameValuePair("notify_url", "http://lvgounet.oicp.net:24561/tenpay/tenpaynotify"));
// 订单
// packageParams.add(new BasicNameValuePair("out_trade_no", genOutTradNo(orderNos)));
packageParams.add(new BasicNameValuePair("out_trade_no", orderNos));
// 订单价格
// long total_fee = (long) (1);
// 订单
packageParams.add(new BasicNameValuePair("spbill_create_ip", "127.0.0.1"));
packageParams.add(new BasicNameValuePair("total_fee", price));
// Log.e("sjdfajsadf", "==============="+price );
// 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 new String(xmlstring.toString().getBytes(), "ISO8859-1");//这句加上就可以了吧xml转码下
// return xmlstring;
} catch (Exception e) {
// Log.e(TAG, "genProductArgs fail, ex = " + e.getMessage());
return null;
}
}
public Map decodeXml(String content) {
try {
Map xml = new HashMap();
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 genPackageSign(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(API_KEY);
String packageSign = MD5.getMessageDigest(sb.toString().getBytes())
.toUpperCase();
Log.e("orionStringBuilder", sb.toString());
Log.e("orionAppMd5", packageSign);
return packageSign;
}
private String toXml(List params) {
StringBuilder sb = new StringBuilder();
sb.append("");
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("");
Log.e("orionsdsd", sb.toString());//new String(sb2.toString().getBytes(), "ISO8859-1")
return sb.toString();
}
/**
* 订单号信息
*
* @return
*/
private String genOutTradNo(String orderNos) {
// Random random = new Random();
return MD5.getMessageDigest(String.valueOf(orderNos).getBytes());
}
}
还有使用微信支付,一定要在自己项目里新建一个位置为wxapi,还要新建WXPayEntryActivity这样一个类,
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import com.lvgou.distribution.utils.MyToast;import android.widget.Toast;
import com.lvgou.distribution.R;
import com.lvgou.distribution.activity.BaseActivity;
import com.lvgou.distribution.activity.RechargeRecordListActivity;
import com.lvgou.distribution.presenter.TuanbiExchangePresenter;
import com.lvgou.distribution.utils.TGmd5;
import com.lvgou.distribution.view.GroupView;
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import org.greenrobot.eventbus.EventBus;
/**
* Created by Administrator on 2017/4/11.
*/
public class WXPayEntryActivity extends BaseActivity implements IWXAPIEventHandler, GroupView {
private TuanbiExchangePresenter tuanbiExchangePresenter;
private static final String TAG = "MicroMsg.SDKSample.WXPayEntryActivity";
/**
* 微信支付业务:入参app_id
*/
public static final String WXAPPID = "";
private IWXAPI api;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pay_result);
tuanbiExchangePresenter = new TuanbiExchangePresenter(this);
api = WXAPIFactory.createWXAPI(this, WXAPPID);
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) {
int errCode = resp.errCode;
if (errCode == 0) {
//0 成功 展示成功页面
// MyToast.makeText(this, "支付成功", Toast.LENGTH_SHORT).show();
/*Intent intent = new Intent(Constant.ACTION_NAME);
sendBroadcast(intent);*/
showLoadingProgressDialog(this, "");
String logid = mcache.getAsString("wxlogid");
String sign = TGmd5.getMD5(logid + "1" + "-");
tuanbiExchangePresenter.doAlipay(logid, "1", "-", sign);
} else if (errCode == -1) {
//-1 错误 可能的原因:签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常等。
MyToast.makeText(this, "支付失败", Toast.LENGTH_SHORT).show();
showLoadingProgressDialog(this, "");
String logid = mcache.getAsString("wxlogid");
String sign = TGmd5.getMD5(logid + "0" + resp.errStr);
tuanbiExchangePresenter.doAlipay(logid, "0", resp.errStr, sign);
} else if (errCode == -2) {
//-2 用户取消 无需处理。发生场景:用户不支付了,点击取消,返回APP。
MyToast.makeText(this, "取消支付", Toast.LENGTH_SHORT).show();
finish();
}
}
@Override
public void OnFamousSuccCallBack(String state, String respanse) {
closeLoadingProgressDialog();
// MyToast.makeText(this, "=" + respanse, Toast.LENGTH_SHORT).show();
// Log.e("kjhaskfhs", "===========" + respanse);
openActivity(RechargeRecordListActivity.class);
EventBus.getDefault().post("rechargesuccess");
finish();
// finish();
}
@Override
public void OnFamousFialCallBack(String state, String respanse) {
closeLoadingProgressDialog();
// Log.e("kjhaskfhs", "**********" + respanse);
// MyToast.makeText(this, "*" + respanse, Toast.LENGTH_SHORT).show();
}
@Override
public void closeProgress() {
}
@Override
public void showProgress() {
}
}