移动支付-支付宝篇(微信支付见篇尾)


2016年12月26日 补充蚂蚁金服后台账号申请之后需要进行的操作。
蚂蚁金服首页
点进去进入应用页之后点击要开发的应用旁边的查看按钮之后,你会发现有这么些东东
这里写图片描述
这里app开发接口加密一般都是选择RSA加密,具体RSA公私钥申请戳这里
没填写的时候这里是设置按钮,点击,然后填入生成的public_key到这里就可以了
私钥交给服务端生成sign并返回给你。
大坑来了,其实吧,在这里填写偶尔会有点然并卵的感觉,因为,你还要在这里去填写!!!
右上角“更多”旁边被我打了马赛克的地方,鼠标放上面然后点击弹窗中出现的“账户中心”,进入之后是这样的。
这里写图片描述
后台人员口中的安全校验码又是什么鬼呢?
答案在这里
就是文档中的key啦。

这里为什么要着重讲公私钥这些东东呢,应为刚遇到了一个和外公司对接的坑,跳进去爬进去了半天 - -!


第一步:下载官方SDK。

点击这里[下载支付宝开放平台SDK](https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.tLpblb&treeId=193&articleId=104509&docType=1),根据自己的需要下载相应的SDK,并添加到工程依赖里。

第二步:代码实现

在开始代码实现之前,我们应该准备好这样几样资料:
1:商户id 即PARTNER
2:商户收款账号 即SELLER
3:商户私钥,pkcs8格式([这里写链接内容] 即RSA_PRIVATE。生成方式详见(http://www.2cto.com/Article/201308/239148.html))
4:了解支付宝支付的业务交互流程。[这里写链接内容](https://img.alicdn.com/top/i1/LB1d7GlMVXXXXbTXFXXXXXXXXXX)

当准备完成之后,我们可以开始写代码啦:
1:在工程的AndroidManifest.xml中添加以下声明:
<activity
            android:name="com.alipay.sdk.app.H5PayActivity"
            android:configChanges="orientation|keyboardHidden|navigation"
            android:exported="false"
            android:screenOrientation="behind" >
</activity>
<activity
            android:name="com.alipay.sdk.auth.AuthActivity"
            android:configChanges="orientation|keyboardHidden|navigation"
            android:exported="false"
            android:screenOrientation="behind" >
 </activity>

和权限声明

<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" />
2:找到支付的点击事件,点击调用payByZhiFuBao();
    /**
     * 
     * @param subject  商品名
     * @param discrib  对商品的描述
     * @param price    商品价格(支付宝规定商品价格必须精确到0.01)
     */

    private void payByZhiFuBao(String subject, String discrib, String price) {

        if (TextUtils.isEmpty(PayConstant.PARTNER) || TextUtils.isEmpty(PayConstant.RSA_PRIVATE) || TextUtils.isEmpty(PayConstant.SELLER)) {
            new AlertDialog.Builder(this).setTitle("警告").setMessage("需要配置PARTNER | RSA_PRIVATE| SELLER")
                    .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialoginterface, int i) {
                            //
                            finish();
                        }
                    }).show();
            return;
        }
        try {
            /**
             * 从服务端获取sign,将签名过程放在客户端是很不安全的行为。
             *
             * 仅需对sign 做URL编码
             */
            Log.d("OrderConfirmActivity", sign); 
            sign = URLEncoder.encode(sign, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        /**
         * 完整的符合支付宝参数规范的订单信息
         */

        String orderInfo = getOrderInfo(subject, discrib, price);
        Log.d("OrderConfirmActivity", orderInfo.toString());
        final String payInfo = orderInfo + "&sign=\"" + sign + "\"&" + getSignType();

        Runnable payRunnable = new Runnable() {

            @Override
            public void run() {
                // 构造PayTask 对象
                PayTask alipay = new PayTask(OrderConfirmActivity.this);
                // 调用支付接口,获取支付结果
                String result = alipay.pay(payInfo, true);
                Message msg = new Message();
                msg.what = SDK_PAY_FLAG;
                msg.obj = result;
                mHandler.sendMessage(msg);
            }
        };

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

payByZhiFuBao() 要使用到的方法。

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

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

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

        // 商户网站唯一订单号,这里的订单号是服务器生成的唯一订单号,我们直接从服务器拿就可以了
        orderInfo += "&out_trade_no=" + "\"" + mOrderId + "\"";

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

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

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

        // 服务器异步通知页面路径
        orderInfo += "后台给的回调地址";

        // 服务接口名称, 固定值
        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,带上此参数用户将使用授权的账户进行支付
        // decs += "&extern_token=" + "\"" + extern_token + "\"";

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

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

        return orderInfo;
    }
 /**
     * get the sign type we use. 获取签名方式
     */
    private String getSignType() {
        return "sign_type=\"RSA\"";
    }
然后是支付结果的通知,支付宝的通知分为两步,同步的通过handler到我们的主线程中,异步通过getOrderInfo()方法里面填写的异步页面路径通知给后台服务器。
@SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        @SuppressWarnings("unused")
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case SDK_PAY_FLAG: {
                    PayResult payResult = new PayResult((String) msg.obj);
                    /**
                     * 同步返回的结果必须放置到服务端进行验证(验证的规则请看https://doc.open.alipay.com/doc2/
                     * detail.htm?spm=0.0.0.0.xdvAU6&treeId=59&articleId=103665&
                     * docType=1) 建议商户依赖异步通知
                     */
                    String resultInfo = payResult.getResult();// 同步返回需要验证的信息

                    String resultStatus = payResult.getResultStatus();
                    // 判断resultStatus 为“9000”则代表支付成功,具体状态码代表含义可参考接口文档
                    if (TextUtils.equals(resultStatus, "9000")) {
                    } else {
                        // 判断resultStatus 为非"9000"则代表可能支付失败
                        // "8000"代表支付结果因为支付渠道原因或者系统原因还在等待支付结果确认,最终交易是否成功以服务端异步通知为准(小概率状态)
                        Intent intent = new Intent(OrderConfirmActivity.this, ShoppingCartActivity.class);
                        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
                        if (TextUtils.equals(resultStatus, "8000")) {
                            Toast.makeText(OrderConfirmActivity.this, "支付结果确认中", Toast.LENGTH_SHORT).show();
                            startActivity(intent);
                            finish();
                        } else {
                            // 其他值就可以判断为支付失败,包括用户主动取消支付,或者系统返回的错误
                            Toast.makeText(OrderConfirmActivity.this, "支付已取消~", Toast.LENGTH_SHORT).show();
                            startActivity(intent);
                            finish();
                        }
                    }
                    break;
                }
                default:
                    break;
            }
        }
    };

