Java支付宝支付(Alipay),支付接口,同步异步通知

做这个测试必须先注册成为支付宝开发者,最好要有一定的Java基础.注意同步异步通知这个必须要让支付宝可以访问你的项目,也就是说必须让支付宝可以访问你的项目中的方法,所以要把项目放在公网上,如果只是简单测试推荐使用花生壳

 

1.添加Alipay-sdk支付jar包: 

alipay-sdk-java20170324180803.jar

alipay-sdk-java20170324180803-source.jar

commons-logging-1.1.1.jar    //spring框架有日志包可忽略

2.编写支付宝网关密钥等配置文件

import java.io.FileWriter;
import java.io.IOException;

/* *
 *类名:AlipayConfig
 *功能:基础配置类
 *详细:设置帐户有关信息及返回路径
 *修改日期:2017-04-05
 *说明:
 *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
 *该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
 */

public class AlipayConfig {

//↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

    // 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
    public static String app_id = "20160926******";

    // 商户私钥,您的PKCS8格式RSA2私钥
    public static String merchant_private_key = "私钥";

    // 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
    public static String alipay_public_key = "公钥";

    // 服务器异步通知页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
public static String notify_url = "http://yan.eicp.net:26003/MyCSDN/pay/pay_notify";

// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
public static String return_url = "http://yan.eicp.net:26003/MyCSDN/pay/pay_return";



    // 签名方式
    public static String sign_type = "RSA2";

    // 字符编码格式
    public static String charset = "utf-8";

    // 支付宝网关
    public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";

    // 支付宝网关
    public static String log_path = "C:\\";


//↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

    /**
     * 写日志,方便测试(看网站需求,也可以改成把记录存入数据库)
     * @param sWord 要写入日志里的文本内容
     */
    public static void logResult(String sWord) {
        FileWriter writer = null;
        try {
            writer = new FileWriter(log_path + "alipay_log_" + System.currentTimeMillis()+".txt");
            writer.write(sWord);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

 

 

3.编写支付宝支付工具类 :做的是将订单信息公钥私钥等交给支付宝进行加密后返回到界面层

import com.alipay.api.*;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.request.*;
import com.it.exception.AlipayRuntimeException;

public class AlipayUtil {

    public static String pay(String out_trade_no, String total_amount, String subject, String body) {
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id,  AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);
        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);

        //设置订单信息
        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
        model.setOutTradeNo(out_trade_no);//必填,商户订单号
        model.setSubject(subject);//必填,订单名称
        model.setTotalAmount(total_amount);//必填,付款金额
        model.setBody(body);//选填,商品描述
        model.setProductCode("FAST_INSTANT_TRADE_PAY");//必填,电脑支付FAST_INSTANT_TRADE_PAY,手机支付QUICK_WAP_WAY
        //model.setTimeoutExpress(timeout_express);//选填,增加自定义超时时间参数timeout_express
        alipayRequest.setBizModel(model);

        //请求
        try {
            //把支付信息加密好(私钥),向支付宝后端申请支付,后端用公钥解开信息,生成带有二维码的连接返回给用户,要求用户按链接跳转
            String result = alipayClient.pageExecute(alipayRequest).getBody();
            return result;
        } catch (AlipayApiException e) {
            throw new AlipayRuntimeException("支付宝支付失败", e);
        }

    }
}

 

 

4.编写控制器调用支付工具类

 

//发起支付,等待支付宝返回支付页面
    @RequestMapping(value = "/paydo", method = RequestMethod.POST)
    public void payDo(HttpServletRequest request, HttpServletResponse response,float money) throws Exception {
//        System.out.println("测试支付");
        Member m = (Member) request.getSession().getAttribute("m");
        response.setContentType("text/html; charset=utf-8");//千万不要忘了设编码,否则密钥报错!!!!!!
        PrintWriter out = response.getWriter();    //输出流

        String out_trade_no = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + "_" + m.getId();//订单号
        String total_amount = money + "";                 //支付金额
        String subject = m.getNickName() + "充值";        //订单名称
        String body = "手机充值";                       //商品描述


        out.print(AlipayUtil.pay(out_trade_no, total_amount, subject, body));
    }

 

//异步通知
    @RequestMapping(value = "/pay_notify",method = RequestMethod.POST)
    public void notifyUrl(HttpServletResponse response,HttpServletRequest request) throws IOException, AlipayApiException {
        System.out.println("异步通知");
        PrintWriter out  = response.getWriter();
        request.setCharacterEncoding("utf-8");//乱码解决,这段代码在出现乱码时使用
        //获取支付宝POST过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        Map<String,String[]> requestParams = request.getParameterMap();
        for(String str :requestParams.keySet()){
            String name = str;
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }

        boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); //调用SDK验证签名

