戴南做网站,电子商务网站建设课程,企业网络营销的意义,网站建设的目的是什么环境说明#xff1a;SpringBoot3.0.2
支付宝沙箱地址#xff1a;沙箱地址 获取配置信息 因支付需要回调地址#xff0c;回调地址必须是公网#xff0c;如果有公网的话#xff0c;那直接在下面配置文件填写自己的公网#xff0c;没有的话#xff0c;就需要我们借助第三…环境说明SpringBoot3.0.2
支付宝沙箱地址沙箱地址 获取配置信息 因支付需要回调地址回调地址必须是公网如果有公网的话那直接在下面配置文件填写自己的公网没有的话就需要我们借助第三方工具来进行回调。具体操作请看这篇博客
引入依赖
dependencygroupIdcom.alipay.sdk/groupIdartifactIdalipay-sdk-java/artifactIdversion4.22.110.ALL/version
/dependency配置文件
yz:alipay:gatewayUrl: https://openapi-sandbox.dl.alipaydev.com/gateway.doappId: 你的appidprivateKey: 你的私钥format: jsonpublicKey: 你的公钥charset: UTF-8signType: RSA2returnUrl: http://xxxxxx.natappfree.cc/api/pay/finish # 回调成功后调用的地址notifyUrl: http://xxxxxx.natappfree.cc/api/pay/notify # 回调地址expireTime: 15mreturn:url: http://localhost:8000/account/center # 这个就写你支付成功跳转的页面
配置类
Data
Configuration
ConfigurationProperties(prefix yz.alipay)
public class AliPayProperties {private String gatewayUrl;private String appId;private String privateKey;private String format;private String publicKey;private String charset;private String signType;private String notifyUrl;private String returnUrl;private String expireTime;
}
Data
Configuration
ConfigurationProperties(prefix yz.return)
public class ReturnProperties {private String url;
}订单信息
Data
public class PayOrderRequest {private static final long serialVersionUID 3191241716373120793L;Schema(description 订单号)private Long id;Schema(description 用户id)private Long uid;Schema(description 主题)private String subject;Schema(description 充值金额)private Long amount;Schema(description 实际金额)private Float realAmount;Schema(description 优惠率)private Float discountRate;
}支付的回调信息封装成类
Data
public class AlipayNotifyDto {private String gmt_create;private String charset;private String gmt_payment;private String notify_time;private String subject;private String sign;private String buyer_id;private String invoice_amount;private String version;private String notify_id;private String fund_bill_list;private String notify_type;private String out_trade_no;private String total_amount;private String trade_status;private String trade_no;private String auth_app_id;private String receipt_amount;private String point_amount;private String buyer_pay_amount;private String app_id;private String sign_type;private String seller_id;
}Facade接口
Tag(name 支付接口)
public interface PayFacade {Operation(summary 支付)Parameters(value {Parameter(name uid, description 用户id, in ParameterIn.HEADER)})PostMapping(/pay/)BaseResponseString reCharge(RequestHeader Long uid, RequestBody PayOrderRequest payOrderRequest);Operation(summary 支付宝异步通知支付宝支付后会回调该接口)PostMapping(/pay/notify)String notify(AlipayNotifyDto alipayNotifyDto);Operation(summary 同步跳转告诉你是否调用成功不能拿来判断支付成功)GetMapping(/pay/finish)void finish(HttpServletResponse response);
}
Controller类
Slf4j
RestController
RequiredArgsConstructor
public class PayController implements PayFacade {private final PayService payService;Overridepublic BaseResponseString reCharge(Long uid, PayOrderRequest payOrderRequest) {if(payOrderRequest null || uid null){throw new RuntimeException(参数不能为空);}String res payService.reCharge(uid, payOrderRequest);return ResultUtils.success(,res);}public String notify(AlipayNotifyDto alipayNotifyDto) {if(alipayNotifyDto null){throw new RuntimeException(参数不能为空);}String res payService.notifyUrl(alipayNotifyDto);return res;}public void finish(HttpServletResponse response) {try{response.sendRedirect(returnProperties.getUrl());} catch (Exception e){log.error(【同步跳转告诉你是否调用成功不能拿来判断支付成功】,e);}}
}Service类
Slf4j
Service
RequiredArgsConstructor
public class PayServiceImpl extends ServiceImplPayMapper, PayFlow implements PayService {private final AliPayProperties aliPayProperties;private final PayMessageProducer payMessageProducer;private final UserMessageProducer userMessageProducer;private final PromotionMessageProducer promotionMessageProducer;private final OrderMessageProducer orderMessageProducer;// 携带订单信息获取支付urlOverridepublic String reCharge(Long uid, PayOrderRequest payOrderRequest) {try{log.info(payOrderRequest支付信息:{}, payOrderRequest);//保存流水---交给mq处理payMessageProducer.sendMessage(JSON.toJSONString(payOrderRequest));// 交易String path sendPayment(payOrderRequest);return path;}catch (Exception e){log.info(支付异常, e);throw new RuntimeException(系统出错);}}// 处理回调逻辑Overridepublic String notifyUrl(AlipayNotifyDto alipayNotifyDto) {log.info(setTradeStatus: {}, alipayNotifyDto.getTrade_status());log.info(回调了);String payStatus fail;boolean signVerified false;MapString, String mp JSON.parseObject(JSON.toJSONString(alipayNotifyDto), Map.class);try {signVerified AlipaySignature.rsaCheckV1(mp, aliPayProperties.getPublicKey(), aliPayProperties.getCharset(), aliPayProperties.getSignType());log.info(【异步通知签名验证】 signVerified);}catch (AlipayApiException e){System.out.println(【异步签名异常】 e.getErrMsg());return payStatus;}if(signVerified TRADE_SUCCESS.equals(alipayNotifyDto.getTrade_status())){// 更新流水---这块应该也交给mq处理不想写了就这样吧updatePayFlowSuccess(alipayNotifyDto.getOut_trade_no());// 更新订单---交给mq处理orderMessageProducer.sendMessage(alipayNotifyDto.getOut_trade_no());// 消费优惠卷---交给mq处理promotionMessageProducer.sendMessage(alipayNotifyDto.getOut_trade_no());// 用户金币新增---交给mq处理userMessageProducer.sendMessage(alipayNotifyDto.getOut_trade_no());payStatus success;}log.info(【异步通知签名验证】 payStatus);return payStatus;}Overridepublic void returnUrl(HttpServletRequest request) throws UnsupportedEncodingException {}// 更新支付流水private void updatePayFlowSuccess(String outTradeNo){QueryWrapperPayFlow queryWrapper new QueryWrapper();queryWrapper.eq(out_trade_no, Long.parseLong(outTradeNo));PayFlow payFlow PayFlow.builder().build();payFlow.setTradeStatus(PayConstant.TRADE_SUCCESS);payFlow.setPaySuccess(true);boolean update this.update(payFlow, queryWrapper);if(!update){log.info(更新流水失败);throw new RuntimeException(更新流水失败);}}// 支付配置private AlipayConfig getAlipayConfig() {AlipayConfig alipayConfig new AlipayConfig();alipayConfig.setServerUrl(aliPayProperties.getGatewayUrl());alipayConfig.setAlipayPublicKey(aliPayProperties.getPublicKey());alipayConfig.setPrivateKey(aliPayProperties.getPrivateKey());alipayConfig.setAppId(aliPayProperties.getAppId());alipayConfig.setFormat(aliPayProperties.getFormat());alipayConfig.setCharset(aliPayProperties.getCharset());alipayConfig.setSignType(aliPayProperties.getSignType());return alipayConfig;}// 返回支付urlprivate String sendPayment(PayOrderRequest payOrderRequest){try {AlipayClient alipayClient new DefaultAlipayClient(this.getAlipayConfig());AlipayTradePagePayRequest request this.getAlipayTradePagePayRequest(payOrderRequest);request.setReturnUrl(aliPayProperties.getReturnUrl());request.setNotifyUrl(aliPayProperties.getNotifyUrl());// 调用SDK生成表单AlipayTradePagePayResponse alipayTradePagePayResponse alipayClient.pageExecute(request, GET);String body alipayTradePagePayResponse.getBody();return body;} catch (Exception e) {e.printStackTrace();}return null;}private AlipayTradePagePayRequest getAlipayTradePagePayRequest(PayOrderRequest payOrderRequest) {AlipayTradePagePayRequest request new AlipayTradePagePayRequest();//异步接收地址仅支持http/https公网可访问request.setNotifyUrl();//同步跳转地址仅支持http/httpsrequest.setReturnUrl();/******必传参数******/JSONObject bizContent new JSONObject();//商户订单号商家自定义保持唯一性bizContent.put(out_trade_no, payOrderRequest.getId());//支付金额最小值0.01元bizContent.put(total_amount, payOrderRequest.getRealAmount());//订单标题不可使用特殊符号bizContent.put(subject, payOrderRequest.getSubject());//电脑网站支付场景固定传值FAST_INSTANT_TRADE_PAYbizContent.put(product_code, FAST_INSTANT_TRADE_PAY);bizContent.put(timeout_express, aliPayProperties.getExpireTime());request.setBizContent(bizContent.toString());return request;}
}