微信支付踩坑之路

本文分享了安卓项目中集成和调起微信支付的踩坑经验。作者在项目中遇到支付返回 -1 的问题,经排查发现是应用签名不匹配所致。同时介绍了微信支付的准备工作、接入流程、注意事项,还给出了相关代码示例,包括支付工具类、回调处理等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:以前只是听开发的朋友们讲过微信支付比较负责,集成,和调起微信支付是个很大的问题,换了一家公司之后,在我的项目中也用到了这个,接下来就讲讲自己的踩坑之路!!!!!!!

项目的微信支付我微调之后,打印微信支付返回的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

微信开发平台:

https://open.weixin.qq.com/

 

准备工作:

 

接入流程:

 

到微信开放平台添加移动应用,申请权限

 

到微信开放平台注册开发者账号,并添加应用,申请支付权限,等待审核,需要提前做,审核需要时间,一般在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;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值