2016年12月26日 添加
第二个项目集成中遇到的坑:
① 三星部分机型上碰到的问题:会报这个权限错误android.permission.INTERACT_ACROSS_USERS_FULL
解决方法:我是先验证当前手机是否是三星手机,然后判断是否有安装支付宝客户端(其他手机型号目前没有碰到过这类情况,即使没安装也会调起网页版登录)。

//常量
public static final String SAMSUNG = "samsung";//三星标识

//写在判断处
String brand = android.os.Build.BRAND.toLowerCase(Locale.ENGLISH);
String manufacturer = android.os.Build.MANUFACTURER.toLowerCase(Locale.ENGLISH);
            if (brand.equals(SAMSUNG) || manufacturer.equals(SAMSUNG)) {
                if (checkAliPayInstalled(activity)) {
                    map.put("payMent", "3");
                } else {
                    showToast("请先安装支付宝");
                }
            }


/**
     * 判断当前是否安装支付宝
     * @param context
     * @return
     */
    public boolean checkAliPayInstalled(Context context) {
        Uri uri = Uri.parse("alipays://platformapi/startApp");
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        ComponentName componentName = intent.resolveActivity(context.getPackageManager());
        return componentName != null;
    }


//然后在AndroidManifast中添加权限
<!-- 适配三星加入的权限 -->
    <permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" android:protectionLevel="signature"/>

至此应该能正常调用了,只是到现在还没有弄清楚这个权限的作用,后期弄清楚了再加上,如果有知道的大牛也欢迎私信。


微信支付戳这里,新版微信支付流程,作者介绍的很详细。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值