网站调用支付宝进行支付-Java后台调用支付宝支付

网站调用支付宝进行支付-Java后台调用支付宝支付

最近公司一个产品用到了打赏支付,其中一个是支付宝,记录一下java后台调用支付宝的过程付代码。本文讲的是使用沙箱环境(支付宝提供的一种开发专用模式,不要实际支付,可以走通整个流程)。

一、准备工作

1.首先要到 蚂蚁金服开发者中心 注册商家账户,并认证。 2.下载java版的sdk和demo sdk&demo下载地址 3.将sdk加入到项目中,在项目根路径下新建libs文件夹,将jar包复制进去,我这里使用的是gradle,如果各位使用的是maven,请自行修改。

compile fileTree(dir:'libs',include:['*.jar'])
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.0' //谷歌json相关的包,可以用其他的

4.公钥、私钥的生成。生成公钥、私钥官方教程 ,按照官网教程操作,很简单的,这里就不上图片了。生成完之后将你的公钥要上传上去,具体位置看图片。

这里写图片描述

二、开发接口

1、因为开发环境是使用沙箱环境,上线后会使用真实环境,所以支付宝的一些参数我们放到配置文件里 pay-dev.properties appid和支付宝公钥上面图片中有,直接在网页上复制就好。

注意: 支付宝回调接口一定要是公网可以访问到的,我这里用了花生壳内网穿透,你们可以自行解决,只要能实现公网访问即可

ALIPAY.PRIVATEKEY=你生成的私钥
ALIPAY.PUBLICKEY=支付宝的公钥
ALIPAY.APPID=2016080300156724 #沙箱环境下的appid
ALIPAY.SERVER=https://openapi.alipaydev.com/gateway.do
ALIPAY.NOTIFY_URL=http://sanqi.iask.in:31017/alipay/notify  #公网可以访问的地址
ALIPAY.RETURNA_URL=http://sanqi.iask.in:31017/alipay/return
ALIPAY.SIGN=RSA2
ALIPAY.LOG=C:\\alipaylog\\

2、加载配置文件,我的项目是基于springboot的,如果是基于xml配置的,请自行在xml中配置。

/**
 * @ClassName: PropertiesConfig 
 * @Description: 读取配置文件
 * @author nelson
 * @date 2018年3月21日 下午5:35:21 
 *
 */
@Configuration
public class PropertiesConfig {
    @Bean
    public PropertySourcesPlaceholderConfigurer createPropertySourcesPlaceholderConfigurer() {
        ClassPathResource resource = new ClassPathResource("pay-dev.properties");
        PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
        propertyPlaceholderConfigurer.setLocation(resource);
        return propertyPlaceholderConfigurer;
    }
}

3、开始编写写接口 这里支付宝要用的一些参数,我是通过@Value自动注入进来的,官方给的demo是,定义个AlipayConfig类,然后全部定义成静态变量,根据个人喜好问题选择,官方的demo中有,可以直接复制,然后修改为你自己的参数即可。

代码中适当的写了一些参数,但是并非全部参数,官网参数列表及解释

/**
 * @Title: AlipayController.java
 * @Package cn.trmap.tdcloud.pay
 * @Description: 支付宝后台接口
 * @author nelson
 * @date 2018年3月21日 下午5:31:03
 */
@RequestMapping("alipay")
@RestController
public class AlipayController {
    
    @Value("${ALIPAY.APPID}")
    private String app_id;
    @Value("${ALIPAY.PRIVATEKEY}")
    private String merchant_private_key;
    @Value("${ALIPAY.PUBLICKEY}")
    private String alipay_public_key;
    @Value("${ALIPAY.NOTIFY_URL}")
    private String notify_url;
    @Value("${ALIPAY.RETURNA_URL}")
    private String return_url;
    @Value("${ALIPAY.SIGN}")
    private String sign_type = "RSA2";
    private String charset = "utf-8";
    
    @Value("${ALIPAY.SERVER}")
    private String gatewayUrL;

    @GetMapping("pay")
    private String alipayPay() throws AlipayApiException {
        //这个应该是从前端端传过来的,这里为了测试就从后台写死了
        AlipayVo vo = new AlipayVo();
        vo.setOut_trade_no(UUID.randomUUID().toString().replace("-", ""));
        vo.setTotal_amount("0.01");
        vo.setSubject("nelson-test-title");
        vo.setProduct_code("FAST_INSTANT_TRADE_PAY"); //这个是固定的
        String json = new Gson().toJson(vo);
        System.out.println(json);

        AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrL, app_id, merchant_private_key, "json",charset,alipay_public_key,sign_type);
        // 设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(return_url);
        alipayRequest.setNotifyUrl(notify_url);
        alipayRequest.setBizContent(json);
        String result = alipayClient.pageExecute(alipayRequest).getBody();
        System.out.println(result);
        return result; //这里生成一个表单,会自动提交
    }
/**
 * @Title: AlipayVo.java
 * @Package cn.trmap.tdcloud.pay.vo
 * @Description: 支付请求参数
 * @author nelson
 * @date 2018年3月23日 上午9:00:02
 */
