ping++ 支付

一.最近要开发支付,考虑到以后接入的支付类型比较多,如常用的,微信,支付宝,银联,以及后期需要接入qq,京东,易宝支付等。为了以后统一管理支付,就考虑使用ping++ 支付,提供了统一的支付接口。

    下面我介绍下,利用ping++ 接入支付宝的支付功能。

二.请求服务器 支付接口 orderpay.

    1.配置:ping++ api key ,appId,webhooksParse

    2.在ping++ 官网 找到 rsa private key ,官网提供的是rsc pacs#1 ,这里需要转成 pkcs8,我是利用在线的一个网站转换 : http://tool.chacuo.net/cryptrsapkcs1pkcs8

    3.创建charge对象,这里着重要说明的是 获取客户端ip,这也是官网demo 未强调的点,对于不了解代理请求转发的小伙伴来说,这里又会遇到大坑,项目不上线 不知道,一上线支付就调用不起来,根源就在

    x-forwarded-for  获取客户端IP这里。给一个地址介绍下x-forwarded-for :http://www.360doc.com/content/12/0409/15/1073512_202198496.shtml,他最终结果是将所有的代理过的ip地址全拼接在一起,而我        们需要的是最开始发起支付请求的客户端IP。下面是代码部分:



一.最近要开发支付,考虑到以后接入的支付类型比较多,如常用的,微信,支付宝,银联,以及后期需要接入qq,京东,易宝支付等。为了以后统一管理支付,就考虑使用ping++ 支付,提供了统一的支付接口。

扫描二维码关注公众号,回复: 2487832 查看本文章

    下面我介绍下,利用ping++ 接入支付宝的支付功能。

二.请求服务器 支付接口 orderpay.

    1.配置:ping++ api key ,appId,webhooksParse

    2.在ping++ 官网 找到 rsa private key ,官网提供的是rsc pacs#1 ,这里需要转成 pkcs8,我是利用在线的一个网站转换 : http://tool.chacuo.net/cryptrsapkcs1pkcs8

    3.创建charge对象,这里着重要说明的是 获取客户端ip,这也是官网demo 未强调的点,对于不了解代理请求转发的小伙伴来说,这里又会遇到大坑,项目不上线 不知道,一上线支付就调用不起来,根源就在

    x-forwarded-for  获取客户端IP这里。给一个地址介绍下x-forwarded-for :http://www.360doc.com/content/12/0409/15/1073512_202198496.shtml,他最终结果是将所有的代理过的ip地址全拼接在一起,而我        们需要的是最开始发起支付请求的客户端IP。下面是代码部分:


三.创建支付对象 charge

   1.指定 支付使用的appid

   2.调用 charge对象的create 方法,创建支付对象。

public Charge createCharge(String orderId,int price,String orderNo,String channel,String clent_ip,String subject,String body){
        //String appId = PingppTestData.getAppID();
        String appId = Cont.API_ID;
        Charge charge = null;
        Map<String, Object> chargeMap = new HashMap<String, Object>();
        chargeMap.put("amount", price);//订单总金额, 人民币单位:分(如订单总金额为 1 元,此处请填 100)
        chargeMap.put("currency", "cny");
        chargeMap.put("subject", subject);
        chargeMap.put("body", body);
        chargeMap.put("order_no", orderNo);// 推荐使用 8-20 位,要求数字或字母,不允许其他字符
        chargeMap.put("channel", channel);// 支付使用的第三方支付渠道取值,请参考:https://www.pingxx.com/api#api-c-new
        
        Calendar cal = Calendar.getInstance();  
        cal.add(Calendar.MINUTE, 5);//5分钟失效  
        long timestamp = cal.getTimeInMillis()/ 1000L;  
        chargeMap.put("time_expire", timestamp);
        Timer timer = new Timer();
        //发起一个定时任务,半小时后自动触发,取消订单流程
       //以"X"结尾,则标识需求订单,
        if(orderNo.endsWith("X")){
            //需求订单
            timer.schedule(new DemandlobbyNoPayCancel(Long.valueOf(orderId)), 1000 * 60 * 5);
        }else{
            //普通订单
            timer.schedule(new OrderNoPayCancel(Long.valueOf(orderId)), 1000 * 60 * 5);
        }
        
        chargeMap.put("client_ip", clent_ip); // 发起支付请求客户端的 IP 地址,格式为 IPV4,如: 127.0.0.1
        Map<String, String> app = new HashMap<String, String>();
        app.put("id", appId);
        chargeMap.put("app", app);


        Map<String, Object> extra = new HashMap<String, Object>();
//            extra.put("success_url", "http://127.0.0.1/succeeded");
        chargeMap.put("extra", extra);
        try {
            // 发起 charge 创建请求
            charge = Charge.create(chargeMap);


        } catch (APIConnectionException e) {
            e.printStackTrace();
        } catch (ChannelException e) {
            e.printStackTrace();
        } catch (RateLimitException e) {
            e.printStackTrace();
        } catch (AuthenticationException e) {
            e.printStackTrace();
        } catch (APIException e) {
            e.printStackTrace();
        } catch (InvalidRequestException e) {
            e.printStackTrace();
        }


        return charge;

    }


