手把手教你如何对接支付宝支付接口(奶爸级别)

Posted 胡金水

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手把手教你如何对接支付宝支付接口(奶爸级别)相关的知识,希望对你有一定的参考价值。

步骤:

第一步:准备支付宝相关的参数,如appId、公私钥

第二步:写代码,搞起

第一步:

1.你需要登录支付宝https://open.alipay.com/platform/developerIndex.htm。

2.点击控制台—>研发服务
在这里插入图片描述
3.到这个地址上生成一对公私钥:https://miniu.alipay.com/keytool/create
在这里插入图片描述
4.私钥保存下来,是要放在项目配置里面的,公钥是下面的步骤要用到的。
5.复制上面的公钥,放到这个输入框里面在这里插入图片描述
6.保存设置后,打开就可以看到这样的窗口,下面的【敲黑板了!!!支付宝公钥】是放在代码里面的,自己保存下来。
在这里插入图片描述
7.点击左边的【沙箱账号】,把账号密码保存下来,支付的时候要用到。
在这里插入图片描述
8.到了这一步,咱们所需要的配置基本上就准备齐了

请看配置
# 应用ID,您的APPID
alipay.appId=2021xxxx
# 支付宝公私钥生成地址:https://miniu.alipay.com/keytool/create
# 商户私钥,您的PKCS8格式RSA2私钥
alipay.merchantPrivateKey=第一次生成的私钥
# 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm
alipay.alipayPublicKey=支付宝公钥
# 页面跳转异步通知页面路径,需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
alipay.notifyUrl=http://5ktbak.natappfree.cc/payment/alipay
# 页面跳转同步通知页面路径,需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
alipay.returnUrl=http://5ktbak.natappfree.cc/alipayResult

# 签名方式
alipay.signType=RSA2
# 字符编码格式
alipay.charset=utf-8
# 支付宝网关
alipay.gatewayUrl=https://openapi.alipaydev.com/gateway.do

第二步

alipay.properties
# 应用ID,您的APPID
alipay.appId=2021xxxx
# 支付宝公私钥生成地址:https://miniu.alipay.com/keytool/create
# 商户私钥,您的PKCS8格式RSA2私钥
alipay.merchantPrivateKey=第一次生成的私钥
# 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm
alipay.alipayPublicKey=支付宝公钥
# 页面跳转异步通知页面路径,需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
alipay.notifyUrl=http://5ktbak.natappfree.cc/payment/alipay
# 页面跳转同步通知页面路径,需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
alipay.returnUrl=http://5ktbak.natappfree.cc/alipayResult

# 签名方式
alipay.signType=RSA2
# 字符编码格式
alipay.charset=utf-8
# 支付宝网关
alipay.gatewayUrl=https://openapi.alipaydev.com/gateway.do
AliPayResource.java
package com.alipay.resource;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

@Data
@Component
@ConfigurationProperties(prefix="alipay")
@PropertySource("classpath:alipay.properties")
public class AliPayResource {

    private String appId;
    private String merchantPrivateKey;
    private String alipayPublicKey;

    private String notifyUrl;
    private String returnUrl;

    private String signType;
    private String charset;
    private String gatewayUrl;
}
AlipayController.java
package com.alipay.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.resource.AliPayResource;
import com.alipay.utils.DateUtil;
import com.alipay.utils.JsonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * @author: HuGoldWater
 * @description:
 */
@Slf4j
@RestController
@RequestMapping("payment")
public class AlipayController {

    @Autowired
    private AliPayResource aliPayResource;

