前言:以前只是听开发的朋友们讲过微信支付比较负责,集成,和调起微信支付是个很大的问题,换了一家公司之后,在我的项目中也用到了这个,接下来就讲讲自己的踩坑之路!!!!!!!
项目的微信支付我微调之后,打印微信支付返回的code值,发现一直是-1。(0:成功,-1:失败,2:取消)微信官网上对于支付返回-1是这样的描述的,可能的原因:签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常等。这么坑。反复尝试,发现网上有说清除微信的缓存(不是项目是微信)好使的清况,于是清除微信缓存一试,神一般的好使了,激动中第二次尝试又失败了,然后又清除缓存,又成功,第二次又失败,陷入深深的沉思。虽然失败但是知道最起码是可以支付的,那么流程及代码就没有问题,于是又检查,百度,因为也是第一次做微信支付,去看了下开发者中心,发现IOS只需要一个Bundle ID(IOS应用唯一标识,包名),而Android需要包名以及应用签名,于是想会不会是应用签名的问题,那么应用签名是什么呢,是由微信提供的一个第三方生成应用签名的工具,安装到手机中,输入自己对应的本个项目的包名,自动生成的一段字符串,开发者中心所填的应用签名与当前运行的情况要一样,就是说有调试时的应用签名跟正式时的应用签名,总之,要对应上。首先,先用工具输入包名生成自己的应用签名,对比后发现不一样,改过应用签名之后,果然,微信支付可以顺利支付了。啊~呼~长~
还有的情况,需要打包后进行微信支付的测试。总之,具体问题看自己的项目,各种问题都可能出现的,具体情况具体分析,遇到问题不要慌,保持一个好的心态。但愿能帮到你。
签名工具下载地址:
https://open.weixin.qq.com/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android.apk
微信支付参考网站:
http://blog.youkuaiyun.com/qq_16131393/article/details/52277708
微信开发平台:
准备工作:
接入流程:
到微信开放平台添加移动应用,申请权限
到微信开放平台注册开发者账号,并添加应用,申请支付权限,等待审核,需要提前做,审核需要时间,一般在7个工作日内。
获得参数配置:
APPID appid
微信支付商户号 mch_id
API秘钥 key
Appsecret secret
后台设置:
应用签名,应用包名
注意事项:
1.开发者平台ID要和当前开发的appID一致
2.交易预支付会话的PrayPayId必须要保证正确
3.最后的签名,这个签名是经过服务器处理之后的二次签名
4.需要在manifest中注册 WXPayEntryActivity 需要注意一定要在项目的包名.wxapi.WXPayEntryActivity
例如我的项目包名为L:com.bj.home.smartbuilding
则正确写法应为如下目录
5.接下来最主要的步骤,在调用之前
一定要以动态广播形式注册微信支付api (如果不注册,将不能正常调起微信支付的界面)
public class AppRegister extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { final IWXAPI wxapi = WXAPIFactory.createWXAPI(context, null); // 将该app注册到微信 wxapi.registerApp(Constant.WE_PAY_APP_ID); } } 如何处理微信支付的过渡页面
1.在配置文件中设置微信的WXPayEntryActivity 为透明状态(主要解决支付出现白屏,闪屏,或者黑屏的问题)
2.避免在此Actvity做耗时操作,可以采用回调接口实现(callBack),或者使用EventBus事件处理当前任务内容
项目:
(1).导入微信的libs包libammsdk.jar;
(2).有网站说测试时使用weixinDemo中的debug_keystore;(具体看自己,我没有用)
(3).接入微信支付的时候一定要反复检查自己的参数(key 值),有在代码中写死的秘钥,id那些的。
后天返回数据的时候,有个签名一定是二次加密过的,微信返回的时候会加密,然后后台再次加密。
1.首先点击微信支付时,先判断是否安装微信及当前版本是否支持微信支付
/**
* 检查微信版本是否支持微信支付
*
* @return boolean
*/
public static boolean isWXAppSupportAPI() {
return BaseApplication.getInstance().getWxapi().getWXAppSupportAPI() >= Build.PAY_SUPPORTED_SDK_INT;
}
/**
* 检查微信是否安装
*
* @return
*/
public static boolean isWXAppInstalled() {
return BaseApplication.getInstance().getWxapi().isWXAppInstalled();
}
2.微信支付具体的参数可以写在APP端,也可以后台返回
这是微信支付的工具类,方法传入的是发起微信支付的请求参数,以及一个接口,该接口用来销毁Activity
public class WeixpayUtil {
private static WXResultBean wxResultBean;
/**
* 支付的方法
*/
public static void pay(String result, IOnWxPayResultListener listener) {
Gson gson=new Gson();
wxResultBean = gson.fromJson(result, WXResultBean.class);
int code = wxResultBean.getCode();
if(code==1){
PayReq req = new PayReq();
req.appId = wxResultBean.getAppid();//微信开放平台审核通过的应用APPID
req.partnerId = wxResultBean.getPartnerid();//微信支付分配的商户号
req.prepayId = wxResultBean.getPrepayid();//预支付交易会话ID, 微信返回的支付交易会话ID
req.nonceStr = wxResultBean.getNoncestr();//随机字符串,不长于32位。推荐随机数生成算法
req.timeStamp = wxResultBean.getTimestamp();//时间戳,请见接口规则-参数规定
req.packageValue = wxResultBean.getPackageX();//默认的Sign=WXpay
req.sign = wxResultBean.getSign();//签名,详见签名生成算法
// 在支付之前,如果应用没有注册到微信,应该先调用IWXMsg.registerApp将应用注册到微信
BaseApplication.getInstance().getWxapi().sendReq(req);
if (listener != null) {
listener.wxpayLaunch();
}
} else {
ToastUtil.show(UiUtil.getContext(), "微信支付失败");
}
}
/**
* 检查微信版本是否支持微信支付
*
* @return boolean
*/
public static boolean isWXAppSupportAPI() {
return BaseApplication.getInstance().getWxapi().getWXAppSupportAPI() >= Build.PAY_SUPPORTED_SDK_INT;
}
/**
* 检查微信是否安装
*
* @return
*/
public static boolean isWXAppInstalled() {
return BaseApplication.getInstance().getWxapi().isWXAppInstalled();
}
/**
* 调用该接口将当前Activity销毁;
*/
public interface IOnWxPayResultListener {
public abstract void wxpayLaunch();
}
}
3.BaseApplication中的操作
//IWXAPI 是第三方app和微信通信的openapi接口
public IWXAPI wxApi;
/**
* 注册应用到微信 AppData.WEIX_APP_ID是APPID,
*/
public IWXAPI getWxapi() {
if (wxApi == null) {
wxApi = WXAPIFactory.createWXAPI(getContext(), AppData.WEIX_APP_ID);
wxApi.registerApp(AppData.WEIX_APP_ID);
}
return wxApi;
}
4.WXEntryActivity,这个好像是必须的Activity,类名不能改
/**
* 微信客户端回调activity示例
*/
public class WXEntryActivity extends WechatHandlerActivity {
/**
* 处理微信发出的向第三方应用请求app message
* <p/>
* 在微信客户端中的聊天页面有“添加工具”,可以将本应用的图标添加到其中
* 此后点击图标,下面的代码会被执行。Demo仅仅只是打开自己而已,但你可
* 做点其他的事情,包括根本不打开任何页面
*/
public void onGetMessageFromWXReq(WXMediaMessage msg) {
Intent iLaunchMyself = getPackageManager().getLaunchIntentForPackage(getPackageName());
startActivity(iLaunchMyself);
}
/**
* 处理微信向第三方应用发起的消息
* <p/>
* 此处用来接收从微信发送过来的消息,比方说本demo在wechatpage里面分享
* 应用时可以不分享应用文件,而分享一段应用的自定义信息。接受方的微信
* 客户端会通过这个方法,将这个信息发送回接收方手机上的本demo中,当作
* 回调。
* <p/>
* 本Demo只是将信息展示出来,但你可做点其他的事情,而不仅仅只是Toast
*/
public void onShowMessageFromWXReq(WXMediaMessage msg) {
if (msg != null && msg.mediaObject != null
&& (msg.mediaObject instanceof WXAppExtendObject)) {
WXAppExtendObject obj = (WXAppExtendObject) msg.mediaObject;
Toast.makeText(this, obj.extInfo, Toast.LENGTH_SHORT).show();
}
}
}
5.微信支付回调的Activity,WXPayEntryActivity,类名不能改
AndroidManifest文件中配置
<!-- 微信支付回调页面 -->
<activity
android:name="com.bee.hjzr.wxapi.WXPayEntryActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:exported="true"
android:launchMode="singleTop"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Light.NoTitleBar" />
/**
* 微信客户端回调activity
*/
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler, View.OnClickListener {
private TextView tvwxpaycomplete;
private ImageView ivpayicon;
private TextView tvpaystatus;
private TextView tvcontinuebuy;
private TextView tvpaylist;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wxpay_entry);
initialize();
initEvent();
BaseApplication.getInstance().getWxapi().handleIntent(getIntent(), this);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
BaseApplication.getInstance().getWxapi().handleIntent(intent, this);
}
@Override
public void onReq(BaseReq baseReq) {
}
@Override
public void onResp(BaseResp baseResp) {
//返回的信息,弹框展示,什么都可以的
if (baseResp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
wxPayResult(baseResp.errCode,baseResp.transaction);
}
}
private void initialize() {
tvwxpaycomplete = (TextView) findViewById(R.id.tv_wxpay_complete);
tvpaystatus = (TextView) findViewById(R.id.tv_pay_status);
ivpayicon = (ImageView) findViewById(R.id.iv_pay_icon);
tvcontinuebuy = (TextView) findViewById(R.id.tv_continue_buy);
tvpaylist = (TextView) findViewById(R.id.tv_pay_list);
}
private void initEvent() {
tvwxpaycomplete.setOnClickListener(this);
tvcontinuebuy.setOnClickListener(this);
tvpaylist.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.tv_wxpay_complete:
break;
case R.id.tv_continue_buy:
Intent intent = new Intent(this, ShoppingCartActivity.class);
startActivity(intent);
break;
case R.id.tv_pay_list:
Intent intent1 = new Intent(this, OrderTotalListActivity.class);
startActivity(intent1);
break;
}
this.finish();
}
private void wxPayResult(int status,String msg) {
System.out.println("111:::::status::::"+status);
ToastUtil.showShort(WXPayEntryActivity.this,"status::"+status);
switch (status) {
case 0://支付成功
ivpayicon.setImageResource(R.mipmap.pay_complete);
tvpaystatus.setText(UiUtil.getContext().getString(R.string.zhifubao_pay_success));
break;
case -1: //支付失败
ivpayicon.setImageResource(R.mipmap.pay_failed);
tvpaystatus.setText(UiUtil.getContext().getString(R.string.zhifubao_pay_failed));
//tvpaystatus.setTextColor(BaseApplication.getContext().getColor(R.color.color_e00032));
break;
case -2://取消支付
ivpayicon.setImageResource(R.mipmap.pay_cancel);
tvpaystatus.setText(UiUtil.getContext().getString(R.string.cancle_pay));
//tvpaystatus.setTextColor(BaseApplication.getContext().getColor(R.color.color_54676E));
break;
}
}
}
我的布局,一个简单的页面展示,成功失败与取消
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/iv_wxpay_finish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="@dimen/x16"
android:src="@mipmap/icon_back" />
<TextView
android:layout_width="wrap_content"
android:layout_height="?android:attr/actionBarSize"
android:layout_centerInParent="true"
android:gravity="center"
android:minHeight="?android:attr/actionBarSize"
android:text="@string/weixin_payway"
android:textColor="@color/color_333333"
android:textSize="@dimen/sp18"
android:textStyle="bold" />
<TextView
android:id="@+id/tv_wxpay_complete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_gravity="center"
android:paddingBottom="@dimen/x10"
android:paddingLeft="@dimen/x20"
android:paddingRight="@dimen/x20"
android:paddingTop="@dimen/x10"
android:text="完成"
android:textColor="@color/color_333333"
android:textSize="@dimen/sp16" />
</RelativeLayout>
<View style="@style/line_division_1dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/placeholder"
android:gravity="center"
android:orientation="vertical"
android:padding="@dimen/x56">
<ImageView
android:id="@+id/iv_pay_icon"
android:layout_width="@dimen/x36"
android:layout_height="@dimen/x36"
android:layout_gravity="center"
android:src="@mipmap/pay_complete" />
<TextView
android:id="@+id/tv_pay_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/x18"
android:text="@string/zhifubao_pay_success"
android:textColor="@color/grey_dark"
android:textSize="@dimen/sp16" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/x32"
android:orientation="horizontal"
android:paddingLeft="@dimen/x48"
android:paddingRight="@dimen/x48">
<TextView
android:id="@+id/tv_continue_buy"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/x56"
android:layout_weight="1"
android:background="@drawable/btn_style_alert_dialog_sure"
android:gravity="center"
android:padding="@dimen/x8"
android:text="继续购物"
android:textSize="@dimen/sp14" />
<TextView
android:id="@+id/tv_pay_list"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/btn_style_alert_dialog_sure"
android:gravity="center"
android:padding="@dimen/x8"
android:text="查看订单"
android:textSize="@dimen/sp14" />
</LinearLayout>
</LinearLayout>
6.微信支付的实体类
/**
* 微信支付结果的实体类
* Created by mayupu on 2016/12/05.
*/
public class WXResultBean implements Serializable {
/**
* appid : wx2a77de3a7ccaff9d
* noncestr : z9jq2ow2f1p89zqk8gw8ofe04c8dokeb
* package : Sign=WXPay
* partnerid : 1321646901
* prepayid : wx20161205145019b5dc62af0f0410249199
* sign : FFF2DC94D4855D865A88878DC04E1312
* timestamp : 1480920619
*/
private String appid;
private String noncestr;
@SerializedName("package")
private String packageX;
private String partnerid;
private String prepayid;
private String sign;
private String timestamp;
private int code;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getAppid() {
return appid;
}
public void setAppid(String appid) {
this.appid = appid;
}
public String getNoncestr() {
return noncestr;
}
public void setNoncestr(String noncestr) {
this.noncestr = noncestr;
}
public String getPackageX() {
return packageX;
}
public void setPackageX(String packageX) {
this.packageX = packageX;
}
public String getPartnerid() {
return partnerid;
}
public void setPartnerid(String partnerid) {
this.partnerid = partnerid;
}
public String getPrepayid() {
return prepayid;
}
public void setPrepayid(String prepayid) {
this.prepayid = prepayid;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public String getTimestamp() {
return timestamp;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
}