Android中关于微信支付和支付宝支付

前一段时间公司项目要求实现支付宝支付和微信支付的功能。作为一个入门不是太久的菜鸟,踩了不少坑。官方的demo的文档也是不想吐槽了。
进入正文吧!
1.支付宝支付:
相对于微信支付来说,支付宝正是简单的不得了了。就是那个用户私钥公钥什么的有点麻烦了。
先说第一步:
移步支付宝官网,注册申请。
https://openhome.alipay.com/platform/appManage.htm
有点麻烦的是开发用到的key是pkcs8格式的,要用命令行转一下哦。
命令:
RSA密钥生成命令
生成RSA私钥
openssl>genrsa -out rsa_private_key.pem 1024
生成RSA公钥
openssl>rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
将RSA私钥转换成PKCS8格式
openssl>pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt
加粗部分是你的key文件名称哦。

然后把支付宝那边的某些工具类拷过来,就直接可以开发啦;

  public   void zhifu(String DingDan,String dprice,Context context) {
        if (TextUtils.isEmpty(PARTNER) || TextUtils.isEmpty(RSA_PRIVATE)) {
            new AlertDialog.Builder(context).setTitle("警告").setMessage("需要配置APPID | RSA_PRIVATE")
                    .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialoginterface, int i) {
                            //
                             ((Activity) context).finish();
                        }
                    }).show();
            return;
        }

        /**
         * 这里只是为了方便直接向商户展示支付宝的整个支付流程;所以Demo中加签过程直接放在客户端完成;
         * 真实App里,privateKey等数据严禁放在客户端,加签过程务必要放在服务端完成;
         * 防止商户私密数据泄露,造成不必要的资金损失,及面临各种安全风险;
         *
         * orderInfo的获取必须来自服务端;
         */
        Map<String, String> params = buildOrderParamMap("甬尚鲜定金",dprice+"",DingDan);
        String orderParam = buildOrderParam(params);
        String sign =getSign(params, RSA_PRIVATE);
        final String orderInfo = orderParam + "&" + sign;

        Runnable payRunnable = new Runnable() {

            @Override
            public void run() {
                PayTask alipay = new PayTask((Activity) context);
                Map<String, String> result = alipay.payV2(orderInfo, true);
                // Log.i("msp", result.toString());

                Message msg = new Message();
                msg.what = SDK_PAY_FLAG;
                msg.obj = result;
                mHandler.sendMessage(msg);
            }
        };

        Thread payThread = new Thread(payRunnable);
        payThread.start();
    }
 private static final String PARTNER = "你的使用者ID";
    // 商户收款账号
    private static final String APP_IDD ="你的APPID";
    private final String SELLER = "你的收款账号";
    // 商户私钥,pkcs8格式
    private static final String RSA_PRIVATE ="你的私钥";
    private static final int SDK_PAY_FLAG = 1;
    private static final int SDK_CHECK_FLAG = 2;
    /**
     * get the out_trade_no for an order. 生成商户订单号,该值在商户端应保持唯一(可自定义格式规范)
     *
     */
    private 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;
    }

    private static String Date(){
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
        Date date = new Date();
        String key = format.format(date);
        return key;
    }
  /**
     * 构造支付订单参数列表
     * @param
     * @param
     * @param
     * @return
     */
    public static Map<String, String> buildOrderParamMap(String body,String money,String dindan) {
        Map<String, String> keyValues = new HashMap<>();

        keyValues.put("app_id", APP_IDD);

        keyValues.put("biz_content", "{\"timeout_express\":\"30m\",\"product_code\":\"QUICK_MSECURITY_PAY\",\"total_amount\":\""+money+"\",\"subject\":\""+body+"\",\"body\":"+"{\"purpose\" : \"0\", \"value\" : \""+money+"\",\"UserTel\" : \""+ LocalStorage.get("UserTel").toString()+"\",\"OrderID\" : \""+dindan+"\"}"+",\"out_trade_no\":\"" + dindan+  "\"}");

        keyValues.put("charset", "utf-8");

        keyValues.put("method", "alipay.trade.app.pay");

        keyValues.put("notify_url", "http://120.27.141.95:8225/ashx/alipay_index.ashx");

        keyValues.put("sign_type", "RSA");

        keyValues.put("timestamp", Date());

        keyValues.put("version", "1.0");
        return keyValues;
    }


    /**
     * 构造支付订单参数信息
     *
     * @param map
     * 支付订单参数
     * @return
     */
    public static String buildOrderParam(Map<String, String> map) {
        List<String> keys = new ArrayList<>(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;
    }

 private static boolean isZhiFu;
    private static Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case SDK_PAY_FLAG: {
                    //     PayResult payResult = new PayResult((String) msg.obj);
                    PayResult payResult = new PayResult((Map<String, String>) msg.obj);
                    // 支付宝返回此次支付结果及加签,建议对支付宝签名信息拿签约时支付宝提供的公钥做验签
                    String resultInfo = payResult.getResult();
                    System.out.println(resultInfo + "______________________");
                    String resultStatus = payResult.getResultStatus();
                    System.out.println(resultStatus + "+++++++++++++++++");
                    // 判断resultStatus 为“9000”则代表支付成功,具体状态码代表含义可参考接口文档
                    if (TextUtils.equals(resultStatus, "9000")) {
                        isZhiFu = true;
                        Toast.makeText(context, "支付成功",
                                Toast.LENGTH_SHORT).show();
                        if (isZhiFu) {
                            Intent i = new Intent(context,
                                    MainActivity.class);
                            context.startActivity(i);
                            ((Activity) context).finish();
                        } else {
                            ((Activity) context).finish();
                        }
                    } else {
                        // 判断resultStatus 为非“9000”则代表可能支付失败
                        // “8000”代表支付结果因为支付渠道原因或者系统原因还在等待支付结果确认,最终交易是否成功以服务端异步通知为准(小概率状态)
                        if (TextUtils.equals(resultStatus, "8000")) {
                            Toast.makeText(context, "支付结果确认中",
                                    Toast.LENGTH_SHORT).show();

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

                        }
                    }
                    break;
                }
                case SDK_CHECK_FLAG: {
                    // Toast.makeText(WoDeDingDanXQ.this, "检查结果为:" + msg.obj,
                    // Toast.LENGTH_SHORT).show();
                    break;
                }
                default:
                    break;
            }
        };
    };

