支付宝开放平台
扫码登录支付宝开放平台
沙箱环境
沙箱环境介绍
沙箱控制台
应用网关:该地址用于接收开放平台的异步通知。目前沙箱环境不需要配置此参数;
授权回调地址;第三方应用授权或获取用户信息中用于接收授权回调信息的地址。使用相关产品时需进行配置:
第三方应用授权:授权 url 中的 redirect_uri 必须与此值相同。
获取用户信息:授权 url 中的 redirect_uri 的域名必须与此值相同(例如:授权回调地址配置:/authCallBack 高亮部分需和授权url相同)。
RSA(SHA1)密钥:配置 RSA2(SHA256) 的应用公钥后,不需要配置 RSA(SHA1) 密钥。
AES 密钥:目前不再使用。
扫码测试的时候需要沙箱版支付宝App,目前只有安卓版
下载
配置
首先导入支付宝的依赖
<!--ali pay--><dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-sdk-java</artifactId><version>3.1.0</version></dependency>
配置文件
alipay:app-id: # AppIDprivate-key: # 应用私匙 需要用支付宝助手生成public-key: # 支付宝公匙gateway: /gateway.do
支付宝公匙点击RSA2(SHA256)密钥设置,然后查看
应用私匙:
会生成txt文件,然后复制到配置文件中
APPID和网关就不说了,需要注意的是正式接入支付宝的网关和沙箱环境的应用网关,区分是/
代码实现
构建支付信息视图对象PayInfoVO.java
@Data@AllArgsConstructor@ToString@EqualsAndHashCode@NoArgsConstructor@ApiModel("支付信息")public class PayInfoVO implements Serializable {@ApiModelProperty("二维码URL")private String url;@ApiModelProperty("订单编号")private String orderId;@ApiModelProperty("商家名称")private String shopName;}
PayServiceImpl
@Service("PayServiceImpl")@Slf4jpublic class PayServiceImpl implements PayService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate ShopMapper shopMapper;@Value("${alipay.app-id}")private String appId;@Value("${alipay.private-key}")private String privateKey;@Value("${alipay.public-key}")private String publicKey;@Value("${alipay.gateway}")private String gateway;private AlipayClient alipayClient;@PostConstructpublic void init() {alipayClient = new DefaultAlipayClient(gateway,appId, privateKey, "json", "utf-8", publicKey, "RSA2");}@Overridepublic PayInfoVO getPayInfo(String orderId) {log.info("info ============= {}",orderId);// 根据订单id得到订单详情Order order = orderMapper.selectById(orderId);String sellId = order.getSellId();// 根据商家ID获取商家信息Shop shop = shopMapper.selectById(sellId);String shopSellName = shop.getSellName();AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();// 支付请求request.setBizContent("{" +" \"out_trade_no\":\"" + orderId + "\"," +//商户订单号" \"total_amount\":\"" + order.getOrderPrice().setScale(2, RoundingMode.CEILING) + "\"," +" \"subject\":\"" + shopSellName + "当面付" + "\"," +" \"store_id\":\"00100\"," + // (必填) 商户门店编号,通过门店号和商家后台可以配置精准到门店的折扣信息,详询支付宝技术支持" \"timeout_express\":\"5m\"}");//订单允许的最晚付款时间AlipayTradePrecreateResponse response = null;//支付宝二维码URLString qrCode = "";try {response = alipayClient.execute(request);if (!response.isSuccess()) {throw new CustomException("生成支付宝订单失败:" + response.getMsg());}qrCode = response.getQrCode();} catch (AlipayApiException e) {throw new CustomException(e.getMessage());}// 封装支付信息 返回PayInfoVO payInfoVO = new PayInfoVO();payInfoVO.setOrderId(order.getOrderId());payInfoVO.setShopName(shopSellName);payInfoVO.setUrl(qrCode);log.info("payInfo: {}",payInfoVO);return payInfoVO;}}
controller
@Autowired@Qualifier("PayServiceImpl")private PayService payService;@ApiOperation("返回支付二维码和支付信息")@GetMapping("/qr/{orderId}")public AjaxResult getPayInfo(@PathVariable String orderId) {PayInfoVO payInfoVO = payService.getPayInfo(orderId);return AjaxResult.success("支付成功", payInfoVO);}
支付状态
@AllArgsConstructor@Getterpublic enum PayStatusEnum {/** 等待扫码 */WAIT_SCANNED(0,"等待扫码"),/** 等待支付(已扫码,未支付) */UN_PROCESSED(1,"等待支付"),/** 商家已完成,等待骑手取餐 */PROCESSED(2,"已支付"),/** 订餐者关闭或者超时关闭 */SHIPPING(3,"已取消"),;private Integer code;private String msg;public static PayStatusEnum valueOf(Integer code){for (PayStatusEnum value : values()) {if (value.code.equals(code)) {return value;}}return null;}}
支付结果对象
@Data@ToStringpublic class PayResultDTO implements Serializable {//支付IDprivate Long payId;// 支付状态private Integer status;// 支付金额private BigDecimal amount;// 支付信息private String msg;}
获取支付状态
// 根据orderId获取支付状态public PayResultDTO getPayStatus(String orderId) {log.info("status: ========= {}",orderId);//创建API对应的request类AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();request.setBizContent("{" +" \"out_trade_no\":\"" + orderId + "\"}");AlipayTradeQueryResponse response = null;Order order = new Order();order.setOrderId(orderId);PayResultDTO payResultDTO = new PayResultDTO();try {response = alipayClient.execute(request);if (!response.isSuccess()) {// 获取支付信息失败payResultDTO.setStatus(PayStatusEnum.WAIT_SCANNED.getCode());payResultDTO.setMsg("等待扫码");return payResultDTO;}payResultDTO.setThirdPartId(response.getTradeNo());switch (response.getTradeStatus()) {case "WAIT_BUYER_PAY":payResultDTO.setStatus(PayStatusEnum.UN_PROCESSED.getCode());payResultDTO.setMsg("已扫码,等待用户支付");break;case "TRADE_CLOSED":payResultDTO.setStatus(PayStatusEnum.SHIPPING.getCode());payResultDTO.setMsg("支付已关闭");break;case "TRADE_SUCCESS":payResultDTO.setStatus(PayStatusEnum.PROCESSED.getCode());payResultDTO.setAmount(new BigDecimal(response.getTotalAmount()));payResultDTO.setMsg("支付成功");order.setPayStatus(Constants.PAY_STATUS_PAID);// 这里写支付成功的逻辑,例如设置支付时间,订单状态什么的break;default:break;}return payResultDTO;} catch (AlipayApiException e) {payResultDTO.setStatus(-1);payResultDTO.setMsg("查询订单状态错误:" + e.getErrMsg());return payResultDTO;}}
controller
获取支付状态
@ApiOperation("获取支付状态")@GetMapping("/status/{orderId}")public AjaxResult getPayStatus(@PathVariable String orderId){PayResultDTO payStatus = payService.getPayStatus(orderId);return AjaxResult.success("支付状态对象",payStatus);}
最终测试
使用沙箱版App登录账户扫码支付
希望对大家有所帮助!