首页 支付宝支付功能实践
文章
取消

支付宝支付功能实践

目标

为了使应用拥有初步的支付功能,我决定引入微信/支付宝的支付功能,后来因为微信的资格审查较为严格,因此决定使用支付宝支付功能,且由于学生个体用户申请商家身份较为麻烦,因此使用支付宝提供的沙箱环境来实现和测试支付功能。

使用支付宝支付产品功能

支付宝专门为个体和组织提供方便好用的支付功能开发工具包,按照支付宝的开发文档就能非常方便和简单的实现自己的支付功能。下面是具体的使用步骤:

  1. 使用开发者账号登录 开放平台控制台 > 开发工具推荐,点击 沙箱 即可进入沙箱环境。创建沙箱应用后默认会提供给我们应用的 APPID、应用名称和绑定的商家账号(PID)
  2. 创建好应用之后,需要设置接口加签方式,因为支付功能是及其敏感,涉及到个人财产安全的功能开发,所以在信息安全这方面上必须做足准备,因为对应接口调用信息的传递必须进行加密,而一般采用的加密方式属于非对称加密,其中的RSA256加密方式目前足够支撑支付安全。然后使用支付宝密钥生成器就能自动生成属于应用的密钥和私钥了,其中应用密钥和支付宝公钥需填写到代码中供签名时使用,应用公钥需上传到支付宝开放平台。如下所示:

引入 jar 包

为了在程序中使用支付宝支付功能,需要引入开发工具包:

1
2
3
4
5
6
<!-- 支付宝支付SDK -->
<dependency>
    <groupId>com.alipay.sdk</groupId>
    <artifactId>alipay-sdk-java</artifactId>
    <version>4.35.101.ALL</version>
</dependency>

引入 Demo 代码

支付宝提供了简单的支付功能 demo 代码,经过简单改造就能在程序中使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
public class PaymentTemplate {
  // 商户appid
  private String appId;
  // 私钥 pkcs8格式的
  private String rsaPrivateKey;
  // 服务器异步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
  private String notifyUrl;
  // 页面跳转同步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 商户可以自定义同步跳转地址
  private String returnUrl;
  // 请求网关地址
  private String url;
  // 编码
  private String charset;
  // 返回格式
  private String format;
  // 支付宝公钥
  private String alipayPublicKey;
  // 日志记录目录
  private String logPath;
  // RSA2
  private String signType;

  public String pay(String outTradeNo){
    AlipayClient client = new DefaultAlipayClient(url, appId, rsaPrivateKey, format, charset, alipayPublicKey, signType);
    AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
    //异步接收地址,仅支持http/https,公网可访问
    request.setNotifyUrl("notifyUrl");
    //同步跳转地址,仅支持http/https
    request.setReturnUrl(returnUrl);

    /******必传参数******/
    JSONObject bizContent = new JSONObject();
    //商户订单号,商家自定义,保持唯一性
    bizContent.put("out_trade_no", "20210817010101004");
    //支付金额,最小值0.01元
    bizContent.put("total_amount", 0.01);
    //订单标题,不可使用特殊符号
    bizContent.put("subject", "测试商品");

    /******可选参数******/
    //手机网站支付默认传值FAST_INSTANT_TRADE_PAY
    bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");

    //bizContent.put("time_expire", "2022-08-01 22:00:00");
    //// 商品明细信息,按需传入
    //JSONArray goodsDetail = new JSONArray();
    //JSONObject goods1 = new JSONObject();
    //goods1.put("goods_id", "goodsNo1");
    //goods1.put("goods_name", "子商品1");
    //goods1.put("quantity", 1);
    //goods1.put("price", 0.01);
    //goodsDetail.add(goods1);
    //bizContent.put("goods_detail", goodsDetail);

    //// 扩展信息,按需传入
    //JSONObject extendParams = new JSONObject();
    //extendParams.put("sys_service_provider_id", "2088511833207846");
    //bizContent.put("extend_params", extendParams);

    request.setBizContent(bizContent.toString());
    AlipayTradeWapPayResponse response = null;
    try {
      response = client.pageExecute(request);
    } catch (AlipayApiException e) {
      throw new RuntimeException(e);
    }

    return response.getBody();
  }
}

下面的时序图展示了代码的执行流程:

  1. 首先由用户选择商品,在我的智慧停车场管理系统中需要进行支付的模块包括:自动停车消费,充值会员消费,抽优惠券/洗车券消费。这些统一会生成一个应用唯一的订单号。
  2. 支付宝开发工具客户端则主要需要:商户appid、请求网关地址、应用私钥、支付宝公钥和加解密类型等主要信息,另外还需要订单的相关信息,比如订单的支付金额、购买商品的基本信息和订单标题等信息,然后就会向支付宝后台请求执行支付功能。

如何在程序中使用

在页面进行支付的时候会调用下面的接口:

1
2
3
4
5
6
7
8
9
/**
 * 统一支付接口
 *
 * @param outTradeNo 商户唯一订单号
 */
@GetMapping("/pay")
public CommonResult<String> pay(String outTradeNo) {
return CommonResult.success(paymentTemplate.pay(outTradeNo));
}

然后执行上面改造后的支付逻辑,最后会返回给前端一段 html 代码,可与页面进行展示,效果如下:

这样简单的支付功能就完成了。

本文由作者按照 CC BY 4.0 进行授权

MySQL为什么有时候会选错索引?

停车计费功能实践