public class AlipayVo implements Serializable{
    private static final long serialVersionUID = 1L;
    /**
     * 订单名称
     */
    private String subject;
    /**
     * 商户网站唯一订单号
     */
    private String out_trade_no;
    /**
     * 该笔订单允许的最晚付款时间
     */
    private String timeout_express;
    /**
     * 付款金额
     */
    private String total_amount;
    /**
     * 销售产品码,与支付宝签约的产品码名称
     */
    private String product_code;

    ****此处省去get和set方法
}

4、支付宝异步通知回调接口

这个接口的请求方式只能是post,如果用get会拿不到数据,不支持。

    /**
     * @Title: alipayNotify 
     * @Description: 支付宝回调接口
     * @author nelson
     * @param request
     * @param out_trade_no 商户订单号
     * @param trade_no 支付宝交易凭证号
     * @param trade_status 交易状态
     * @throws AlipayApiException
     * @return String 
     * @throws
     */
    @PostMapping("notify")
    private String alipayNotify(HttpServletRequest request, String out_trade_no,String trade_no,String trade_status)
            throws AlipayApiException {
        Map<String, String> map = new HashMap<String, String>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = iter.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
                System.out.println(valueStr);
            }
            map.put(name, valueStr);
        }
        boolean signVerified = false;
        try {
            signVerified = AlipaySignature.rsaCheckV1(map,alipay_public_key,charset,sign_type);
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return ("fail");// 验签发生异常,则直接返回失败
        }
        if (signVerified) {
            //处理你的业务逻辑,更细订单状态等
            return ("success");
        } else {
            System.out.println("验证失败,不去更新状态");
            return ("fail");
        }
    }

5、支付宝回调接口 return url

    /**
     * @Title: alipayReturn 
     * @Description: 支付宝回调接口
     * @author nelson
     * @param request
     * @param out_trade_no 商户订单号
     * @param trade_no 支付宝交易凭证号
     * @param trade_status 交易状态
     * @throws AlipayApiException
     * @return String 
     * @throws
     */
    @GetMapping("return")
    private String alipayReturn(Map<String, String> params, HttpServletRequest request, String out_trade_no,String trade_no,String total_amount)
            throws AlipayApiException {
        Map<String, String> map = new HashMap<String, String>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = iter.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
                System.out.println(valueStr);
            }
            map.put(name, valueStr);
        }
        boolean signVerified = false;
        try {
            signVerified = AlipaySignature.rsaCheckV1(map, alipay_public_key, charset, sign_type);
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return ("fail");// 验签发生异常,则直接返回失败
        }
        if (signVerified) {
            return ("success");
        } else {
            System.out.println("验证失败,不去更新状态");
            return ("fail");
        }
    }

三、测试接口

启动项目,访问接口地址 项目地址/alipay/pay 我的是 http://sanqi.iask.in:31017/alipay/pay

如果后台没有报错的话,他会自动重定向到,支付宝的付款页面,如下图所示。这时候我们下载安装沙箱版的app,然后使用官方提供的账户扫描然后直接付款,付款成功后会回调后面那两个接口,在通知的那个接口里处理你的业务逻辑。 查看沙箱app的登录帐户名和密码

这里写图片描述

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏CodeSheep的技术分享

ElasticSearch搜索引擎在SpringBoot中的实践

首先当然需要安装好elastic search环境,最好再安装上可视化插件 elasticsearch-head来便于我们直观地查看数据。

34011
来自专栏张善友的专栏

Autofac正式发布2.1版

Nicholas Blumhardt经过了2年多的开发,设计和试验,Autofac发布了第二版,针对1.4版本进行了重组,提供了更好的开发体验,你可以到这里下载...

17710
来自专栏圣杰的专栏

Abp通用配置模块的设计

下面我将尝试用最简单易懂的方式,对Abp源码中通用配置模块的实现方式加以提炼和精简,尽量继承原作者的设计思想,给大家呈现通用配置模块的“最佳实践”。

1031
来自专栏比原链

Derek解读Bytom源码-protobuf生成比原核心代码

Gitee地址:https://gitee.com/BytomBlockchain/bytom

843
来自专栏技术小讲堂

使用WCF进行跨平台开发之三(JAVA调用WCF服务)1.开发必备2.生成WCF客户端3.开发程序4.结束语

     前两篇写了在.net中和php中调用WCF。这一篇将要解决java中调用WCF的问题,使用的依旧是上一篇中托管在IIS中的WCF服务,本来我是打算用a...

3205
来自专栏码农笔录

网站调用支付宝进行支付-Java后台调用支付宝支付

1203
来自专栏GreenLeaves

WebService 之 身份验证

  在项目开发,我们经常会使用WebService,但在使用WebService时我们经常会考虑到了WebService是安全问题,很容易想到通过一组用户名与密...

2087
来自专栏Android-JessYan

看到如此多的MVP+Dagger2+Retrofit+Rxjava项目,轻松拿star,心动了吗?

原文地址: http://www.jianshu.com/p/4bbecd0bb027

782
来自专栏博客园

Asp.Net Web API(六)

     Asp.Net Web API不可以需要IIS。可以自己在主机上承载一个Web API

704
来自专栏菩提树下的杨过

C#代码也VB

习惯于用某一种语言做开发,时间长了以后很多人可能会对其它语言有排斥或抵触,其实... 退一步海阔天空! 比如:经常看到有人问"如何用c# ping 网址?",园...

1936

扫码关注云+社区