android 微信支付

微信开放平台有demo和开发文档,但是对于我第一次写支付真的不够细致、具体好吗!


第一步先申请一个APPID,然后添加依赖包--》libammsdk.jar,以及WXPayEntryActivity类。类的路径为  包名.wxapi。下载的demo里都有这些内容。记得要在清单中注册

<activity
    android:name=".wxapi.WXPayEntryActivity"
    android:exported="true"
    android:launchMode="singleTop" />


使用微信支付前要将APP注册到微信

private IWXAPI msgApi;
HashMap<String, String> content = new HashMap<String, String>();
private boolean isPay = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


    // 将该app注册到微信
    msgApi = WXAPIFactory.createWXAPI(App.getInstance(), null);

}

要使用到的一些方法(全是博主在网上找的,忘记出处了。)

/**
 * 获取本地IP的方法
 */
public String getLocalIpAddress() {
    try {
        for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
            NetworkInterface intf = en.nextElement();
            for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                InetAddress inetAddress = enumIpAddr.nextElement();
                if (!inetAddress.isLoopbackAddress()) {
                    return inetAddress.getHostAddress().toString();
                }
            }
        }
    } catch (SocketException ex) {
    }
    return null;
}


/**
 * 获取WIFI的IP
 */
private String getWifiIp() {
    //获取wifi服务
    WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
    //判断wifi是否开启
    if (!wifiManager.isWifiEnabled()) {
        wifiManager.setWifiEnabled(true);
    }
    WifiInfo wifiInfo = wifiManager.getConnectionInfo();
    int ipAddress = wifiInfo.getIpAddress();
    String ip = intToIp(ipAddress);
    return ip;
}

private String intToIp(int i) {

    return (i & 0xFF) + "." +
            ((i >> 8) & 0xFF) + "." +
            ((i >> 16) & 0xFF) + "." +
            (i >> 24 & 0xFF);
}
 
/**
 * 生成随机字符串
 */
public static String genOutTradNo() {
    Random random = new Random();
    return MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());
}

/**
 * 签名工具
 */

public static String genAppSign(Map<String, String> params) {
    Map<String, String> sortMap = new TreeMap<String, String>(params);
    StringBuilder sb = new StringBuilder();

    for (Map.Entry<String, String> s : sortMap.entrySet()) {
        String k = s.getKey();
        String v = s.getValue();
        if ("".equals(v) || v == null) {// 过滤空值
            continue;
        }
        sb.append(k).append("=").append(v).append("&");
    }
    sb.append("key=");
    sb.append(App.API_KEY);
    String appSign = MD5.md5(sb.toString()).toUpperCase();
    LogOut("=====AppSign=====", appSign);
    return appSign;
}
/* public static String md5(String string) {
     byte[] encodeBytes = null;
     try {
         encodeBytes = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8"));
     } catch (NoSuchAlgorithmException neverHappened) {
         throw new RuntimeException(neverHappened);
     } catch (UnsupportedEncodingException neverHappened) {
         throw new RuntimeException(neverHappened);
     }

     return toHexString(encodeBytes);
 }*/

/**
 * 转换成xml
 */
public static String toXml(Map<String, String> params) {
    StringBuilder sb = new StringBuilder();
    sb.append("<xml>");
    for (Map.Entry<String, String> s : params.entrySet()) {
        sb.append("<" + s.getKey() + ">");
        sb.append(s.getValue());
        sb.append("</" + s.getKey() + ">");
    }
    sb.append("</xml>");

    LogOut("=====xml=====", sb.toString());
    return sb.toString();
}

/**
 * 解析xml
 */
public static HashMap<String, String> decodeXml(String content) {
    try {
        HashMap<String, String> xml = new HashMap<String, String>();
        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) {
        LogOut("orion", e.toString());
    }
    return null;

}
/*将字符串转为时间戳*/
public static long getStringToDate(String time) {
    sf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
    Date date = new Date();
    try{
        date = sf.parse(time);
    } catch(ParseException e) {
        e.printStackTrace();
    }
    return date.getTime();
}

public static long getTimeStr(){
    return (getStringToDate(getCurrentDate())/1000);
}


准备工作做好就可以开始写支付代码了,根据文档先是统一下单。因为要签名,所以先将除签名外的字段都添加到HashMap中。订单号是自己设置的,我是设置成了时间戳+10位随机数。这里尤其要注意的一点是notify_url,这是接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。这个地址很重要,微信支付结果全部会返到这个地址,如果在APP端接收会出现一些意料之外的后果。所以,一定要在后台处理微信回调结果!一定要在后台处理!后台处理!重要的事情说三遍!地址让后台给你。


content.clear();// 每次使用前记得要清空
String ip = getWifiIp();
if ("".equals(ip)) {
    ip = getLocalIpAddress();
}
content.put("body", "等级提升");
content.put("total_fee", 1 + "");// 微信以分为单位
content.put("appid", App.API_ID);// 申请的应用ID
content.put("mch_id", App.MCH_ID);// 商户号
content.put("nonce_str", CommTools.genOutTradNo());// 随机字符串
String orderNum = CommTools.getTimeStr() + CommTools.genOutTradNo().substring(0, 9);
content.put("out_trade_no", orderNum);// 商户订单号
content.put("spbill_create_ip", ip);
content.put("notify_url", "http://www.weixin.qq.com/wxpay/pay.php");// 通知地址
content.put("trade_type", "APP");