        if(!signVerified) {
            System.out.println("验签失败");
            out.print("fail");
            return;
        }

        //商户订单号,之前生成的带用户ID的订单号
        String out_trade_no = params.get("out_trade_no");
        //支付宝交易号
        String trade_no = params.get("trade_no");
        //付款金额
        String total_amount = params.get("total_amount");
        //交易状态
        String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");

        if(trade_status.equals("TRADE_FINISHED")){
            /*此处可自由发挥*/
            //判断该笔订单是否在商户网站中已经做过处理
            //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
            //如果有做过处理,不执行商户的业务程序
            //注意:
            //退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
        }else if (trade_status.equals("TRADE_SUCCESS")){
            //判断该笔订单是否在商户网站中已经做过处理
            //如果没有做过处理,根据订单号(out_trade_no在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
            //如果有做过处理,不执行商户的业务程序


            //增加用户在数据库余额
            String[] ss = out_trade_no.split("_");
            int mid = Integer.parseInt(ss[1]);
            Member m = memberService.findOne(mid);
            m.setScore(m.getScore() + (int)Double.parseDouble(total_amount));
            memberService.edit(m);
            //添加充值记录
            service.add(new PayInfo(trade_no,new Date(),"积分充值",m));
            System.out.println("trade_no:"+trade_no+"<br/>out_trade_no:"+out_trade_no+"<br/>total_amount:"+total_amount);

        }

        out.print("success");
    }

    //同步通知
    @RequestMapping(value = "/pay_return",method = RequestMethod.GET)
    public String returnUrl(HttpServletRequest request) throws UnsupportedEncodingException, AlipayApiException {
        System.out.println("同步通知");
        request.setCharacterEncoding("utf-8");//乱码解决,这段代码在出现乱码时使用
        //获取支付宝GET过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        Map<String,String[]> requestParams = request.getParameterMap();
        for(String str :requestParams.keySet()){
            String name = str;
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }

        boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); //调用SDK验证签名

        if(signVerified) {
            System.out.println("验签成功-跳转到成功后页面");
            //跳转至支付成功后的页面,
            return "redirect:payment";
        }else {
            System.out.println("验签失败-跳转到充值页面让用户重新充值");
            return "redirect:addmoney";
        }

        //打印请求中的字段
//        for (String str:params.keySet()) {
//            System.out.println(str +":"+ params.get(str));
//        }
    }

5.前端页面,调用controller方法即可

<form action="${pageContext.request.contextPath}/paydo" method="POST">
   充值金额:<input type="text" name="money" />
<br/>
<input type="submit"  value="充值"/>
</form>

 

 

 

 

 

 

 

  • 11
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
支付宝异步通知接口是用来接收支付宝服务器发送的交易状态信息的。下面是一个简单的示例代码: ```php <?php // 配置信息 $alipay_config = array( 'partner' => '208800XXXXXXXXXX', // 合作身份者id,以2088开头的16位数字。 'key' => 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', // 安全检验码,以数字和字母组成的32位字符。 'sign_type' => 'MD5', // 签名方式,目前支持RSA和MD5两种方式。 'input_charset' => 'utf-8', // 字符编码格式,目前支持GBK或UTF-8。 'cacert' => getcwd() . '\\cacert.pem', // CA证书路径地址,用于curlssl校验。 'transport' => 'http', // 访问模式,本例采用默认的curl实现。 ); // 异步通知参数 $notify_data = $_POST['notify_data']; // 创建支付宝通知对象 require_once('alipay_notify.class.php'); $alipayNotify = new AlipayNotify($alipay_config); // 验证签名 $verify_result = $alipayNotify->verifyNotify(); if ($verify_result) { // 验证成功 // 获取交易状态 $trade_status = $_POST['trade_status']; if ($trade_status == 'TRADE_FINISHED' || $trade_status == 'TRADE_SUCCESS') { // 处理交易成功逻辑 } else { // 处理交易失败逻辑 } echo 'success'; // 返回success告诉支付宝服务器已成功接收通知 } else { // 验证失败 echo 'fail'; // 返回fail告诉支付宝服务器接收通知失败 } ``` 在上面的代码,我们使用了支付宝提供的 `alipay_notify.class.php` 类来验证签名和处理交易状态。如果验证成功,我们就可以根据交易状态进行相应的业务逻辑处理,并返回 `success` 通知支付宝服务器已成功接收通知。如果验证失败,则返回 `fail` 告诉支付宝服务器接收通知失败。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值