这些都是直接拷贝进去就行的。

2.微信支付

微信支付的坑,主要在于签名
记得是md5,不是SHA1码。
主要是就算第一次支付成功,后面就一直掉不起来啦!!!返回码是-2,就是签名问题。签名对了其实也就不麻烦哦。

所以啊,测试的时候,先签名再测试,不然就失败啦!!
在注册的时候也注意,要用正式的签名哦。

代码如下:

“`
public static void WXpay(Context context,int type,String DingDan,String price){
String s;
IWXAPI api = WXAPIFactory.createWXAPI(context, “你的appid”,false);//微信
api.registerApp(APP_ID);
//String s=”{\”purpose\”:\”1\”,\”value\”:\”“+String+”\”,\”UserTel\”:\”“+ LocalStorage.get(“UserTel”).toString()+”\”}”;
if(type==0){
s=”{\”purpose\”:\”0\”,\”value\”:\”“+price+”\”,\”UserTel\”:\”“+ LocalStorage.get(“UserTel”).toString()+”\”,\”OrderID\” :\”“+DingDan+”\”}”;
}else {
s=”{\”purpose\”:\”1\”,\”value\”:\”“+price+”\”,\”UserTel\”:\”“+ LocalStorage.get(“UserTel”).toString()+”\”}”;
}

   System.out.println(s);
   //注意,这里出于安全考虑,要和服务器商量好哦!!!不要直接写在代码里。支付宝也是!
   RetrofitUtil colRetrofit = new RetrofitUtil(context);
   Map<String, String> map = new HashMap<>();
   map.put("Function", "StartPay");
   map.put("Body",s);
   colRetrofit.getStringDataFromNet("wxpay_index", map, new RetrofitUtil.CallBack<String>() {
       @Override
       public void onLoadingDataComplete(String body) {
           Log.i("wwwwwwwwwwwwww", "on "+body);
           if ("".equals(body) || null == body) {

           } else {
               try {
                   JSONObject json = new JSONObject(body.trim());
                   if(null != json && !json.has("retcode") ){
                       PayReq req = new PayReq();
                       //req.appId = "你的appid";  //你的appid
                       req.appId            = json.getString("appid");
                       req.partnerId        = json.getString("partnerid");
                       req.prepayId     = json.getString("prepayid");
                       req.nonceStr     = json.getString("noncestr");
                       req.timeStamp        = json.getString("timestamp");
                       req.packageValue = json.getString("package");
                       req.sign         = json.getString("sign");
                       req.extData          = "app data"; // optional
                       Toast.makeText(context, "正常调起支付", Toast.LENGTH_SHORT).show();
                       // 在支付之前,如果应用没有注册到微信,应该先调用IWXMsg.registerApp将应用注册到微信
                       api.sendReq(req);
                   }else{
                       Log.d("PAY_GET", "返回错误"+json.getString("retmsg"));
                       Toast.makeText(context, "返回错误"+json.getString("retmsg"), Toast.LENGTH_SHORT).show();
                   }
               } catch (JSONException e) {
                   Log.e("PAY_GET", "异常:"+e.getMessage());
                   Toast.makeText(context, "异常:"+e.getMessage(), Toast.LENGTH_SHORT).show();
               }
           }
       }
       @Override
       public void onLoadingDataFailed(Throwable t) {
           Log.d("PAY_GET", "服务器请求错误");
           Toast.makeText(context, "服务器请求错误", Toast.LENGTH_SHORT).show();
       }
   });

};“`
希望帮到你~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值