然后调用写好的签名工具生成签名,开放平台有签名算法,并且有校验签名是否正确的工具。将生成的签名也放入map中,然后转换成xml。

String sign = CommTools.genAppSign(content);
content.put("sign", sign);
String xml = CommTools.toXml(content);

我的项目用的xutils3.0,已经都封装好了,这里我就直接使用它的post方法,将xml添加进去,发送给微信给出的

URL地址:https://api.mch.weixin.qq.com/pay/unifiedorder

回调成功,使用decodeXml()解析微信返回的数据,获得prepayid,实例化一个map,存取数据生成签名,调起微信支付接口

String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
requestParams = new RequestParams(url);
requestParams.setBodyContent(xml);
x.http().post(requestParams, new Callback.CommonCallback<String>() {
    @Override
    public void onSuccess(String result) {
        LogOut(result);
        Map<String, String> xml = CommTools.decodeXml(result);
        PayReq request = new PayReq();
        HashMap<String, String> map = new HashMap<String, String>();
        request.appId = App.API_ID;
        map.put("appid", App.API_ID);

        request.partnerId = xml.get("mch_id");// 商户号
        map.put("partnerid", xml.get("mch_id"));

        request.prepayId = xml.get("prepay_id");// 预支付交易会话ID
        map.put("prepayid", xml.get("prepay_id"));

        request.packageValue = "Sign=WXPay";// 扩展字段
        map.put("package", "Sign=WXPay");

        request.nonceStr = xml.get("nonce_str");
        map.put("noncestr", xml.get("nonce_str"));

        String time = CommTools.getTimeStr() + "";
        request.timeStamp = time;
        map.put("timestamp", time);

        request.sign = CommTools.genAppSign(map);
        msgApi.registerApp(App.API_ID);
        msgApi.sendReq(request);
        isPay = true;

    }

    @Override
    public void onError(Throwable ex, boolean isOnCallback) {

    }

    @Override
    public void onCancelled(CancelledException cex) {

    }

    @Override
    public void onFinished() {

    }
});

在WXPayEntryActivity类中获取返回值并保存在本地,setConfig()是我封装好的方法,你也可以使用SharedPreferences保存值,我的博客中有关于SharedPreferences的使用。最后记得finish()

public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {

    private IWXAPI api;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        api = WXAPIFactory.createWXAPI(this, App.API_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) {
            setConfig("resp", resp.errCode + "");// 将返回结果保存在本地
            finish();

        }

    }

}

我写了个对话框用于显示微信支付结果,写在了onResume()方法中

@Override
protected void onResume() {
    super.onResume();
    if (isPay) {

        LayoutInflater inflaterDl = LayoutInflater.from(this);
        FrameLayout layout = (FrameLayout) inflaterDl.inflate(R.layout.dialog_pay_result, null);

        //对话框
        final Dialog dialog = new AlertDialog.Builder(ActivityMyPoints.this).create();
        dialog.show();
        dialog.getWindow().setContentView(layout);

        TextView message = (TextView) layout.findViewById(R.id.message);
        ImageView state = (ImageView) layout.findViewById(R.id.iv_pay_statu);

        switch (Integer.valueOf(getConfig("resp"))) {
            case 0:
                message.setText("支付成功");
                state.setImageResource(R.drawable.pay_success);

                break;
            case -1:
                message.setText("支付失败");
                state.setImageResource(R.drawable.pay_fail);
                break;
            case -2:
                message.setText("取消支付");
                state.setImageResource(R.drawable.pay_fail);
                break;
            default:
                break;
        }

        // 确定按钮
        Button btnOK = (Button) layout.findViewById(R.id.positiveButton);
        btnOK.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                initData();// 刷新界面
                dialog.dismiss();
            }
        });

        isPay = false;

    } else {

    }
}

感兴趣的可以参考我的界面

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/dialog_shape"
    android:clickable="true">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:orientation="vertical">
        <ImageView
            android:id="@+id/iv_pay_statu"
            android:layout_marginTop="20dp"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:scaleType="centerInside"
            android:layout_gravity="center_horizontal"
            android:src="@drawable/pay_success"/>

            <TextView
                android:id="@+id/message"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:layout_margin="10dp"
                android:text="支付成功"
                android:textColor="#333"
                android:textSize="20sp" />

            <Button
                android:id="@+id/positiveButton"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="20dp"
                android:layout_marginRight="20dp"
                android:layout_marginBottom="10dp"
                android:layout_marginTop="20dp"
                android:background="#526CFD"
                android:text="确定"
                android:textColor="#fff"
                android:textSize="16sp" />


    </LinearLayout>

</FrameLayout>

写完了!调试的时候一定要匹配应用签名,很多人直接运行会发现不能跳转到微信,那是因为app有一个debug签名和一个正式签名,一定要确保与开放平台填写的签名、包名保持一致。


获取应用签名的方法  获取应用签名

SharedPreferences存值  SharedPreferences轻量级存储


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值