Browse Source

feat 0 支付工程

devlop
yang_shj 4 years ago
parent
commit
426b53f326
  1. 10
      payment-base-app/payment-base-app.iml
  2. 6
      payment-base-app/pom.xml
  3. 13
      payment-base-app/src/main/java/com/base/springcloud/bo/SaleBillBO.java
  4. 8
      payment-base-app/src/main/java/com/base/springcloud/constant/ErrorConstant.java
  5. 6
      payment-base-app/src/main/java/com/base/springcloud/constant/PaymentConstant.java
  6. 22
      payment-base-app/src/main/java/com/base/springcloud/controller/PaymentController.java
  7. 2
      payment-base-app/src/main/java/com/base/springcloud/dao/SaleBillMapper.java
  8. 2
      payment-base-app/src/main/java/com/base/springcloud/entity/Order.java
  9. 9
      payment-base-app/src/main/java/com/base/springcloud/service/BillService.java
  10. 28
      payment-base-app/src/main/java/com/base/springcloud/service/imp/BillServiceImp.java
  11. 11
      payment-base-app/src/main/java/com/base/springcloud/service/imp/MerchantServiceImp.java
  12. 17
      payment-base-app/src/main/java/com/base/springcloud/service/imp/OrderServiceImp.java
  13. 12
      payment-base-app/src/main/java/com/base/springcloud/service/imp/PaymentServiceImp.java
  14. 133
      payment-base-app/src/main/java/com/base/springcloud/service/imp/WecPaymentServiceImp.java
  15. 42
      payment-base-app/src/main/java/com/base/springcloud/util/ParameterUtil.java
  16. 73
      payment-base-app/src/main/java/com/base/springcloud/wxsdk/WxpayUtils.java
  17. 9
      payment-base-app/src/main/resources/com/base/payment/mapper/OrderMapper.xml
  18. 7
      payment-base-app/src/main/resources/com/base/payment/mapper/SaleBillMapper.xml

10
payment-base-app/payment-base-app.iml

@ -74,13 +74,13 @@
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:json-smart:2.3" level="project" /> <orderEntry type="library" scope="TEST" name="Maven: net.minidev:json-smart:2.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:accessors-smart:1.2" level="project" /> <orderEntry type="library" scope="TEST" name="Maven: net.minidev:accessors-smart:1.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.ow2.asm:asm:5.0.4" level="project" /> <orderEntry type="library" scope="TEST" name="Maven: org.ow2.asm:asm:5.0.4" level="project" />
<orderEntry type="library" name="Maven: junit:junit:4.12" level="project" /> <orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.assertj:assertj-core:3.11.1" level="project" /> <orderEntry type="library" scope="TEST" name="Maven: org.assertj:assertj-core:3.11.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-core:2.23.4" level="project" /> <orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-core:2.23.4" level="project" />
<orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.9.12" level="project" /> <orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.9.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy-agent:1.9.12" level="project" /> <orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy-agent:1.9.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:2.6" level="project" /> <orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:2.6" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" /> <orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-library:1.3" level="project" /> <orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-library:1.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.skyscreamer:jsonassert:1.5.0" level="project" /> <orderEntry type="library" scope="TEST" name="Maven: org.skyscreamer:jsonassert:1.5.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.vaadin.external.google:android-json:0.0.20131108.vaadin1" level="project" /> <orderEntry type="library" scope="TEST" name="Maven: com.vaadin.external.google:android-json:0.0.20131108.vaadin1" level="project" />
@ -106,7 +106,7 @@
<orderEntry type="library" name="Maven: org.mapstruct:mapstruct:1.2.0.Final" level="project" /> <orderEntry type="library" name="Maven: org.mapstruct:mapstruct:1.2.0.Final" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-swagger-ui:2.9.2" level="project" /> <orderEntry type="library" name="Maven: io.springfox:springfox-swagger-ui:2.9.2" level="project" />
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.6.2" level="project" /> <orderEntry type="library" name="Maven: com.google.code.gson:gson:2.6.2" level="project" />
<orderEntry type="library" name="Maven: com.github.wechatpay-apiv3:wechatpay-apache-httpclient:0.2.2" level="project" /> <orderEntry type="library" name="Maven: com.github.wechatpay-apiv3:wechatpay-apache-httpclient:0.4.2" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.apache.httpcomponents:httpmime:4.5.8" level="project" /> <orderEntry type="library" scope="RUNTIME" name="Maven: org.apache.httpcomponents:httpmime:4.5.8" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.9.8" level="project" /> <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.9.8" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.9.8" level="project" /> <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.9.8" level="project" />
@ -166,9 +166,9 @@
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form-spring:3.2.2" level="project" /> <orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form-spring:3.2.2" level="project" />
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.3.3" level="project" /> <orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.3.3" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form:3.2.2" level="project" /> <orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form:3.2.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.11" level="project" /> <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.12" level="project" />
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.11" level="project" /> <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.11" level="project" />
<orderEntry type="library" name="Maven: commons-httpclient:commons-httpclient:3.0.1" level="project" /> <orderEntry type="library" name="Maven: commons-httpclient:commons-httpclient:3.1" level="project" />
<orderEntry type="library" name="Maven: commons-logging:commons-logging:1.1" level="project" /> <orderEntry type="library" name="Maven: commons-logging:commons-logging:1.1" level="project" />
<orderEntry type="library" name="Maven: log4j:log4j:1.2.17" level="project" /> <orderEntry type="library" name="Maven: log4j:log4j:1.2.17" level="project" />
<orderEntry type="library" name="Maven: logkit:logkit:1.0.1" level="project" /> <orderEntry type="library" name="Maven: logkit:logkit:1.0.1" level="project" />

6
payment-base-app/pom.xml

@ -78,7 +78,7 @@
<dependency> <dependency>
<groupId>com.github.wechatpay-apiv3</groupId> <groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-apache-httpclient</artifactId> <artifactId>wechatpay-apache-httpclient</artifactId>
<version>0.2.2</version> <version>0.4.2</version>
</dependency> </dependency>
<!-- ftp client --> <!-- ftp client -->
@ -142,7 +142,7 @@
<dependency> <dependency>
<groupId>org.apache.httpcomponents</groupId> <groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId> <artifactId>httpclient</artifactId>
<version>4.5.11</version> <version>4.5.12</version>
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>commons-codec</groupId> <groupId>commons-codec</groupId>
@ -155,7 +155,7 @@
<dependency> <dependency>
<groupId>commons-httpclient</groupId> <groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId> <artifactId>commons-httpclient</artifactId>
<version>3.0.1</version> <version>3.1</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>commons-logging</groupId> <groupId>commons-logging</groupId>

13
payment-base-app/src/main/java/com/base/springcloud/bo/SaleBillBO.java

@ -0,0 +1,13 @@
package com.base.springcloud.bo;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class SaleBillBO {
private String id;
private BigDecimal payAmount;
}

8
payment-base-app/src/main/java/com/base/springcloud/constant/ErrorConstant.java

