1.  配置清单文件


uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<activity

    android:name="com.alipay.sdk.app.H5PayActivity"
    android:configChanges="orientation|keyboardHidden|navigation|screenSize"
    android:exported="false"
    android:screenOrientation="behind"
    android:windowSoftInputMode="adjustResize|stateHidden" >
</activity>


/**
 * create the order info. 创建订单信息
 *
 */
private String getOrderInfo(String subject, String body, String price) {

// 签约合作者身份ID
    String orderInfo = "partner=" + "\"" + PARTNER + "\"";

    // 签约卖家支付宝账号
    orderInfo += "&seller_id=" + "\"" + SELLER + "\"";

    // 商户网站唯一订单号
    orderInfo += "&out_trade_no=" + "\"" + getOutTradeNo() + "\"";

    // 商品名称
    orderInfo += "&subject=" + "\"" + subject + "\"";

    // 商品详情
    orderInfo += "&body=" + "\"" + body + "\"";

    // 商品金额
    orderInfo += "&total_fee=" + "\"" + price + "\"";

    // 服务器异步通知页面路径,由支付宝服务器直接通知商家服务器的地址
    orderInfo += "¬ify_url=" + "\"" + "http://api" + "\"";

    // 服务接口名称, 固定值
    orderInfo += "&service=\"mobile.securitypay.pay\"";

    // 支付类型, 固定值
    orderInfo += "&payment_type=\"1\"";

    // 参数编码, 固定值
    orderInfo += "&_input_charset=\"utf-8\"";

    // 设置未付款交易的超时时间
    // 默认30分钟,一旦超时,该笔交易就会自动被关闭。
    // 取值范围:1m~15d。
    // m-分钟,h-小时,d-天,1c-当天(无论交易何时创建,都在0点关闭)。
    // 该参数数值不接受小数点,如1.5h,可转换为90m。
    orderInfo += "&it_b_pay=\"30m\"";

    // extern_token为经过快登授权获取到的alipay_open_id,带上此参数用户将使用授权的账户进行支付
    // orderInfo += "&extern_token=" + "\"" + extern_token + "\"";

    // 支付宝处理完请求后,当前页面跳转到商户指定页面的路径,可空
    orderInfo += "&return_url=\"m.alipay.com\"";

    // 调用银行卡支付,需配置此参数,参与签名, 固定值 (需要签约《无线银行卡快捷支付》才能使用)
    // orderInfo += "&paymethod=\"expressGateway\"";

    return orderInfo;
}


/**
         * 签名逻辑放在服务端,因为APP容易被反编译,所以应由服务端签名,通过接口,这里暂时放到客户端,实际开发要放到服务端
         */
        String sign = sign(orderInfo);

        try {
            sign = URLEncoder.encode(sign, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
/**
         * 完整的符合支付宝参数规范的订单信息
         */
        final String payInfo = orderInfo + "&sign=\"" + sign + "\"&" + getSignType();
        Runnable payRunnable = new Runnable() {
@Override
            public void run() {
//构造PayTask对象
                PayTask alipay = new PayTask(MainActivity.this);
                //调用支付接口  获取支付结果
                String result = alipay.pay(payInfo, true);
                Message msg = new Message();
                msg.what = SDK_PAY_FLAG;
                msg.obj = result;

            }
        };
        //必须异步调用
        Thread payThread = new Thread(payRunnable);
        payThread.start();

    }
});


private Handler mHandler = new Handler() {
@Override
    public void handleMessage(Message msg) {
super.handleMessage(msg);
        switch (msg.what) {
case SDK_PAY_FLAG: {
                PayResult payResult = new PayResult((String) msg.obj);
                String resultInfo = payResult.getResult();//同步返回需要验证的信息
                String resultStatus = payResult.getResultStatus();
                if (TextUtils.equals(resultStatus, "9000")) {
//这里异步通知服务器支付状态,让服务器能进行校验(这里上传给服务器一份,支付宝服务器给服务器一份)
                    Toast.makeText(MainActivity.this, "支付成功", Toast.LENGTH_SHORT).show();
                } else {
// 判断resultStatus 为非"9000"则代表可能支付失败
                    // "8000"代表支付结果因为支付渠道原因或者系统原因还在等待支付结果确认,最终交易是否成功以服务端异步通知为准(小概率状态)
                    if (TextUtils.equals(resultStatus, "8000")) {
                        Toast.makeText(MainActivity.this, "支付结果确认中", Toast.LENGTH_SHORT).show();

                    } else {
// 其他值就可以判断为支付失败,包括用户主动取消支付,或者系统返回的错误
                        Toast.makeText(MainActivity.this, "支付失败", Toast.LENGTH_SHORT).show();

                    }

                }
break;
            }
default:
break;
        }
    }
};