四.支付回调方法

   1.回调地址,是在ping++ 官网配置,官网提供 test 和 live 两版本,开发过程先用test 做回调地址配置,测通后,项目正式上线改成live模式.

   2.回调地址进行业务处理,回调方法获取event type类型,是支付成功,还是退款成功或者红包发送成功..... 具体可参考 ping++ 开发api: https://www.pingxx.com/api#events-事件

   3.贴出我的回调处理方法代码,这里主要会发生的签名验签的错误,那么遇到这种情况,你还是要核对下,是否直接使用了ping++的私钥 并没有转成 pkcs8 加密方式,或者直接拷入了ping++的公钥....


public String webhooksParseCharge(){
          HttpServletRequest request  = getRequest();
          HttpServletResponse response = getResponse();
        try {
            request.setCharacterEncoding("UTF8");
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        }  
        //获取头部所有信息  
        Enumeration<String> headerNames = request.getHeaderNames();  
        String signature=null;  
        while (headerNames.hasMoreElements()) {  
            String key = (String) headerNames.nextElement();  
            String value = request.getHeader(key);  
            if("x-pingplusplus-signature".equals(key)){  
                signature=value;  
            }  
        }  
 
        // 获得 http body 内容  
       StringBuffer eventJson=new StringBuffer();  
       BufferedReader reader= null;  
        try {  
            reader = request.getReader();  
            do{  
                eventJson.append(reader.readLine());  
            }while(reader.read()!=-1);  
            reader.close();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
        
        JSONObject event=JSONObject.fromObject(eventJson.toString()); 
        System.out.println("=========event=========== "+event);
        boolean verifyRS=false;  
        try {  
            PublicKey publicKey = WebhooksVerifyService.getPubKey();  
            System.out.println("============公钥============"+publicKey);  
            verifyRS = WebhooksVerifyService.verifyData(eventJson.toString(),signature,publicKey);  
            System.out.println("============== 是否签名验证成功! "+ verifyRS);
            //verifyRS = true;
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
   
        if(verifyRS) {  
            // charge.succeeded    支付对象,支付成功时触发。
            // refund.succeeded    退款对象,退款成功时触发。
            if ("charge.succeeded".equals(event.get("type"))) {  
                JSONObject data = JSONObject.fromObject(event.get("data").toString());  
                JSONObject object = JSONObject.fromObject(data.get("object").toString()); 
                
                String channel = (String) object.get("channel");  
                String payType = null;  
                int amountFen = (int) object.get("amount");  
                //交易流水号
                String transaction_no = object.get("transaction_no")+"";
                        
                Double amountYuan = amountFen * 1.0 / 100;//ping++扣款,精确到分,而数据库精确到元  
                Double weiXinInput = null;  
                Double aliPayInput = null;  
                Double bankCardInput = null;  
                
                if ("wx".equals(channel)) {  
                    payType = "2";//支付类型(1:支付宝2微信)  
                    weiXinInput = amountYuan;  
                } else if ("alipay".equals(channel)) {  
                    payType = "1";  
                    aliPayInput = amountYuan;  
                } 
                
                String orderNo = (String) object.get("order_no");                  
                // 支付成功业务处理
            }else if("refund.succeeded".equals(event.get("type"))){//退款事件
                // 退款业务处理
                
            }  
            
        }else{  
            System.out.println("签名验证失败");
            setJsonString(AppJSON.errReq("签名验证失败!"));
        }  
          
          return "ajax";
      }




猜你喜欢

转载自blog.csdn.net/qq_31546841/article/details/80900495
今日推荐