1.开发前准备
1.1 支付宝沙盒配置
1.1.1 注册支付宝开发者账号,进入开发者控制台
https://openhome.alipay.com/platform/developerIndex.htm
1.1.2 沙盒入口
https://open.alipay.com/develop/sandbox/app
![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)
![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)
将上面的APPID、支付宝网关消息、应用密钥和支付宝公钥保管好,下面会使用到。
2 集成沙盒支付
2.1 再pom.xml文件中添加下面依赖
1 2 3 4 5 6 7 8 9 10
| <dependency> <groupId>com.alipay.sdk</groupId> <artifactId>alipay-easysdk</artifactId> <version>2.2.0</version> </dependency> <dependency> <groupId>com.alipay.sdk</groupId> <artifactId>alipay-sdk-java</artifactId> <version>4.22.110.ALL</version> </dependency>
|
2.2 在application.yml 里面进行配置:
1 2 3 4 5
| alipay: appId: APPID appPrivateKey: 应用私钥 alipayPublicKey: 支付宝公钥 notifyUrl: 后面再填
|
2.3 创建AlipayConfig.java
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
| import com.alipay.easysdk.factory.Factory; import com.alipay.easysdk.kernel.Config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Data @Component @ConfigurationProperties(prefix = "alipay") public class AliPayConfig { private String appId; private String appPrivateKey; private String alipayPublicKey; private String notifyUrl;
@PostConstruct public void init(){ Config config = new Config(); config.protocol = "https"; config.gatewayHost = "openapi-sandbox.dl.alipaydev.com"; config.signType = "RSA2"; config.appId = this.appId; config.merchantPrivateKey = this.appPrivateKey; config.alipayPublicKey = this.alipayPublicKey; config.notifyUrl = this.notifyUrl; Factory.setOptions(config); System.out.println("=====支付宝SDK初始化成功====="); } }
|
2.4 支付接口
2.4.1 新建一个AliPay.java
1 2 3 4 5 6 7 8 9
| import lombok.Data;
@Data public class AliPay { private String traceNo; private double totalAmount; private String subject; private String alipayTraceNo; }
|
2.4.2 新建一个AliPayController.java
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
| import cn.hutool.json.JSONObject; import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayClient; import com.alipay.api.DefaultAlipayClient; import com.alipay.api.request.AlipayTradePagePayRequest; import com.alipay.easysdk.factory.Factory; import com.example.learnrabbitmq.config.AliPayConfig; import com.example.learnrabbitmq.model.AliPay; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.HashMap; import java.util.Map;
@RestController @RequestMapping("alipay") @Transactional(rollbackFor = Exception.class) public class AliPayController {
@Resource AliPayConfig aliPayConfig;
private static final String GATEWAY_URL ="https://openapi-sandbox.dl.alipaydev.com/gateway.do"; private static final String FORMAT ="JSON"; private static final String CHARSET ="UTF-8"; private static final String SIGN_TYPE ="RSA2";
@GetMapping("pay") public void pay(AliPay aliPay, HttpServletResponse httpResponse) throws IOException { AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(), aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest(); request.setNotifyUrl(aliPayConfig.getNotifyUrl()); JSONObject bizContent = new JSONObject(); bizContent.set("out_trade_no", aliPay.getTraceNo()); bizContent.set("total_amount", aliPay.getTotalAmount()); bizContent.set("subject", aliPay.getSubject()); bizContent.set("product_code", "FAST_INSTANT_TRADE_PAY"); request.setBizContent(bizContent.toString());
String form = ""; try { form = alipayClient.pageExecute(request).getBody(); } catch (AlipayApiException e) { e.printStackTrace(); } httpResponse.setContentType("text/html;charset=" + CHARSET); httpResponse.getWriter().write(form); httpResponse.getWriter().flush(); httpResponse.getWriter().close(); }
|
2.5 接口测试
测试的url格式: http://localhost:你的端口/alipay/pay?subject=任意填&traceNo=任意填&totalAmount=填数字
age:http://localhost:8081/alipay/pay?subject=test&traceNo=666&totalAmount=1000
成功截图:
![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)
然后使用沙盒账号中的买家账号进行登录
![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)
成功界面:
![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)
2.6 回调接口
在AliPayController.java添加以下代码
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
| @PostMapping("/notify") public String payNotify(HttpServletRequest request) throws Exception { if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) { System.out.println("=========支付宝异步回调========");
Map<String, String> params = new HashMap<>(); Map<String, String[]> requestParams = request.getParameterMap(); for (String name : requestParams.keySet()) { params.put(name, request.getParameter(name)); }
String tradeNo = params.get("out_trade_no"); String gmtPayment = params.get("gmt_payment"); String alipayTradeNo = params.get("trade_no"); if (Factory.Payment.Common().verifyNotify(params)) { System.out.println("交易名称: " + params.get("subject")); System.out.println("交易状态: " + params.get("trade_status")); System.out.println("支付宝交易凭证号: " + params.get("trade_no")); System.out.println("商户订单号: " + params.get("out_trade_no")); System.out.println("交易金额: " + params.get("total_amount")); System.out.println("买家在支付宝唯一id: " + params.get("buyer_id")); System.out.println("买家付款时间: " + params.get("gmt_payment")); System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));
} } return "success"; } }
|
使用该接口必须在外网的条件下,这里作者使用内外穿透来实现。
内外穿透:https://natapp.cn/
观看该文档:https://natapp.cn/article/natapp_newbie
本地端口改为自己的端口。
得到地址之后在application.yml中的notifyUrl去添加。
再次调用pay接口,支付完成后后台会打印出以下内容。
![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)
这就是全篇内容了,感谢您的阅读,菠萝屋祝你愉快的度过每一天。