    /**
     * 前往支付宝进行支付
     */
    @GetMapping(value="/goAlipay")
    public JsonResult goAlipay(String merchantUserId, String merchantOrderId) throws Exception{
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(aliPayResource.getGatewayUrl(),
                aliPayResource.getAppId(),
                aliPayResource.getMerchantPrivateKey(),
                "json",
                aliPayResource.getCharset(),
                aliPayResource.getAlipayPublicKey(),
                aliPayResource.getSignType());

        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(aliPayResource.getReturnUrl());
        alipayRequest.setNotifyUrl(aliPayResource.getNotifyUrl());

        // 商户订单号, 商户网站订单系统中唯一订单号, 必填
        String out_trade_no = merchantOrderId;
        // 付款金额, 必填 单位元
       String total_amount = "0.01";  // 测试用 1分钱
        // 订单名称, 必填
        String subject = "胡金水-付款用户[" + merchantUserId + "]";
        // 商品描述, 可空, 目前先用订单名称
        String body = subject;

        // 该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。 该参数数值不接受小数点, 如 1.5h,可转换为 90m。
        String timeout_express = "1h";
        alipayRequest.setBizContent("{\\"out_trade_no\\":\\""+ out_trade_no +"\\","
                + "\\"total_amount\\":\\""+ total_amount +"\\","
                + "\\"subject\\":\\""+ subject +"\\","
                + "\\"body\\":\\""+ body +"\\","
                + "\\"timeout_express\\":\\""+ timeout_express +"\\","
                + "\\"product_code\\":\\"FAST_INSTANT_TRADE_PAY\\"}");

        //请求
        String alipayForm = "";
        try {
            alipayForm = alipayClient.pageExecute(alipayRequest).getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        log.info("支付宝支付 - 前往支付页面, alipayForm: \\n{}", alipayForm);
        return JsonResult.ok(alipayForm);
    }


    /**
     * 支付成功后的支付宝异步通知
     */
    @RequestMapping(value="/alipay")
    public String alipay(HttpServletRequest request, HttpServletResponse response) throws Exception {

        log.info("支付成功后的支付宝异步通知");

        //获取支付宝POST过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        Map<String,String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            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] + ",";
            }
            //乱码解决,这段代码在出现乱码时使用
//       valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }

        boolean signVerified = AlipaySignature.rsaCheckV1(params,
                aliPayResource.getAlipayPublicKey(),
                aliPayResource.getCharset(),
                aliPayResource.getSignType()); //调用SDK验证签名

        if(signVerified) {//验证成功
            // 商户订单号
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
            // 支付宝交易号
            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");
            // 交易状态
            String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");
            // 付款金额
            String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"),"UTF-8");

            if (trade_status.equals("TRADE_SUCCESS")){
//                String merchantReturnUrl = paymentOrderService.updateOrderPaid(out_trade_no, CurrencyUtils.getYuan2Fen(total_amount));
//                notifyFoodieShop(out_trade_no,merchantReturnUrl);
            }

            log.info("************* 支付成功(支付宝异步通知) - 时间: {} *************", DateUtil.getCurrentDateString(DateUtil.DATETIME_PATTERN));
            log.info("* 订单号: {}", out_trade_no);
            log.info("* 支付宝交易号: {}", trade_no);
            log.info("* 实付金额: {}", total_amount);
            log.info("* 交易状态: {}", trade_status);
            log.info("*****************************************************************************");

            return "success";
        }else {
            //验证失败
            log.info("验签失败, 时间: {}", DateUtil.getCurrentDateString(DateUtil.DATETIME_PATTERN));
            return "fail";
        }
    }

}
Application.java
package com.alipay;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
   public static void main(String[] args) {
      SpringApplication.run(Application.class, args);
   }

}

运行Application,在页面输入localhost:9090/payment/goAlipay?merchantUserId=123456&merchantOrderId=654321

结果如下:

五月 08, 2021 11:30:51 下午 org.apache.catalina.core.ApplicationContext log
信息: Initializing Spring DispatcherServlet 'dispatcherServlet'
INFO  DispatcherServlet:525 - Initializing Servlet 'dispatcherServlet'
INFO  DispatcherServlet:547 - Completed initialization in 3 ms
INFO  AlipayController:80 - 支付宝支付 - 前往支付页面, alipayForm: 
<form name="punchout_form" method="post" action="https://openapi.alipaydev.com/gateway.do?charset=utf-8&method=alipay.trade.page.pay&sign=0G7TbOfYZn8BS1dYY%2FITfZLBHgz%2F0uBz3XU4ndiw%2Fpd%2BADurlNMtYNugvZpGTjrL4JBJb%2Fgzl6vG%2B9urFCbeLiVDXhnGMIvqzXOY67YVGIMfIDxR%2BOytOzZ3zctPeEVHDZBAjRNy4aOqW1elJ491Q%2BptPNT2X3vy8Qts0Ago1HaOyoCRlFag5nB3fwD5t3NQz4ZCEG8slwERixJnN2sIQLj4NGI2bM2T6x8ayDtehRC89hwXJ1ZY9IyLVkwhby%2BW4HU2LiQ%2BqD%2FOKLmxsC65M5pWNF7vw9uswmEuN5qBswJ5rqlTl6iyYd5EKK2Xqhj6hCQYz0IMR1cymRhqDoPG1Q%3D%3D&return_url=http%3A%2F%2F5ktbak.natappfree.cc%2FalipayResult&notify_url=http%3A%2F%2F5ktbak.natappfree.cc%2Fpayment%2Falipay&version=1.0&app_id=2021000117651511&sign_type=RSA2&timestamp=2021-05-08+23%3A30%3A51&alipay_sdk=alipay-sdk-java-3.7.110.ALL&format=json">
<input type="hidden" name="biz_content" value="{&quot;out_trade_no&quot;:&quot;654321&quot;,&quot;total_amount&quot;:&quot;0.01&quot;,&quot;subject&quot;:&quot;胡金水-付款用户[123456]&quot;,&quot;body&quot;:&quot;胡金水-付款用户[123456]&quot;,&quot;timeout_express&quot;:&quot;1h&quot;,&quot;product_code&quot;:&quot;FAST_INSTANT_TRADE_PAY&quot;}">
<input type="submit" value="立即支付" style="display:none" >
</form>
<script>document.forms[0].submit();</script>

