接入alipay-sdk
沙箱环境申请地址:https://open.alipay.com/platform/appDaily.htm?tab=info所需参数://支付宝网关地址:https://openapi.alipay.com/gateway.do//支付宝申请的APPID//商户应用私钥(与支付宝数据交互时,保证数据安全,防止数据被篡改)//支付宝公钥(与支付宝数据交互时,保证数据安全,防止数据被篡改)//签名算
·
沙箱环境申请地址:https://open.alipay.com/platform/appDaily.htm?tab=info
所需参数:
//支付宝网关地址:https://openapi.alipay.com/gateway.do
//支付宝申请的APPID
//商户应用私钥(与支付宝数据交互时,保证数据安全,防止数据被篡改)
//支付宝公钥(与支付宝数据交互时,保证数据安全,防止数据被篡改)
//签名算法类型(RSA2或者RSA,支付宝推荐使用RSA2)
//编码格式(utf-8,gb2312,gbk)
各接口详细参数地址:https://opendocs.alipay.com/apis
沙箱app下载地址(注意沙箱APP只有安卓版本的):https://open.alipay.com/platform/appDaily.htm?tab=tool
maven包地址:
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.22.57.ALL</version>
</dependency>
SDK所需初始化参数类:
app:
pay:
ali:
app_id: 你的appId
mch_id: 你的沙箱商户id
server_url: https://openapi.alipaydev.com/gateway.do #这里是沙箱版本的地址
alipay_private_key: 你的应用私钥
alipay_public_key: 你的支付宝公钥
charset: UTF-8
sign_type: RSA2
format: json
notify_url: http://localhost:8080/api/pay/ali/notify
return_url: http://localhost:8080/api
refund_url: http://localhost:8080/api
/**
* @author zhangyujie
* @since 2022-04-05
**/
@Data
public class AliProperties {
/**
* 应用id
*/
public String appId;
/**
* 应用私钥
*/
public String alipayPrivateKey;
/**
* 支付宝公钥
*/
public String alipayPublicKey;
/**
* 字符编码
*/
public String charset;
/**
* 签名方式
*/
public String signType;
/**
* 数据格式
*/
public String format;
/**
* 商家id
*/
private String mchId;
/**
* 调用接口的url
*/
private String serverUrl;
/**
* 支付回调url
*/
private String notifyUrl;
/**
* pc支付前台通知
*/
private String returnUrl;
/**
* 退款url
*/
private String refundUrl;
}
/**
* @author zhangyujie
* @since 2022-04-05
**/
@Configuration
@ConfigurationProperties(prefix = "app.pay")
public class AppProperties {
private AliProperties ali = new AliProperties();
public AliProperties getAli() {
return ali;
}
public void setAli(AliProperties ali) {
this.ali = ali;
}
}
创建AlipayClient:
@Resource
private AppProperties appProperties;
/**
* 阿里 sdk 封装
*/
private AlipayClient alipayClient;
@PostConstruct
public void initMethod() {
alipayClient = new DefaultAlipayClient(
appProperties.getAli().getServerUrl(),
appProperties.getAli().getAppId(),
appProperties.getAli().getAlipayPrivateKey(),
appProperties.getAli().getFormat(),
appProperties.getAli().getCharset(),
appProperties.getAli().getAlipayPublicKey(),
appProperties.getAli().getSignType());
}
获取支付二维码:
/**
* 支付宝扫码支付生成二维码响应到浏览器
*
* @param amount
* @param response
* @return
*/
public void aliQrCodePay(Integer amount, HttpServletResponse response) throws Exception {
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
Map<String, String> params = new TreeMap<>();
params.put("out_trade_no", RandomUtil.randomNumbers(10));
params.put("total_amount", amount.toString());
params.put("subject", "备注");
params.put("body", "详情");
params.put("store_id", "NJ_2031");
params.put("timeout_express", "90m");
request.setBizContent(objectMapper.writeValueAsString(params));
request.setNotifyUrl(appProperties.getAli().getNotifyUrl());
AlipayTradePrecreateResponse responseData = alipayClient.execute(request);
log.info("response:{}", responseData.getBody());
String qrCode = responseData.getQrCode();
if (!ObjectUtils.isEmpty(qrCode)) {
// 这里工具类是根据支付宝返回的qrCode利用谷歌的zxing包生成的二维码放进response
PaymentUtils.createQRCode(qrCode, response);
}
}
测试生成二维码:
/**
* @author zhangyujie
* @since 2022-04-05
**/
@Slf4j
@RestController
@RequestMapping(value = "/api/pay/ali")
public class AliPayController {
@Resource
private AliPayService aliPayService;
/**
* 支付宝扫码支付预下单
*
* @param amount
* @param response
* @return
* @throws Exception
*/
@GetMapping("/qrcode")
public void qrCodePay(Integer amount, HttpServletResponse response) throws Exception {
aliPayService.aliQrCodePay(amount, response);
}
}
可以看到我们的sdk客户端创建的没问题,参数一切正常:这是调用返回的二维码字符串:
根据支付宝返回的qrCode利用谷歌的zxing包生成的二维码放进response
public static void createQRCode(String content, HttpServletResponse response) {
int width = 300, height = 300;
String format = "png";
Map<EncodeHintType, Object> hashMap = new HashMap<>();
hashMap.put(EncodeHintType.CHARACTER_SET, StandardCharsets.UTF_8);
hashMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
hashMap.put(EncodeHintType.MARGIN, 1);
try {
response.setHeader("Cache-control", "no-cache");
response.setHeader("Pragma", "no-cache");
response.setHeader("content-type", "image/png");
response.setCharacterEncoding(StandardCharsets.UTF_8.displayName());
response.setDateHeader("Expires", 0);
BitMatrix bitMatrix = new MultiFormatWriter()
.encode(content, BarcodeFormat.QR_CODE, width, height, hashMap);
BufferedImage img = MatrixToImageWriter.toBufferedImage(bitMatrix);
ImageIO.write(img, format, response.getOutputStream());
} catch (Exception e) {
log.warn("create QRCode error message:{}", e.getMessage());
}
}
postmain返回结果:
可以看到二维码是正常出来的,接下来我们使用沙箱APP扫码支付出现问题,咨询了支付宝开发组客服得知沙箱APP在升级,正常情况下是可以看到沙箱app的余额的,现在查看余额也是提示网络不给力请稍后重试
支付宝提现:
/**
* 支付宝提现
*
* @param amount
*/
public Result deposit(Integer amount) {
AlipayFundTransToaccountTransferModel transferModel = new AlipayFundTransToaccountTransferModel();
transferModel.setOutBizNo(RandomUtil.randomNumbers(10));
transferModel.setAmount("0.01");
transferModel.setPayeeAccount("收款方账户");
transferModel.setPayeeRealName("收款方真实姓名");
transferModel.setPayerShowName("付款方姓名");
transferModel.setRemark("remark");
// ALIPAY_LOGONID:支付宝登录号,支持邮箱和手机号格式
transferModel.setPayeeType("ALIPAY_LOGONID");
try {
AlipayFundTransToaccountTransferRequest request = new AlipayFundTransToaccountTransferRequest();
request.setBizModel(transferModel);
AlipayFundTransToaccountTransferResponse response = alipayClient.execute(request);
} catch (AlipayApiException e) {
log.info("ali deposit error message:{}", e.getMessage());
return Result.success(CommonMessage.ALI_DEPOSIT_SUCCESS);
}
return Result.error(CommonMessage.ALI_DEPOSIT_FAILED);
}
PC支付:
/**
* 阿里pc支付
*
* @param amount
* @param servletRequest
* @return
*/
public String aliPcPay(Integer amount, HttpServletRequest servletRequest) throws Exception {
AlipayTradePagePayRequest payRequest = new AlipayTradePagePayRequest();
// 前台通知
payRequest.setReturnUrl(appProperties.getAli().getReturnUrl());
// 后台回调
payRequest.setNotifyUrl(appProperties.getAli().getNotifyUrl());
Map<String, String> params = new TreeMap<>();
params.put("out_trade_no", "订单号");
// 订单金额:元
params.put("total_amount", amount.toString());
params.put("subject", "订单标题");
// 实际收款账号,一般填写商户PID即可
params.put("seller_id", appProperties.getAli().getMchId());
// 电脑网站支付
params.put("product_code", "FAST_INSTANT_TRADE_PAY");
params.put("body", "两个橘子");
payRequest.setBizContent(objectMapper.writeValueAsString(params));
log.info("业务参数:" + payRequest.getBizContent());
String result = CommonMessage.ERROR.getMessage();
try {
result = alipayClient.pageExecute(payRequest).getBody();
} catch (AlipayApiException e) {
log.error("ali pay error message:{}", e.getMessage());
}
return result;
}
支付宝退款:
/**
* 支付宝退款
* @param outTradeNo
* @param tradeNo
* @param amount
* @param servletRequest
* @return
* @throws Exception
*/
public Result aliRefund(String outTradeNo,String tradeNo,Integer amount, HttpServletRequest servletRequest) throws Exception {
// 创建退款请求builder,设置请求参数
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
Map<String, String> params = new TreeMap<>();
// 必须 商户订单号
params.put("out_trade_no", outTradeNo);
// 必须 支付宝交易号
params.put("trade_no", tradeNo);
// 必须 退款金额
params.put("refund_amount", amount.toString());
// 可选 代表 退款的原因说明
params.put("refund_reason", "退款的原因说明");
// 可选 标识一次退款请求,同一笔交易多次退款需要保证唯一(就是out_request_no在2次退款一笔交易时,要不一样),如需部分退款,则此参数必传
params.put("out_request_no", RandomUtil.randomNumbers(10));
// 可选 代表 商户的门店编号
params.put("store_id", "90m");
request.setBizContent(objectMapper.writeValueAsString(params));
AlipayTradeRefundResponse responseData = alipayClient.execute(request);
if (responseData.isSuccess()) {
log.info("ali refund success tradeNo:{}", "订单号");
return Result.success(CommonMessage.SUCCESS);
}
log.info("ali refund failed tradeNo:{}", "订单号");
return Result.error(CommonMessage.ALI_PAY_REFUND_FAILED);
}
APP支付:
/**
* 支付宝App支付
*
* @param amount
* @param servletRequest
* @return
*/
public String appPay(Integer amount, HttpServletRequest servletRequest) {
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
// SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setBody("购买手机");
model.setSubject("iPhone 13 pro max");
model.setOutTradeNo(RandomUtil.randomNumbers(10));
model.setTimeoutExpress("30m");
model.setTotalAmount(amount.toString());
model.setProductCode("QUICK_MSECURITY_PAY");
request.setBizModel(model);
request.setNotifyUrl(appProperties.getAli().getNotifyUrl());
try {
// 这里和普通的接口调用不同,使用的是sdkExecute
AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
//就是orderString 可以直接给客户端请求,无需再做处理。
log.info("orderString:{}", response.getBody());
return response.getBody();
} catch (AlipayApiException e) {
e.printStackTrace();
}
return null;
}
支付宝回调地址:
/**
* 支付回调通知
*
* @param request
* @param response
*/
public void aliNotify(HttpServletRequest request, HttpServletResponse response) throws IOException {
String requestXml = PaymentUtils.getRequestData(request);
Map requestMap = PaymentUtils.xmlToMap(requestXml);
Assert.notNull(requestMap, CommonMessage.XML_DATA_INCORRECTNESS.getMessage());
// 当返回的return_code为SUCCESS则回调成功
if (requestMap.get("code").equals(10000)) {
log.info("notify success");
} else {
log.error("notify failed");
}
}
更多推荐
已为社区贡献1条内容
所有评论(0)