创建商户号-创建支付宝小程序-开通JSAPI支付(含前后端代码)

上一次做支付宝小程序开发还是三四年前,主要也是做写前后端业务逻辑的内容,但是商户号的创建、小程序、JSAPI的申请都没有做过,而且这些年过去,版本变了,我原来用的代码也行不通了,所以这次我做一回备忘录,记录一下大致的步骤,省的又忘记了,不记录的太详细是因为过几年支付宝可能又会改动

1、注册商家(我注册的是企业,而非个人)
小程序 - 支付宝开放平台

然后按照流程一步一步走下去即可(会涉及到登录密码和支付的设置,需要记录好,以免忘记)

备案后,会收到验证短信通知,短信验证码有效期1天,需要注意验证码和手机号的输入

支付宝小程序备案踩坑-CSDN博客

2、申请成功后,进入工作台,创建小程序 登录 - 支付宝

按照流程一步一步走下去,注册申请有不明白的看这里,官方 小程序文档 - 支付宝文档中心

3、申请好了之后将小程序绑定到企业号中

4、我做的小程序涉及到支付功能,详细流程看 JSAPI 支付 文档 小程序文档 - 支付宝文档中心

需要获取到登录人的openid,之前用的userid已经不在支持了,还有一堆的公钥、私钥

5、配置密钥 小程序文档 - 支付宝文档中心

点击设置

下载密钥生成工具(我之前用的还是1.0.几的版本,老掉牙了)

下载后点击生成密钥,生成好了再上传到平台上

赋值公钥上传

保存私钥

使用密钥的案例  小程序文档 - 支付宝文档中心

不支持userID的文档说明在这里 小程序文档 - 支付宝文档中心

6、获取到openid后,参考这个文档,开通JSAPI支付,发起支付 登录 - 支付宝

选择类目、APPID然后验证,就能提交

7、去支付业务的文档中查看相关的代码接口 小程序文档 - 支付宝文档中心

8、我的代码如下 - 获取小程序的oepnid

maven:

<!-- 支付宝官方SDK -->
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>4.39.218.ALL</version>
<!--            <version>4.35.37.ALL</version>-->
        </dependency>

前端:

my.getAuthCode({
   scopes: 'auth_user',
   success: (res) => {
       console.log('res.authCode:',res.authCode);
       this.getUserId(res.authCode); 
   },
});

// 获取支付宝ID
  getUserId(code){
    this.sendRequest({
      url: this.api()+'deviceInfo/AliPay/getUserId',  
      method: 'GET',  
      data: {code:code}
    }).then(response => {
      console.log("获取支付宝ID结果:",response)
      if(response.code == 200){
        const key = 'openid';
        const data = response.openid;
        my.setStorage({ key, data });
      }else{
        alert('信息获取失败')
      }
    }).catch(error => {
      alert('信息获取失败')
    });
  },

后端:

public static Map<String, Object> getUserId(String authCode){
        Map<String, Object> map = new HashMap<>();

        // 配置支付宝客户端
        AlipayClient alipayClient = new DefaultAlipayClient(
                server_url,
                appid,
                private_key,
                "json",
                "UTF-8",
                alipay_public_key,
                sign_type
        );

        try {
            // 1. 换取访问令牌
            AlipaySystemOauthTokenRequest tokenRequest = new AlipaySystemOauthTokenRequest();
            tokenRequest.setGrantType("authorization_code");
            tokenRequest.setCode(authCode);

            // 2. 执行请求
            AlipaySystemOauthTokenResponse tokenResponse = alipayClient.execute(tokenRequest);

            // 3. 直接获取 user_id(auth_user 场景需确认是否返回)
            if (tokenResponse.isSuccess()) {
                map.put("msg", tokenResponse);
                map.put("openid", tokenResponse.getOpenId());
                map.put("code", 200);
                return map;  // 部分情况下直接返回 user_id‌:ml-citation{ref="3,4" data="citationList"}
            }
        }catch (Exception e){
            e.printStackTrace();
            map.put("msg", e.getMessage());
            map.put("code", 505);
        }
        return map;
    }

9、发起支付以及查询支付结果

前端:

注意:NO必须为大写,否则无法成功发起

 this.sendRequest({
      url: this.api()+'deviceInfo/AliPay/tradeCreate',  
      method: 'GET',  
      data: feeRecords
    }).then(response => {
        console.log('支付信息: ', response);  
        if(response.code == 200){
          this.requestPayment(response.tradeNo);
        }else{
          this.showModal("支付异常"+response.msg);
        }
    }).catch(error => {
      this.setData({
        isPaying:false
      })
      console.error('Request Failed:', error); 
    });

/**
   * 发起支付,并开启循环,查询订单是否成功
   * 因为requestPayment中的success只有在点击结束后页面的【完成】按钮,才能被触发
   * 所以这里我只能通过查询的方式来实现支付结果的监听
   * @param data 
   */
  requestPayment(tradeNo){
    console.log("支付订单号:",tradeNo)
    my.tradePay({
      tradeNO: tradeNo, // 这里参数绝对要注意,NO要全部大写
      success: (res) => {
        console.log("res.resultCode:",res.resultCode)
        // if (res.resultCode === '9000') {
        //   // 支付成功逻辑
        // }
      },
      fail: (res) => {
        // 支付失败处理
        console.log("fail:",res)
        this.stopOrderQueryInterval();
        my.exitMiniProgram();
        this.setData({
          isPaying:false
        })
      }
    });
    this.startOrderQueryInterval(tradeNo);
  },

 /**
   * 发起支付结果查询
   */
  startOrderQueryInterval(data) {
    const interval_order = setInterval(() => {
      this.queryOrder(data);
    }, 3000); // 3秒 = 3000毫秒
    this.setData({
      intervalOrder: interval_order
    });
  },

  /**
   * 停止订单查询定时器
   */
  stopOrderQueryInterval() {
    if (this.data.intervalOrder) {
      console.log("停止订单查询定时器")
      clearInterval(this.data.intervalOrder);
      this.setData({
        cycles:0,
        intervalOrder: null
      });
    }
  },

