Android app支付-支付宝

来源:互联网 发布:sql添加新字段 编辑:程序博客网 时间:2024/06/02 12:59

前言:

银联、微信支付都已经讲解过,今天写的是支付宝支付,支付宝支付应该是比较常用的了,在2016年8月份以后在支付宝平台申请得App支付都使用2.0的了,要搞清楚,不要导错包了。

一.支付宝支付资料下载和开发文档。

1.支付宝支付的开发文档:点击打开链接

 2.支付宝sdk下载地址:点击打开链接

 

二.支付宝支付流程图:



三.支付宝资源导入和配置

 1.把alipaySdk-20161222.jar复制到libs目录下,并添加依赖.

  2.在AndroidManifest配置权限和配置支付宝控件。

<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            android:name="com.alipay.sdk.app.H5AuthActivity"            android:configChanges="orientation|keyboardHidden|navigation"            android:exported="false"            android:screenOrientation="behind"            android:windowSoftInputMode="adjustResize|stateHidden" />



四.前期工作准备好,开始接入代码

1.订单数据的生成(这步可以在服务端完成,也可以在客户端)

在支付宝的demo有一个OrderInfoUtil2_0工具类,我们可以拷贝到我们自己的项目,该类是用来生成订单的。这个工具类,我进行了改动,可能跟支付宝Demo的不一样.

       /** * 构造支付订单参数列表 * @param app_id * @return */public static Map<String, String> buildOrderParamMap(String title,String body,String amount) {Map<String, String> keyValues = new HashMap<String, String>();keyValues.put("app_id", AppId)keyValues.put("biz_content", "{\"timeout_express\":\"30m\",\"product_code\":\"QUICK_MSECURITY_PAY\",\"total_amount\":\""+amount+"\",\"subject\":\""+title+"\",                                       \"body\":\""+body+"\",\"out_trade_no\":\"" + getOutTradeNo()+ "\"}");keyValues.put("charset", "utf-8");keyValues.put("method", "alipay.trade.app.pay");keyValues.put("notify_url", "这里填写支付宝支付成功的回调地址,需要服务端提供");keyValues.put("sign_type", "RSA");keyValues.put("timestamp", "2016-07-29 16:55:53");//这个日期可以自己生成keyValues.put("version", "1.0");return keyValues;}        /** * 构造支付订单参数信息 *  * @param map * 支付订单参数 * @return */public static String buildOrderParam(Map<String, String> map) {List<String> keys = new ArrayList<String>(map.keySet());StringBuilder sb = new StringBuilder();for (int i = 0; i < keys.size() - 1; i++) {String key = keys.get(i);String value = map.get(key);sb.append(buildKeyValue(key, value, true));sb.append("&");}String tailKey = keys.get(keys.size() - 1);String tailValue = map.get(tailKey);sb.append(buildKeyValue(tailKey, tailValue, true));return sb.toString();}/** * 拼接键值对 *  * @param key * @param value * @param isEncode * @return */private static String buildKeyValue(String key, String value, boolean isEncode) {StringBuilder sb = new StringBuilder();sb.append(key);sb.append("=");if (isEncode) {try {sb.append(URLEncoder.encode(value, "UTF-8"));} catch (UnsupportedEncodingException e) {sb.append(value);}} else {sb.append(value);}return sb.toString();}/** * 对支付参数信息进行签名 *  * @param map *            待签名授权信息 *  * @return */public static String getSign(Map<String, String> map, String rsaKey) {List<String> keys = new ArrayList<String>(map.keySet());// key排序Collections.sort(keys);StringBuilder authInfo = new StringBuilder();for (int i = 0; i < keys.size() - 1; i++) {String key = keys.get(i);String value = map.get(key);authInfo.append(buildKeyValue(key, value, false));authInfo.append("&");}String tailKey = keys.get(keys.size() - 1);String tailValue = map.get(tailKey);authInfo.append(buildKeyValue(tailKey, tailValue, false));String oriSign = SignUtils.sign(authInfo.toString(), rsaKey);String encodedSign = "";try {encodedSign = URLEncoder.encode(oriSign, "UTF-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}return "sign=" + encodedSign;}/** * 要求外部订单号必须唯一。 * @return */private static String getOutTradeNo() {SimpleDateFormat format = new SimpleDateFormat("MMddHHmmss", Locale.getDefault());Date date = new Date();String key = format.format(date);Random r = new Random();key = key + r.nextInt();key = key.substring(0, 15);return key;}


2.调用buildOrderParamMap方法,传入标题,描述,金额构建订单。
Map<String, String>  params = OrderInfoUtil2_0.buildOrderParamMap("订单标题","订单描述","金额");
把params 订单拼接成字符串(也可以在后台进行这个操作),注意,这里有个编码问题,在转成字符串时,会进行UTF-8编码,如果前端进行编码,服务端就无需再转码,注意,不然会出错。

String orderParam = OrderInfoUtil2_0.buildOrderParam(params);

3.把orderParam传给后台进行加签.(加签要放在服务端进行,不然很容易泄漏信息)


4.后台会返回一个加签后的字符串sign(个人命名),生成完整的符合支付宝支付的订单信息.
final String orderInfo = orderParam + "&" + sign;
注意:orderInfo大概是这样的

partner="2088101568358171"&seller_id="xxx@alipay.com"&out_trade_no="0819145412-6177"&subject="测试"&body="测试测试"&total_fee="0.01"¬ify_url="http://notify.msp.hk/notify.htm"&service="mobile.securitypay.pay"&payment_type="1"&_input_charset="utf-8"&it_b_pay="30m"&sign="lBBK%2F0w5LOajrMrji7DUgEqNjIhQbidR13GovA5r3TgIbNqv231yC1NksLdw%2Ba3JnfHXoXuet6XNNHtn7VE%2BeCoRO1O%2BR1KugLrQEZMtG5jmJIe2pbjm%2F3kb%2FuGkpG%2BwYQYI51%2BhA3YBbvZHVQBYveBqK%2Bh8mUyb7GM1HxWs9k4%3D"&sign_type="RSA"


5.最终,服务端会返回加签后的订单信息,我们可以发送一步请求去支付了

Runnable payRunnable = new Runnable() {            @Override            public void run() {                PayTask alipay = new PayTask(PayMentActivity.this);                Map<String, String> result = alipay.payV2(orderInfos, true);                Message msg = new Message();                msg.what = SDK_PAY_FLAG;                msg.obj = result;                mHandler.sendMessage(msg);            }        };// 必须异步调用        Thread payThread = new Thread(payRunnable);        payThread.start();


6.在当前Activity新建一个Handler,用于接收异步的信息

@SuppressLint("HandlerLeak")    private Handler mHandler = new Handler() {        @SuppressWarnings("unused")        public void handleMessage(Message msg) {            switch (msg.what) {                case SDK_PAY_FLAG: {                    @SuppressWarnings("unchecked")                    PayResult payResult = new PayResult((Map<String, String>) msg.obj);                    /**                     对于支付结果,请商户依赖服务端的异步通知结果。同步通知结果,仅作为支付结束的通知。                     */                    String resultInfo = payResult.getResult();// 同步返回需要验证的信息                    String resultStatus = payResult.getResultStatus();                    // 判断resultStatus 为9000则代表支付成功                    if (TextUtils.equals(resultStatus, "9000")) {                        ToastUtil.showShortToast(PayMentActivity.this,"用户支付成功");                    } else if(TextUtils.equals(resultStatus,"6001")){                        ToastUtil.showShortToast(PayMentActivity.this,"用户取消了支付");                    } else {                        ToastUtil.showShortToast(PayMentActivity.this,"用户支付失败");                    }                    break;                }                default:                    break;            }        }        ;    };

注意:java使用的是pack8格式的私钥,私钥不要暴露在客户端。




原创博客,转载请注明:
http://blog.csdn.NET/lgl5785592



                                             
0 0