努力好了,时间会给你答案。--------magic_guo

支付模块是电商项目的核心,毕竟电商是属于B2C的,最终的盈利才是最重要的,第三方支付平台有很多,而且第三方支付平台对于商家接入都会有一些开发文档和demo作为指引,因此这部分虽然重要,但是开发相对简单;

下面我们来了解一下对接支付宝的一些流程:

1、首先我们对接支付宝需要到支付宝开放平台
2、然后选择自己的支付能力,我这里选择的是“电脑网站支付”;
电脑网站支付
在这里插入图片描述
点击电脑网站支付的基础功能,便可以看到一些基础的参数和接口描述以及代码示例、流程图:
在这里插入图片描述
然后登陆进行秘钥操作:
秘钥操作
1、生成秘钥并上传
2、生成秘钥请求签名
3、使用生成秘钥验签

下面看代码:
maven:
使用feign来调用order模块,最重要的依赖是支付宝sdk的依赖;

   <dependencies>
        <dependency>
            <groupId>com.guo</groupId>
            <artifactId>shop-common</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>4.12.4.ALL</version>
        </dependency>
        <dependency>
            <groupId>com.guo</groupId>
            <artifactId>shop-feign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

controller接口:

@Controller
@RequestMapping("/aliPay")
public class AliPayController {

    // 支付宝提供的网关
    private String serverUrl = "https://openapi.alipaydev.com/gateway.do";

    // 支付宝分配给开发者的应用ID
    private String APP_ID = "2021000117670024";

    // 加签配置的时候,支付宝分配的应用私钥
    private String APP_PRIVATE_KEY = "";

    // 仅支持JSON
    private String FORMAT = "JSON";

    // 请求使用的编码格式,如utf-8,gbk,gb2312等
    private String CHARSET = "utf-8";

    // 加签配置时,上传应用公钥到支付宝,会生成一个支付宝公钥;这样才算加签内容完成
    private String ALIPAY_PUBLIC_KEY = "";

    // 商户生成签名字符串所使用的签名算法类型,目前支持RSA2和RSA,推荐使用RSA2
    private String SIGN_TYPE = "RSA2";

    @Autowired
    private IOrderService orderService;

    public void pay (String orderId, HttpServletResponse httpResponse)   throws ServletException, IOException {
        //获得初始化的AlipayClient
        AlipayClient alipayClient =  new DefaultAlipayClient(
                serverUrl,
                APP_ID,
                APP_PRIVATE_KEY,
                FORMAT,
                CHARSET,
                ALIPAY_PUBLIC_KEY,
                SIGN_TYPE
        );
        //创建API对应的request
        AlipayTradePagePayRequest alipayRequest =  new AlipayTradePagePayRequest();
        // 用户付款之后同步跳转的地址
        alipayRequest.setReturnUrl("https://www.baidu.com/");
        // 异步返回通知商家的地址, 支付之后就更新数据库订单的状态
        alipayRequest.setNotifyUrl("http://domain.com/CallBack/notify_url.jsp");

        // 根据订单Id,通过feign查询此订单
        Order order = orderService.getOrderByOrderId(orderId);

        //填充业务参数
        alipayRequest.setBizContent( "{"  +
                "    \"out_trade_no\":" + orderId + ","  +                      // 订单号
                "    \"product_code\":\"FAST_INSTANT_TRADE_PAY\","  +           // 商品/产品编号  必填项
                "    \"total_amount\":" + order.getTotalPrice() + ","  +        // 订单总金额    必填项
                "    \"subject\":\"电商平台商品支付\","  +                       // 订单的主题/标题  必填项
                "    \"body\":\"具体商品的信息\","  +                            // 订单的描述
                // passback_params 公用回传参数:如果请求时传递了该参数,则返回给商户时会回传该参数。支付宝只会在异步通知时将该参数原样返回。
                // 本参数必须进行UrlEncode之后才可以发送给支付宝
                "    \"passback_params\":\"merchantBizType%3d3C%26merchantBizNo%3d2016010101111\","  +
                "    \"extend_params\":{"  +                            // 业务扩展参数
                "    \"sys_service_provider_id\":\"2088511833207846\""  +
                "    }" +
                "  }" );

        String form= "" ;
        try  {
            // 获取一个登陆页面
            form = alipayClient.pageExecute(alipayRequest).getBody();  //调用SDK生成表单
        }  catch  (AlipayApiException e) {
            e.printStackTrace();
        }
        // 把登录页面响应给用户
        httpResponse.setContentType( "text/html;charset="  + CHARSET);
        httpResponse.getWriter().write(form); //直接将完整的表单html输出到页面
        httpResponse.getWriter().flush();
        httpResponse.getWriter().close();
    }

    /**
     * 此过程需要对异步返回结果进行验签
     * @param request 异步返回通知商家的请求
     * @return
     * @throws AlipayApiException
     */
    @RequestMapping("/updateOrderStatus")
    public ResultEntity updateOrderStatus(HttpServletRequest request) throws AlipayApiException {
        // 异步返回通知商家的请求参数
        Map<String, String[]> parameterMap = request.getParameterMap();

        // 将异步通知中收到的所有参数都存放到 map 中
        Map<String, String> paramsMap = new HashMap<>();

        Set<Map.Entry<String, String[]>> entries = parameterMap.entrySet();
        for (Map.Entry<String, String[]> entry : entries) {
            paramsMap.put(entry.getKey(), entry.getValue()[0]);
        }

        // 调用SDK验证签名
        boolean  signVerified = AlipaySignature.rsaCheckV1(paramsMap, ALIPAY_PUBLIC_KEY, CHARSET, SIGN_TYPE);
        if (signVerified){
            String orderId = paramsMap.get("out_trade_no");
            String orderStatus = paramsMap.get("trade_status");
            HashMap<String, Object> map = new HashMap<>();
            map.put("orderId", orderId);
            map.put("orderStatus", 2);
            if ("TRADE_SUCCESS".equals(orderStatus)) {
                // 更改订单状态为已支付
                orderService.updateOrderStatus(map);
                return ResultEntity.success("更改订单状态为已支付!");
            }
            return ResultEntity.error("订单状态异常!");
            // TODO 验签成功后,按照支付结果异步通知中的描述,对支付结果中的业务内容进行二次校验,校验成功后在response中返回success并继续商户自身业务处理,校验失败返回failure
        } else {
            // TODO 验签失败则记录异常日志,并在response中返回failure.
            System.out.println("此请求是非法的;");
            return ResultEntity.error("此请求是非法的;");
        }
    }

    /**
     * 退款接口
     */
    public void refund() {

    }

    /**
     * 商家主动退款接口
     * 若用户一直未支付,商户可以调用该接口关闭指定交易;成功关闭交易后该交易不可支付
     */
    public void closeTransaction(){

    }

    /**
     * 下载账单接口
     */
    public void downloadBill() {

    }

}

这些接口的调试可以去支付宝提供的沙箱环境,登录支付宝,在沙箱环境中想充多少Money就冲多少,享受一下有钱人的滋味!

根据文档指引,所有的接口开发并不太难,因此只写了一个支付接口和验签的接口(即更改订单状态),其它接口可以根据翁当之后自行补充;其中最重要的是一些细节上的操作,毕竟此模块是关于Money的,刚入职的同学肯定不会负责这一模块;

ok!


本文章教学视频来自:https://www.bilibili.com/video/BV1tb4y1Q74E?p=3&t=125


静下心,慢慢来,会很快!

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