支付接入流程
官方文档
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_5
项目的应用(AppRegister有什么用?求指导)
1.导入jar包
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419319167&token=&lang=zh_CN
2.清单文件的配置
<!-- 微信支付 -->
<activity
android:name="com.lx.edu.wxapi.WXPayEntryActivity"
android:exported="true"
android:launchMode="singleTop" />
<receiver android:name="com.lx.edu.wxapi.AppRegister" >
<intent-filter>
<action android:name="com.tencent.mm.plugin.openapi.Intent.ACTION_REFRESH_WXAPP" />
</intent-filter>
</receiver>
3.初始化的类
package com.lx.edu.wxapi;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.lx.edu.common.Constant;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.WXAPIFactory;
public class AppRegister extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
final IWXAPI api = WXAPIFactory.createWXAPI(context, null);
api.registerApp(Constant.PAY_WX_APP_ID);
}
}
4.支付的调用类
package com.lx.edu;
import java.util.Map;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.BroadcastReceiver;
/**
*
* @项目名称:LxeduComm
* @类名称:PaymentActivity
* @类描述: 微信支付
* @创建人:sdh
* @创建时间:2015-1-19下午3:05
* @version
*/
public class ServiceOrderActivity extends Activity implements OnClickListener {
protected static final String TAG = "ServiceOrderActivity";
private Context mContext;
private String selectPayment;
private StringBuffer sb;
private PayReq req;
Map<String, String> resultunifiedorder;
private RadioButton radiobtnWXPay;
private RadioButton radiobtnAliPay;
private String payInfo;
private String outTradeNO;
private SharedPreferencesUtil share;
String sign;
String partnerid;
String noncestr;
String package_str;
String prepayid;
String out_trade_no;
String timestamp;
//初始化微信的api对象
final IWXAPI msgApi = WXAPIFactory.createWXAPI(this, null);
private Handler handler = new Handler();
private Runnable runnable = new Runnable() {
public void run() {
payResult();
handler.postDelayed(this, 5000);
}
};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_payment);
mContext = ServiceOrderActivity.this;
init();
radiobtnAliPay.setChecked(true);
// 注册广播 支付成功后发送了广播 这里进行接收
IntentFilter filter = new IntentFilter();
filter.addAction(Constant.ACTION_MESSAGE_WXPAY_SUCCESS);
mContext.registerReceiver(receiver, filter);
}
private void init() {
//注册APPID 这里的appid是注册后拿到的 写死在了配置文件里面
msgApi.registerApp(Constant.PAY_WX_APP_ID);
sb = new StringBuffer();
req = new PayReq();
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btn_pay:
getNetDataForWx(serviceInstId,studentId);
break;
default:
break;
}
}
//微信网络接口调用 后面会贴出接口文档
private void getNetDataForWx(String serviceInstId,String studentId){
final TranLoading loading = new TranLoading(mContext);
loading.show();
RequestParams params = new RequestParams();
params.addBodyParameter(Constant.NET_USERID,
share.getString(Constant.SP_USERID, ""));
params.addBodyParameter(Constant.NET_TOKEN,
share.getString(Constant.SP_TOKEN, " "));
params.addBodyParameter(Constant.NET_STUDENT_ID,studentId);
params.addBodyParameter(Constant.NET_SERVICEINST_ID, serviceInstId);
HttpUtils http = new HttpUtils(Constant.HTTP_TIME_OUT_LONG);
http.send(HttpRequest.HttpMethod.POST, UrlUtis.SERVICE_ORDER_PAY_WX,
params, new RequestCallBack<String>() {
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
try {
JSONObject jsonObject = new JSONObject(
responseInfo.result);
final String success = jsonObject
.getString("success");
Log.e(TAG, jsonObject.toString());
JSONObject ob = new JSONObject(jsonObject
.getString(Constant.NET_OBJ));
sign=ob.getString("sign");
partnerid=ob.getString("partnerid");
noncestr=ob.getString("noncestr");
package_str=ob.getString("package_str");
prepayid=ob.getString("prepayid");
out_trade_no=ob.getString("out_trade_no");
timestamp=ob.getString("timestamp");
if (Constant.NET_ALI_SUCCESS_TRUE.equals(success)) {
payForWX();
} else if (Constant.NET_ALI_SUCCESS_FSLSE
.equals(success)) {
final String msg = jsonObject.getString("msg");
ViewUtil.shortToast(mContext, msg);
}
} catch (JSONException e) {
e.printStackTrace();
}
loading.dismiss();
}
@Override
public void onFailure(HttpException error, String msg) {
loading.dismiss();
ViewUtil.shortToast(mContext,
mContext.getString(R.string.error_net));
}
});
}
// 轮循接口
private void payResult() {
final TranLoading loading = new TranLoading(mContext);
loading.show();
RequestParams params = new RequestParams();
params.addBodyParameter(Constant.NET_OUTTRADENO, outTradeNO);
params.addBodyParameter(Constant.NET_TOKEN,
share.getString(Constant.SP_TOKEN, " "));
HttpUtils http = new HttpUtils(Constant.HTTP_TIME_OUT_LONG);
http.send(HttpRequest.HttpMethod.POST,
UrlUtis.SERVICE_ORDER_PAY_RESULT, params,
new RequestCallBack<String>() {
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
try {
JSONObject jsonObject = new JSONObject(
responseInfo.result);
Log.d(TAG, jsonObject.toString());
JSONObject ob = new JSONObject(jsonObject
.getString(Constant.NET_OBJ));
final String payStatus = ob
.getString(Constant.NET_PAYSTATUS_RESULT);
if (Constant.NET_PAYSTATUS_PAID.equals(payStatus)) {
// 成功
handler.removeCallbacks(runnable);
ViewUtil.shortToast(mContext, mContext
.getString(R.string.pay_success));
} else if (Constant.NET_PAYSTATUS_FAIL
.equals(payStatus)) {
// 失败
ViewUtil.shortToast(mContext, mContext
.getString(R.string.pay_status_fails));
} else {
// 支付中
ViewUtil.shortToast(mContext, mContext
.getString(R.string.pay_be_sure));
}
} catch (JSONException e) {
e.printStackTrace();
}
loading.dismiss();
}
@Override
public void onFailure(HttpException error, String msg) {
loading.dismiss();
ViewUtil.shortToast(mContext,
mContext.getString(R.string.error_net));
}
});
}
// 微信支付
private void payForWX() {
IWXAPI api;
api = WXAPIFactory.createWXAPI(this, Constant.PAY_WX_APP_ID);
PayReq req = new PayReq();
req.appId = Constant.PAY_WX_APP_ID;
req.partnerId = partnerid;
req.prepayId = prepayid;
req.nonceStr = noncestr;
req.timeStamp = timestamp;
req.packageValue = package_str;
req.sign = sign;
req.extData = "app data";
api.sendReq(req);
}
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String wxPay=intent.getStringExtra(Constant.EXTRA_WXPAY);
String action = intent.getAction();
if(Constant.ACTION_MESSAGE_WXPAY_SUCCESS.equals(action)&&Constant.EXTRA_WXPAY_SUCCESS.equals(wxPay)){
CommonUtils.getServiceData(mContext);
ServiceOrderActivity.this.setResult(RESULT_OK, intent.putExtra(
Constant.EXTRA_SERVICE_PAY_SUCCESS,
Constant.EXTRA_SERVICE_PAY_SUCCESS_TRUE));
finish();
}
}
};
public void onDestroy() {
if (mContext != null) {
mContext.unregisterReceiver(receiver);
}
super.onDestroy();
}
}
5,支付回掉
package com.lx.edu.wxapi;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import com.lx.edu.R;
import com.lx.edu.common.Constant;
import com.lx.edu.common.Rules;
import com.lx.edu.common.ViewUtil;
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;
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
private IWXAPI api;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pay_result);
api = WXAPIFactory.createWXAPI(this, Constant.PAY_WX_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) {
//支付成功
ViewUtil.shortToast(WXPayEntryActivity.this, getString(R.string.pay_success));
Intent intent1 = new Intent();
intent1.setAction(Constant.ACTION_MESSAGE_WXPAY_SUCCESS);
intent1.putExtra(
Constant.EXTRA_WXPAY,Constant.EXTRA_WXPAY_SUCCESS);
sendBroadcast(intent1);
} else if (resp.errCode == -2) {
ViewUtil.shortToast(WXPayEntryActivity.this, getString(R.string.pay_fails));
}
else {
ViewUtil.shortToast(WXPayEntryActivity.this, getString(R.string.pay_status_fails));
}
WXPayEntryActivity.this.finish();
}
}
}
微信支付陷阱
1.交互时序图
WXEntryActivity这个回调界面实际上不会影响前面的调起支付的逻辑,这个Activity一定要放到“App包名.wxapi”的package中,否则无法响应回调,
当然别忘了在AndroidManifest.xml中注册。(是根据反射找到的这个类)
首先如果要使用微信支付的话,必须先到微信开放平台注册应用,具体地址为https://open.weixin.qq.com/,注册时需要填应用的包名和签名,注意
这里的签名是App正式版的签名,可以找一个已上线的包或打一个正式包,使用微信提供的工具(签名工具下载地址为https://open.weixin.qq.com/zh_CN
/htmledition/res/dev/download/sdk/Gen_Signature_Android.apk)来获取,获取后填上即可。待审核通过后,会得到一个AppID和AppSecret,AppID
分享和支付都要用到,AppSecret没什么实际用途,此时微信分享能力是直接拥有的,支付能力还要额外申请,其中涉及到财务信息等,最好让公司财务部门去申请,
申请成功后会拿到一个商户id,后面生成sign时会用到。只有所有审核都通过后,才可调用微信支付功能,这点是前提。
测试微信支付时,务必对自己的App做正式签名,因为一开始就在微信平台注册过签名信息,微信SDK会做校验,只有这样才能调起微信分享和微信支付,直接debug版的
包则绝对调不起来,这点务必注意,很多人是跌在这里了!当初做微信分享曾遇到过,所以会很留心,也因为如此,如果微信分享能调起来,微信支付不行,那就不要怀
疑签名问题了
还是签名,网上有人说要注意大小写,这点其实是不必的。在微信开放平台看到审核通过的App的签名是大写的,而用微信签名获取工具获得的则显示小写,这个没关系,
不要贸然改动平台注册信息,不然又可能导致漫长的审核等待,上面也说了,微信分享如可以,那就不是签名问题。
生成sign时特别需要注意,首先将key-value键值对拼成字符串,注意key都要小写,如appid,noncestr,package,partnerid,prepayid,timestamp,key,并且名
字得按上述名称,我们遇到的错误就是因为partnerid写成了partnerId,prepayid写成了PrepayId,当然我们是在服务端写的,如果在客户端生成sign的话,也需要注
意大小写及名称,详细信息请参考官方文档。还有这里的key并非AppID或AppSectet,而是在商户平台设置的,官方描述为“key设置路径:微信商户平台(pay.weixin.qq.com)
>账户设置-->API安全-->密钥设置”。对于noncestr,申请prepayid和生成sign时两次需要用到
req.packageValue=”Sign=WXPay”,一般都是这样写死这个参数值。也有人说写成req.packageValue=”prepay_id=” + prepayid,经测试Android两种写法都是可以
调起微信支付的,至少最新版本SDK是可以的,以后则不清楚,官方也建议写Sign=WXPay。