支付宝支付功能的实现(沙箱测试)

1.登陆支付宝开放平台

进入开发者中心
点击 研发服务
扫码 下载沙箱版支付宝

2.设置公钥私钥

在这里插入图片描述
然后下载密钥生成工具
在这里插入图片描述
生成完以后把(应用公钥)粘贴到沙箱环境中
在这里插入图片描述
下载沙箱版支付宝,账号密码在这
在这里插入图片描述
沙箱环境配置完毕

3.配置服务器

要添加一个支付宝的SDK的依赖

       <!--支付宝的SDK-->
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>4.3.0.ALL</version>
            <exclusions>
                <exclusion>
                    <groupId>org.bouncycastle</groupId>
                    <artifactId>bcprov-jdk15on</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

4.创建一个pay.properties配置文件

注意要在spring配置文件中加载
改三个,用户私钥,阿里公钥,AAPID

#支付宝网关地址
serverUrl=https://openapi.alipaydev.com/gateway.do
#应用编号  自己的AAPID
appId=2016091300500103
#用户私钥  在公钥私钥生成工具里面粘贴
privateKey=用户私钥
#阿里公钥  在开放平台沙箱环境里面查看 然后 粘贴
alipayPulicKey=阿里公钥
#传递数据格式json
format=json
#编码
charset=utf-8
#加密方式
signType=RSA2

5.在spring配置文件中配置支付宝客户端对象的bean(记得扫描properties配置文件)

  <!--配置支付宝客户端对象-->
    <bean id="payClient" class="com.alipay.api.DefaultAlipayClient">
        <constructor-arg name="serverUrl" value="${serverUrl}"/>
        <constructor-arg name="appId" value="${appId}"/>
        <constructor-arg name="privateKey" value="${privateKey}"/>
        <constructor-arg name="format" value="${format}"/>
        <constructor-arg name="charset" value="${charset}"/>
        <constructor-arg name="alipayPublicKey" value="${alipayPulicKey}"/>
        <constructor-arg name="signType" value="${signType}"/>
    </bean>

6.编写一个预下单的代码

具体思路可查看这个
在这里插入图片描述
1.写一个接口pay_interface
参数1:订单编号 参数2:支付金额

package com.offcn.pay.service;
import java.util.Map;
/**
 * 支付宝支付接口
 * @author Administrator
 *
 */
public interface AliPayService {

    /**
     * 生成支付宝支付二维码
     * @param out_trade_no 订单号
     * @param total_fee 金额(分)
     * @return
     */
    public Map createNative(String out_trade_no,String total_fee);
}

2.写实现类pay_service
传入参数
参数1:订单编号 参数2:支付金额

package com.offcn.pay.service.impl;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.offcn.pay.service.AliPayService;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

public class AliPayServiceImpl implements AliPayService {
    @Autowired
    AlipayClient alipayClient;
    @Override
    public Map createNative(String out_trade_no, String total_fee) {
        Map<String,String> map=new HashMap<String, String>();
        //创建预下单请求对象
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        //转换下单金额按照元,因为传进来的金额单位是 分
        long total = Long.parseLong(total_fee);
        BigDecimal bigTotal = BigDecimal.valueOf(total);
        BigDecimal cs = BigDecimal.valueOf(100d);

        BigDecimal bigYuan = bigTotal.divide(cs);
        System.out.println("预下单金额:"+bigYuan.doubleValue());
        request.setBizContent("{" +
                "    \"out_trade_no\":\""+out_trade_no+"\"," +   //商家订单号
                "    \"total_amount\":\""+bigYuan.doubleValue()+"\"," +  //与下单金额 单位 :元
                "    \"subject\":\"优乐选商城商品\"," +  //商家标题
                "    \"store_id\":\"xa_001\"," + //店铺编号
                "    \"timeout_express\":\"90m\"}");//设置业务参数  预下单失效时间 90m
        //3.发出预下单业务请求
        try {
            AlipayTradePrecreateResponse response = alipayClient.execute(request);
            //4.从相应对象读取相应结果
            String code = response.getCode();
            System.out.println("响应码:"+code);
            //全部的响应结果
            String body = response.getBody();
            System.out.println("返回结果:"+body);

            if(code!=null&&code.equals("10000")){
                //获取响应订单二维码  并且 封装进去
                map.put("qrcode", response.getQrCode());
                //订单编号
                map.put("out_trade_no", response.getOutTradeNo());
                //订单金额
                map.put("total_fee",total_fee);
                System.out.println("qrcode:"+response.getQrCode());
                System.out.println("out_trade_no:"+response.getOutTradeNo());
                System.out.println("total_fee:"+total_fee);
            }else{
                System.out.println("预下单接口调用失败:"+body);
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }


        return map;

    }
}

7.测试访问接口

使用IdWorker工具类生成订单编号,这里测试金额写死 写成1

