| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- package com.izouma.nineth.service;
- import cn.com.sandpay.cashier.sdk.*;
- import com.alibaba.fastjson.JSONObject;
- import com.izouma.nineth.config.SandPayProperties;
- import com.izouma.nineth.domain.GiftOrder;
- import com.izouma.nineth.domain.MintOrder;
- import com.izouma.nineth.domain.Order;
- import com.izouma.nineth.enums.MintOrderStatus;
- import com.izouma.nineth.enums.OrderStatus;
- import com.izouma.nineth.exception.BusinessException;
- import com.izouma.nineth.repo.GiftOrderRepo;
- import com.izouma.nineth.repo.MintOrderRepo;
- import com.izouma.nineth.repo.OrderRepo;
- import com.izouma.nineth.utils.DateTimeUtils;
- import lombok.AllArgsConstructor;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.commons.codec.binary.Base64;
- import org.apache.commons.lang.StringUtils;
- import org.springframework.cache.annotation.Cacheable;
- import org.springframework.stereotype.Service;
- import java.io.IOException;
- import java.math.BigDecimal;
- import java.net.URLDecoder;
- import java.nio.charset.StandardCharsets;
- import java.text.DecimalFormat;
- import java.text.DecimalFormatSymbols;
- import java.text.SimpleDateFormat;
- import java.time.LocalDateTime;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.Locale;
- import java.util.Map;
- @Service
- @AllArgsConstructor
- @Slf4j
- public class SandPayService {
- private final OrderRepo orderRepo;
- private final GiftOrderRepo giftOrderRepo;
- private final SandPayProperties sandPayProperties;
- private final MintOrderRepo mintOrderRepo;
- public JSONObject requestServer(JSONObject header, JSONObject body, String reqAddr) {
- Map<String, String> reqMap = new HashMap<String, String>();
- JSONObject reqJson = new JSONObject();
- reqJson.put("head", header);
- reqJson.put("body", body);
- String reqStr = reqJson.toJSONString();
- String reqSign;
- // 签名
- try {
- reqSign = new String(Base64.encodeBase64(CryptoUtil.digitalSign(reqStr.getBytes(StandardCharsets.UTF_8), CertUtil.getPrivateKey(), "SHA1WithRSA")));
- } catch (Exception e) {
- log.error(e.getMessage());
- return null;
- }
- //整体报文格式
- reqMap.put("charset", "UTF-8");
- reqMap.put("data", reqStr);
- reqMap.put("signType", "01");
- reqMap.put("sign", reqSign);
- reqMap.put("extend", "");
- String result;
- try {
- log.info("请求报文:\n" + JSONObject.toJSONString(reqJson, true));
- result = HttpClient.doPost(reqAddr, reqMap, 30000, 30000);
- result = URLDecoder.decode(result, StandardCharsets.UTF_8);
- } catch (IOException e) {
- log.error(e.getMessage());
- return null;
- }
- Map<String, String> respMap = SDKUtil.convertResultStringToMap(result);
- String respData = respMap.get("data");
- String respSign = respMap.get("sign");
- // 验证签名
- boolean valid;
- try {
- valid = CryptoUtil.verifyDigitalSign(respData.getBytes(StandardCharsets.UTF_8), Base64.decodeBase64(respSign), CertUtil.getPublicKey(), "SHA1WithRSA");
- if (!valid) {
- log.error("verify sign fail.");
- return null;
- }
- log.info("verify sign success");
- JSONObject respJson = JSONObject.parseObject(respData);
- if (respJson != null) {
- log.info("响应码:[" + respJson.getJSONObject("head").getString("respCode") + "]");
- log.info("响应描述:[" + respJson.getJSONObject("head").getString("respMsg") + "]");
- log.info("响应报文:\n" + JSONObject.toJSONString(respJson, true));
- } else {
- log.error("服务器请求异常!!!");
- }
- return respJson;
- } catch (Exception e) {
- log.error(e.getMessage());
- return null;
- }
- }
- public JSONObject requestAlipay(String orderId, BigDecimal amount, String subject, String desc,
- LocalDateTime timeout, String extend) {
- if (orderId.length() < 12) {
- for (int i = orderId.length(); i < 12; i++) {
- orderId = "0" + orderId;
- }
- }
- JSONObject header = new JSONObject();
- header.put("version", "1.0"); //版本号
- header.put("method", "sandpay.trade.precreate"); //接口名称:统一下单并支付
- header.put("productId", "00000006"); //产品编码
- header.put("mid", sandPayProperties.getMid()); //商户号
- header.put("accessType", "1"); //接入类型设置为普通商户接入
- header.put("channelType", "07"); //渠道类型:07-互联网 08-移动端
- header.put("reqTime", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())); //请求时间
- DecimalFormat df = new DecimalFormat("000000000000", DecimalFormatSymbols.getInstance(Locale.US));
- JSONObject body = new JSONObject();
- body.put("payTool", "0401"); //支付工具: 固定填写0401
- body.put("orderCode", orderId); //商户订单号
- body.put("totalAmount", df.format(amount.multiply(new BigDecimal("100")))); //订单金额 12位长度,精确到分
- //body.put("limitPay", "5"); //限定支付方式 送1-限定不能使用贷记卡 送4-限定不能使用花呗 送5-限定不能使用贷记卡+花呗
- body.put("subject", subject); //订单标题
- body.put("body", desc); //订单描述
- body.put("txnTimeOut", DateTimeUtils.format(timeout, "yyyyMMddHHmmss")); //订单超时时间
- body.put("notifyUrl", sandPayProperties.getNotifyUrl()); //异步通知地址
- body.put("bizExtendParams", ""); //业务扩展参数
- body.put("merchExtendParams", ""); //商户扩展参数
- body.put("extend", extend); //扩展域
- return requestServer(header, body, "https://cashier.sandpay.com.cn/qr/api/order/create");
- }
- public JSONObject query(String orderId) {
- JSONObject header = new JSONObject();
- header.put("version", "1.0"); //版本号
- header.put("method", "sandpay.trade.query"); //接口名称:订单查询
- header.put("productId", "00000006"); //产品编码
- header.put("mid", sandPayProperties.getMid()); //商户号
- header.put("accessType", "1"); //接入类型设置为普通商户接入
- header.put("channelType", "07"); //渠道类型:07-互联网 08-移动端
- header.put("reqTime", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())); //请求时间
- JSONObject body = new JSONObject();
- body.put("orderCode", orderId);
- body.put("extend", ""); //扩展域
- return requestServer(header, body, "https://cashier.sandpay.com.cn/qr/api/order/query");
- }
- @Cacheable(value = "sandPay", key = "#orderId")
- public String payOrder(Long orderId) {
- Order order = orderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在"));
- if (order.getStatus() != OrderStatus.NOT_PAID) {
- throw new BusinessException("订单状态错误");
- }
- JSONObject extend = new JSONObject();
- extend.put("type", "order");
- extend.put("id", orderId);
- JSONObject res = requestAlipay(orderId.toString(), order.getTotalPrice(), order.getName(), order.getName(),
- order.getCreatedAt().plusMinutes(3), extend.toJSONString());
- if (res == null)
- throw new BusinessException("下单失败,请稍后再试");
- if (!"000000".equals(res.getJSONObject("head").getString("respCode"))) {
- String msg = res.getJSONObject("head").getString("respMsg");
- if (msg.contains("超限")) {
- throw new BusinessException("超过商户单日额度");
- }
- throw new BusinessException(msg);
- }
- return res.getJSONObject("body").getString("qrCode");
- }
- @Cacheable(value = "sandPay", key = "#orderId")
- public String payGiftOrder(Long orderId) {
- GiftOrder order = giftOrderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在"));
- if (order.getStatus() != OrderStatus.NOT_PAID) {
- throw new BusinessException("订单状态错误");
- }
- JSONObject extend = new JSONObject();
- extend.put("type", "gift");
- extend.put("id", orderId);
- JSONObject res = requestAlipay(orderId.toString(), order.getGasPrice(), "转增" + order.getAssetId(), "转增" + order.getAssetId(),
- order.getCreatedAt().plusMinutes(3), extend.toJSONString());
- if (res == null)
- throw new BusinessException("下单失败,请稍后再试");
- if (!"000000".equals(res.getJSONObject("head").getString("respCode"))) {
- String msg = res.getJSONObject("head").getString("respMsg");
- if (msg.contains("超限")) {
- throw new BusinessException("超过商户单日额度");
- }
- throw new BusinessException(msg);
- }
- return res.getJSONObject("body").getString("qrCode");
- }
- @Cacheable(value = "sandPay", key = "#orderId")
- public String payMintOrder(Long orderId) {
- MintOrder order = mintOrderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在"));
- if (order.getStatus() != MintOrderStatus.NOT_PAID) {
- throw new BusinessException("订单状态错误");
- }
- JSONObject extend = new JSONObject();
- extend.put("type", "mintOrder");
- extend.put("id", orderId);
- JSONObject res = requestAlipay(orderId.toString(), order.getGasPrice(), "铸造活动:" + order.getMintActivityId(),
- "铸造活动:" + order.getMintActivityId(), order.getCreatedAt().plusMinutes(3), extend.toJSONString());
- if (res == null)
- throw new BusinessException("下单失败,请稍后再试");
- if (!"000000".equals(res.getJSONObject("head").getString("respCode"))) {
- String msg = res.getJSONObject("head").getString("respMsg");
- if (msg.contains("超限")) {
- throw new BusinessException("超过商户单日额度");
- }
- throw new BusinessException(msg);
- }
- return res.getJSONObject("body").getString("qrCode");
- }
- }
|