@ -2,8 +2,12 @@ package com.base.springcloud.constant;
public enum ErrorConstant { public enum ErrorConstant {
SUECCESS("RBS00000","交易成功"), SUECCESS("RBS00000","交易成功!"),
NULL_OBJ("RBS00001","参数异常"); NULL_OBJ("RBS00001","参数异常!"),
MCH_ID_PARAM_ERR("RBS00002","商户支付配置异常!"),
BILL_AMOUNT_ERR("RBS00003","销售单合计结算金额异常!"),
BILL_INVALID("RBS00004","无效销售单据!"),
BILL_WRITE_OFF_FAIL("RBS00005","销售单据核销失败!");
private String code; private String code;
private String message; private String message;

6
payment-base-app/src/main/java/com/base/springcloud/constant/PaymentConstant.java

@ -9,6 +9,7 @@ public interface PaymentConstant {
String WAIT = "W"; // 等待付款 String WAIT = "W"; // 等待付款
String SUECCESS = "S"; // 支付成功 String SUECCESS = "S"; // 支付成功
String WX_SUCCESS = "SUCCESS"; // 微信支付成功状态
String REFUND = "R"; // 退款成功 String REFUND = "R"; // 退款成功
String CANCLE = "C"; // 撤销 String CANCLE = "C"; // 撤销
@ -30,4 +31,9 @@ public interface PaymentConstant {
String ORDER_QUEUE = "order_queue"; // 订单队列 String ORDER_QUEUE = "order_queue"; // 订单队列
String ORDER_LOCK_PREFIX = "ORDER_KEY:"; // 订单锁前缀 String ORDER_LOCK_PREFIX = "ORDER_KEY:"; // 订单锁前缀
String DEFAULT_MCH_ID = "1537100771"; // 默认商户ID
String METHOD_GET = "GET"; // GET请求
String METHOD_POST = "POST"; // POST请求
String WX_ORDER_QUERY_URL = "https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/";
} }

22
payment-base-app/src/main/java/com/base/springcloud/controller/PaymentController.java

@ -1,13 +1,11 @@
package com.base.springcloud.controller; package com.base.springcloud.controller;
import com.base.springcloud.base.CommonResult;
import com.base.springcloud.base.ReportResult; import com.base.springcloud.base.ReportResult;
import com.base.springcloud.bo.OrderBO; import com.base.springcloud.bo.OrderBO;
import com.base.springcloud.constant.ErrorConstant; import com.base.springcloud.constant.PaymentConstant;
import com.base.springcloud.dto.NativePlaceOrderDTO; import com.base.springcloud.dto.NativePlaceOrderDTO;
import com.base.springcloud.entity.Order;
import com.base.springcloud.service.PaymentService; import com.base.springcloud.service.PaymentService;
import com.base.springcloud.util.DateUtil; import com.base.springcloud.util.ParameterUtil;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -17,9 +15,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.List; import java.util.List;
@RestController @RestController
@ -28,21 +24,17 @@ import java.util.List;
@RequestMapping("/payment") @RequestMapping("/payment")
public class PaymentController { public class PaymentController {
@Autowired
private ParameterUtil parameterUtil;
@Autowired @Autowired
private PaymentService paymentService; private PaymentService paymentService;
@ApiOperation(value = "native下单", notes = "微信native下单") @ApiOperation(value = "native下单", notes = "微信native下单")
@GetMapping("/nativePlaceOrder") @GetMapping("/nativePlaceOrder")
public ReportResult nativePlaceOrder(@RequestParam String salesBillId) { public ReportResult nativePlaceOrder(@RequestParam String salesBillId) {
String mchId = "888027018000004"; OrderBO orderBO = parameterUtil.nativePlaceOrderBefore(salesBillId);
OrderBO orderBO = new OrderBO();
orderBO.setBillId(salesBillId);
orderBO.setMchId(mchId);
String codeUrl = paymentService.placeOrder(orderBO); String codeUrl = paymentService.placeOrder(orderBO);
List<NativePlaceOrderDTO> array = new ArrayList<>(); return new ReportResult(parameterUtil.nativePlaceOrderAfter(codeUrl));
NativePlaceOrderDTO nativePlaceOrderDTO = new NativePlaceOrderDTO();
nativePlaceOrderDTO.setCodeUrl(codeUrl);
array.add(nativePlaceOrderDTO);
return new ReportResult(array);
} }
} }

2
payment-base-app/src/main/java/com/base/springcloud/dao/SaleBillMapper.java

@ -19,4 +19,6 @@ public interface SaleBillMapper {
int updateByPrimaryKey(SaleBill record); int updateByPrimaryKey(SaleBill record);
SaleBill queryBillInfo(SaleBill saleBill); SaleBill queryBillInfo(SaleBill saleBill);
int writeOffBill(SaleBill bill);
} }

2
payment-base-app/src/main/java/com/base/springcloud/entity/Order.java

@ -33,6 +33,8 @@ public class Order extends BaseEntity {
private String goodId; private String goodId;
private String sourceBillId;
private String orderType; private String orderType;
private String orderState; private String orderState;

9
payment-base-app/src/main/java/com/base/springcloud/service/BillService.java

@ -1,6 +1,8 @@
package com.base.springcloud.service; package com.base.springcloud.service;
import com.base.springcloud.bo.OrderBO; import com.base.springcloud.bo.OrderBO;
import com.base.springcloud.bo.SaleBillBO;
import com.base.springcloud.entity.SaleBill;
public interface BillService { public interface BillService {
@ -9,4 +11,11 @@ public interface BillService {
* @param orderBO * @param orderBO
*/ */
void billCheck(OrderBO orderBO); void billCheck(OrderBO orderBO);
/**
* 核销销售单据
* @param saleBillBO
* @return
*/
void writeOffBill(SaleBillBO saleBillBO);
} }

28
payment-base-app/src/main/java/com/base/springcloud/service/imp/BillServiceImp.java

@ -1,6 +1,10 @@
package com.base.springcloud.service.imp; package com.base.springcloud.service.imp;
import com.base.springcloud.aspect.annotation.BusinessException;
import com.base.springcloud.bo.OrderBO; import com.base.springcloud.bo.OrderBO;
import com.base.springcloud.bo.SaleBillBO;
import com.base.springcloud.constant.ErrorConstant;
import com.base.springcloud.constant.PaymentConstant;
import com.base.springcloud.dao.SaleBillMapper; import com.base.springcloud.dao.SaleBillMapper;
import com.base.springcloud.entity.SaleBill; import com.base.springcloud.entity.SaleBill;
import com.base.springcloud.service.BillService; import com.base.springcloud.service.BillService;
@ -20,17 +24,33 @@ public class BillServiceImp implements BillService {
@Autowired @Autowired
private SaleBillMapper saleBillMapper; private SaleBillMapper saleBillMapper;
/**
* 销售单据核查
* @param orderBO
*/
@Override @Override
public void billCheck(OrderBO orderBO) { public void billCheck(OrderBO orderBO) {
SaleBill saleBill = new SaleBill(); SaleBill saleBill = new SaleBill();
saleBill.setId(orderBO.getBillId()); saleBill.setId(orderBO.getBillId());
SaleBill queryResult = saleBillMapper.queryBillInfo(saleBill); SaleBill queryResult = saleBillMapper.queryBillInfo(saleBill);
if(!Optional.ofNullable(queryResult).isPresent()){ if(!Optional.ofNullable(queryResult).isPresent()){
saleBill.setTotalAmount(new BigDecimal(1)); throw new BusinessException(ErrorConstant.BILL_INVALID);
orderBO.setSaleBill(saleBill);
logger.warn("==================销售单据查询失败!=============================");
return;
} }
orderBO.setSaleBill(queryResult); orderBO.setSaleBill(queryResult);
} }
/**
* 核销销售单据
* @param saleBillBO
* @return
*/
@Override
public void writeOffBill(SaleBillBO saleBillBO) {
SaleBill saleBill = new SaleBill();
saleBill.setId(saleBillBO.getId());
saleBill.setPayAmount(saleBillBO.getPayAmount());
int count = saleBillMapper.writeOffBill(saleBill);
if(count > 0) return;
throw new BusinessException(ErrorConstant.BILL_WRITE_OFF_FAIL);
}
} }

11
payment-base-app/src/main/java/com/base/springcloud/service/imp/MerchantServiceImp.java

@ -1,7 +1,9 @@
package com.base.springcloud.service.imp; package com.base.springcloud.service.imp;
import com.base.springcloud.aspect.annotation.BusinessException;
import com.base.springcloud.bo.MerchantConfigBO; import com.base.springcloud.bo.MerchantConfigBO;
import com.base.springcloud.bo.OrderBO; import com.base.springcloud.bo.OrderBO;
import com.base.springcloud.constant.ErrorConstant;
import com.base.springcloud.dao.MerchantConfigMapper; import com.base.springcloud.dao.MerchantConfigMapper;
import com.base.springcloud.entity.MerchantConfig; import com.base.springcloud.entity.MerchantConfig;
import com.base.springcloud.service.MerchantService; import com.base.springcloud.service.MerchantService;
@ -110,15 +112,16 @@ public class MerchantServiceImp implements MerchantService {
@Override @Override
public void claimMerchantConfig(OrderBO orderBO) { public void claimMerchantConfig(OrderBO orderBO) {
if(!Optional.ofNullable(orderBO).map(o->orderBO.getMchId()).isPresent()){ if(!Optional.ofNullable(orderBO).map(o->orderBO.getMchId()).isPresent()){
// TODO 抛出业务异常 throw new BusinessException(ErrorConstant.MCH_ID_PARAM_ERR);
return;
} }
MerchantConfig merchantConfig = merchantConfigMapper.claimMerchantConfig(orderBO.getMchId()); MerchantConfig merchantConfig = merchantConfigMapper.claimMerchantConfig(orderBO.getMchId());
if(!Optional.ofNullable(merchantConfig).isPresent()){ if(!Optional.ofNullable(merchantConfig).isPresent()){
// TODO 抛出业务异常 throw new BusinessException(ErrorConstant.MCH_ID_PARAM_ERR);
return;
} }
orderBO.setAppId(merchantConfig.getAppId());
orderBO.setMchPrivateKey(merchantConfig.getMchPrivateKey()); orderBO.setMchPrivateKey(merchantConfig.getMchPrivateKey());
orderBO.setCertificate(merchantConfig.getCertPath());
orderBO.setSerialNo(merchantConfig.getSerialNo());
} }
/** /**

17
payment-base-app/src/main/java/com/base/springcloud/service/imp/OrderServiceImp.java

@ -1,9 +1,13 @@
package com.base.springcloud.service.imp; package com.base.springcloud.service.imp;
import com.base.springcloud.aspect.annotation.BusinessException;
import com.base.springcloud.bo.OrderBO; import com.base.springcloud.bo.OrderBO;
import com.base.springcloud.constant.ErrorConstant;
import com.base.springcloud.constant.PaymentConstant; import com.base.springcloud.constant.PaymentConstant;
import com.base.springcloud.dao.OrderMapper; import com.base.springcloud.dao.OrderMapper;
import com.base.springcloud.entity.MerchantConfig;
import com.base.springcloud.entity.Order; import com.base.springcloud.entity.Order;
import com.base.springcloud.entity.SaleBill;
import com.base.springcloud.service.OrderService; import com.base.springcloud.service.OrderService;
import com.base.springcloud.util.DateUtil; import com.base.springcloud.util.DateUtil;
import com.base.springcloud.util.DecimalUtil; import com.base.springcloud.util.DecimalUtil;
@ -23,21 +27,26 @@ public class OrderServiceImp implements OrderService {
@Override @Override
public void registerOrder(OrderBO orderBO) { public void registerOrder(OrderBO orderBO) {
SaleBill saleBill = orderBO.getSaleBill();
BigDecimal amount = saleBill.getTotalAmount();
if(amount.compareTo(BigDecimal.ZERO) <= 0){
throw new BusinessException(ErrorConstant.BILL_AMOUNT_ERR);
}
Order order = new Order(); Order order = new Order();
order.setId(UUID.randomUUID().toString().replace("-", "")); order.setId(UUID.randomUUID().toString().replace("-", ""));
order.setCreateTime(new Date()); order.setCreateTime(new Date());
order.setExpireTime(new Date()); //order.setExpireTime(new Date());
order.setTimeStamp(new Date()); order.setTimeStamp(new Date());
order.setOrderNo(DateUtil.getDateString(new Date(),25)); order.setOrderNo(DateUtil.getDateString(new Date(),25));
order.setOrderType("AL"); order.setOrderType("WEC");
order.setRequestNo(DateUtil.getDateString(new Date(),25)); order.setRequestNo(DateUtil.getDateString(new Date(),25));
order.setGoodName("maomaogongzai"); order.setGoodName("maomaogongzai");
order.setReserved("memo"); order.setReserved("memo");
order.setTimeStamp(new Date()); order.setTimeStamp(new Date());
order.setMchId(orderBO.getMchId()); order.setMchId(orderBO.getMchId());
order.setOrderState(PaymentConstant.WAIT); order.setOrderState(PaymentConstant.WAIT);
BigDecimal amount = orderBO.getSaleBill().getTotalAmount(); order.setSourceBillId(Optional.ofNullable(saleBill.getSourceId()).orElse(saleBill.getId()));
order.setOrderAmount(DecimalUtil.divide(Optional.ofNullable(amount).orElse(new BigDecimal(0.01)),new BigDecimal(100))); order.setOrderAmount(DecimalUtil.multiply(amount,new BigDecimal(100)).setScale(0,BigDecimal.ROUND_DOWN));
orderMapper.insert(order); orderMapper.insert(order);
orderBO.setOrder(order); orderBO.setOrder(order);
} }

12
payment-base-app/src/main/java/com/base/springcloud/service/imp/PaymentServiceImp.java

@ -2,14 +2,18 @@ package com.base.springcloud.service.imp;
import com.base.springcloud.aspect.annotation.Rlock; import com.base.springcloud.aspect.annotation.Rlock;
import com.base.springcloud.bo.OrderBO; import com.base.springcloud.bo.OrderBO;
import com.base.springcloud.bo.SaleBillBO;
import com.base.springcloud.constant.PaymentConstant; import com.base.springcloud.constant.PaymentConstant;
import com.base.springcloud.entity.Order; import com.base.springcloud.entity.Order;
import com.base.springcloud.entity.SaleBill;
import com.base.springcloud.service.*; import com.base.springcloud.service.*;
import com.base.springcloud.util.DecimalUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@ -46,8 +50,7 @@ public class PaymentServiceImp implements PaymentService {
// 登记订单 // 登记订单
orderService.registerOrder(orderBO); orderService.registerOrder(orderBO);
// 请求微信生成二维码 // 请求微信生成二维码
String codeUrl = wecPaymentService.nativePay(orderBO); return wecPaymentService.wecNativePay(orderBO);
return codeUrl;
} }
/** /**
@ -84,6 +87,11 @@ public class PaymentServiceImp implements PaymentService {
// 同步订单状态 // 同步订单状态
String orderNo = order.getOrderNo(); String orderNo = order.getOrderNo();
orderService.updateOrderSuccess(orderNo); orderService.updateOrderSuccess(orderNo);
// 核销销售单据金额
SaleBillBO saleBillBO = new SaleBillBO();
saleBillBO.setId(order.getSourceBillId());
saleBillBO.setPayAmount(DecimalUtil.divide(order.getOrderAmount(),new BigDecimal(100)));
billService.writeOffBill(saleBillBO);
} }
// 参数检查 // 参数检查

133
payment-base-app/src/main/java/com/base/springcloud/service/imp/WecPaymentServiceImp.java

@ -1,13 +1,14 @@
package com.base.springcloud.service.imp; package com.base.springcloud.service.imp;
import com.alibaba.fastjson.JSONObject;
import com.base.springcloud.bo.CodePayBO; import com.base.springcloud.bo.CodePayBO;
import com.base.springcloud.bo.OrderBO; import com.base.springcloud.bo.OrderBO;
import com.base.springcloud.bo.RefundBO; import com.base.springcloud.bo.RefundBO;
import com.base.springcloud.constant.PaymentConstant; import com.base.springcloud.constant.PaymentConstant;
import com.base.springcloud.entity.Order; import com.base.springcloud.entity.Order;
import com.base.springcloud.entity.WxpayRefundVo; import com.base.springcloud.entity.WxpayRefundVo;
import com.base.springcloud.entity.WxpayRefundVo.WxRefundAmountVo;
import com.base.springcloud.entity.WxpayTradeVo; import com.base.springcloud.entity.WxpayTradeVo;
import com.base.springcloud.entity.WxpayTradeVo.WxTradeAmountVo;
import com.base.springcloud.service.WecPaymentService; import com.base.springcloud.service.WecPaymentService;
import com.base.springcloud.util.DateUtil; import com.base.springcloud.util.DateUtil;
import com.base.springcloud.util.DecimalUtil; import com.base.springcloud.util.DecimalUtil;
@ -16,15 +17,14 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import com.hisun.iposm.HiCASignUtil2; import com.hisun.iposm.HiCASignUtil2;
import com.hisun.iposm.HiiposmUtil; import com.hisun.iposm.HiiposmUtil;
import lombok.SneakyThrows;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.text.StrBuilder; import org.apache.commons.lang.text.StrBuilder;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
@Service @Service
@ -133,12 +133,10 @@ public class WecPaymentServiceImp implements WecPaymentService {
* 微信Native支付 * 微信Native支付
* @param orderBO * @param orderBO
*/ */
@SneakyThrows
@Override @Override
public String wecNativePay(OrderBO orderBO) { public String wecNativePay(OrderBO orderBO) {
Order order = Optional.ofNullable(orderBO).map(o->orderBO.getOrder()).orElse(null); Order order = orderBO.getOrder();
if(order == null) {
// TODO 抛出业务异常
}
WxpayTradeVo wxpayTradeVo = new WxpayTradeVo(); WxpayTradeVo wxpayTradeVo = new WxpayTradeVo();
wxpayTradeVo.setAppid(orderBO.getAppId()); wxpayTradeVo.setAppid(orderBO.getAppId());
wxpayTradeVo.setMchid(orderBO.getMchId()); wxpayTradeVo.setMchid(orderBO.getMchId());
@ -146,18 +144,17 @@ public class WecPaymentServiceImp implements WecPaymentService {
wxpayTradeVo.setOut_trade_no(order.getOrderNo()); wxpayTradeVo.setOut_trade_no(order.getOrderNo());
// FIXME 待定为商户系统||RBS系统回调接收 // FIXME 待定为商户系统||RBS系统回调接收
wxpayTradeVo.setNotify_url("https://www.weixin.qq.com/wxpay/pay.php"); wxpayTradeVo.setNotify_url("https://www.weixin.qq.com/wxpay/pay.php");
WxpayTradeVo.WxTradeAmountVo wxTradeAmountVo = new WxpayTradeVo.WxTradeAmountVo(); WxTradeAmountVo wxTradeAmountVo = new WxTradeAmountVo();
wxTradeAmountVo.setTotal(order.getOrderAmount()); wxTradeAmountVo.setTotal(order.getOrderAmount());
wxpayTradeVo.setAmount(wxTradeAmountVo); wxpayTradeVo.setAmount(wxTradeAmountVo);
ObjectNode objectNode = WxpayUtils.getWxpay( JSONObject jsonObject = WxpayUtils.getWxpay(
wxpayTradeVo, wxpayTradeVo,
PaymentConstant.NATIVE, PaymentConstant.NATIVE,
orderBO.getMchPrivateKey(), orderBO.getMchPrivateKey(),
orderBO.getCertificate(), orderBO.getCertificate(),
orderBO.getSerialNo()); orderBO.getSerialNo());
logger.info("Native支付订单 :{} 接收响应数据 :{}",order.getOrderNo(),objectNode.toString()); logger.info("Native支付订单 :{} 接收响应数据 :{}",order.getOrderNo(),jsonObject.toString());
JsonNode jsonNode = objectNode.get("code_url"); return jsonObject.get("code_url").toString();
return jsonNode.toString();
} }
/** /**
@ -169,7 +166,7 @@ public class WecPaymentServiceImp implements WecPaymentService {
WxpayRefundVo wxpayRefundVo = new WxpayRefundVo(); WxpayRefundVo wxpayRefundVo = new WxpayRefundVo();
wxpayRefundVo.setTransaction_id(refundBO.getOrigOrderNo()); wxpayRefundVo.setTransaction_id(refundBO.getOrigOrderNo());
wxpayRefundVo.setReason(refundBO.getReason()); wxpayRefundVo.setReason(refundBO.getReason());
WxRefundAmountVo wxRefundAmountVo = new WxRefundAmountVo(); WxpayRefundVo.WxRefundAmountVo wxRefundAmountVo = new WxpayRefundVo.WxRefundAmountVo();
wxRefundAmountVo.setTotal(refundBO.getOrderAmount()); wxRefundAmountVo.setTotal(refundBO.getOrderAmount());
wxRefundAmountVo.setRefund(refundBO.getRefundAmount()); wxRefundAmountVo.setRefund(refundBO.getRefundAmount());
wxpayRefundVo.setNotify_url(refundBO.getNotifyUrl()); wxpayRefundVo.setNotify_url(refundBO.getNotifyUrl());
@ -186,35 +183,6 @@ public class WecPaymentServiceImp implements WecPaymentService {
public void codePay(CodePayBO codePayBO) { public void codePay(CodePayBO codePayBO) {
} }
/*public static void main(String[] args) {
CodePayBO codePayBO = new CodePayBO();
codePayBO.setAppId("wxa91984b310053c3d");
codePayBO.setMchId("1610494969");
codePayBO.setDeviceInfo("sb0001");
codePayBO.setSpbillCreateIp("8.8.8.8");
codePayBO.setBody("Image形象店-深圳腾大-QQ公仔");
codePayBO.setOrderNo(DateUtil.getDateString(25));
codePayBO.setAmount(new BigDecimal(1));
codePayBO.setMchPrivateKey("MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCVVy4CUrRTPJZ49vuK9Tr5Rurd3dE3eiz7lsnWPAYgZtdWsC6TORUaP0Px/ZMtaJYNURMpVKC5koXZSPTNr9ROHa6B6IX4lTMERzHgiVzGIqLlE/twBYXbSuh8yXy3k59adFDYZZNN+2THWdst2Ao7pD+GXlDby8gfF67ax9CbWq5yyx6MYMKHwOVe3H/ON2pcmZR6I809Lwa4zfmUyOez1U5pwNiwv2cyorM5UXzVMsvK5jfIKDaskNVIV/+ax15tf+OQ/6t9iaWzRAV1zeeJd/TuVVGB/QU5slg5xyIwaqKzJM1H3n64er5QNRKpU31Ru0dHzJTW7ljtILWCQZubAgMBAAECggEAVga6QixSJACqzVO44vsQ1be8Y8H7WvHOJ79c1UQOY2vab91ddwFS3qPDCAsCVQ4CIfmqCAzv6PY2lEwqeLHooncGp17Cjcekc7pvSODXyGr7Wup/1K/Zw9EKy5dleHpZOUn3qDAbArjl/NAOKgJhIqoizcxW18YzqXWDDBQ+Xr6kqmjWXWZ3Kj6ghZNoSkdoynTQ7Ti0C2lq0UeXg611ea6Zs3fgjOgYEBMSSI7v4zE/6RN7jFGlZe5Z1NgO15rl8r3YdDnXTCIpEiTV+yHsDkluqJquB0E1Xrr1AXl9AGMuq6lYEB4houJUPtGgQ6bLs93MrnyzgnGTLbLSnXDNwQKBgQDD6Z+0xZ8lApXZylI2N4zuSrCsi6wB6Qp/64jr+C7GAdmC7w9WRoIlIF7Q2s9p5ulGyxD2hAbrajY5CsjV3S0uIDAaULoG3dw5vxYFEdvcKgxphf8j0gcajUnPGzCxF5vm29B9D+o1mrylr04dtWHlP0KpKwQ6HiTX7if+DcXMhwKBgQDDJOFpoCcVdZ0clfpvJPZpgRTu3I4HFTs27elCQ98g1UWav/VY7729YLAKU27d6lG+iqH1X5lVu2lr/du8wdJoMbpBPD34V+V6ye8gV9lCG7wSCgsNnPqM/HoyBSe6+JUgwG+vCRh1KMhNBmqEMCqPRAtbW3wfDdCShfTBHAjxTQKBgCjYrNOj4Gp2/4dJB5sGOfv01qEi/dnoHKhPE10fgaEHAbKq5Se3y6qx9RLWjCgoXLrF2+OJ42dx3ZxHA1iTpLfZPi4+ZorH9wKTNKQZ9R0SJ0RZC7kMMS74BkuH/77sjTS03+MzTkGe4XYp9r968c46QkvDDD6Ryly66tutQ3BBAoGBAJiE/MDncWSuVit/dQrlYso3HztJmqAikfNuoz8tePlad1pp6cKnLi8ToMORTjeX6mf4RnlXTKrbHZxP/yxaeK8DHsXZ5b1yRWNg7MrknmOy9Z1LyDPNm24R7xelO9ZAb533idLOUxVO2K6K8zl5w+nRjubKbAqBa6D5ncBIvxyJAoGAP9cSun39cFuzjdTaWojmbQMM8k5pyvFWr2UdY50GFrFCdajkAxqoTLkFEUP5fx8InIU/X9aSbVE6Va5fdOKiifbx5KaSKFrH/xZS6XykAbIkWDWqOPMovHoMWj3lGO96wDInry9YZNy7JA8AuZsLSBUA7Xb33FqZ2WU5ePeFOAA=");
codePayBO.setAuthCode("135276524069149568");
Map<String, String> params = MicroPayModel
.builder()
.appid(codePayBO.getAppId())
.mch_id(codePayBO.getMchId())
.device_info(codePayBO.getDeviceInfo())
.nonce_str(WxPayKit.generateStr())
.body(codePayBO.getBody())
//.attach(codePayBO.getAttach())
.out_trade_no(codePayBO.getOrderNo())
.total_fee(codePayBO.getAmount().toPlainString())
.spbill_create_ip(codePayBO.getSpbillCreateIp())
.auth_code(codePayBO.getAuthCode())
.build()
.createSign(codePayBO.getMchPrivateKey(), SignType.HMACSHA256);
System.out.println(WxPayApi.microPay(false,params));
}
*/
/** /**
* 订单状态查询 * 订单状态查询
* *
@ -224,50 +192,45 @@ public class WecPaymentServiceImp implements WecPaymentService {
@Override @Override
public Boolean orderResult(OrderBO orderBO) { public Boolean orderResult(OrderBO orderBO) {
Order order = orderBO.getOrder(); Order order = orderBO.getOrder();
String orderId = order.getOrderNo(); String url = PaymentConstant.WX_ORDER_QUERY_URL + order.getOrderNo() + "?mchid=" + order.getMchId();
String req_url = "https://ipos.10086.cn/cps/cmpayService"; logger.info("order_result_url : {}",url);
String type = "AggregQueryCPS"; return WxpayUtils.queryWxOrder(url,orderBO.getMchId(),orderBO.getMchPrivateKey(),orderBO.getCertificate(),orderBO.getSerialNo());
String version = "1.0.0";
String reserved = order.getReserved();
String signType = PaymentConstant.SIGN_TYPE;
String requestId = DateUtil.getDateString(25);
String merchantId = order.getMchId();
String privateKey = orderBO.getMchPrivateKey();
String characterSet = PaymentConstant.CHARACTER_SET;
StringBuilder signData = new StringBuilder();
signData.append(merchantId);
signData.append(requestId);
signData.append(signType);
signData.append(type);
signData.append(version);
signData.append(orderId);
signData.append(reserved);
try {
StrBuilder requestParam = new StrBuilder();
HiCASignUtil2 rsa = new HiCASignUtil2(privateKey, "111");
requestParam.append("hmac=").append(rsa.sign(signData.toString()));
requestParam.append("&characterSet=").append(PaymentConstant.CHARACTER_SET);
requestParam.append("&merchantId=").append(merchantId);
requestParam.append("&requestId=").append(requestId);
requestParam.append("&signType=").append(signType);
requestParam.append("&type=").append(type);
requestParam.append("&version=").append(version);
requestParam.append("&orderId=").append(orderId);
requestParam.append("&reserved1=").append(reserved);
HiiposmUtil util = new HiiposmUtil();
String res = util.sendAndRecv(req_url, requestParam.toString(), characterSet);
logger.info("订单: {} 查询参数响应: {}",order.getOrderNo(),res);
if(util.getValue(res, "status").equals("SUCCESS")){
return true;
} }
return false;
} catch (IOException e) { public static void main(String[] args) {
e.printStackTrace(); OrderBO orderBO = new OrderBO();
} catch (Exception e) { orderBO.setAppId("wxe61ee6c21345d74d");
e.printStackTrace(); orderBO.setMchId("1537100771");
orderBO.setMchPrivateKey("MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDU7qXRin2MGdDGPQLgMCMlAWccseGXDz99Ulu0KL3u7QBH0eJZoxDpHGqE/sMtQnDUD446Khi3AZgd2xwWOoshkleSOkNd20+tVaq91vw/lJEF4kv4DbFFNLObs1kBqGYZi4HUrbyRH1UqFujImJXDvSOKd53SPjEPs6rRFDwXAQaEQEftwQVvv6ycHc7symgYL486KCVZLm2yfsMA0fu/MiSTIeZCMR1OEx+YK61K4Rzv6rdE8Yf6o2Rwl0xWqcrm2C2RFLgGqmrYmxscgI6ufEEdbWO0YkqFQndcVhT8vooTYdwShrB5rp7TDs3G3qQMzqQpfi2J/gWsWT1S4ZnLAgMBAAECggEAUavLfCijaQZJ1o92N+kewcXc99uejGMz1eyt8dciqq7KycFOEVWDWfYlQSe6UvTF9ACXa+XTnvYEk4cEKd6AmPrZjeO9DRXeZLyUBcac8AIa8efPfbA6yzGgplrPC9y8dJXW0W1mAz/CWad51972qqI0LJsetJJYHQ6ruRAK0ENH7LUAHAzrSbD96y+YuXB6n2x7GQZF1e8PCzVdpNEsDfEwNBB19CyLpCIW3JQMZvVcWUv+8MJwdzvNprwkDKeMC0F/p7R+ErZL1z1pfi9aMV2DzQ25qKW758juTTnGf6z+tTND+cQoeMh1GxqK3CuUpz1Y7lUctF2jyP/6EPctWQKBgQD5m4ZaiW+ucQ1hEkxW4T9TPugyHxvNBtOQvs3F5kin2QVeIkY9ssGHmTx5I5r63sDQylSQRildaIX6EAxYzoy5AHtAKiltiB3ppLdQxX7adoSWNORZ/pjd/sNKTAZtqd0IBNtjuI3y/BxYrqii7cUC/aWv+gxHFUjoyG01aU8mHwKBgQDaYqwrm0gRmpKlhigoXRYGEo24kJHsGjXnpxy9Klq3S7A9zAfEF4WqfuAM3vXbUm8RrDU045N4kyakwfJNewVSzkL9N0vcGHqoB5DNWSrS6qmIZgUAuU55iRXR16Kluv0k3pF1Ar4gtJuDHpEvjlqV8J4Z0bWNrOkXZ5sjIAje1QKBgGJDX7j0sgqyZtn4IiVxt0RGV5KjvIYSUeeBtfBan++z9/D+/Tf8z0Nah/wIkFKCrtWDUZcah95F77hp6PJtHekWz26LKpP8Kgp41dHubeoDDl8zo1HqcLO0P51YII+7d1BY2SWA2iD2LxKab7j0ccKjqD6G6Z5yOqmpfZSxSH9xAoGAPqSVPIDzYFFVhXOBK2rgOWezDWEy6mXuVn/CJ6Txlqh4apGPHLmelvSD8k02eu4ffBNIw94P3ENhj1su1PjX4xPVdWsaMI05Cd/5sl3EgfHcJYsWHkoJb6VaA/J17lI/8QaC9OyPezQzc54eCWUtKNt3jnJwQK57wkHu51l2Ee0CgYBuqDJjYcw1xHYtA+hH/tTrU1t8arwdeoz0QN+Cj1DgGW6zY0WRyIcnl4M1v51bIyrluqpN4e0Dh2VVV0r1LAIlhvAzsz3alCIJzVTVaJXKAGwN9vMxRbnCdg1h+QzAeZ+VC1zLNzHKUPYsGEnH5Hig5mml1pZz4b6LSNDFG6VBqw==");
orderBO.setCertificate("MIID8DCCAtigAwIBAgIUbAm85GX1um+ESCWizOGXEoH6gnowDQYJKoZIhvcNAQELBQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsTFFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3QgQ0EwHhcNMjExMTE2MDczNDUzWhcNMjYxMTE1MDczNDUzWjCBgTETMBEGA1UEAwwKMTUzNzEwMDc3MTEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMS0wKwYDVQQLDCTlm5vlt53nm5vlkozmnLrmorDorr7lpIfmnInpmZDlhazlj7gxCzAJBgNVBAYMAkNOMREwDwYDVQQHDAhTaGVuWmhlbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANTupdGKfYwZ0MY9AuAwIyUBZxyx4ZcPP31SW7Qove7tAEfR4lmjEOkcaoT+wy1CcNQPjjoqGLcBmB3bHBY6iyGSV5I6Q13bT61Vqr3W/D+UkQXiS/gNsUU0s5uzWQGoZhmLgdStvJEfVSoW6MiYlcO9I4p3ndI+MQ+zqtEUPBcBBoRAR+3BBW+/rJwdzuzKaBgvjzooJVkubbJ+wwDR+78yJJMh5kIxHU4TH5grrUrhHO/qt0Txh/qjZHCXTFapyubYLZEUuAaqatibGxyAjq58QR1tY7RiSoVCd1xWFPy+ihNh3BKGsHmuntMOzcbepAzOpCl+LYn+BaxZPVLhmcsCAwEAAaOBgTB/MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgTwMGUGA1UdHwReMFwwWqBYoFaGVGh0dHA6Ly9ldmNhLml0cnVzLmNvbS5jbi9wdWJsaWMvaXRydXNjcmw/Q0E9MUJENDIyMEU1MERCQzA0QjA2QUQzOTc1NDk4NDZDMDFDM0U4RUJEMjANBgkqhkiG9w0BAQsFAAOCAQEArtZJ2FICGrykPJziJxPjTaaA/nn//tXI6rUW9aSHe6atLWgduUDlBQjn8pckAeReuXF6J1D9u45iQY8fc5Mb5BAQsg4qC1zxoRINBNL5HVEf+9uolfJI2urw3cfwbAdrymMDUWc0xFZWgo5z3KFXso8ERb73j/5utbIqZ+C7MtesHs1Em5FRSZgX86wy9zDcbIMtw2LeHymQ3MV8C6cASwlBIJ/UptDieuHRr0FoUxkmtSN1POQRhhYVT2gaHpNOVHmrK6Tbd6nblQ70GdLH7kdb9LPr4kS0GXPz+Gvk8y15PKI02MFcNqJCuLJTpFlAf4gTwWule2Z5/1WlOF1+sA==");
orderBO.setSerialNo("6C09BCE465F5BA6F844825A2CCE1971281FA827A");
Order order1 = new Order();
order1.setGoodName("形象大公仔");
order1.setOrderNo("20220304112022");
order1.setOrderAmount(new BigDecimal(1));
orderBO.setOrder(order1);
Order order = Optional.ofNullable(orderBO).map(o->orderBO.getOrder()).orElse(null);
if(order == null) {
// TODO 抛出业务异常
} }
return false; WxpayTradeVo wxpayTradeVo = new WxpayTradeVo();
wxpayTradeVo.setAppid(orderBO.getAppId());
wxpayTradeVo.setMchid(orderBO.getMchId());
wxpayTradeVo.setDescription(order.getGoodName());
wxpayTradeVo.setOut_trade_no(order.getOrderNo());
// FIXME 待定为商户系统||RBS系统回调接收
wxpayTradeVo.setNotify_url("https://www.weixin.qq.com/wxpay/pay.php");
WxpayTradeVo.WxTradeAmountVo wxTradeAmountVo = new WxpayTradeVo.WxTradeAmountVo();
wxTradeAmountVo.setTotal(order.getOrderAmount());
wxpayTradeVo.setAmount(wxTradeAmountVo);
JSONObject objectNode = WxpayUtils.getWxpay(
wxpayTradeVo,
PaymentConstant.NATIVE,
orderBO.getMchPrivateKey(),
orderBO.getCertificate(),
orderBO.getSerialNo());
System.out.println("Native支付订单 :{} " + order.getOrderNo() + " 接收响应数据 :{} "+ objectNode.toString());
System.out.println(objectNode.toString());
} }
} }

42
payment-base-app/src/main/java/com/base/springcloud/util/ParameterUtil.java

@ -0,0 +1,42 @@
package com.base.springcloud.util;
import com.base.springcloud.bo.OrderBO;
import com.base.springcloud.constant.PaymentConstant;
import com.base.springcloud.dto.NativePlaceOrderDTO;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
public class ParameterUtil {
/**
* native下单入场设置
* @param billId
* @return
*/
public OrderBO nativePlaceOrderBefore(String billId){
OrderBO orderBO = new OrderBO();
orderBO.setBillId(billId);
orderBO.setMchId(PaymentConstant.DEFAULT_MCH_ID);
return orderBO;
}
/**
* native下单响应设置
* @param codeUrl
* @return
*/
public List<NativePlaceOrderDTO> nativePlaceOrderAfter(String codeUrl){
if(StringUtils.isEmpty(codeUrl)){
return null;
}
List<NativePlaceOrderDTO> nativePlaceOrderDTOList = new ArrayList<>();
NativePlaceOrderDTO nativePlaceOrderDTO = new NativePlaceOrderDTO();
nativePlaceOrderDTO.setCodeUrl(codeUrl);
nativePlaceOrderDTOList.add(nativePlaceOrderDTO);
return nativePlaceOrderDTOList;
}
}

73
payment-base-app/src/main/java/com/base/springcloud/wxsdk/WxpayUtils.java

@ -1,6 +1,7 @@
package com.base.springcloud.wxsdk; package com.base.springcloud.wxsdk;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.base.springcloud.constant.PaymentConstant; import com.base.springcloud.constant.PaymentConstant;
import com.base.springcloud.entity.CallbackBodyVo; import com.base.springcloud.entity.CallbackBodyVo;
import com.base.springcloud.entity.WxpayRefundVo; import com.base.springcloud.entity.WxpayRefundVo;
@ -13,6 +14,7 @@ import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity; import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType; import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity; import org.apache.http.entity.StringEntity;
@ -60,35 +62,80 @@ public class WxpayUtils {
* @param serialNo * @param serialNo
* @return * @return
*/ */
public static ObjectNode getWxpay(WxpayTradeVo tradeVo, String scene, String privateKey, String certificate, String serialNo) { public static JSONObject getWxpay(WxpayTradeVo tradeVo, String scene, String privateKey, String certificate, String serialNo) {
// ... // ...
String responseBody = response(JSON.toJSONString(tradeVo), getUrl(scene), tradeVo.getMchid(), privateKey, certificate, serialNo); String responseBody = response(JSON.toJSONString(tradeVo), getUrl(scene), tradeVo.getMchid(), privateKey, certificate, serialNo);
log.info("======>>> wxpay response body: ", responseBody); log.info("======>>> wxpay response body: ", responseBody);
// parse // parse
Map<String, String> resultMap = StringHelper.json2map(responseBody); Map<String, String> resultMap = StringHelper.json2map(responseBody);
ObjectMapper objectMapper = new ObjectMapper(); JSONObject jsonObject = new JSONObject();
ObjectNode objectNode = objectMapper.createObjectNode();
if (PaymentConstant.NATIVE.equals(scene)) {// pc - 扫码支付(Native) if (PaymentConstant.NATIVE.equals(scene)) {// pc - 扫码支付(Native)
objectNode.put("code_url", resultMap.get("code_url")); jsonObject.put("code_url", resultMap.get("code_url"));
} else if (PaymentConstant.H5.equals(scene)) {// 手机网页(H5) } else if (PaymentConstant.H5.equals(scene)) {// 手机网页(H5)
objectNode.put("h5_url", resultMap.get("h5_url")); jsonObject.put("h5_url", resultMap.get("h5_url"));
} else if (PaymentConstant.JSAPI.equals(scene)) {// 微信公众号(H5) } else if (PaymentConstant.JSAPI.equals(scene)) {// 微信公众号(H5)
String prepayId = resultMap.get("prepay_id"); String prepayId = resultMap.get("prepay_id");
objectNode.put("prepay_id", prepayId); jsonObject.put("prepay_id", prepayId);
// ... // ...
objectNode.put("appId", tradeVo.getAppid()); jsonObject.put("appId", tradeVo.getAppid());
String timestamp = getTimestamp(); String timestamp = getTimestamp();
objectNode.put("timeStamp", timestamp); jsonObject.put("timeStamp", timestamp);
String nonceStr = CreateNoncestr(); String nonceStr = CreateNoncestr();
objectNode.put("nonceStr", nonceStr); jsonObject.put("nonceStr", nonceStr);
String packageStr = "prepay_id=" + prepayId; String packageStr = "prepay_id=" + prepayId;
objectNode.put("package", packageStr); jsonObject.put("package", packageStr);
// 签名 // 签名
String paySign = doRequestSign(privateKey, tradeVo.getAppid(), timestamp, nonceStr, packageStr); String paySign = doRequestSign(privateKey, tradeVo.getAppid(), timestamp, nonceStr, packageStr);
objectNode.put("paySign", paySign); jsonObject.put("paySign", paySign);
objectNode.put("signType", "RSA"); jsonObject.put("signType", "RSA");
} }
return objectNode; return jsonObject;
}
/**
* 订单查询
* @param url
* @param mchId
* @param privateKey
* @param certificate
* @param serialNo
* @return true - 成功 false - 失败
*/
public static Boolean queryWxOrder(String url,String mchId, String privateKey, String certificate, String serialNo) {
HttpGet httpGet = new HttpGet(url);
httpGet.addHeader("Accept", "application/json");
CloseableHttpResponse response = null;
try {
// 商户私钥
PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
response = getClient(mchId, serialNo, merchantPrivateKey, certificate).execute(httpGet);
log.info("query_wx_order response: {}",response);
int statusCode = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
String body = EntityUtils.toString(entity);
EntityUtils.consume(entity);
JSONObject jsonObject = JSONObject.parseObject(body);
if (statusCode != 200) {
Map<String, String> errorMsg = StringHelper.json2map(body);
// FIXME 请求微信失败
}
log.info("query_wx_order response resultMap: {}",jsonObject.toJSONString());
if (PaymentConstant.WX_SUCCESS.equals(jsonObject.getString("trade_state"))) {
log.info("query_wx_order query true");
return true;
}
} catch (IOException e) {
log.error("======>>> wxpay response, client exception: {}", e);
} catch (Exception e) {
log.error("======>>> wxpay response, exception: {}", e);
} finally {
try {
response.close();
} catch (IOException e) {
log.error("======>>> wxpay response, ioe exception: {}", e);
}
}
return false;
} }
/** /**

9
payment-base-app/src/main/resources/com/base/payment/mapper/OrderMapper.xml

@ -12,12 +12,13 @@
<result column="order_amount" jdbcType="VARCHAR" property="orderAmount" /> <result column="order_amount" jdbcType="VARCHAR" property="orderAmount" />
<result column="good_name" jdbcType="VARCHAR" property="goodName" /> <result column="good_name" jdbcType="VARCHAR" property="goodName" />
<result column="good_id" jdbcType="VARCHAR" property="goodId" /> <result column="good_id" jdbcType="VARCHAR" property="goodId" />
<result column="source_bill_id" jdbcType="VARCHAR" property="sourceBillId" />
<result column="order_type" jdbcType="VARCHAR" property="orderType" /> <result column="order_type" jdbcType="VARCHAR" property="orderType" />
<result column="reserved" jdbcType="VARCHAR" property="reserved" /> <result column="reserved" jdbcType="VARCHAR" property="reserved" />
</resultMap> </resultMap>
<sql id="Base_Column_List"> <sql id="Base_Column_List">
id, order_no,order_state,mch_id,create_time, expire_time, request_no, order_amount, good_name, good_id, id, order_no,order_state,mch_id,create_time, expire_time, request_no, order_amount, good_name, good_id,
order_type, reserved order_type, reserved,source_bill_id
</sql> </sql>
<select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap"> <select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
select select
@ -32,10 +33,10 @@
<insert id="insert" parameterType="com.base.springcloud.entity.Order"> <insert id="insert" parameterType="com.base.springcloud.entity.Order">
insert into pay_order (id, order_no, mch_id, create_time, insert into pay_order (id, order_no, mch_id, create_time,
expire_time, request_no, order_amount, order_state, expire_time, request_no, order_amount, order_state,
good_name, good_id, order_type, reserved,time_stamp) good_name, good_id, source_bill_id,order_type, reserved,time_stamp)
values (#{id,jdbcType=VARCHAR}, #{orderNo,jdbcType=VARCHAR},#{mchId,jdbcType=VARCHAR},#{createTime,jdbcType=TIMESTAMP}, values (#{id,jdbcType=VARCHAR}, #{orderNo,jdbcType=VARCHAR},#{mchId,jdbcType=VARCHAR},#{createTime,jdbcType=TIMESTAMP},
#{expireTime,jdbcType=TIMESTAMP}, #{requestNo,jdbcType=VARCHAR}, #{orderAmount,jdbcType=VARCHAR}, #{expireTime,jdbcType=TIMESTAMP}, #{requestNo,jdbcType=VARCHAR}, #{orderAmount,jdbcType=VARCHAR}, #{orderState,jdbcType=VARCHAR},
#{orderState,jdbcType=VARCHAR},#{goodName,jdbcType=VARCHAR}, #{goodId,jdbcType=VARCHAR}, #{orderType,jdbcType=VARCHAR}, #{goodName,jdbcType=VARCHAR}, #{goodId,jdbcType=VARCHAR},#{sourceBillId,jdbcType=VARCHAR}, #{orderType,jdbcType=VARCHAR},
#{reserved,jdbcType=VARCHAR},#{timeStamp,jdbcType=TIMESTAMP}) #{reserved,jdbcType=VARCHAR},#{timeStamp,jdbcType=TIMESTAMP})
</insert> </insert>
<insert id="insertSelective" parameterType="com.base.springcloud.entity.Order"> <insert id="insertSelective" parameterType="com.base.springcloud.entity.Order">

7
payment-base-app/src/main/resources/com/base/payment/mapper/SaleBillMapper.xml

@ -536,4 +536,11 @@
from stk_io_bill from stk_io_bill
where id = #{id,jdbcType=VARCHAR} where id = #{id,jdbcType=VARCHAR}
</select> </select>
<update id="writeOffBill" parameterType="com.base.springcloud.entity.SaleBill">
update stk_io_bill
set lock_amount = IF(lock_amount = 0,total_amount - #{payAmount,jdbcType=DECIMAL},lock_amount - #{payAmount,jdbcType=DECIMAL}),
pay_amount = pay_amount + #{payAmount,jdbcType=DECIMAL}
where id = #{id,jdbcType=VARCHAR}
</update>
</mapper> </mapper>
Loading…
Cancel
Save