后端:

/**
     * 生成支付订单
     * @param totalAmount
     * @return
     */
    public static Map<String,Object> tradeCreate(String totalAmount, String userId) {
        // 配置支付宝客户端
        AlipayClient alipayClient = new DefaultAlipayClient(
                server_url,
                appid,
                private_key,
                "json",
                "UTF-8",
                alipay_public_key,
                sign_type
        );

        Map<String,Object> map = new HashMap();

        // 构造请求参数以调用接口
        AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
        AlipayTradeCreateModel model = new AlipayTradeCreateModel();

        // 设置商户订单号
        String outTradeNo = "tradeCreate" + System.currentTimeMillis() + (long) (Math.random() * 10000000L);
        System.out.println("商户订单号:"+outTradeNo);
        model.setOutTradeNo(outTradeNo);

        // 设置订单总金额-单位是元,和微信不一样
        model.setTotalAmount(totalAmount);

        // 设置订单标题
        model.setSubject("IJ");

        // 设置产品码
        model.setProductCode("JSAPI_PAY");

        // 设置小程序支付中
        model.setOpAppId(appid);

        // 设置订单附加信息
        //model.setBody("缴费金额:"+totalAmount+"元");

        // 设置买家支付宝用户唯一标识
        model.setBuyerOpenId(userId);
        request.setBizModel(model);

        // 支付结束后,触发的回调方法
        //request.setNotifyUrl("https://xxxx/AliPay/notifyUrl");
        try {
            AlipayTradeCreateResponse response = alipayClient.execute(request);
            System.out.println(JSON.toJSONString(response));
            if (response.isSuccess()) {
                String tradeNo = response.getTradeNo(); // 支付宝交易号‌:ml-citation{ref="2" data="citationList"}
                System.out.println("订单创建成功,交易号:" + tradeNo);
                map.put("msg", response);
                map.put("tradeNo", tradeNo);
                map.put("code", 200);
                aliPayQuery(outTradeNo);
            } else {
                System.err.println("错误码:" + response.getCode() + ",错误信息:" + response.getMsg());
                map.put("msg", response.getMsg());
                map.put("code", response.getCode());
                // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
                String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
                System.out.println(diagnosisUrl);
            }
        } catch (AlipayApiException e) {
            map.put("msg", e.getMessage());
            map.put("code", 505);
            e.printStackTrace();
        }
        return map;
    }

//订单查询
    public static Map<String,Object> aliPayQuery(String outTradeNo){
        Map<String,Object> m = new HashMap<>();
        try {
            // 1. 创建AlipayClient实例
            AlipayClient alipayClient = new DefaultAlipayClient(server_url, appid, private_key, "json", "UTF-8", alipay_public_key, sign_type);

            // 2. 构建请求对象
            AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
            request.setBizContent("{"
                    + "\"out_trade_no\":\"" + outTradeNo + "\","
                    + "\"query_options\":[\"trade_settle_info\"]" // 可选查询选项
                    + "}");

            // 3. 执行API调用
            AlipayTradeQueryResponse response = alipayClient.execute(request);

            // 4. 处理响应结果
            if (response.isSuccess()) {
                System.out.println("订单状态查询成功");
                System.out.println("支付宝交易号: " + response.getTradeNo());
                System.out.println("订单金额: " + response.getTotalAmount());
                m.put("msg",response);
                m.put("status",response.getTradeStatus());
                m.put("code",200);

                // 判断支付状态(2025年最新状态码)
                switch(response.getTradeStatus()) {
                    case "TRADE_SUCCESS":
                        System.out.println("支付已完成");
                        break;
                    case "TRADE_FINISHED":
                        System.out.println("交易完结(不可退款)");
                        break;
                    case "WAIT_BUYER_PAY":
                        System.out.println("等待用户付款");
                        break;
                    case "TRADE_CLOSED":
                        System.out.println("交易已关闭");
                        break;
                    default:
                        System.out.println("未知状态: " + response.getTradeStatus());
                }
            } else {
                System.out.println("查询失败,错误码: " + response.getSubCode());
                System.out.println("错误描述: " + response.getSubMsg());
                m.put("msg",response.getSubMsg());
                m.put("code",response.getSubCode());
            }
        } catch (Exception e) {
            System.err.println("API调用异常: " + e.getMessage());
            m.put("msg",e.getMessage());
            m.put("code",505);
            e.printStackTrace();
        }
        return m;
    }

注意:回调地址,NotifyUrl不是必填的,但是如果有需要,可以参考这个

/**
     * 
     * 查询支付宝小程序订单支付回调函数
     * @return
     */
    @GetMapping(value = "/AliPay/notifyUrl")
    public void notifyUrl(HttpServletRequest request, HttpServletResponse response){
        //循环获取到支付宝发送过来的信息
        Map<String,String[]>requestParams =request.getParameterMap();
        for(String str:requestParams.keySet()){
            String name =str;
            String[] values = requestParams.get(name);
            String valuestr = "";
            for (int i=0;i< values.length;i++){
                System.out.println("name:"+name+" <====> valuestr:"+valuestr);
            }
        }
    }

如果支付出现莫名其妙的问题可以在社区里直接问人工客服

支付如果出现问题,可以在支付宝提供的诊断工具上进行调试
诊断工具

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值