这是必要条件!!!
这是必要条件!!!
这是必要条件!!!
开通当面付,个人、企业账号均可,个人账号可以私聊我帮忙代开通,10分钟就OK !!!
获取订单点击,然后扫码支付

支付成功后就会响应支付成功

接下来介绍应用的创建和配置,一定要仔细哦!!!
首先进入支付宝开放平台,进入控制台,创建一个应用,大概1个工作日内就会审核

把这几个必填项填写,然后确认创建,注意名字要清晰,应用图标要有一定的可识别性,不然不给过,应用类型选网页应用

创建好后,进入产品详情页面,点击产品绑定,然后去绑定

选择支付 -> 当面付[勾选] -> 绑定,另外你还可以找到花呗支付,这样用户扫码时就支持花呗支付了

要确认是开通状态哦,如果没有开通需要开通哦,看上面的 前提条件

然后需要配置密钥,点击下图中侧边栏中的 开发设置,需要配置的是 接口加签方式(证书/密钥)

接下来你可以结合着官方的开发文档看我的文章,官方文档:https://opendocs.alipay.com/open/02ekfg?ref=api&scene=19
SDK集成
首先获取相应的SDK,SDK下载页面(官方):https://opendocs.alipay.com/open/54/103419
我这里以Maven的方式集成,另外我集成了zxing,用于生成支付二维码使用
com.alipay.sdk alipay-sdk-java 4.35.9.ALL
com.google.zxing core 3.5.1
Controller实例
以下为简单的Demo演示,一定要结合官方文档,阅读接入注意事项:https://opendocs.alipay.com/open/194/105322
package com.demo.pay;import com.alibaba.fastjson.JSONObject;
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.AlipayTradePrecreateRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Map;/*** @author ThirdGoddess* @version 1.0.0* @time 2022/12/22 14:37* @desc AliPay当面付Demo*/
@RestController
@RequestMapping("pay")
public class AliPayController {//模拟一个用户的支付状态private boolean userPayState = false;//==================================================================================================================//这里都是固定的//支付宝网关地址private static final String SERVER_URL = "https://openapi.alipay.com/gateway.do";//charsetprivate static final String CHARSET = "GBK";//formatprivate static final String FORMAT = "json";//sign typeprivate static final String SIGN_TYPE = "RSA2";//==================================================================================================================//下面这三个是需要配置的//APPID,即创建应用的那个ID,在应用详情中的左上角可以看到private static final String APPID = "**************";//应用私钥,注意是应用私钥!!!应用私钥!!!应用私钥!!!private static final String APP_PRIVATE_KEY = "**************";//支付宝公钥,注意是支付宝公钥!!!支付宝公钥!!!支付宝公钥!!!private static final String ALIPAY_PUBLIC_KEY = "**************";/*** 获取二维码* 获取的是用户要扫码支付的二维码* 创建订单,带入自己的业务逻辑*/@RequestMapping(value = "/getQr", produces = MediaType.IMAGE_JPEG_VALUE)@ResponseBodypublic byte[] getQr() {userPayState = false;AlipayClient alipayClient = new DefaultAlipayClient(SERVER_URL, APPID, APP_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE);AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();//配置这是一个url,下图我已经配置好了,这个意思是当用户成功后,支付宝那边会调用这个地址url,他会给你传过去一些订单信息,//你处理完你的业务逻辑给支付宝响应success就行,就代表这个订单完成交易了!//* 建议前期开发的时候加上内网穿透调试,不然支付宝是没有办法调到你开发的接口的request.setNotifyUrl("http://**************.com/pay/payNotification");JSONObject bizContent = new JSONObject();//自己生成一个订单号,我这里直接用时间戳演示,正常情况下创建完订单需要存储到自己的业务数据库,做记录和支付完成后校验String orderNumber = "pay" + System.currentTimeMillis();bizContent.put("out_trade_no", orderNumber);//订单号bizContent.put("total_amount", 0.01);//订单金额bizContent.put("subject", "demo");//支付主题,自己稍微定义一下request.setBizContent(bizContent.toString());try {AlipayTradePrecreateResponse response = alipayClient.execute(request);if (response.isSuccess()) {System.out.println("调用成功");} else {System.out.println("调用失败");}//获取生成的二维码,这里是一个String字符串,即二维码的内容;//然后用二维码生成SDK生成一下二维码,弄成图片返回给前端就行,我这里使用Zxing生成//其实也可以直接把这个字符串信息返回,让前端去生成,一样的道理,只需要关心这个二维码的内容就行String qrCode = response.getQrCode();//生成支付二维码图片BufferedImage image = QrCodeUtil.createImage(qrCode);ByteArrayOutputStream out = new ByteArrayOutputStream();ImageIO.write(image, "jpeg", out);byte[] b = out.toByteArray();out.write(b);out.close();//最终返回图片return b;} catch (Exception e) {e.printStackTrace();System.out.println("调用失败");}return null;}/*** 支付完成后支付宝会请求这个回调*/@PostMapping("payNotification")public String payNotification(HttpServletRequest request) {Map params = new HashMap<>();Map requestParams = request.getParameterMap();for (String name : requestParams.keySet()) {String[] values = requestParams.get(name);String valueStr = "";for (int i = 0; i < values.length; i++) {valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";}params.put(name, valueStr);}for (Map.Entry entry : params.entrySet()) {System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());}//==============================================================================================================try {//执行验签,确保结果是支付宝回调的,而不是被恶意调用,一定要做这一步boolean signVerified = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, CHARSET, SIGN_TYPE);if (signVerified) {//验签成功,继续执行业务逻辑System.out.println("验签成功");//再次主动查询订单,不要只依赖支付宝回调的结果String orderStatus = searchOrderStatus(params.get("out_trade_no"), params.get("trade_no"));switch (orderStatus) {case "TRADE_SUCCESS"://交易支付成功;case "TRADE_FINISHED": //交易结束,不可退款;//TODO 在这里继续执行用户支付成功后的业务逻辑userPayState = true;break;}return "success";} else {//验签失败(很可能接口被非法调用)System.out.println("验签失败");return "fail";}} catch (AlipayApiException e) {e.printStackTrace();return "fail";}}/*** 封装一个订单查询** @param outTradeNo 商户订单号* @param tradeNo 支付宝交易号。支付宝交易凭证号* @return 订单状态:String* @throws AlipayApiException AlipayApiException* @desc "WAIT_BUYER_PAY":交易创建,等待买家付款;"TRADE_CLOSED":未付款交易超时关闭,或支付完成后全额退款; "TRADE_SUCCESS":交易支付成功;"TRADE_FINISHED":交易结束,不可退款;*/private String searchOrderStatus(String outTradeNo, String tradeNo) throws AlipayApiException {AlipayClient alipayClient = new DefaultAlipayClient(SERVER_URL, APPID, APP_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE); //获得初始化的AlipayClientAlipayTradeQueryRequest aliRequest = new AlipayTradeQueryRequest();//创建API对应的request类JSONObject bizContent = new JSONObject();bizContent.put("out_trade_no", outTradeNo);bizContent.put("trade_no", tradeNo);aliRequest.setBizContent(bizContent.toString()); //设置业务参数AlipayTradeQueryResponse response = alipayClient.execute(aliRequest);//通过alipayClient调用API,获得对应的response类JSONObject responseObject = JSONObject.parseObject(response.getBody());JSONObject alipayTradeQueryResponse = responseObject.getJSONObject("alipay_trade_query_response");return alipayTradeQueryResponse.getString("trade_status");}/*** 前端轮询查询这个接口,来查询订单的支付状态** @return OrderStateEntity*/@CrossOrigin@GetMapping("searchOrder")public OrderStateEntity searchOrder() {//userPayState是一个模拟值if (userPayState) {//用户支付成功了return new OrderStateEntity(200, "支付成功了");} else {//用户还没有支付return new OrderStateEntity(201, "你还没有支付哦");}}/*** 响应给前端的实体*/static class OrderStateEntity {private int code;private String msg;public OrderStateEntity(int code, String msg) {this.code = code;this.msg = msg;}public int getCode() {return code;}public void setCode(int code) {this.code = code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}}}
用户支付后的回调
当使用setNotifyUrl后,用户成功支付后,会回调其设置的url,如 setNotifyUrl(“http://xxx.com/pay/payNotification”) ,那么支付宝会等待用户支付成功后会以POST去请求 http://xxx.com/pay/payNotification 这个地址来达成回调,需要响应success或者fail,只有这两种值哦!
| 响应值 | 描述 | 异步是否重试发送 |
|---|---|---|
| fail | 消息获取失败 | 重试 |
| success | 消息获取成功 | 不重试 |
支付宝当面付Demo演示
Github:https://github.com/ThirdGoddess/aliPay
上一篇:自动控制原理1~3章课后练习题