    @RequestMapping("/createNative")
    public Map createNative(){
        //生成订单编号
        long out_trade_no = idWorker.nextId();
Map map=payService.createNative(out_trade_no ,1+"");
        }
        return map;
    }

访问接口进行测试
在这里插入图片描述
这个url地址就是生成二维码的地址,扫描二维码就可以支付了
关于二维码生成的方法,看我的另一篇博文
链接: 查看地址.

如何判断支付是否成功

思路:在生成二维码后,就立马访问判断支付是否成功的接口,并用一个死循环,不停的查询状态,可以设置可最大循环次数,超过次数就说明支付超时,是通过订单编号来查询的

8.实现类方法
    public Map queryPayStatus(String out_trade_no){
        System.out.println("需要查询支付状态的订单编号:"+out_trade_no);
        Map map=new HashMap();
        //1、创建交易查询请求对象
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        //2、设置查询参数
        request.setBizContent("{" +
                "    \"out_trade_no\":\""+out_trade_no+"\"," +//设置电商平台生成订单编号
                "    \"trade_no\":\"\"}");//支付宝生成交易流水号
        //发出查询
        try {
            AlipayTradeQueryResponse response = payClient.execute(request);
            //获取响应状态码
            String code = response.getCode();
            System.out.println("交易查询返回结果:"+response.getBody());
            if(code!=null&&code.equals("10000")){
                //判断交易状态 交易状态:WAIT_BUYER_PAY(交易创建,等待买家付款)、TRADE_CLOSED(未付款交易超时关闭,或支付完成后全额退款)、TRADE_SUCCESS(交易支付成功)、TRADE_FINISHED(交易结束,不可退款)
                String tradeStatus = response.getTradeStatus();
                //封装交易状态
                map.put("tradestatus",response.getTradeStatus());
                //支付宝生成交易流水号
                map.put("trade_no",response.getTradeNo());
                //订单编号
                map.put("out_trade_no",out_trade_no);
            }else {
                System.out.println("交易查询失败:"+code);
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return map;
    }

map里就封装了支付的状态,一共就四个值 //交易状态:WAIT_BUYER_PAY(交易创建,等待买家付款)、
TRADE_CLOSED(未付款交易超时关闭,或支付完成后全额退款)、
TRADE_SUCCESS(交易支付成功)、
TRADE_FINISHED(交易结束,不可退款)

接口

这里采用while(true)循环,不断地去查询支付状态,可以设置个最大循环次数,支付结果用Map封装

    //查询交易状态
    @RequestMapping("/queryPayStatus")
    public Result queryPayStatus(String out_trade_no){
        Result result=null;
        int  x=0;
        while (true) {
        //调用实现类方法
            Map map = payService.queryPayStatus(out_trade_no);
            if (map == null) {
                //查询异常,不在查询
                result = new Result(false, "请求交易状态查询服务异常");
                //跳出循环
                break;
            }

            //判断返回状态
            //交易状态:WAIT_BUYER_PAY(交易创建,等待买家付款)、
            // TRADE_CLOSED(未付款交易超时关闭,或支付完成后全额退款)、
            // TRADE_SUCCESS(交易支付成功)、
            // TRADE_FINISHED(交易结束,不可退款)
            //判断交易状态为 TRADE_CLOSED(未付款交易超时关闭,或支付完成后全额退款)
            if (map.get("tradestatus") != null && map.get("tradestatus").equals("TRADE_CLOSED")) {
                result = new Result(false, "未付款交易超时关闭,或支付完成后全额退款");
                break;
            }

            if (map.get("tradestatus") != null && map.get("tradestatus").equals("TRADE_SUCCESS")) {
                result = new Result(true, "交易支付成功");
               //调用订单服务 修改订单状态
                orderService.uodateOrderStatus(out_trade_no,map.get("trade_no")+"");
                break;
            }

            if (map.get("tradestatus") != null && map.get("tradestatus").equals("TRADE_FINISHED")) {
                result = new Result(false, "交易结束,不可退款");
                break;
            }
            if (map.get("tradestatus") != null && map.get("tradestatus").equals("TRADE_CLOSED")) {
                result = new Result(false, "未付款交易超时关闭,或支付完成后全额退款");
                break;
            }

            x++;
            if(x>=99){
                result=new Result(false,"二维码超时");
                break;
            }
            //为了防止一直查询,网关屏蔽掉,可以让查询线程等待3秒
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return result;
    }
理解思路图

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JavaSupeMan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值