begin new project
This commit is contained in:
269
src/main/java/com/peanut/modules/pay/IOSPay/Result.java
Normal file
269
src/main/java/com/peanut/modules/pay/IOSPay/Result.java
Normal file
@@ -0,0 +1,269 @@
|
||||
package com.peanut.modules.pay.IOSPay;
|
||||
|
||||
import lombok.Data;
|
||||
import org.apache.http.HttpStatus;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Data
|
||||
public class Result<T> implements Serializable {
|
||||
|
||||
/**
|
||||
* 成功标志
|
||||
*/
|
||||
private boolean success = true;
|
||||
|
||||
/**
|
||||
* 返回代码
|
||||
*/
|
||||
private Integer code = 0;
|
||||
|
||||
/**
|
||||
* 返回处理消息
|
||||
*/
|
||||
private String message = "操作成功!";
|
||||
|
||||
/**
|
||||
* 返回数据对象 result
|
||||
*/
|
||||
private T result;
|
||||
|
||||
/**
|
||||
* 时间戳
|
||||
*/
|
||||
private long timestamp = System.currentTimeMillis();
|
||||
public Result() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
public void setSuccess(boolean success) {
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
public void setCode(Integer code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
|
||||
public T getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public void setResult(T result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public static Result error00(String msg) {
|
||||
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
|
||||
}
|
||||
public static Result<Object> error() {
|
||||
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "=================================");
|
||||
}
|
||||
|
||||
public Result<T> error500(String message) {
|
||||
this.setMessage(message);
|
||||
this.setCode(500);
|
||||
this.setSuccess(false);
|
||||
return this;
|
||||
}
|
||||
|
||||
public static Result<Object> error1() {
|
||||
Result<Object> r = new Result<Object>();
|
||||
r.setCode(500);
|
||||
r.setMessage("bundle有误");
|
||||
r.setSuccess(false);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
public Result<T> success(String message) {
|
||||
this.setMessage(message);
|
||||
this.setCode(200);
|
||||
this.setSuccess(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public static Result<Object> ok() {
|
||||
Result<Object> r = new Result<Object>();
|
||||
r.setMessage("操作成功");
|
||||
r.setCode(200);
|
||||
r.setSuccess(true);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
public static Result<Object> updateok() {
|
||||
Result<Object> r = new Result<Object>();
|
||||
r.setMessage("修改成功");
|
||||
r.setCode(200);
|
||||
r.setSuccess(true);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static Result<Object> ok0() {
|
||||
Result<Object> r = new Result<Object>();
|
||||
r.setMessage("操作成功");
|
||||
r.setCode(0);
|
||||
r.setSuccess(true);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static Result<Object> nook(String msg) {
|
||||
return error(500, msg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static Result<Object> nook(int code, String msg) {
|
||||
Result<Object> r = new Result<Object>();
|
||||
r.setCode(code);
|
||||
r.setSuccess(false);
|
||||
r.setMessage(msg);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static Result<Object> ok(String msg) {
|
||||
Result<Object> r = new Result<Object>();
|
||||
r.setMessage(msg);
|
||||
r.setCode(200);
|
||||
r.setSuccess(true);
|
||||
r.setResult(null);
|
||||
return r;
|
||||
}
|
||||
public static Result<Object> err() {
|
||||
Result<Object> r = new Result<Object>();
|
||||
r.setMessage("该笔订单待支付");
|
||||
r.setCode(500);
|
||||
r.setSuccess(true);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static Result<Object> ok(Map data) {
|
||||
Result<Object> r = new Result<Object>();
|
||||
r.setCode(200);
|
||||
r.setMessage("操作成功");
|
||||
r.setSuccess(true);
|
||||
r.setResult(data);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static Result<Object> ok(Map data,String msg) {
|
||||
Result<Object> r = new Result<Object>();
|
||||
r.setCode(200);
|
||||
r.setMessage(msg);
|
||||
r.setSuccess(true);
|
||||
r.setResult(data);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static Result<Object> ok(List data) {
|
||||
Result<Object> r = new Result<Object>();
|
||||
r.setCode(200);
|
||||
r.setSuccess(true);
|
||||
r.setResult(data);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static Result<List<?>> okl(List<?> data) {
|
||||
Result<List<?>> r = new Result<List<?>>();
|
||||
r.setCode(200);
|
||||
r.setSuccess(true);
|
||||
r.setResult(data);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static Result<Object> ok(Object data) {
|
||||
Result<Object> r = new Result<Object>();
|
||||
r.setCode(200);
|
||||
r.setSuccess(true);
|
||||
r.setResult(data);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static Result<Object> error(String msg) {
|
||||
return error(403, msg);
|
||||
}
|
||||
|
||||
public static Result<Object> error(int code, String msg) {
|
||||
Result<Object> r = new Result<Object>();
|
||||
r.setCode(code);
|
||||
r.setSuccess(false);
|
||||
r.setMessage(msg);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static Result<Object> error(Map data,String msg) {
|
||||
Result<Object> r = new Result<Object>();
|
||||
r.setCode(403);
|
||||
r.setMessage(msg);
|
||||
r.setSuccess(false);
|
||||
r.setResult(data);
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* 无权限访问返回结果
|
||||
*/
|
||||
public static Result<Object> noauth(String msg) {
|
||||
return error(401, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 无权限访问返回结果
|
||||
*/
|
||||
public static Result<List<?>> noauth() {
|
||||
Result<List<?>> r = new Result<List<?>>();
|
||||
r.setCode(401);
|
||||
r.setSuccess(false);
|
||||
r.setMessage("您没有该接口的权限!");
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// public static Result<Object> ok() {
|
||||
// Result<Object> r = new Result<Object>();
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.peanut.modules.pay.IOSPay.constant;
|
||||
|
||||
public interface VerifyReceiptConstant {
|
||||
|
||||
/**
|
||||
* ios 端app bundle id
|
||||
|
||||
* URL_SANDBOX 沙盒测试
|
||||
* URL_VERIFY 正式
|
||||
*/
|
||||
|
||||
String APP_BUNDLE_IDENTIFIER = "com.cn.nuttyreading";
|
||||
String MEDICINE_APP_BUNDLE_IDENTIFIER = "com.cn.medicine";
|
||||
String ZMZM_APP_BUNDLE_IDENTIFIER = "com.cn.zmzm";
|
||||
String XLKJ_APP_BUNDLE_IDENTIFIER = "com.nuttyreading.soul";
|
||||
String THYY_APP_BUNDLE_IDENTIFIER = "com.cn.taimed";
|
||||
|
||||
String URL_SANDBOX = "https://sandbox.itunes.apple.com/verifyReceipt";
|
||||
String URL_VERIFY = "https://buy.itunes.apple.com/verifyReceipt";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
package com.peanut.modules.pay.IOSPay.controller;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.peanut.common.utils.*;
|
||||
import com.peanut.modules.book.service.*;
|
||||
import com.peanut.modules.common.entity.*;
|
||||
import com.peanut.modules.common.service.JfTransactionDetailsService;
|
||||
import com.peanut.modules.pay.IOSPay.Result;
|
||||
import com.peanut.modules.pay.IOSPay.constant.VerifyReceiptConstant;
|
||||
import com.peanut.modules.pay.IOSPay.model.dto.IapRequestDTO;
|
||||
import com.peanut.modules.pay.IOSPay.model.dto.IapResponseDTO;
|
||||
import com.peanut.modules.pay.IOSPay.model.entities.IosPayOrderEntity;
|
||||
|
||||
import com.peanut.modules.pay.IOSPay.service.IapVerifyReceiptService;
|
||||
import com.peanut.modules.pay.IOSPay.service.OrderService;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.interceptor.TransactionAspectSupport;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(value = "/Ipa")
|
||||
@RequiredArgsConstructor
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
|
||||
@Configuration
|
||||
public class AppController {
|
||||
@Autowired
|
||||
IapVerifyReceiptService iapVerifyReceiptService;
|
||||
@Autowired
|
||||
OrderService orderService;
|
||||
@Autowired
|
||||
private MyUserService userService;
|
||||
@Autowired
|
||||
private BookBuyConfigService bookBuyConfigService;
|
||||
@Autowired
|
||||
private TransactionDetailsService transactionDetailsService;
|
||||
@Autowired
|
||||
private JfTransactionDetailsService jfTransactionDetailsService;
|
||||
@Autowired
|
||||
private PayPaymentOrderService payPaymentOrderService;
|
||||
@Autowired
|
||||
private BuyOrderService buyOrderService;
|
||||
|
||||
@RequestMapping(value = "/text", method = RequestMethod.POST)
|
||||
public String verif() {
|
||||
return "test";
|
||||
}
|
||||
|
||||
/**
|
||||
* 苹果内购二次校验
|
||||
*
|
||||
* @param dto 入参: 订单id, 苹果凭证
|
||||
* @return 验证结果
|
||||
*/
|
||||
@RequestMapping(value = "/veri", method = RequestMethod.POST)
|
||||
@Transactional
|
||||
public Result verifyIap(@RequestBody IapRequestDTO dto) {
|
||||
Lock lock = new ReentrantLock();
|
||||
lock.lock();
|
||||
try {
|
||||
// 1. 校验入参
|
||||
if (dto == null)
|
||||
return Result.error("入参不能为空");
|
||||
if (dto.getOrderId().isEmpty()) {
|
||||
return Result.error("订单id不能为空");
|
||||
}
|
||||
if (dto.getProductId().isEmpty()) {
|
||||
return Result.error("订单号不能为空");
|
||||
}
|
||||
if (dto.getTransactionId().isEmpty())
|
||||
return Result.error("内购订单号不能为空");
|
||||
if (dto.getReceiptData().isEmpty())
|
||||
return Result.error("凭证不能为空");
|
||||
IapResponseDTO receipt = iapVerifyReceiptService.verifyIapReceipt(dto.getReceiptData(), dto.isSandBox());
|
||||
BuyOrder order2 = this.buyOrderService.getOne(new QueryWrapper<BuyOrder>().eq("order_sn", dto.getOrderId()).eq("del_flag", "0"));
|
||||
order2.setPaymentDate(new Date());
|
||||
order2.setProductId(dto.getProductId());
|
||||
this.buyOrderService.updateById(order2);
|
||||
IosPayOrderEntity order = new IosPayOrderEntity();
|
||||
//todo 判断状态 订单状态 0-未付款 1-待发货 2-已发货 3-交易成功 4-交易失败
|
||||
String order01 = order.getOrderid();
|
||||
String order02 = order2.getOrderSn();
|
||||
if (order01 == order02) {
|
||||
return Result.ok();
|
||||
}
|
||||
else
|
||||
if (order01 == null ) {
|
||||
// 3.1 校验bundle id
|
||||
if (!receipt.getReceipt().getBundle_id().equals(VerifyReceiptConstant.APP_BUNDLE_IDENTIFIER)&&
|
||||
!receipt.getReceipt().getBundle_id().equals(VerifyReceiptConstant.MEDICINE_APP_BUNDLE_IDENTIFIER)&&
|
||||
!receipt.getReceipt().getBundle_id().equals(VerifyReceiptConstant.ZMZM_APP_BUNDLE_IDENTIFIER)&&
|
||||
!receipt.getReceipt().getBundle_id().equals(VerifyReceiptConstant.XLKJ_APP_BUNDLE_IDENTIFIER)&&
|
||||
!receipt.getReceipt().getBundle_id().equals(VerifyReceiptConstant.THYY_APP_BUNDLE_IDENTIFIER)) {
|
||||
return Result.error1();
|
||||
}
|
||||
if (receipt.getStatus().equals("0")) {
|
||||
IapResponseDTO.AppleOrder appleOrder = receipt.getReceipt().getIn_app()[0];
|
||||
if (receipt.getReceipt().getBundle_id().equals(VerifyReceiptConstant.XLKJ_APP_BUNDLE_IDENTIFIER)){
|
||||
for (int i=0;i<receipt.getReceipt().getIn_app().length;i++){
|
||||
IapResponseDTO.AppleOrder ao = receipt.getReceipt().getIn_app()[i];
|
||||
if (ao.getProduct_id().contains("x")){
|
||||
appleOrder = ao;
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("开始进入判断3"+appleOrder.getTransaction_id()+"====="+dto.getTransactionId()+"====="+
|
||||
appleOrder.getProduct_id()+"====="+dto.getProductId());
|
||||
if (appleOrder.getTransaction_id().equals(dto.getTransactionId()) &&
|
||||
//p+productid为吴门医述商品,单id为疯子读书商品x为心灵空间
|
||||
(appleOrder.getProduct_id().equals(dto.getProductId())||
|
||||
appleOrder.getProduct_id().equals("p"+dto.getProductId())||
|
||||
appleOrder.getProduct_id().equals("Z"+dto.getProductId())||
|
||||
appleOrder.getProduct_id().equals("x"+dto.getProductId())||
|
||||
appleOrder.getProduct_id().equals("t"+dto.getProductId()))) {
|
||||
order.setOrderid(dto.getOrderId());
|
||||
order.setReceiptData(dto.getReceiptData());
|
||||
order.setProductID(dto.getProductId());
|
||||
order.setTransactionId(dto.getTransactionId());
|
||||
order.setCustomerOid(dto.getCustomerOid());
|
||||
order.setOrderStatus(order2.getOrderStatus());
|
||||
order.setDelFlag(order2.getDelFlag());
|
||||
order.setCloseOrder(0);
|
||||
order.setCreateTime(new Date());
|
||||
order.setFailureflag(dto.getFailureflag());
|
||||
orderService.saveOrUpdate(order);
|
||||
String customerid = dto.getCustomerOid();
|
||||
String body = dto.getProductId();
|
||||
// 插入花生币 变动记录
|
||||
BookBuyConfigEntity bookBuyConfigEntity = this.bookBuyConfigService.getById(Integer.valueOf(body));
|
||||
MyUserEntity userEntity = userService.getById(Integer.valueOf(customerid));
|
||||
if (bookBuyConfigEntity != null && bookBuyConfigEntity.getGivejf().compareTo(BigDecimal.ZERO)>0) {
|
||||
userEntity.setJf(userEntity.getJf().add(bookBuyConfigEntity.getGivejf()));
|
||||
userService.updateById(userEntity);
|
||||
JfTransactionDetails jfTransactionDetails = new JfTransactionDetails();
|
||||
jfTransactionDetails.setUserId(userEntity.getId());
|
||||
jfTransactionDetails.setChangeAmount(bookBuyConfigEntity.getGivejf());
|
||||
jfTransactionDetails.setActType(0);
|
||||
jfTransactionDetails.setUserBalance(userEntity.getJf());
|
||||
jfTransactionDetails.setRelationId(order2.getOrderId());
|
||||
jfTransactionDetails.setRemark("充币送积分:"+bookBuyConfigEntity.getDescription()+",订单号:"+order2.getOrderSn());
|
||||
jfTransactionDetailsService.save(jfTransactionDetails);
|
||||
}
|
||||
BigDecimal realMoney = bookBuyConfigEntity.getMoney();
|
||||
userService.rechargeHSPoint(userEntity, realMoney.intValue());
|
||||
//插入虚拟币消费记录
|
||||
transactionDetailsService.rechargeRecord(userEntity,realMoney.toString(),order.getId(),"苹果",order.getOrderid());
|
||||
//插入花生币充值记录
|
||||
payPaymentOrderService.insertDetail(userEntity,bookBuyConfigEntity,order.getTransactionId());
|
||||
buyOrderService.updateOrderStatus(Integer.valueOf(customerid), dto.getOrderId(), "2");
|
||||
order.setMoney(bookBuyConfigEntity.getRealMoney().intValue());
|
||||
order.setUsername(userEntity.getName());
|
||||
orderService.saveOrUpdate(order);
|
||||
return Result.ok0();
|
||||
}else {
|
||||
return Result.nook(500,"订单id错误或者商品id");
|
||||
}
|
||||
}
|
||||
return Result.ok("第一次付款成功");
|
||||
}
|
||||
return Result.nook(500,"订单加载失败");
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*/
|
||||
|
||||
@RequestMapping(value = "/failure")
|
||||
|
||||
public Result update(@Validated @RequestBody IapRequestDTO vo) {
|
||||
IosPayOrderEntity order = new IosPayOrderEntity();
|
||||
order.setOrderid(vo.getOrderId());
|
||||
order.setReceiptData(vo.getReceiptData());
|
||||
order.setProductID(vo.getProductId());
|
||||
order.setTransactionId(vo.getTransactionId());
|
||||
|
||||
order.setCustomerOid(vo.getCustomerOid());
|
||||
order.setCloseOrder(0);
|
||||
order.setCreateTime(new Date());
|
||||
order.setFailureflag(vo.getFailureflag());
|
||||
|
||||
orderService.saveOrUpdate(order);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return Result.updateok();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 查询失败数据接口
|
||||
*/
|
||||
// @Transactional
|
||||
@RequestMapping(value = "/showFailure")
|
||||
public R showFailure(@RequestParam Map<String, Object> params )throws Exception{
|
||||
|
||||
PageUtils pageUtils = orderService.queryPage1(params);
|
||||
|
||||
return R.ok().put("page",pageUtils);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*/
|
||||
@RequestMapping(value = "/list",method = RequestMethod.GET)
|
||||
public R list(@RequestParam Map<String, Object> params)throws Exception {
|
||||
|
||||
|
||||
PageUtils pageUtils = orderService.queryPage1(params);
|
||||
|
||||
return R.ok().put("page", pageUtils);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.peanut.modules.pay.IOSPay.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.peanut.modules.pay.IOSPay.model.entities.IosPayOrderEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
@Mapper
|
||||
public interface PayIOSOrderMapper extends BaseMapper<IosPayOrderEntity> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.peanut.modules.pay.IOSPay.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
import com.peanut.modules.pay.IOSPay.model.entities.IosPayOrderEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
@Mapper
|
||||
public interface PayPaymentOrderMapper extends BaseMapper<IosPayOrderEntity> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.peanut.modules.pay.IOSPay.model.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class GenOrderReqDTO implements Serializable {
|
||||
/*
|
||||
* 用户id
|
||||
* */
|
||||
String id;
|
||||
/*
|
||||
*商品id
|
||||
* */
|
||||
String productId;
|
||||
|
||||
String OrderId;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.peanut.modules.pay.IOSPay.model.dto;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
import jakarta.persistence.Column;
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class IapRequestDTO implements Serializable {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 订单id
|
||||
*/
|
||||
String orderId;
|
||||
|
||||
/**
|
||||
* 苹果内购生成的交易id,对应SwiftyStoreKit-PaymentTransaction-transactionIdentifier
|
||||
*/
|
||||
@JsonProperty("transactionId")
|
||||
String transactionId;
|
||||
/**
|
||||
* base64 字符串
|
||||
*/
|
||||
@Column(name = "receiptData")
|
||||
String receiptData;
|
||||
|
||||
@JsonProperty("isSandBox")
|
||||
boolean isSandBox;
|
||||
|
||||
String relevanceoid;
|
||||
|
||||
String productId;
|
||||
|
||||
String customerOid;
|
||||
String Body;
|
||||
// String subject;
|
||||
|
||||
//o 成功 1失败
|
||||
Integer failureflag;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.peanut.modules.pay.IOSPay.model.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class IapResponseDTO {
|
||||
|
||||
private String environment;
|
||||
private AppleReceipt receipt;
|
||||
private String status;
|
||||
|
||||
|
||||
|
||||
@Data
|
||||
static public class AppleReceipt implements Serializable {
|
||||
private String receipt_type;
|
||||
private Long adam_id;
|
||||
private Long app_item_id;
|
||||
private String bundle_id;
|
||||
private String application_version;
|
||||
private Long download_id;
|
||||
private Long version_external_identifier;
|
||||
private String receipt_creation_date;
|
||||
private String receipt_creation_date_ms;
|
||||
private String receipt_creation_date_pst;
|
||||
private String request_date;
|
||||
private String request_date_ms;
|
||||
private String request_date_pst;
|
||||
private String original_purchase_date;
|
||||
private String original_purchase_date_ms;
|
||||
private String original_purchase_date_pst;
|
||||
private String original_application_version;
|
||||
private AppleOrder[] in_app;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class AppleOrder implements Serializable {
|
||||
|
||||
private String quantity;
|
||||
private String product_id;
|
||||
private String transaction_id;
|
||||
private String original_transaction_id;
|
||||
private String purchase_date;
|
||||
private String purchase_date_ms;
|
||||
private String purchase_date_pst;
|
||||
private String original_purchase_date;
|
||||
private String original_purchase_date_ms;
|
||||
private String original_purchase_date_pst;
|
||||
private String is_trial_period;
|
||||
private String in_app_ownership_type;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
package com.peanut.modules.pay.IOSPay.model.entities;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import lombok.Data;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@TableName("pay_apple_order")
|
||||
public class IosPayOrderEntity implements Serializable {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
|
||||
|
||||
@TableId(value = "id")
|
||||
private int id;
|
||||
/**
|
||||
*订单号的唯一标识*/
|
||||
|
||||
@TableField("orderid")
|
||||
private String orderid;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 购买的商品ID
|
||||
*/
|
||||
|
||||
@TableField("productID")
|
||||
private String productID;
|
||||
/**
|
||||
*用户ID
|
||||
*/
|
||||
|
||||
@TableField("customerOid")
|
||||
private String customerOid;
|
||||
/**
|
||||
*订单交易凭证
|
||||
*/
|
||||
|
||||
@TableField("authToken")
|
||||
private String receiptData;
|
||||
/**
|
||||
*创建订单时间
|
||||
*/
|
||||
@TableField("create_time")
|
||||
private Date createTime;
|
||||
/**
|
||||
*订单交易状态 0-交易成功 1-交易失败
|
||||
*/
|
||||
@TableField("order_status")
|
||||
private String orderStatus;
|
||||
/**
|
||||
*充值金额
|
||||
*/
|
||||
@TableField("money")
|
||||
private Integer money;
|
||||
/**
|
||||
*实际到账金额
|
||||
*/
|
||||
@TableField("point")
|
||||
private Integer point;
|
||||
|
||||
|
||||
/**
|
||||
* 轮询十次失败标记
|
||||
*/
|
||||
@TableField("failureflag")
|
||||
private Integer failureflag;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*删除标记 1 -未删除 0-已删除
|
||||
*/
|
||||
@TableField("del_flag")
|
||||
@TableLogic
|
||||
private Integer delFlag;
|
||||
|
||||
|
||||
/**
|
||||
*0-未关单 1-已关单 @Column(name = "close_order")
|
||||
*/
|
||||
@TableField("close_order")
|
||||
private Integer closeOrder;
|
||||
|
||||
|
||||
/**
|
||||
* 充值金额
|
||||
*/
|
||||
|
||||
@TableField("recharge_Amount")
|
||||
private BigDecimal rechargeAmount;
|
||||
/**
|
||||
* 充值渠道
|
||||
*/
|
||||
|
||||
|
||||
@TableField("recharge_Channel")
|
||||
private String rechargeChannel;
|
||||
|
||||
/**
|
||||
* 实际充值金额
|
||||
*/
|
||||
|
||||
|
||||
@TableField("realAmount")
|
||||
private BigDecimal realAmount;
|
||||
/**
|
||||
* 充值状态
|
||||
*/
|
||||
|
||||
|
||||
@TableField("recharge_Status")
|
||||
private String rechargeStatus;
|
||||
|
||||
/**
|
||||
* 支付成功时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private Date successTime;
|
||||
|
||||
|
||||
|
||||
@TableField("Body")
|
||||
private String Body;
|
||||
|
||||
/*
|
||||
商品描述
|
||||
* */
|
||||
|
||||
|
||||
|
||||
@TableField("username")
|
||||
private String username;
|
||||
/*
|
||||
标识内购商品和相关操作的ID
|
||||
* */
|
||||
|
||||
|
||||
@TableField("relevanceoid")
|
||||
private String relevanceoid;
|
||||
/*
|
||||
买方支付的金额包括税和折扣
|
||||
* */
|
||||
|
||||
@TableField("buyerPay_Amount")
|
||||
private String buyerPayAmount;
|
||||
|
||||
|
||||
@TableField("TransactionId")
|
||||
private String transactionId;
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.peanut.modules.pay.IOSPay.service;
|
||||
import com.peanut.modules.pay.IOSPay.model.dto.IapResponseDTO;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public interface IapVerifyReceiptService {
|
||||
/**
|
||||
* 苹果凭证二次校验
|
||||
* @param receipt 苹果凭证
|
||||
* @param isSandBox 是否是沙盒环境
|
||||
* @return 校验结果
|
||||
*/
|
||||
IapResponseDTO verifyIapReceipt(String receipt, boolean isSandBox);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.peanut.modules.pay.IOSPay.service;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.peanut.common.utils.PageUtils;
|
||||
import com.peanut.modules.pay.IOSPay.model.entities.IosPayOrderEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
public interface OrderService extends IService<IosPayOrderEntity> {
|
||||
|
||||
|
||||
IosPayOrderEntity genOrder(String id, String productId);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param failureflag 失败标识
|
||||
* @param
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
|
||||
String failure(String failureflag, String orderid);
|
||||
|
||||
PageUtils queryPage1(Map<String, Object> params) throws Exception;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.peanut.modules.pay.IOSPay.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.peanut.modules.pay.IOSPay.constant.VerifyReceiptConstant;
|
||||
import com.peanut.modules.pay.IOSPay.model.dto.IapResponseDTO;
|
||||
import com.peanut.modules.pay.IOSPay.service.IapVerifyReceiptService;
|
||||
import com.peanut.modules.pay.IOSPay.utils.IapRequestUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class IapVerifyReceiptServiceImpl implements IapVerifyReceiptService {
|
||||
|
||||
@Override
|
||||
public IapResponseDTO verifyIapReceipt(String receipt, boolean isSandBox) {
|
||||
// String url = isSandBox ? VerifyReceiptConstant.URL_SANDBOX : VerifyReceiptConstant.URL_VERIFY;
|
||||
|
||||
// 发送receipt给苹果服务器
|
||||
// Object o = new Object(String.valueOf("MIIUKAYJKoZIhvcNAQcCoIIUGTCCFBUCAQExCzAJBgU"));
|
||||
// String receipt1= "MIIUKAYJKoZIhvcNAQcCoIIUGTCCFBUCAQExCzAJBgUrDgMCGgUAMIIDZgYJKoZIhvcNAQcBoIIDVwSCA1MxggNPMAoCAQgCAQEEAhYAMAoCARQCAQEEAgwAMAsCAQECAQEEAwIBADALAgELAgEBBAMCAQAwCwIBDwIBAQQDAgEAMAsCARACAQEEAwIBADALAgEZAgEBBAMCAQMwDAIBCgIBAQQEFgI0KzAMAgEOAgEBBAQCAgCJMA0CAQMCAQEEBQwDMTEwMA0CAQ0CAQEEBQIDAf4oMA0CARMCAQEEBQwDMS4wMA4CAQkCAQEEBgIEUDI2MDAYAgEEAgECBBAX4ibAXjZ7IAwLx10evzedMBsCAQACAQEEEwwRUHJvZHVjdGlvblNhbmRib3gwHAIBBQIBAQQUYpDtGI14h";
|
||||
String res = IapRequestUtils.sendVerifyReceiptRequest(VerifyReceiptConstant.URL_VERIFY, receipt);
|
||||
if (res.contains(":21007}")) {
|
||||
res = IapRequestUtils.sendVerifyReceiptRequest(VerifyReceiptConstant.URL_SANDBOX, receipt);
|
||||
}
|
||||
IapResponseDTO iapResponseDTO = JSON.parseObject(res, IapResponseDTO.class);
|
||||
return iapResponseDTO;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
package com.peanut.modules.pay.IOSPay.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.peanut.common.utils.ExcludeEmptyQueryWrapper;
|
||||
import com.peanut.common.utils.PageUtils;
|
||||
import com.peanut.common.utils.Query;
|
||||
import com.peanut.modules.common.entity.BookBuyConfigEntity;
|
||||
import com.peanut.modules.common.entity.BuyOrder;
|
||||
import com.peanut.modules.common.entity.MyUserEntity;
|
||||
import com.peanut.modules.book.service.BookBuyConfigService;
|
||||
import com.peanut.modules.book.service.BuyOrderService;
|
||||
import com.peanut.modules.book.service.MyUserService;
|
||||
import com.peanut.modules.pay.IOSPay.mapper.PayIOSOrderMapper;
|
||||
import com.peanut.modules.pay.IOSPay.mapper.PayPaymentOrderMapper;
|
||||
import com.peanut.modules.pay.IOSPay.model.entities.IosPayOrderEntity;
|
||||
import com.peanut.modules.pay.IOSPay.service.OrderService;
|
||||
import com.peanut.modules.pay.IOSPay.vo.FailureVo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
public class OrderServiceImpl extends ServiceImpl<PayIOSOrderMapper,IosPayOrderEntity> implements OrderService {
|
||||
|
||||
@Autowired
|
||||
private PayPaymentOrderMapper payPaymentOrderMapper;
|
||||
@Autowired
|
||||
private PayIOSOrderMapper payIOSOrderMapper;
|
||||
@Autowired
|
||||
private BuyOrderService buyOrderService;
|
||||
@Autowired
|
||||
private MyUserService userService;
|
||||
|
||||
@Autowired
|
||||
private MyUserService myUserService;
|
||||
@Autowired
|
||||
private BookBuyConfigService bookBuyConfigService;
|
||||
@Override
|
||||
|
||||
public IosPayOrderEntity genOrder(String id, String productId) {
|
||||
|
||||
IosPayOrderEntity insertEntity = new IosPayOrderEntity();
|
||||
insertEntity.setProductID(productId);
|
||||
insertEntity.setRechargeChannel("后台手动充值");
|
||||
insertEntity.setRechargeStatus("");
|
||||
insertEntity.setId(Integer.valueOf(id));
|
||||
|
||||
|
||||
|
||||
insertEntity.setRealAmount(BigDecimal.ZERO);
|
||||
insertEntity.setRechargeAmount(BigDecimal.ZERO);
|
||||
|
||||
payIOSOrderMapper.insert(insertEntity);
|
||||
return insertEntity;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String failure(String failureflag, String orderid) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageUtils queryPage1(Map<String, Object> params) throws Exception {
|
||||
|
||||
List<IosPayOrderEntity> orders = payIOSOrderMapper.selectList(new QueryWrapper<IosPayOrderEntity>().eq("failureflag", 1));
|
||||
|
||||
|
||||
IosPayOrderEntity iosPayOrderEntity = new IosPayOrderEntity();
|
||||
IPage<IosPayOrderEntity> page = null;
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||
String startTime = null;
|
||||
String endTime = null;
|
||||
if (params.containsKey("startTime")) {
|
||||
startTime = sdf.format(Long.parseLong(params.get("startTime").toString()));
|
||||
endTime = sdf.format(Long.parseLong(params.get("endTime").toString()));
|
||||
}
|
||||
if (params.get("failureflag") != null ) {
|
||||
|
||||
page = this.page(
|
||||
new Query<IosPayOrderEntity>().getPage(params),
|
||||
new ExcludeEmptyQueryWrapper<IosPayOrderEntity>().eq("failureflag", 1).eq("orderid", params.get("key")).like("username", params.get("key"))
|
||||
.apply(startTime != null, "date_format (create_time,'%Y-%m-%d') >= date_format ({0},'%Y-%m-%d')", startTime)
|
||||
.apply(endTime != null, "date_format (create_time,'%Y-%m-%d') <= date_format ({0},'%Y-%m-%d')", endTime).orderByDesc("create_time")
|
||||
|
||||
|
||||
);
|
||||
} else {
|
||||
page = this.page(
|
||||
new Query<IosPayOrderEntity>().getPage(params),
|
||||
|
||||
new ExcludeEmptyQueryWrapper<IosPayOrderEntity>().eq("failureflag",1).eq("failureflag", params.get("key"))
|
||||
.apply(startTime != null, "date_format (create_time,'%Y-%m-%d') >= date_format ({0},'%Y-%m-%d')", startTime)
|
||||
.apply(endTime != null, "date_format (create_time,'%Y-%m-%d') <= date_format ({0},'%Y-%m-%d')", endTime).orderByDesc("create_time")
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
List<FailureVo> results = new ArrayList<FailureVo>();
|
||||
for (IosPayOrderEntity order : orders) {
|
||||
if (0!=order.getFailureflag()) {
|
||||
FailureVo vo = new FailureVo();
|
||||
vo.setId(order.getId());
|
||||
vo.setOrderid(order.getOrderid());
|
||||
vo.setProductID(order.getProductID());
|
||||
vo.setCustomerOid(order.getCustomerOid());
|
||||
vo.setReceiptData(order.getReceiptData());
|
||||
vo.setCreateTime(order.getCreateTime());
|
||||
vo.setFailureflag(order.getFailureflag());
|
||||
vo.setTransactionId(order.getTransactionId());
|
||||
MyUserEntity user = this.myUserService.getById(Integer.valueOf(order.getCustomerOid()));
|
||||
if (null == user) {
|
||||
vo.setUsername("");
|
||||
} else {
|
||||
vo.setUsername(user.getName());
|
||||
}
|
||||
BookBuyConfigEntity bookBuyConfigEntity = this.bookBuyConfigService.getById(Integer.valueOf(null == order.getProductID() ? "0" : order.getProductID()));
|
||||
vo.setRealMoney(null == bookBuyConfigEntity ? "0" : bookBuyConfigEntity.getRealMoney().toString());
|
||||
|
||||
BuyOrder orderEntity = buyOrderService.getBaseMapper().selectOne(new QueryWrapper<BuyOrder>().eq("order_sn", order.getOrderid()));
|
||||
if (null != orderEntity) {
|
||||
vo.setPaymentMethod(orderEntity.getPaymentMethod());
|
||||
}
|
||||
|
||||
|
||||
results.add(vo);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return new PageUtils(page);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.peanut.modules.pay.IOSPay.utils;
|
||||
import javax.net.ssl.*;
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
public class IapRequestUtils {
|
||||
|
||||
|
||||
static public String sendVerifyReceiptRequest(String url, String receipt) {
|
||||
try {
|
||||
SSLContext sslContext = SSLContext.getInstance("SSL");
|
||||
sslContext.init(null, new TrustManager[]{ new TrustAnyTrustManager() },new java.security.SecureRandom());
|
||||
URL console = new URL(url);
|
||||
HttpsURLConnection conn = (HttpsURLConnection)console.openConnection();
|
||||
conn.setSSLSocketFactory(sslContext.getSocketFactory());
|
||||
conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
|
||||
conn.setRequestMethod("POST");
|
||||
conn.setRequestProperty("content-type", "application/json");
|
||||
conn.setRequestProperty("Proxy-Connection", "Keep-Alive");
|
||||
conn.setDoInput(true);
|
||||
conn.setDoOutput(true);
|
||||
String str = String.format("{\"receipt-data\":\"%s\"}", receipt);//拼成固定的格式传给平台
|
||||
|
||||
try (OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream())) {
|
||||
out.write(str);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
try (InputStream is = conn.getInputStream();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
sb.append(line);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// log.error("苹果服务器验证出错:{}",e.getMessage());
|
||||
System.out.println("苹果服务器验证出错:{}"+e.getMessage());
|
||||
|
||||
|
||||
}
|
||||
return "ok";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
private static class TrustAnyTrustManager implements X509TrustManager {
|
||||
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return new X509Certificate[0];
|
||||
}
|
||||
|
||||
}
|
||||
private static class TrustAnyHostnameVerifier implements HostnameVerifier {
|
||||
|
||||
@Override
|
||||
public boolean verify(String s, SSLSession sslSession) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
108
src/main/java/com/peanut/modules/pay/IOSPay/vo/FailureVo.java
Normal file
108
src/main/java/com/peanut/modules/pay/IOSPay/vo/FailureVo.java
Normal file
@@ -0,0 +1,108 @@
|
||||
package com.peanut.modules.pay.IOSPay.vo;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
public class FailureVo implements Serializable {
|
||||
|
||||
private int id;
|
||||
private String orderid;
|
||||
private String productID;
|
||||
private String customerOid;
|
||||
private String receiptData;
|
||||
private Date createTime;
|
||||
private String paymentMethod;
|
||||
private Integer failureflag;
|
||||
private String transactionId;
|
||||
private String username;
|
||||
private String realMoney;
|
||||
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getOrderid() {
|
||||
return orderid;
|
||||
}
|
||||
|
||||
public void setOrderid(String orderid) {
|
||||
this.orderid = orderid;
|
||||
}
|
||||
|
||||
public String getProductID() {
|
||||
return productID;
|
||||
}
|
||||
|
||||
public void setProductID(String productID) {
|
||||
this.productID = productID;
|
||||
}
|
||||
|
||||
public String getCustomerOid() {
|
||||
return customerOid;
|
||||
}
|
||||
|
||||
public void setCustomerOid(String customerOid) {
|
||||
this.customerOid = customerOid;
|
||||
}
|
||||
|
||||
public String getReceiptData() {
|
||||
return receiptData;
|
||||
}
|
||||
|
||||
public void setReceiptData(String receiptData) {
|
||||
this.receiptData = receiptData;
|
||||
}
|
||||
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
public String getPaymentMethod() {
|
||||
return paymentMethod;
|
||||
}
|
||||
|
||||
public void setPaymentMethod(String paymentMethod) {
|
||||
this.paymentMethod = paymentMethod;
|
||||
}
|
||||
|
||||
public Integer getFailureflag() {
|
||||
return failureflag;
|
||||
}
|
||||
|
||||
public void setFailureflag(Integer failureflag) {
|
||||
this.failureflag = failureflag;
|
||||
}
|
||||
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
public void setTransactionId(String transactionId) {
|
||||
this.transactionId = transactionId;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getRealMoney() {
|
||||
return realMoney;
|
||||
}
|
||||
|
||||
public void setRealMoney(String realMoney) {
|
||||
this.realMoney = realMoney;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user