把上面的html代码放到html文件中:

<form name="punchout_form" method="post" action="https://openapi.alipaydev.com/gateway.do?charset=utf-8&method=alipay.trade.page.pay&sign=0G7TbOfYZn8BS1dYY%2FITfZLBHgz%2F0uBz3XU4ndiw%2Fpd%2BADurlNMtYNugvZpGTjrL4JBJb%2Fgzl6vG%2B9urFCbeLiVDXhnGMIvqzXOY67YVGIMfIDxR%2BOytOzZ3zctPeEVHDZBAjRNy4aOqW1elJ491Q%2BptPNT2X3vy8Qts0Ago1HaOyoCRlFag5nB3fwD5t3NQz4ZCEG8slwERixJnN2sIQLj4NGI2bM2T6x8ayDtehRC89hwXJ1ZY9IyLVkwhby%2BW4HU2LiQ%2BqD%2FOKLmxsC65M5pWNF7vw9uswmEuN5qBswJ5rqlTl6iyYd5EKK2Xqhj6hCQYz0IMR1cymRhqDoPG1Q%3D%3D&return_url=http%3A%2F%2F5ktbak.natappfree.cc%2FalipayResult&notify_url=http%3A%2F%2F5ktbak.natappfree.cc%2Fpayment%2Falipay&version=1.0&app_id=2021000117651511&sign_type=RSA2&timestamp=2021-05-08+23%3A30%3A51&alipay_sdk=alipay-sdk-java-3.7.110.ALL&format=json">
    <input type="hidden" name="biz_content" value="{&quot;out_trade_no&quot;:&quot;654321&quot;,&quot;total_amount&quot;:&quot;0.01&quot;,&quot;subject&quot;:&quot;胡金水-付款用户[123456]&quot;,&quot;body&quot;:&quot;胡金水-付款用户[123456]&quot;,&quot;timeout_express&quot;:&quot;1h&quot;,&quot;product_code&quot;:&quot;FAST_INSTANT_TRADE_PAY&quot;}">
    <input type="submit" value="立即支付" style="display:none" >
</form>
<script>document.forms[0].submit();</script>

打开html文件后,会进入这个页面:
在这里插入图片描述
输入沙箱的账号密码:

在这里插入图片描述
在这里插入图片描述
输入密码后,就已经付款完成了,控制台会打印支付成功的回调通知。

INFO  AlipayController:91 - 支付成功后的支付宝异步通知
INFO  AlipayController:129 - ************* 支付成功(支付宝异步通知) - 时间: 2021-05-09 00:09:32 *************
INFO  AlipayController:130 - * 订单号: 123123123123
INFO  AlipayController:131 - * 支付宝交易号: 2021050922001489970501658602
INFO  AlipayController:132 - * 实付金额: 0.01
INFO  AlipayController:133 - * 交易状态: TRADE_SUCCESS
INFO  AlipayController:134 - *****************************************************************************

如何让支付宝将付款成功的通知,回调到你本机,我使用的是内网穿透:Natapp,可以看到另一篇文章:https://blog.csdn.net/qq_17555933/article/details/116549415

以上是关于手把手教你如何对接支付宝支付接口(奶爸级别)的主要内容,如果未能解决你的问题,请参考以下文章

手把手教你撸支付宝红包

个人的网站如何对接支付宝和微信的支付接口?自己的网站急需接入支付接口,有没有大佬指点一下?

thinkphp框架对接支付宝即时到账接口回调的代码

android怎么和支付宝实现接口对接

支付宝当面付怎么对接易支付

对接支付宝支付接口开发详细步骤(证书签名方式)