-- 新版提交
This commit is contained in:
@@ -4,7 +4,7 @@ public interface VerifyReceiptConstant {
|
||||
|
||||
/**
|
||||
* ios 端app bundle id
|
||||
* 也可以配置在nacos里面,动态获取
|
||||
|
||||
* URL_SANDBOX 沙盒测试
|
||||
* URL_VERIFY 正式
|
||||
*/
|
||||
@@ -15,7 +15,7 @@ public interface VerifyReceiptConstant {
|
||||
String URL_VERIFY = "https://sandbox.itunes.apple.com/verifyReceipt";
|
||||
|
||||
|
||||
// String URL_VERIFY = "https://buy.itunes.apple.com/verifyReceipt";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ public class AppController {
|
||||
try {
|
||||
|
||||
|
||||
System.out.println("==============veri=================================" + dto);
|
||||
|
||||
// 1. 校验入参
|
||||
if (dto == null)
|
||||
return Result.error("入参不能为空");
|
||||
@@ -90,13 +90,15 @@ public class AppController {
|
||||
IapResponseDTO receipt = iapVerifyReceiptService.verifyIapReceipt(dto.getReceiptData(), dto.isSandBox());
|
||||
BuyOrderEntity order2 = this.buyOrderService.getOne(new QueryWrapper<BuyOrderEntity>().eq("order_sn", dto.getOrderId()).eq("del_flag", "0"));
|
||||
order2.setPaymentDate(new Date());
|
||||
System.out.println("============order2=================" + order2);
|
||||
|
||||
|
||||
|
||||
order2.setProductId(dto.getProductId());
|
||||
this.buyOrderService.updateById(order2);
|
||||
|
||||
IosPayOrderEntity order = new IosPayOrderEntity();
|
||||
|
||||
//todo 判断状态 订单状态 0-未付款 1-待发货 2-已发货 3-交易成功 4-交易失败
|
||||
System.out.println("============保存中=================" + order);
|
||||
String order01 = order.getOrderid();
|
||||
String order02 = order2.getOrderSn();
|
||||
if (order01 == order02) {
|
||||
@@ -142,7 +144,7 @@ public class AppController {
|
||||
String body = dto.getProductId();
|
||||
if ("point".equals(subject)) {
|
||||
// 插入花生币 变动记录
|
||||
System.out.printf("body====:" + body);
|
||||
|
||||
BookBuyConfigEntity bookBuyConfigEntity = this.bookBuyConfigService.getById(Integer.valueOf(body));
|
||||
String realMoney = bookBuyConfigEntity.getMoney();
|
||||
Integer money = Integer.valueOf(realMoney);
|
||||
@@ -153,7 +155,6 @@ public class AppController {
|
||||
transactionDetailsEntity.setOrderType("充值");
|
||||
transactionDetailsEntity.setRelationId(order.getId());
|
||||
transactionDetailsEntity.setRemark("充值");
|
||||
System.out.println("===============进入了point获取ID=========================" + order.getId());
|
||||
MyUserEntity user = userService.getById(Integer.valueOf(customerid));
|
||||
BigDecimal peanutCoin = user.getPeanutCoin();
|
||||
transactionDetailsEntity.setUserBalance(peanutCoin);
|
||||
@@ -176,12 +177,12 @@ public class AppController {
|
||||
order.setMoney(Integer.valueOf(bookBuyConfigEntity.getRealMoney()));
|
||||
order.setUsername(user.getName());
|
||||
orderService.saveOrUpdate(order);
|
||||
System.out.println("==========ok================================================================================================================================================");
|
||||
|
||||
|
||||
|
||||
}
|
||||
orderService.update();
|
||||
System.out.println("==========ok================================================================================================================================================");
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -200,7 +201,7 @@ public class AppController {
|
||||
lock.unlock();
|
||||
|
||||
}
|
||||
// return null;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -210,24 +211,21 @@ public class AppController {
|
||||
*/
|
||||
|
||||
@RequestMapping(value = "/failure")
|
||||
// @RequestBody
|
||||
|
||||
public Result update(@Validated @RequestBody IapRequestDTO vo) {
|
||||
System.out.println("=========entity1111================"+vo);
|
||||
|
||||
IosPayOrderEntity order = new IosPayOrderEntity();
|
||||
|
||||
order.setOrderid(vo.getOrderId());
|
||||
order.setReceiptData(vo.getReceiptData());
|
||||
order.setProductID(vo.getProductId());
|
||||
order.setTransactionId(vo.getTransactionId());
|
||||
System.out.println("=========dto.getTransactionId()============" + vo.getTransactionId());
|
||||
|
||||
order.setCustomerOid(vo.getCustomerOid());
|
||||
order.setCloseOrder(0);
|
||||
order.setCreateTime(new Date());
|
||||
order.setFailureflag(vo.getFailureflag());
|
||||
System.out.println("============v0===================================================================================="+vo.getFailureflag());
|
||||
|
||||
orderService.saveOrUpdate(order);
|
||||
System.out.println("=======order================"+order);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
package com.peanut.modules.pay.IOSPay.model.entities;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
@@ -88,6 +85,7 @@ public class IosPayOrderEntity implements Serializable {
|
||||
*删除标记 1 -未删除 0-已删除
|
||||
*/
|
||||
@TableField("del_flag")
|
||||
@TableLogic
|
||||
private Integer delFlag;
|
||||
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -11,30 +11,31 @@ import com.alipay.api.DefaultAlipayClient;
|
||||
public class AliPayConfig {
|
||||
|
||||
/**
|
||||
* 花生appId 沙箱id 2021000117696096
|
||||
* 花生appId 沙箱id 2021002161620176
|
||||
*/
|
||||
public static final String HS_APP_ID = "2021000118600784";
|
||||
public static final String HS_APP_ID ="2021003191621137";
|
||||
|
||||
/**
|
||||
* 花生应用私钥
|
||||
*/
|
||||
public static final String HS_MERCHANT_PRIVATE_KEY = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCIrSciDRMFvEopt/F8O/SpQBZcyUXUcqe3rz2Sl0StpP5eu1IoB4GsX2wbYmOe6a0jfVrRLhvJINjYLrZiWUVGdSD3pkVtfQyp0pjmvi7sv/xtiUMhR7TZ2xWHieVN4h/4JsmdGMbirCnxJcqIKsdOkzHpm2CkmvwaBcLW1t5CGF5p2QKYAWVrtRfZemeXbseIHSQI0yhNVNA2moVVNny7+DMEY7jBwG/rsT5vymRa0R+Em4aBsi5LdR3h71hCxNwuizM8Z9WWamO6L0xj8s/FsaIxizprgcUH2WagqY0il5KBaOr3Kp/Tb8NvcTT4P9etwYV9YZAXqAkCHOo6zqbLAgMBAAECggEACPg8IjrzbaPuxhAhVALnSpg/H3XCFHA125Mvmkg9JJw4aWUnviLH+tUEVkO9v/cb+sFGTYYWIrv6Hy3poEi1iCs1r6sE0WusghSlHjeLAtSSr2mbszpufwGmxw9gshzN9k4tWxb+LnAYDJBrW0ZbcCeu1eLxk7vsIZURNWJCkdnIV2ColgqRPydvLAxPQTzz6P93BaG9jQrBBDhjpfqd1MI3QoRDSkFmSDAfv78DKV1G893lGWcbdDWdXNyR4EVmOLcT/Mmod1wY9dZSwT/faCYMekoVvXYl/r1KMq8HjgcHXArBELGayiA1dis2qO+Biz6t+ImJyHAK1LTsIRg4AQKBgQDsMWAzS8hbmj23EfPotmOLUZdIjfRlOLZ+zQ9PXn+Uxr0qWRmf3FFvcHm76onHFfkkYjIjqfibBVPeVP4cyYexEiHJSWbMNa8sRJAs8+2nyxufQqiN5l65KGGEVVREN6xWpacTdYGcF3RLeHlGrVYgJrAvkpCia2nLIUoIC0hyywKBgQCUI1eKJvQYiViG2BpjK1BUj12Pd0DmvyDI318N0xrpqWXjTklVwWHgESBM5lhtoTG4SKIclxKglnqsn9CC6IbiugFyxC6dWJpXi5Fl0R8CPcIUSwzQJAFUjgbMNqpx+9j/UkG/BETfFdvyb8GJ7mhKJIwOHzlPK3MzD3GEUegcAQKBgF8hU/nVIBGlAg5mMLMeIuHOLvyOEE1kljxkIzJ4gTJPCYmw8V0tw676wk0pneyNsRcyZbdvki3961W1LdQyZ3CuOOV1pu3BAZj21IsGhEX8zFdM5c6hZq100jIWnCYNtl//wFdaEKXp3HE5SL9quTGh43yFr7N7R9UEx2iOAtQZAoGANMJlkhmPhBGeit/6felWQdeRnd/+KHBXz9LmOrk984xWcl9WdQlbv365/0lmoxzu5VBRFFel1bXiWQrOK2F/cM6IZ4SBiZ6d0aIulZGmNpkiPzH/jT3Vj3TJ7P9nMxNcVIrKSarOkJlrbWvqBSL417cufnUWZyD1dXEBn/u/7AECgYB2722mJNfoRX6NAdP1VgJQ2i7Mt4Gv4RVLgYC9f3p/QETaexDvwuwbxzhTHPPBtcfCtlMlLhA5b6seFiQkBZJS+2NuJp/r7VRAw99ZBTb3Yn6NXXu713VUnZsisokKlqzNvLoH722NWPOVAmA8eAQnZqmWtPOkIcq6rjaGOKpnTA==";
|
||||
public static final String HS_MERCHANT_PRIVATE_KEY = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCa+oIVGBAKp+VjHIeE/IFUFWifnUWQYBPwffWEC5+EKJbqEC/wcVSfZPKXpPAB3T0c6V6yxCOMxguUZEdeRM5W93Wf0jktrtius34Xo79vgnLXsj2TtAN1ku9Qp5ebVVw+WPdpIl1nOFNwCoiaSPmwXOsVIT5MccxUvmGUDNUg8dYVoD9WHYu13O30c4vm+jYGCu7lviRqcjnEFooJ/ORocLqJbHFaTzWMGiiAYnUUSTL1BI5vhDNJDhm3B5wUZ7/j49EWQYZbV0fXlCrZRerfPLrAgXYR95P+62K9Xh8edzThTrPXmLXP9/jTqz2118ijXSoF8EgfhVD2NLCSDid3AgMBAAECggEAR3cPN0TyWMeVer+0Knn59Vkt9rSiWHJFn5el+K8Xbuz8spCmWp0YJax6Rb10Q5fOz5854PubXRYSTupzEqBt+iKApiNd5JgFKYJxudrzsysXZCm4RX00PypzmuC9g464S7Pg2yVSpv+NUlQ5K9RM96vRZ9v9i2jKjaWA/7FvMpI3auOJgrJVoSbPYNx6/QIN1b9imukCMSga9OzF66LhfzACWxJx+DzgAX+7GcfhTF8PbhytPPg9LhlfcGq2gA/TcG6zUorFz5Qy+k//g4rxIvjcPnGfcRgoT+Xgi7I8wnm3O5icIZ6k6+B+wwN3zRTBSmXwbwsgdncGA1RUhe2tAQKBgQDweYu2ij8Io/g7KCvCtVpGHqhzKxgaOZXy0nvPFXY5KFcrrapACriztCaxjvRTXm7t25KJQazICs50OvyTZL5+U3GHp/8GK7KwzZKz5NkHHMtKoKwQADBNau/nHdro4E+PnvL9ucaFX69JF4DZqiw2aDkQkDB/BablHyvuTagJgQKBgQCk++uzero6bXOxFMadLLyWTvlOJP71U1fVSf4Nou+L4ce7k2bMpSDyEDNDOUW3WOO7zz9i8mFGCTUaoX3mhC+B9UQqKZXK2rjFgZtkNDumoCTzvjuPIWTMNN6ABetiLxbq/UD0O1xwThVQNmYwTOzwMHUMkT21ynD23KXE0JL89wKBgGg1Q8YmwooMBFYeYlhOHoCkaHsAAcHbko9Xhy+GLWU3hg73gv+dpcy6FMp9GIPIOGn67NVuEGHfzPexWCLHVYWIw3n14x3ZceYML7alRSc/4xjD58xHSKdD4BJXbbXc/p1OVB5/kvfZLyyNctjgVah+Ibx7v4hL+rbveyoZnOgBAoGAG34je+giqmPc2JB2vHBdCMsmPkBqACWgSFmpLUqOkofQSdC5W7bUs6HBeR1NIc19Pam+jVWIoiwcnlB083nplMVzU3dUj9Y83iTH6T3PBug+4CM+N47ABkt1HG5gGB9yuTv0m/5cXBaW9KPsCXZ4MVpR1wNI/kc65dhFA3QiWmcCgYEA6CfUjOWe201IC332e142WfPGp7hy8p6RHrPtlXS5YnuxVsJVusyuncVdG10kPkvPHakFokqNNUW76Trf++IPnNooMP9ucYj060hYTM7JK9F0mAdx0Mo/+nDC7voXw8rBSsLZHAWfxMh/KjQ5D7L6E2S71wP6ep25hoOuuuLTnrI=";
|
||||
|
||||
/**
|
||||
* 花生支付宝应用公钥
|
||||
* 应用公钥
|
||||
*/
|
||||
public static final String HS_ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiK0nIg0TBbxKKbfxfDv0qUAWXMlF1HKnt689kpdEraT+XrtSKAeBrF9sG2JjnumtI31a0S4bySDY2C62YllFRnUg96ZFbX0MqdKY5r4u7L/8bYlDIUe02dsVh4nlTeIf+CbJnRjG4qwp8SXKiCrHTpMx6ZtgpJr8GgXC1tbeQhheadkCmAFla7UX2Xpnl27HiB0kCNMoTVTQNpqFVTZ8u/gzBGO4wcBv67E+b8pkWtEfhJuGgbIuS3Ud4e9YQsTcLoszPGfVlmpjui9MY/LPxbGiMYs6a4HFB9lmoKmNIpeSgWjq9yqf02/Db3E0+D/XrcGFfWGQF6gJAhzqOs6mywIDAQAB";
|
||||
|
||||
//沙箱支付宝公钥
|
||||
|
||||
public static final String HS_ALI_PUBLIC_KEY ="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmjFqCkYZ7/2TmINtDlFap8MUu/Z+SN6anxJH73LojB5qmQAHlUN5n55NvhcY+eaE6khpn9BCQDJ8URWs2DDhVKSw6EUwEFafkXmWNEAAjhpT9O5YrMACg8d0zhQirS4zrG/6tjPvx9X2X/CIohlu8jif79m46o11NI+iUmdiaT/IU4gMSUFqZ9KR9Qz6xzjJQ0tULHl+7S9qTQLbqqfJgzDEh06SU9F7KnQ0T9wIIPI7KCfn72kNMRUC2DGOZxFA8eztg1bprRhwufrT52ijEH+z/8hkyYVz1+MrrCaDGvSrC9xVj1FFzAofsMQxgKtSgjbgs0+reLoJ/uL/SKXWpQIDAQAB";
|
||||
|
||||
public static final String HS_ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmvqCFRgQCqflYxyHhPyBVBVon51FkGAT8H31hAufhCiW6hAv8HFUn2Tyl6TwAd09HOlessQjjMYLlGRHXkTOVvd1n9I5La7YrrN+F6O/b4Jy17I9k7QDdZLvUKeXm1VcPlj3aSJdZzhTcAqImkj5sFzrFSE+THHMVL5hlAzVIPHWFaA/Vh2Ltdzt9HOL5vo2Bgru5b4kanI5xBaKCfzkaHC6iWxxWk81jBoogGJ1FEky9QSOb4QzSQ4ZtwecFGe/4+PRFkGGW1dH15Qq2UXq3zy6wIF2EfeT/utivV4fHnc04U6z15i1z/f406s9tdfIo10qBfBIH4VQ9jSwkg4ndwIDAQAB";
|
||||
|
||||
/**
|
||||
* 回调地址
|
||||
* 支付宝公钥
|
||||
*/
|
||||
|
||||
public static final String HS_ALI_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiVLUVTnNuq+2C1FRtcIRcG3rCgtVVulkz2QljKbPr7NNWTJJIIfGwyhNuH76s5D1lvNmn2NkuoqM0cMJCSd+W+JW9KpdQ0dgumFHCoRA/OWUoqpLvEOmm2hRMaWpvd+OQq2aPz+p+z6pqZ9SAlgUIolzrUn4idCvgIycqRaGsf1sEJFR5W+rneqtMhNYHdwemqaqnysInwshHR3cHs1AC6y/eL6pcQhaYJ5qVMIRg54/6Lr4CU114Rmph7UM9C28ulmHkFMN/DKPUDbM1+glxjzmqHQChY293Db0dlwZeiDWF3Tli2BVd6pz5KEkQlUsGeLW1O0rT9T9sxzsavxArwIDAQAB";
|
||||
|
||||
/**
|
||||
* 回调地址 因为是内网开发 目前为内网穿透地址
|
||||
*/
|
||||
public static final String NOTIFY_URL = "http://59.110.212.44:9100/pb/pay/aliPay/notify";
|
||||
// public static final String NOTIFY_URL = "http://kvv6y4.natappfree.cc/pb/pay/aliPay/notify";
|
||||
|
||||
/**
|
||||
* 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数
|
||||
|
||||
@@ -44,8 +44,8 @@ public class AliPayController {
|
||||
Map<String, String[]> parameterMap = request.getParameterMap();
|
||||
String jsonStr = JSONObject.toJSONString(parameterMap);
|
||||
System.out.println("支付宝回调信息=============》"+jsonStr);
|
||||
aliPayService.aliNotify(request);
|
||||
return R.ok();
|
||||
String aliNotify = aliPayService.aliNotify(request);
|
||||
return R.ok().put("aliNotify",aliNotify);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ public class AliPayServiceImpl implements AliPayService {
|
||||
return "success";
|
||||
}
|
||||
PayZfbOrderEntity oldPayZfbOrderEntity = payZfbOrderService.getOne(new QueryWrapper<PayZfbOrderEntity>().eq("out_trade_no", aliNotifyDto.getOutTradeNo()));
|
||||
CopyUtils.copyProperties(aliNotifyDto,oldPayZfbOrderEntity);
|
||||
CopyUtils.copyProperties(aliNotifyDto,oldPayZfbOrderEntity);
|
||||
|
||||
payZfbOrderService.updateById(oldPayZfbOrderEntity);
|
||||
|
||||
@@ -160,10 +160,12 @@ public class AliPayServiceImpl implements AliPayService {
|
||||
transactionDetailsEntity.setOrderType("充值");
|
||||
transactionDetailsEntity.setRelationId(oldPayZfbOrderEntity.getId().intValue());
|
||||
transactionDetailsEntity.setRemark("充值");
|
||||
|
||||
MyUserEntity user = userService.getById(Integer.valueOf(customerid));
|
||||
Integer peanutCoin = user.getPeanutCoin();
|
||||
BigDecimal balance = new BigDecimal(peanutCoin);
|
||||
transactionDetailsEntity.setUserBalance(balance);
|
||||
BigDecimal peanutCoin = user.getPeanutCoin();
|
||||
transactionDetailsEntity.setUserBalance(peanutCoin);
|
||||
transactionDetailsEntity.setUserName(user.getNickname());
|
||||
transactionDetailsEntity.setTel(user.getTel());
|
||||
transactionDetailsService.save(transactionDetailsEntity);
|
||||
// 插入 花生币 充值记录
|
||||
PayPaymentOrderEntity payPaymentOrderEntity = new PayPaymentOrderEntity();
|
||||
@@ -174,15 +176,20 @@ public class AliPayServiceImpl implements AliPayService {
|
||||
payPaymentOrderEntity.setRechargeChannel(bookBuyConfigEntity.getQudao());
|
||||
payPaymentOrderEntity.setRechargeStatus("success");
|
||||
payPaymentOrderEntity.setSuccessTime(new Date());
|
||||
payPaymentOrderEntity.setUserName(user.getNickname());
|
||||
payPaymentOrderEntity.setTel(user.getTel());
|
||||
payPaymentOrderService.save(payPaymentOrderEntity);
|
||||
buyOrderService.updateOrderStatus(Integer.valueOf(customerid),oldPayZfbOrderEntity.getRelevanceoid(),"2");
|
||||
}
|
||||
if ("order".equals(subject)) {
|
||||
|
||||
System.out.println("=====到order更新字段==================================================================================================================");
|
||||
BuyOrderEntity orderEntity = buyOrderService.getBaseMapper().selectOne(new QueryWrapper<BuyOrderEntity>().eq("order_sn", oldPayZfbOrderEntity.getRelevanceoid()));
|
||||
System.out.println("======orderEntity=========="+orderEntity);
|
||||
BigDecimal realMoney = orderEntity.getRealMoney();
|
||||
|
||||
System.out.println("======realMoney=========="+realMoney);
|
||||
BigDecimal bigDecimal = new BigDecimal(oldPayZfbOrderEntity.getBuyerPayAmount());
|
||||
|
||||
System.out.println("======bigDecimal=========="+bigDecimal);
|
||||
//更新 订单 记录
|
||||
if (bigDecimal.compareTo(realMoney) == 0) {
|
||||
buyOrderService.updateOrderStatus(Integer.valueOf(customerid),oldPayZfbOrderEntity.getRelevanceoid(),"0");
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.peanut.modules.pay.weChatPay.config;
|
||||
|
||||
import cn.hutool.core.io.resource.ClassPathResource;
|
||||
import cn.hutool.core.io.resource.Resource;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
|
||||
import com.wechat.pay.contrib.apache.httpclient.auth.*;
|
||||
@@ -7,9 +9,11 @@ import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
|
||||
import com.wechat.pay.contrib.apache.httpclient.exception.HttpCodeException;
|
||||
import com.wechat.pay.contrib.apache.httpclient.exception.NotFoundException;
|
||||
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.Data;
|
||||
import lombok.Value;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
@@ -18,11 +22,18 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.*;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.PrivateKey;
|
||||
import java.util.Enumeration;
|
||||
|
||||
|
||||
/**
|
||||
@@ -94,15 +105,47 @@ public class WechatPayConfig implements Serializable {
|
||||
|
||||
private String domain;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//获取私钥工具
|
||||
public PrivateKey getPrivateKey(String keyPemPath) {
|
||||
|
||||
try {
|
||||
return PemUtil.loadPrivateKey(new FileInputStream(keyPemPath));
|
||||
/*
|
||||
|
||||
解决方案
|
||||
1. 将私钥文件放在应用的外部,然后通过文件路径来读取。例如:
|
||||
privateKeyPath = "/etc/myapp/apiclient_key.pem";
|
||||
File file = new File(privateKeyPath);
|
||||
return PemUtil.loadPrivateKey(new FileInputStream(file));
|
||||
这样你就可以将 privateKeyPath 设置为任意位置的文件路径。
|
||||
|
||||
|
||||
2.如果你确实需要将私钥文件打包到应用中,你可以使用 ResourceUtils.getURL(filename).openStream() 来获取文件内容,例如:
|
||||
privateKeyPath = "classpath:cert/apiclient_key.pem";
|
||||
return PemUtil.loadPrivateKey(ResourceUtils.getURL(privateKeyPath).openStream());
|
||||
这样你就可以从应用的 classpath 中读取文件内容。
|
||||
|
||||
ResourceUtils.getURL(filename).openStream() 来获取资源,这是与平台无关的,所以在Windows、Linux以及其他任何支持Java的平台上都能正常使用。只要你的资源文件(在这个例子中是私钥文件)被正确的包含在了你的应用的classpath中,那么你就可以在任何平台上使用这个方法来读取资源文件的内容。
|
||||
这里需要注意的是,classpath: 是一个特殊的协议前缀,它表示资源是从classpath中获取的。当你的资源文件被打包进jar或war时,它们就位于应用的classpath中,因此你可以使用 classpath: 前缀来获取这些文件。
|
||||
因此,无论你的应用运行在Windows还是Linux,或者是其他任何操作系统上,使用方法2都不会有问题。只要你的资源文件被正确地打包进了应用,那么就可以使用这种方法来读取文件内容。
|
||||
*/
|
||||
|
||||
|
||||
// 修改后的方法
|
||||
|
||||
return PemUtil.loadPrivateKey(ResourceUtils.getURL(keyPemPath).openStream());
|
||||
|
||||
} catch (FileNotFoundException e) {
|
||||
//抛出异常,并把错误文件继续向上抛出
|
||||
throw new RuntimeException("私钥文件不存在",e);
|
||||
throw new RuntimeException("私钥文件不存在", e);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("私钥文件流失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,7 +162,8 @@ public class WechatPayConfig implements Serializable {
|
||||
log.info("获取证书管理器实例");
|
||||
|
||||
//获取商户私钥
|
||||
// PrivateKey privateKey = getPrivateKey(keyPemPath);
|
||||
|
||||
|
||||
PrivateKey privateKey = getPrivateKey(keyPemPath);
|
||||
|
||||
//私钥签名对象
|
||||
@@ -146,12 +190,13 @@ public class WechatPayConfig implements Serializable {
|
||||
* @return
|
||||
*/
|
||||
@Bean(name = "wxPayClient")
|
||||
// @Bean
|
||||
|
||||
|
||||
public CloseableHttpClient getWxPayClient(Verifier verifier) {
|
||||
log.info("获取HttpClient");
|
||||
|
||||
//获取商户私钥
|
||||
|
||||
PrivateKey privateKey = getPrivateKey(keyPemPath);
|
||||
|
||||
WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
|
||||
@@ -168,12 +213,11 @@ public class WechatPayConfig implements Serializable {
|
||||
/**
|
||||
* 获取HttpClient,无需进行应答签名验证,跳过验签的流程
|
||||
*/
|
||||
@Bean(name = "wxPayNoSignClient")
|
||||
public CloseableHttpClient getWxPayNoSignClient() {
|
||||
|
||||
//获取商户私钥
|
||||
PrivateKey privateKey = getPrivateKey(keyPemPath);
|
||||
|
||||
|
||||
//用于构造HttpClient
|
||||
WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
|
||||
//设置商户信息
|
||||
|
||||
@@ -88,11 +88,6 @@ public class WeChatPayController {
|
||||
|
||||
|
||||
|
||||
@RequestMapping(value = "/Vxtext", method = RequestMethod.POST)
|
||||
public String vxPAYtext(@RequestBody Integer user) {
|
||||
|
||||
return "=============================test============"+user;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -106,39 +101,7 @@ public class WeChatPayController {
|
||||
@RequestMapping(value = "/placeAnOrder/app")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R pay(@RequestBody WechatDto dto ) throws Exception{
|
||||
// Date afterDate = new Date(nowDate.getTime()+300000*3);
|
||||
|
||||
|
||||
//
|
||||
// Date nowDate = new Date();
|
||||
// Date afterDate = new Date(nowDate.getTime() + 60000);
|
||||
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ssXXX");
|
||||
// sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
|
||||
//
|
||||
// String dateString = sdf.format(afterDate); // 将修改后的时间转换为字符串
|
||||
|
||||
//
|
||||
// ZoneId zoneId = ZoneId.of("Asia/Shanghai");
|
||||
// Instant now = Instant.now();
|
||||
// Instant after = now.plus(60, ChronoUnit.SECONDS);
|
||||
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ssXXX");
|
||||
//// .withZone(zoneId);
|
||||
// sdf.setTimeZone(TimeZone.getTimeZone(zoneId));
|
||||
//
|
||||
// String afterString = sdf.format(after);
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// System.out.println("修改后时间:" + afterString);
|
||||
|
||||
|
||||
|
||||
|
||||
System.out.println("==========ordersn================"+dto.getOrderSn());
|
||||
log.info("生成订单");
|
||||
log.info("微信生成订单");
|
||||
List<BuyOrderEntity> one = this.buyOrderService.getBaseMapper().selectList(new QueryWrapper<BuyOrderEntity>().eq("order_sn", dto.getOrderSn()));
|
||||
BuyOrderEntity order = one.get(0);
|
||||
// 获取订单
|
||||
@@ -154,12 +117,27 @@ public class WeChatPayController {
|
||||
// paramMap.put("time_expire",afterString);
|
||||
// 实收金额0.38乘100=38
|
||||
BigDecimal realsmoney= order.getRealMoney();
|
||||
BigDecimal hand=new BigDecimal("100");
|
||||
realsmoney =realsmoney.multiply(hand) ;
|
||||
BigDecimal hand=new BigDecimal("100");
|
||||
realsmoney =realsmoney.multiply(hand) ;
|
||||
Map<String,Object> amountMap = new HashMap<>();
|
||||
amountMap.put("total",realsmoney);
|
||||
amountMap.put("currency","CNY");
|
||||
|
||||
|
||||
BigDecimal money= order.getRealMoney();
|
||||
BigDecimal han=new BigDecimal("100");
|
||||
realsmoney =realsmoney.multiply(han) ;
|
||||
Map<String,Object> amount = new HashMap<>();
|
||||
amount.put("total",realsmoney);
|
||||
amount.put("currency","CNY");
|
||||
|
||||
if (dto.getTotalAmount()!=order.getRealMoney()) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
paramMap.put("amount",amountMap);
|
||||
|
||||
JSONObject json = JSONObject.parseObject(JSON.toJSONString(paramMap));
|
||||
log.info("请求参数"+paramMap);
|
||||
com.alibaba.fastjson.JSONObject jsonObject1 = wxPayUtil.doPostWexinV3("https://api.mch.weixin.qq.com/v3/pay/transactions/app", json.toJSONString());
|
||||
@@ -204,7 +182,7 @@ public class WeChatPayController {
|
||||
wechat.setCreateTime(new Date()); //创建订单时间
|
||||
wechat.setOrderSn(order.getOrderSn()); //订单编号
|
||||
wechat.setPrepayId(prepayid); //预支付回话标识 标识为响应体EntityUtils.toString(response.getEntity())
|
||||
wechat.setTotalAmount(order.getRealMoney()); //支付实收金额
|
||||
wechat.setTotalAmount(dto.getTotalAmount()); //支付实收金额
|
||||
wechat.setSystemLog(response.toString()); //日志
|
||||
wechat.setPayType(order.getOrderType()); //交易类型
|
||||
wechat.setOrderId(order.getOrderSn()); //订单号
|
||||
@@ -258,13 +236,13 @@ public class WeChatPayController {
|
||||
@PostMapping("/payNotify")
|
||||
public R payNotify(HttpServletRequest request, HttpServletResponse response) {
|
||||
log.info("##############################微信支付回调#######################");
|
||||
PayWechatOrderEntity wechatEntity = new PayWechatOrderEntity();
|
||||
|
||||
|
||||
// 处理通知参数
|
||||
Map<String,Object> bodyMap = getNotifyBody(request);
|
||||
if(bodyMap==null){
|
||||
return null;
|
||||
}
|
||||
log.warn("=========== 在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱 ===========");
|
||||
if(lock.tryLock()) {
|
||||
try {
|
||||
// 解密resource中的通知数据
|
||||
@@ -272,19 +250,21 @@ public class WeChatPayController {
|
||||
Map<String, Object> resourceMap = WechatPayValidator.decryptFromResource(resource, wechatPayConfig.getApiV3Key(),1);
|
||||
String orderNo = resourceMap.get("out_trade_no").toString();
|
||||
String transactionId = resourceMap.get("transaction_id").toString();
|
||||
System.out.println("===================回调解密transactionId================================"+transactionId);
|
||||
// 根据订单号,做幂等处理,并且在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱
|
||||
BuyOrderEntity order = this.buyOrderService.getOne(new QueryWrapper<BuyOrderEntity>().eq("order_sn", orderNo));
|
||||
PayWechatOrderEntity wechatEntity = new PayWechatOrderEntity();
|
||||
if(!ObjectUtils.isEmpty(order)){
|
||||
wechatEntity = this.payWechatOrderService.getOne(new QueryWrapper<PayWechatOrderEntity>().eq("order_id", order.getOrderId()));
|
||||
|
||||
wechatEntity = this.payWechatOrderService.getOne(new QueryWrapper<PayWechatOrderEntity>().eq("order_sn", order.getOrderSn()));
|
||||
}else{
|
||||
log.error("无效订单!");
|
||||
return R.error(500,"无效订单!");
|
||||
}
|
||||
// 1.根据订单id获取订单信息
|
||||
log.warn("=========== 根据订单号,做幂等处理 ===========");
|
||||
|
||||
if("order".equals(order.getOrderType())){
|
||||
BuyOrderEntity orderEntity = buyOrderService.getBaseMapper().selectOne(new QueryWrapper<BuyOrderEntity>().eq("order_sn", wechatEntity.getOrderId()));
|
||||
|
||||
BuyOrderEntity orderEntity = buyOrderService.getBaseMapper().selectOne(new QueryWrapper<BuyOrderEntity>().eq("order_sn", wechatEntity.getOrderSn()));
|
||||
BigDecimal realMoney = orderEntity.getRealMoney();
|
||||
|
||||
//更新 订单 记录
|
||||
@@ -373,4 +353,99 @@ public class WeChatPayController {
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping(value = "/placeAnOrder/shoppingpay")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R shoppingpay(@RequestBody WechatDto dto ) throws Exception{
|
||||
log.info("生成订单");
|
||||
List<BuyOrderEntity> one = this.buyOrderService.getBaseMapper().selectList(new QueryWrapper<BuyOrderEntity>().eq("order_sn", dto.getOrderSn()));
|
||||
BuyOrderEntity order = one.get(0);
|
||||
|
||||
// 获取订单
|
||||
Map<String,Object> paramMap = new HashMap<>();
|
||||
paramMap.put("appid",appId);
|
||||
paramMap.put("mchid",mchId);
|
||||
paramMap.put("description","微信充值");
|
||||
// 订单编号
|
||||
paramMap.put("out_trade_no",order.getOrderSn());
|
||||
// paramMap.put("attach",""); //自定义数据 支付完成后才能显示 在查询API和支付通知中原样返回,可作为自定义参数使用
|
||||
paramMap.put("notify_url",wechatPayConfig.getNotifyUrl());
|
||||
BigDecimal realsmoney= dto.getTotalAmount();
|
||||
BigDecimal hand=new BigDecimal("100");
|
||||
realsmoney =realsmoney.multiply(hand) ;
|
||||
Map<String,Object> amountMap = new HashMap<>();
|
||||
amountMap.put("total",realsmoney);
|
||||
amountMap.put("currency","CNY");
|
||||
|
||||
|
||||
paramMap.put("amount",amountMap);
|
||||
|
||||
|
||||
|
||||
JSONObject json = JSONObject.parseObject(JSON.toJSONString(paramMap));
|
||||
log.info("请求参数"+paramMap);
|
||||
com.alibaba.fastjson.JSONObject jsonObject1 = wxPayUtil.doPostWexinV3("https://api.mch.weixin.qq.com/v3/pay/transactions/app", json.toJSONString());
|
||||
String prepayid = jsonObject1.getString("prepay_id");
|
||||
// 传入参数 payUrl 发送post请求
|
||||
HttpPost httpPost = new HttpPost(payUrl);
|
||||
// 将json数据转换成字符串
|
||||
StringEntity entity = new StringEntity(json.toString(),"utf-8");
|
||||
// 设置该请求的Content-Type为application/json 都是json格式
|
||||
entity.setContentType("application/json");
|
||||
// 将实体对象设置到HttpPost表示要传递该数据到服务器端。
|
||||
httpPost.setEntity(entity);
|
||||
// 设置请求头部的Accept属性为"application/json"表示客户端希望接收的为json。
|
||||
httpPost.setHeader("Accept", "application/json");
|
||||
CloseableHttpResponse response = wxPayClient.execute(httpPost);
|
||||
// 向微信支付平台发送请求,处理响应结果,并将订单信息保存到数据库中。
|
||||
String bodyAsString = EntityUtils.toString(response.getEntity());//响应体
|
||||
// 时间戳
|
||||
Long timestamp = System.currentTimeMillis()/1000;
|
||||
// 随机串
|
||||
String nonceStr = UUID.randomUUID().toString().replace("-","");
|
||||
|
||||
String sign = wxPayUtil.getSign(WxPayUtil.appId,timestamp,nonceStr,prepayid);
|
||||
log.info("签名:"+sign);
|
||||
|
||||
Map Map = new HashMap();
|
||||
Map.put("prepayid",prepayid);
|
||||
Map.put("timestamp",timestamp+"");
|
||||
Map.put("noncestr",nonceStr);
|
||||
Map.put("sign",sign);
|
||||
Map.put("appid",appId);
|
||||
Map.put("package","Sign=WXPay");
|
||||
Map.put("extData","sign");
|
||||
Map.put("partnerid",mchId);
|
||||
try {
|
||||
int statusCode = response.getStatusLine().getStatusCode(); //响应状态码
|
||||
if (statusCode == 200) { //处理成功
|
||||
System.out.println("成功,返回结果 = " + bodyAsString); //返回响应体 EntityUtils.toString(response.getEntity())
|
||||
// 添加微信支付订单信息
|
||||
PayWechatOrderEntity wechat = new PayWechatOrderEntity();
|
||||
wechat.setCustomerId(order.getUserId()); //用户id
|
||||
wechat.setCreateTime(new Date()); //创建订单时间
|
||||
wechat.setOrderSn(order.getOrderSn()); //订单编号
|
||||
wechat.setPrepayId(prepayid); //预支付回话标识 标识为响应体EntityUtils.toString(response.getEntity())
|
||||
wechat.setTotalAmount(order.getRealMoney()); //支付实收金额
|
||||
wechat.setSystemLog(response.toString()); //日志
|
||||
wechat.setPayType(order.getOrderType()); //交易类型
|
||||
wechat.setOrderId(order.getOrderSn()); //订单号
|
||||
wechat.setBuyOrderId(dto.getBuyOrderId()); //购买配置id
|
||||
// wechat.setEndtime(after);
|
||||
this.payWechatOrderService.save(wechat); //微信订单表拿到数据保存数据库
|
||||
|
||||
} else if (statusCode == 204) { //处理成功,无返回Body
|
||||
System.out.println("成功");
|
||||
} else {
|
||||
System.out.println("下单失败 = " + statusCode + ",返回结果 = " + bodyAsString);
|
||||
throw new IOException("request failed");
|
||||
}
|
||||
}finally {
|
||||
response.close();
|
||||
}
|
||||
// 返回url和订单号
|
||||
return R.ok().put("paramMap" ,paramMap).put("Map",Map);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -2,18 +2,28 @@ package com.peanut.modules.pay.weChatPay.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
|
||||
@Data
|
||||
public class WechatDto implements Serializable {
|
||||
|
||||
|
||||
|
||||
//totalAmount: payItem.realMoney,
|
||||
// customerId:
|
||||
|
||||
private String orderSn;
|
||||
|
||||
private Integer buyOrderId;
|
||||
private BigDecimal totalAmount;
|
||||
|
||||
public BigDecimal getTotalAmount() {
|
||||
return totalAmount;
|
||||
}
|
||||
|
||||
public void setTotalAmount(BigDecimal totalAmount) {
|
||||
this.totalAmount = totalAmount;
|
||||
}
|
||||
|
||||
public String getOrderSn() {
|
||||
return orderSn;
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
package com.peanut.modules.pay.weChatPay.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.peanut.common.utils.R;
|
||||
import com.peanut.modules.book.entity.PayWechatOrderEntity;
|
||||
import com.peanut.modules.pay.weChatPay.dto.WechatDto;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
@Service
|
||||
public interface WxpayService extends IService<PayWechatOrderEntity> {
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
package com.peanut.modules.pay.weChatPay.util;
|
||||
|
||||
|
||||
import com.peanut.modules.pay.weChatPay.dto.WxchatCallbackRefundData;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
|
||||
/**
|
||||
* 退款处理接口,为了防止项目开发人员,不手动判断退款失败的情况
|
||||
* 退款失败:退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败,可前往商户平台-交易中心,手动处理此笔退款
|
||||
*/
|
||||
|
||||
public interface WechatRefundCallback {
|
||||
|
||||
|
||||
/*
|
||||
* WxchatCallbackRefundData是微信支付退款回调数据的格式,在退款请求完成后,微信支付会将退款结果发送给商户的服务器,
|
||||
* 以此通知商户退款结果。refundData表示退款回调的数据,包含退款结果的各种信息,如退款金额、退款状态、退款时间等等。
|
||||
* */
|
||||
|
||||
|
||||
/**
|
||||
* 退款成功处理情况
|
||||
*/
|
||||
void success(WxchatCallbackRefundData refundData);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 退款失败处理情况
|
||||
*/
|
||||
|
||||
|
||||
void find(WxchatCallbackRefundData refundData);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -32,17 +32,18 @@ import java.util.Base64;
|
||||
|
||||
public static final String apiV3Key = "4aYFklzaULeGlr7oJPZ6rHWKcxjihZUF"; // apiV3秘钥
|
||||
//商户私钥路径
|
||||
public static final String privateKeyUrl = "C:\\Users\\Administrator\\IdeaProjects\\peanut_book\\src\\main\\resources\\cent\\apiclient_key.pem";
|
||||
public static final String privateKeyUrl = "/usr/local/hs/peanut_book/target/classes/cent/apiclient_key.pem";
|
||||
// public static final String privateKeyUrl = "C:/Users/Administrator/IdeaProjects/peanut_book/src/main/resources/cent/apiclient_key.pem";
|
||||
|
||||
//平台证书路径
|
||||
public static final String wechatPayCertificateUrl = "C:\\Users\\Administrator\\IdeaProjects\\peanut_book\\src\\main\\resources\\cent\\wechatpay_7B5676E3CDF56680D0414A009CE501C844DBE2D6.pem";
|
||||
public static final String wechatPayCertificateUrl = "/usr/local/hs/peanut_book/target/classes/cent/wechatpay_7B5676E3CDF56680D0414A009CE501C844DBE2D6.pem";
|
||||
// public static final String wechatPayCertificateUrl = "C:/Users/Administrator/IdeaProjects/peanut_book/src/main/resources/cent/wechatpay_7B5676E3CDF56680D0414A009CE501C844DBE2D6.pem";
|
||||
//第一步申请完证书后,在API证书哪里点击管理证书就能看到
|
||||
public static final String mchSerialNo = "679AECB2F7AC4183033F713828892BA640E4EEE3"; // 商户证书序列号
|
||||
|
||||
private CloseableHttpClient httpClient;
|
||||
|
||||
public void setup() {
|
||||
// PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(privateKey);
|
||||
PrivateKey merchantPrivateKey = null;
|
||||
X509Certificate wechatPayCertificate = null;
|
||||
|
||||
@@ -137,7 +138,7 @@ import java.util.Base64;
|
||||
e.printStackTrace();
|
||||
}
|
||||
Signature sign = Signature.getInstance("SHA256withRSA");
|
||||
//这里需要一个PrivateKey类型的参数,就是商户的私钥。
|
||||
|
||||
sign.initSign(merchantPrivateKey);
|
||||
sign.update(message);
|
||||
return Base64.getEncoder().encodeToString(sign.sign());
|
||||
|
||||
Reference in New Issue
Block a user