1. 添加模拟交易接口
2. 完善支付完成通知接口业务逻辑 3. 新增支付完成通知自定义处理业务接口 4. 添加小程序支付签名生成 5. 完善Jsapi支付预处理逻辑 6. 完善支付业务结构封装
This commit is contained in:
parent
e263433ec7
commit
226483602d
@ -0,0 +1,57 @@
|
||||
package ink.wgink.module.wechat.controller.app.miniapp;
|
||||
|
||||
import ink.wgink.interfaces.consts.ISystemConstant;
|
||||
import ink.wgink.module.wechat.pojo.pay.v3.PaySign;
|
||||
import ink.wgink.module.wechat.pojo.pay.v3.jsapi.pojo.PayPlaceOrder;
|
||||
import ink.wgink.module.wechat.service.pay.v3.jsapi.IJsapiService;
|
||||
import ink.wgink.pojo.result.ErrorResult;
|
||||
import ink.wgink.util.OrderUtil;
|
||||
import io.swagger.annotations.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @ClassName: MiniappPayAppController
|
||||
* @Description: 小程序支付
|
||||
* @Author: wanggeng
|
||||
* @Date: 2021/8/20 5:48 下午
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Api(tags = ISystemConstant.API_TAGS_APP_PREFIX + "小程序用户")
|
||||
@RestController
|
||||
@RequestMapping(ISystemConstant.APP_PREFIX + "/miniapp/pay")
|
||||
public class MiniappPayAppController {
|
||||
|
||||
@Autowired
|
||||
private IJsapiService jsapiService;
|
||||
|
||||
@ApiOperation(value = "下订单测试", notes = "下订单测试接口")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "token", value = "token", paramType = "header")
|
||||
})
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@PostMapping("save-place-order-demo")
|
||||
public PaySign savePlaceOrderDemo(@RequestHeader("token") String token) throws Exception {
|
||||
String atomicOrder = OrderUtil.getAtomicOrder("0001");
|
||||
System.out.println("订单号:" + atomicOrder);
|
||||
|
||||
PayPlaceOrder payPlaceOrder = new PayPlaceOrder();
|
||||
payPlaceOrder.setDescription("测试商品");
|
||||
payPlaceOrder.setOutTradeNo(atomicOrder);
|
||||
payPlaceOrder.setNotifyUrl("https://www.wgink.ink/study/wechat/pay/notice");
|
||||
|
||||
PayPlaceOrder.Amount amount = new PayPlaceOrder.Amount();
|
||||
amount.setTotal(1);
|
||||
payPlaceOrder.setAmount(amount);
|
||||
|
||||
PayPlaceOrder.Payer payer = new PayPlaceOrder.Payer();
|
||||
payer.setOpenid("");
|
||||
payPlaceOrder.setPayer(payer);
|
||||
|
||||
return jsapiService.placeOrder(payPlaceOrder);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package ink.wgink.module.wechat.controller.wechat.pay.v3;
|
||||
|
||||
import ink.wgink.annotation.CheckRequestBodyAnnotation;
|
||||
import ink.wgink.common.base.DefaultBaseController;
|
||||
import ink.wgink.interfaces.consts.ISystemConstant;
|
||||
import ink.wgink.module.wechat.pojo.pay.v3.PayErrorResponse;
|
||||
import ink.wgink.module.wechat.pojo.pay.v3.PayNotice;
|
||||
import ink.wgink.module.wechat.service.pay.v3.IPayService;
|
||||
import io.swagger.annotations.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* @ClassName: PayController
|
||||
* @Description: 微信支付
|
||||
* @Author: wanggeng
|
||||
* @Date: 2021/8/19 9:36 下午
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Api(tags = ISystemConstant.API_TAGS_WECHAT_PREFIX + "微信公众号")
|
||||
@RestController
|
||||
@RequestMapping(ISystemConstant.WECHAT_PREFIX + "/pay")
|
||||
public class PayController extends DefaultBaseController {
|
||||
|
||||
@Autowired
|
||||
private IPayService payService;
|
||||
|
||||
@ApiOperation(value = "通知支付结果", notes = "有微信支付主动发起的支付结果通知接口")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "Wechatpay-Signature", value = "来自微信的签名值", paramType = "header")
|
||||
})
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = PayErrorResponse.class)})
|
||||
@PostMapping("notice")
|
||||
@CheckRequestBodyAnnotation
|
||||
public void notice(HttpServletRequest request, HttpServletResponse response,
|
||||
@RequestHeader("Wechatpay-Signature") String wechatpaySignature, @RequestBody PayNotice payNotice) {
|
||||
payService.notice(request, response, wechatpaySignature, payNotice);
|
||||
}
|
||||
|
||||
}
|
@ -52,6 +52,10 @@ public class OfficialAccountAccessTokenManager {
|
||||
this.officialAccountAccessToken = officialAccountAccessToken;
|
||||
}
|
||||
|
||||
public OfficialAccountAccessToken getAccessToken() {
|
||||
return officialAccountAccessToken;
|
||||
}
|
||||
|
||||
private static class AccessTokenManagerFactory {
|
||||
public static OfficialAccountAccessTokenManager officialAccountAccessTokenManager = new OfficialAccountAccessTokenManager();
|
||||
}
|
||||
|
@ -0,0 +1,168 @@
|
||||
package ink.wgink.module.wechat.pojo.pay.v3;
|
||||
|
||||
import ink.wgink.annotation.CheckBeanAnnotation;
|
||||
import ink.wgink.annotation.CheckEmptyAnnotation;
|
||||
import ink.wgink.annotation.CheckNumberAnnotation;
|
||||
|
||||
/**
|
||||
* @ClassName: PayNotice
|
||||
* @Description: 支付通知
|
||||
* @Author: wanggeng
|
||||
* @Date: 2021/8/20 8:07 上午
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public class PayNotice {
|
||||
|
||||
@CheckEmptyAnnotation(name = "通知ID")
|
||||
private String id;
|
||||
@CheckEmptyAnnotation(name = "通知创建时间")
|
||||
private String create_time;
|
||||
@CheckEmptyAnnotation(name = "通知类型")
|
||||
private String event_type;
|
||||
@CheckEmptyAnnotation(name = "通知数据类型")
|
||||
private String resource_type;
|
||||
@CheckNumberAnnotation(name = "通知数据")
|
||||
@CheckBeanAnnotation
|
||||
private Resource resource;
|
||||
@CheckEmptyAnnotation(name = "回调摘要")
|
||||
private String summary;
|
||||
|
||||
public String getId() {
|
||||
return id == null ? "" : id.trim();
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getCreate_time() {
|
||||
return create_time == null ? "" : create_time.trim();
|
||||
}
|
||||
|
||||
public void setCreate_time(String create_time) {
|
||||
this.create_time = create_time;
|
||||
}
|
||||
|
||||
public String getEvent_type() {
|
||||
return event_type == null ? "" : event_type.trim();
|
||||
}
|
||||
|
||||
public void setEvent_type(String event_type) {
|
||||
this.event_type = event_type;
|
||||
}
|
||||
|
||||
public String getResource_type() {
|
||||
return resource_type == null ? "" : resource_type.trim();
|
||||
}
|
||||
|
||||
public void setResource_type(String resource_type) {
|
||||
this.resource_type = resource_type;
|
||||
}
|
||||
|
||||
public Resource getResource() {
|
||||
return resource;
|
||||
}
|
||||
|
||||
public void setResource(Resource resource) {
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
public String getSummary() {
|
||||
return summary == null ? "" : summary.trim();
|
||||
}
|
||||
|
||||
public void setSummary(String summary) {
|
||||
this.summary = summary;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder("{");
|
||||
sb.append("\"id\":\"")
|
||||
.append(id).append('\"');
|
||||
sb.append(",\"create_time\":\"")
|
||||
.append(create_time).append('\"');
|
||||
sb.append(",\"event_type\":\"")
|
||||
.append(event_type).append('\"');
|
||||
sb.append(",\"resource_type\":\"")
|
||||
.append(resource_type).append('\"');
|
||||
sb.append(",\"resource\":")
|
||||
.append(resource);
|
||||
sb.append(",\"summary\":\"")
|
||||
.append(summary).append('\"');
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static class Resource {
|
||||
@CheckEmptyAnnotation(name = "加密算法类型")
|
||||
private String algorithm;
|
||||
@CheckEmptyAnnotation(name = "数据密文")
|
||||
private String ciphertext;
|
||||
/**
|
||||
* 附加数据
|
||||
*/
|
||||
private String original_type;
|
||||
@CheckEmptyAnnotation(name = "原始类型")
|
||||
private String associated_data;
|
||||
@CheckEmptyAnnotation(name = "随机")
|
||||
private String nonce;
|
||||
|
||||
public String getAlgorithm() {
|
||||
return algorithm == null ? "" : algorithm.trim();
|
||||
}
|
||||
|
||||
public void setAlgorithm(String algorithm) {
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
public String getCiphertext() {
|
||||
return ciphertext == null ? "" : ciphertext.trim();
|
||||
}
|
||||
|
||||
public void setCiphertext(String ciphertext) {
|
||||
this.ciphertext = ciphertext;
|
||||
}
|
||||
|
||||
public String getOriginal_type() {
|
||||
return original_type == null ? "" : original_type.trim();
|
||||
}
|
||||
|
||||
public void setOriginal_type(String original_type) {
|
||||
this.original_type = original_type;
|
||||
}
|
||||
|
||||
public String getAssociated_data() {
|
||||
return associated_data == null ? "" : associated_data.trim();
|
||||
}
|
||||
|
||||
public void setAssociated_data(String associated_data) {
|
||||
this.associated_data = associated_data;
|
||||
}
|
||||
|
||||
public String getNonce() {
|
||||
return nonce == null ? "" : nonce.trim();
|
||||
}
|
||||
|
||||
public void setNonce(String nonce) {
|
||||
this.nonce = nonce;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder("{");
|
||||
sb.append("\"algorithm\":\"")
|
||||
.append(algorithm).append('\"');
|
||||
sb.append(",\"ciphertext\":\"")
|
||||
.append(ciphertext).append('\"');
|
||||
sb.append(",\"original_type\":\"")
|
||||
.append(original_type).append('\"');
|
||||
sb.append(",\"associated_data\":\"")
|
||||
.append(associated_data).append('\"');
|
||||
sb.append(",\"nonce\":\"")
|
||||
.append(nonce).append('\"');
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,590 @@
|
||||
package ink.wgink.module.wechat.pojo.pay.v3;
|
||||
|
||||
/**
|
||||
* @ClassName: PayNoticeCiphertext
|
||||
* @Description: 支付通知密文
|
||||
* @Author: wanggeng
|
||||
* @Date: 2021/8/20 3:02 下午
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public class PayNoticeCiphertext {
|
||||
|
||||
/**
|
||||
* 应用ID
|
||||
*/
|
||||
private String appId;
|
||||
/**
|
||||
* 商户号
|
||||
*/
|
||||
private String mchid;
|
||||
/**
|
||||
* 商户订单号
|
||||
*/
|
||||
private String out_trade_no;
|
||||
/**
|
||||
* 微信支付订单号
|
||||
*/
|
||||
private String transaction_id;
|
||||
/**
|
||||
* 交易类型
|
||||
*/
|
||||
private String trade_type;
|
||||
/**
|
||||
* 交易状态
|
||||
*/
|
||||
private String trade_state;
|
||||
/**
|
||||
* 交易状态描述
|
||||
*/
|
||||
private String trade_state_desc;
|
||||
/**
|
||||
* 付款银行
|
||||
*/
|
||||
private String bank_type;
|
||||
/**
|
||||
* 附加数据
|
||||
*/
|
||||
private String attach;
|
||||
/**
|
||||
* 支付完成时间
|
||||
*/
|
||||
private String success_time;
|
||||
/**
|
||||
* 支付者
|
||||
*/
|
||||
private Payer payer;
|
||||
/**
|
||||
* 订单金额
|
||||
*/
|
||||
private Amount amount;
|
||||
/**
|
||||
* 场景信息
|
||||
*/
|
||||
private SceneInfo scene_info;
|
||||
/**
|
||||
* 优惠功能
|
||||
*/
|
||||
private PromotionDetail promotion_detail;
|
||||
|
||||
public String getAppId() {
|
||||
return appId == null ? "" : appId.trim();
|
||||
}
|
||||
|
||||
public void setAppId(String appId) {
|
||||
this.appId = appId;
|
||||
}
|
||||
|
||||
public String getMchid() {
|
||||
return mchid == null ? "" : mchid.trim();
|
||||
}
|
||||
|
||||
public void setMchid(String mchid) {
|
||||
this.mchid = mchid;
|
||||
}
|
||||
|
||||
public String getOut_trade_no() {
|
||||
return out_trade_no == null ? "" : out_trade_no.trim();
|
||||
}
|
||||
|
||||
public void setOut_trade_no(String out_trade_no) {
|
||||
this.out_trade_no = out_trade_no;
|
||||
}
|
||||
|
||||
public String getTransaction_id() {
|
||||
return transaction_id == null ? "" : transaction_id.trim();
|
||||
}
|
||||
|
||||
public void setTransaction_id(String transaction_id) {
|
||||
this.transaction_id = transaction_id;
|
||||
}
|
||||
|
||||
public String getTrade_type() {
|
||||
return trade_type == null ? "" : trade_type.trim();
|
||||
}
|
||||
|
||||
public void setTrade_type(String trade_type) {
|
||||
this.trade_type = trade_type;
|
||||
}
|
||||
|
||||
public String getTrade_state() {
|
||||
return trade_state == null ? "" : trade_state.trim();
|
||||
}
|
||||
|
||||
public void setTrade_state(String trade_state) {
|
||||
this.trade_state = trade_state;
|
||||
}
|
||||
|
||||
public String getTrade_state_desc() {
|
||||
return trade_state_desc == null ? "" : trade_state_desc.trim();
|
||||
}
|
||||
|
||||
public void setTrade_state_desc(String trade_state_desc) {
|
||||
this.trade_state_desc = trade_state_desc;
|
||||
}
|
||||
|
||||
public String getBank_type() {
|
||||
return bank_type == null ? "" : bank_type.trim();
|
||||
}
|
||||
|
||||
public void setBank_type(String bank_type) {
|
||||
this.bank_type = bank_type;
|
||||
}
|
||||
|
||||
public String getAttach() {
|
||||
return attach == null ? "" : attach.trim();
|
||||
}
|
||||
|
||||
public void setAttach(String attach) {
|
||||
this.attach = attach;
|
||||
}
|
||||
|
||||
public String getSuccess_time() {
|
||||
return success_time == null ? "" : success_time.trim();
|
||||
}
|
||||
|
||||
public void setSuccess_time(String success_time) {
|
||||
this.success_time = success_time;
|
||||
}
|
||||
|
||||
public Payer getPayer() {
|
||||
return payer;
|
||||
}
|
||||
|
||||
public void setPayer(Payer payer) {
|
||||
this.payer = payer;
|
||||
}
|
||||
|
||||
public Amount getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(Amount amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public SceneInfo getScene_info() {
|
||||
return scene_info;
|
||||
}
|
||||
|
||||
public void setScene_info(SceneInfo scene_info) {
|
||||
this.scene_info = scene_info;
|
||||
}
|
||||
|
||||
public PromotionDetail getPromotion_detail() {
|
||||
return promotion_detail;
|
||||
}
|
||||
|
||||
public void setPromotion_detail(PromotionDetail promotion_detail) {
|
||||
this.promotion_detail = promotion_detail;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder("{");
|
||||
sb.append("\"appId\":\"")
|
||||
.append(appId).append('\"');
|
||||
sb.append(",\"mchid\":\"")
|
||||
.append(mchid).append('\"');
|
||||
sb.append(",\"out_trade_no\":\"")
|
||||
.append(out_trade_no).append('\"');
|
||||
sb.append(",\"transaction_id\":\"")
|
||||
.append(transaction_id).append('\"');
|
||||
sb.append(",\"trade_type\":\"")
|
||||
.append(trade_type).append('\"');
|
||||
sb.append(",\"trade_state\":\"")
|
||||
.append(trade_state).append('\"');
|
||||
sb.append(",\"trade_state_desc\":\"")
|
||||
.append(trade_state_desc).append('\"');
|
||||
sb.append(",\"bank_type\":\"")
|
||||
.append(bank_type).append('\"');
|
||||
sb.append(",\"attach\":\"")
|
||||
.append(attach).append('\"');
|
||||
sb.append(",\"success_time\":\"")
|
||||
.append(success_time).append('\"');
|
||||
sb.append(",\"payer\":")
|
||||
.append(payer);
|
||||
sb.append(",\"amount\":")
|
||||
.append(amount);
|
||||
sb.append(",\"scene_info\":")
|
||||
.append(scene_info);
|
||||
sb.append(",\"promotion_detail\":")
|
||||
.append(promotion_detail);
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付者
|
||||
*/
|
||||
public static class Payer {
|
||||
/**
|
||||
* 用户标识
|
||||
*/
|
||||
private String openid;
|
||||
|
||||
public String getOpenid() {
|
||||
return openid == null ? "" : openid.trim();
|
||||
}
|
||||
|
||||
public void setOpenid(String openid) {
|
||||
this.openid = openid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder("{");
|
||||
sb.append("\"openid\":\"")
|
||||
.append(openid).append('\"');
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单金额
|
||||
*/
|
||||
public static class Amount {
|
||||
/**
|
||||
* 总金额
|
||||
*/
|
||||
private int total;
|
||||
/**
|
||||
* 用户支付金额
|
||||
*/
|
||||
private int payer_total;
|
||||
/**
|
||||
* 货币类型
|
||||
*/
|
||||
private String currency;
|
||||
/**
|
||||
* 用户支付币种
|
||||
*/
|
||||
private String payer_currency;
|
||||
|
||||
public int getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(int total) {
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public int getPayer_total() {
|
||||
return payer_total;
|
||||
}
|
||||
|
||||
public void setPayer_total(int payer_total) {
|
||||
this.payer_total = payer_total;
|
||||
}
|
||||
|
||||
public String getCurrency() {
|
||||
return currency == null ? "" : currency.trim();
|
||||
}
|
||||
|
||||
public void setCurrency(String currency) {
|
||||
this.currency = currency;
|
||||
}
|
||||
|
||||
public String getPayer_currency() {
|
||||
return payer_currency == null ? "" : payer_currency.trim();
|
||||
}
|
||||
|
||||
public void setPayer_currency(String payer_currency) {
|
||||
this.payer_currency = payer_currency;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder("{");
|
||||
sb.append("\"total\":")
|
||||
.append(total);
|
||||
sb.append(",\"payer_total\":")
|
||||
.append(payer_total);
|
||||
sb.append(",\"currency\":\"")
|
||||
.append(currency).append('\"');
|
||||
sb.append(",\"payer_currency\":\"")
|
||||
.append(payer_currency).append('\"');
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景信息
|
||||
*/
|
||||
public static class SceneInfo {
|
||||
/**
|
||||
* 商户端设备号
|
||||
*/
|
||||
private String device_id;
|
||||
|
||||
public String getDevice_id() {
|
||||
return device_id == null ? "" : device_id.trim();
|
||||
}
|
||||
|
||||
public void setDevice_id(String device_id) {
|
||||
this.device_id = device_id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder("{");
|
||||
sb.append("\"device_id\":\"")
|
||||
.append(device_id).append('\"');
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 优惠功能
|
||||
*/
|
||||
public static class PromotionDetail {
|
||||
/**
|
||||
* 券ID
|
||||
*/
|
||||
private String coupon_id;
|
||||
/**
|
||||
* 优惠名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 优惠范围
|
||||
*/
|
||||
private String scope;
|
||||
/**
|
||||
* 优惠类型
|
||||
*/
|
||||
private String type;
|
||||
/**
|
||||
* 优惠券面额
|
||||
*/
|
||||
private Integer amount;
|
||||
/**
|
||||
* 活动ID
|
||||
*/
|
||||
private String stock_id;
|
||||
/**
|
||||
* 微信出资
|
||||
*/
|
||||
private Integer wechatpay_contribute;
|
||||
/**
|
||||
* 商户出资
|
||||
*/
|
||||
private Integer merchant_contribute;
|
||||
/**
|
||||
* 其他出资
|
||||
*/
|
||||
private Integer other_contribute;
|
||||
/**
|
||||
* 优惠币种
|
||||
*/
|
||||
private String currency;
|
||||
/**
|
||||
* 单品列表
|
||||
*/
|
||||
private GoodsDetail goods_detail;
|
||||
|
||||
public String getCoupon_id() {
|
||||
return coupon_id == null ? "" : coupon_id.trim();
|
||||
}
|
||||
|
||||
public void setCoupon_id(String coupon_id) {
|
||||
this.coupon_id = coupon_id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name == null ? "" : name.trim();
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getScope() {
|
||||
return scope == null ? "" : scope.trim();
|
||||
}
|
||||
|
||||
public void setScope(String scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type == null ? "" : type.trim();
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Integer getAmount() {
|
||||
return amount == null ? 0 : amount;
|
||||
}
|
||||
|
||||
public void setAmount(Integer amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public String getStock_id() {
|
||||
return stock_id == null ? "" : stock_id.trim();
|
||||
}
|
||||
|
||||
public void setStock_id(String stock_id) {
|
||||
this.stock_id = stock_id;
|
||||
}
|
||||
|
||||
public Integer getWechatpay_contribute() {
|
||||
return wechatpay_contribute == null ? 0 : wechatpay_contribute;
|
||||
}
|
||||
|
||||
public void setWechatpay_contribute(Integer wechatpay_contribute) {
|
||||
this.wechatpay_contribute = wechatpay_contribute;
|
||||
}
|
||||
|
||||
public Integer getMerchant_contribute() {
|
||||
return merchant_contribute == null ? 0 : merchant_contribute;
|
||||
}
|
||||
|
||||
public void setMerchant_contribute(Integer merchant_contribute) {
|
||||
this.merchant_contribute = merchant_contribute;
|
||||
}
|
||||
|
||||
public Integer getOther_contribute() {
|
||||
return other_contribute == null ? 0 : other_contribute;
|
||||
}
|
||||
|
||||
public void setOther_contribute(Integer other_contribute) {
|
||||
this.other_contribute = other_contribute;
|
||||
}
|
||||
|
||||
public String getCurrency() {
|
||||
return currency == null ? "" : currency.trim();
|
||||
}
|
||||
|
||||
public void setCurrency(String currency) {
|
||||
this.currency = currency;
|
||||
}
|
||||
|
||||
public GoodsDetail getGoods_detail() {
|
||||
return goods_detail;
|
||||
}
|
||||
|
||||
public void setGoods_detail(GoodsDetail goods_detail) {
|
||||
this.goods_detail = goods_detail;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder("{");
|
||||
sb.append("\"coupon_id\":\"")
|
||||
.append(coupon_id).append('\"');
|
||||
sb.append(",\"name\":\"")
|
||||
.append(name).append('\"');
|
||||
sb.append(",\"scope\":\"")
|
||||
.append(scope).append('\"');
|
||||
sb.append(",\"type\":\"")
|
||||
.append(type).append('\"');
|
||||
sb.append(",\"amount\":")
|
||||
.append(amount);
|
||||
sb.append(",\"stock_id\":\"")
|
||||
.append(stock_id).append('\"');
|
||||
sb.append(",\"wechatpay_contribute\":")
|
||||
.append(wechatpay_contribute);
|
||||
sb.append(",\"merchant_contribute\":")
|
||||
.append(merchant_contribute);
|
||||
sb.append(",\"other_contribute\":")
|
||||
.append(other_contribute);
|
||||
sb.append(",\"currency\":\"")
|
||||
.append(currency).append('\"');
|
||||
sb.append(",\"goods_detail\":")
|
||||
.append(goods_detail);
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 单品列表
|
||||
*/
|
||||
public static class GoodsDetail {
|
||||
/**
|
||||
* 商品编码
|
||||
*/
|
||||
private String goods_id;
|
||||
/**
|
||||
* 商品数量
|
||||
*/
|
||||
private Integer quantity;
|
||||
/**
|
||||
* 商品单价
|
||||
*/
|
||||
private Integer unit_price;
|
||||
/**
|
||||
* 商品优惠金额
|
||||
*/
|
||||
private Integer discount_amount;
|
||||
/**
|
||||
* 商品备注
|
||||
*/
|
||||
private String goods_remark;
|
||||
|
||||
public String getGoods_id() {
|
||||
return goods_id == null ? "" : goods_id.trim();
|
||||
}
|
||||
|
||||
public void setGoods_id(String goods_id) {
|
||||
this.goods_id = goods_id;
|
||||
}
|
||||
|
||||
public Integer getQuantity() {
|
||||
return quantity == null ? 0 : quantity;
|
||||
}
|
||||
|
||||
public void setQuantity(Integer quantity) {
|
||||
this.quantity = quantity;
|
||||
}
|
||||
|
||||
public Integer getUnit_price() {
|
||||
return unit_price == null ? 0 : unit_price;
|
||||
}
|
||||
|
||||
public void setUnit_price(Integer unit_price) {
|
||||
this.unit_price = unit_price;
|
||||
}
|
||||
|
||||
public Integer getDiscount_amount() {
|
||||
return discount_amount == null ? 0 : discount_amount;
|
||||
}
|
||||
|
||||
public void setDiscount_amount(Integer discount_amount) {
|
||||
this.discount_amount = discount_amount;
|
||||
}
|
||||
|
||||
public String getGoods_remark() {
|
||||
return goods_remark == null ? "" : goods_remark.trim();
|
||||
}
|
||||
|
||||
public void setGoods_remark(String goods_remark) {
|
||||
this.goods_remark = goods_remark;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder("{");
|
||||
sb.append("\"goods_id\":\"")
|
||||
.append(goods_id).append('\"');
|
||||
sb.append(",\"quantity\":")
|
||||
.append(quantity);
|
||||
sb.append(",\"unit_price\":")
|
||||
.append(unit_price);
|
||||
sb.append(",\"discount_amount\":")
|
||||
.append(discount_amount);
|
||||
sb.append(",\"goods_remark\":\"")
|
||||
.append(goods_remark).append('\"');
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package ink.wgink.module.wechat.pojo.pay.v3;
|
||||
|
||||
/**
|
||||
* @ClassName: PaySign
|
||||
* @Description: 支付签名
|
||||
* @Author: wanggeng
|
||||
* @Date: 2021/8/20 5:41 下午
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public class PaySign {
|
||||
|
||||
private String appId;
|
||||
private String timestamp;
|
||||
private String nonceStr;
|
||||
/**
|
||||
* 预支付交易会话标识,预支付交易会话标识。用于后续接口调用中使用,该值有效期为2小时
|
||||
*/
|
||||
private String prepayId;
|
||||
private String paySign;
|
||||
|
||||
public String getAppId() {
|
||||
return appId == null ? "" : appId.trim();
|
||||
}
|
||||
|
||||
public void setAppId(String appId) {
|
||||
this.appId = appId;
|
||||
}
|
||||
|
||||
public String getTimestamp() {
|
||||
return timestamp == null ? "" : timestamp.trim();
|
||||
}
|
||||
|
||||
public void setTimestamp(String timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public String getNonceStr() {
|
||||
return nonceStr == null ? "" : nonceStr.trim();
|
||||
}
|
||||
|
||||
public void setNonceStr(String nonceStr) {
|
||||
this.nonceStr = nonceStr;
|
||||
}
|
||||
|
||||
public String getPrepayId() {
|
||||
return prepayId == null ? "" : prepayId.trim();
|
||||
}
|
||||
|
||||
public void setPrepayId(String prepayId) {
|
||||
this.prepayId = prepayId;
|
||||
}
|
||||
|
||||
public String getPaySign() {
|
||||
return paySign == null ? "" : paySign.trim();
|
||||
}
|
||||
|
||||
public void setPaySign(String paySign) {
|
||||
this.paySign = paySign;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder("{");
|
||||
sb.append("\"appId\":\"")
|
||||
.append(appId).append('\"');
|
||||
sb.append(",\"timestamp\":\"")
|
||||
.append(timestamp).append('\"');
|
||||
sb.append(",\"nonceStr\":\"")
|
||||
.append(nonceStr).append('\"');
|
||||
sb.append(",\"prepayId\":\"")
|
||||
.append(prepayId).append('\"');
|
||||
sb.append(",\"paySign\":\"")
|
||||
.append(paySign).append('\"');
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
@ -30,14 +30,15 @@ public class PlaceOrderPayRequestImpl extends AbstractPayRequest<PayPlaceOrder,
|
||||
bodyObject.put("notify_url", payPlaceOrder.getNotifyUrl());
|
||||
bodyObject.put("goods_tag", payPlaceOrder.getGoodsTag());
|
||||
bodyObject.put("amount", getAmountJsonObject(payPlaceOrder.getAmount()));
|
||||
bodyObject.put("payer", getPayer(payPlaceOrder.getPayer()));
|
||||
if (payPlaceOrder.getDetail() != null) {
|
||||
bodyObject.put("detail", payPlaceOrder.getDetail());
|
||||
bodyObject.put("detail", getDetail(payPlaceOrder.getDetail()));
|
||||
}
|
||||
if (payPlaceOrder.getSceneInfo() != null) {
|
||||
bodyObject.put("scene_info", payPlaceOrder.getSceneInfo());
|
||||
bodyObject.put("scene_info", getSceneInfo(payPlaceOrder.getSceneInfo()));
|
||||
}
|
||||
if (payPlaceOrder.getSettleInfo() != null) {
|
||||
bodyObject.put("settle_info", payPlaceOrder.getSettleInfo());
|
||||
bodyObject.put("settle_info", getSettleInfo(payPlaceOrder.getSettleInfo()));
|
||||
}
|
||||
return bodyObject.toJSONString();
|
||||
}
|
||||
|
@ -0,0 +1,22 @@
|
||||
package ink.wgink.module.wechat.service.pay.v3;
|
||||
|
||||
import ink.wgink.module.wechat.pojo.pay.v3.PayNoticeCiphertext;
|
||||
|
||||
/**
|
||||
* @ClassName: IPayNoticeService
|
||||
* @Description: 支付通知业务,完成支付后,微信支付发起异步通知,实现该类完成业务处理
|
||||
* @Author: wanggeng
|
||||
* @Date: 2021/8/20 4:45 下午
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public interface IPayNoticeService {
|
||||
|
||||
/**
|
||||
* 处理支付通知结果,该方法在所有校验通过,加密文本解密之后调用。
|
||||
*
|
||||
* @param payNoticeCiphertext
|
||||
* @throws Exception
|
||||
*/
|
||||
void handle(PayNoticeCiphertext payNoticeCiphertext) throws Exception;
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package ink.wgink.module.wechat.service.pay.v3;
|
||||
|
||||
import ink.wgink.module.wechat.pojo.pay.v3.PayNotice;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* @ClassName: IPayService
|
||||
* @Description: 支付
|
||||
* @Author: wanggeng
|
||||
* @Date: 2021/8/20 8:15 上午
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public interface IPayService {
|
||||
|
||||
/**
|
||||
* 支付通知
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @param wechatpaySignature
|
||||
* @param payNotice
|
||||
*/
|
||||
void notice(HttpServletRequest request, HttpServletResponse response, String wechatpaySignature, PayNotice payNotice);
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
package ink.wgink.module.wechat.service.pay.v3.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import ink.wgink.common.base.DefaultBaseService;
|
||||
import ink.wgink.module.wechat.enums.PayErrorMsgEnum;
|
||||
import ink.wgink.module.wechat.pojo.pay.v3.PayErrorResponse;
|
||||
import ink.wgink.module.wechat.pojo.pay.v3.PayNotice;
|
||||
import ink.wgink.module.wechat.pojo.pay.v3.PayNoticeCiphertext;
|
||||
import ink.wgink.module.wechat.request.pay.v3.AbstractPayRequest;
|
||||
import ink.wgink.module.wechat.service.pay.v3.IPayNoticeService;
|
||||
import ink.wgink.module.wechat.service.pay.v3.IPayService;
|
||||
import ink.wgink.module.wechat.utils.pay.PayVerifyUtil;
|
||||
import ink.wgink.properties.wechat.pay.v3.PayProperties;
|
||||
import org.joda.time.DateTime;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* @ClassName: IPayServiceImpl
|
||||
* @Description: 支付
|
||||
* @Author: wanggeng
|
||||
* @Date: 2021/8/20 8:15 上午
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Service
|
||||
public class IPayServiceImpl extends DefaultBaseService implements IPayService {
|
||||
|
||||
@Autowired
|
||||
private PayProperties payProperties;
|
||||
@Autowired
|
||||
private IPayNoticeService payNoticeService;
|
||||
|
||||
@Override
|
||||
public void notice(HttpServletRequest request, HttpServletResponse response, String wechatpaySignature, PayNotice payNotice) {
|
||||
String nonce = payNotice.getResource().getNonce();
|
||||
DateTime createTimeDateTime = DateTime.parse(payNotice.getCreate_time());
|
||||
long millis = createTimeDateTime.getMillis();
|
||||
String payNoticeJsonString = JSONObject.toJSONString(payNotice);
|
||||
|
||||
try {
|
||||
LOG.debug("验证签名");
|
||||
boolean checkVerify = PayVerifyUtil.verifySignature(wechatpaySignature, payNoticeJsonString, nonce, String.valueOf(millis), new FileInputStream(payProperties.getCertificatePath()));
|
||||
if (!checkVerify) {
|
||||
errorResult(response, PayErrorMsgEnum.SIGN_ERROR_401);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG.debug("解密内容");
|
||||
PayNotice.Resource resource = payNotice.getResource();
|
||||
AbstractPayRequest.AesUtil aesUtil = new AbstractPayRequest.AesUtil(payProperties.getApiV3Secretkey().getBytes(StandardCharsets.UTF_8));
|
||||
String payNoticeCiphertextJsonString = aesUtil.decryptToString(resource.getAssociated_data().getBytes(StandardCharsets.UTF_8), resource.getNonce().getBytes(StandardCharsets.UTF_8), resource.getCiphertext());
|
||||
PayNoticeCiphertext payNoticeCiphertext = JSONObject.parseObject(payNoticeCiphertextJsonString, PayNoticeCiphertext.class);
|
||||
payNoticeService.handle(payNoticeCiphertext);
|
||||
} catch (Exception e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
errorResult(response, PayErrorMsgEnum.ERROR_500);
|
||||
return;
|
||||
}
|
||||
successResult(response);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 错误结果
|
||||
*
|
||||
* @param payErrorMsgEnum
|
||||
*/
|
||||
private void errorResult(HttpServletResponse response, PayErrorMsgEnum payErrorMsgEnum) {
|
||||
PayErrorResponse payErrorResponse = new PayErrorResponse();
|
||||
payErrorResponse.setCode(payErrorMsgEnum.getErrorCode());
|
||||
payErrorResponse.setMessage(payErrorMsgEnum.getSummary());
|
||||
response.setContentType("application/json; charset=UTF-8");
|
||||
response.setStatus(payErrorMsgEnum.getCode());
|
||||
try (PrintWriter writer = response.getWriter()) {
|
||||
writer.println(JSONObject.toJSONString(payErrorResponse));
|
||||
writer.flush();
|
||||
} catch (IOException e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功结果
|
||||
*/
|
||||
private void successResult(HttpServletResponse response) {
|
||||
response.setContentType("application/json; charset=UTF-8");
|
||||
response.setStatus(HttpStatus.OK.value());
|
||||
JSONObject successJsonObject = new JSONObject();
|
||||
successJsonObject.put("code", "SUCCESS");
|
||||
successJsonObject.put("message", "成功");
|
||||
try (PrintWriter writer = response.getWriter()) {
|
||||
writer.println(successJsonObject.toJSONString());
|
||||
writer.flush();
|
||||
} catch (IOException e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package ink.wgink.module.wechat.service.pay.v3.jsapi;
|
||||
|
||||
import ink.wgink.module.wechat.pojo.pay.v3.PaySign;
|
||||
import ink.wgink.module.wechat.pojo.pay.v3.jsapi.pojo.PayPlaceOrder;
|
||||
|
||||
/**
|
||||
@ -17,6 +18,6 @@ public interface IJsapiService {
|
||||
* @param payPlaceOrder
|
||||
* @return 预支付交易会话标识,预支付交易会话标识。用于后续接口调用中使用,该值有效期为2小时
|
||||
*/
|
||||
String placeOrder(PayPlaceOrder payPlaceOrder) throws Exception;
|
||||
PaySign placeOrder(PayPlaceOrder payPlaceOrder) throws Exception;
|
||||
|
||||
}
|
||||
|
@ -2,13 +2,18 @@ package ink.wgink.module.wechat.service.pay.v3.jsapi.impl;
|
||||
|
||||
import ink.wgink.common.base.DefaultBaseService;
|
||||
import ink.wgink.module.wechat.enums.PayAuthorizationTypeEnum;
|
||||
import ink.wgink.module.wechat.pojo.pay.v3.PaySign;
|
||||
import ink.wgink.module.wechat.pojo.pay.v3.jsapi.pojo.PayPlaceOrder;
|
||||
import ink.wgink.module.wechat.request.pay.v3.jsapi.PlaceOrderPayRequestImpl;
|
||||
import ink.wgink.module.wechat.pojo.pay.v3.jsapi.pojo.PayPrepay;
|
||||
import ink.wgink.module.wechat.request.pay.v3.jsapi.PlaceOrderPayRequestImpl;
|
||||
import ink.wgink.module.wechat.service.pay.v3.jsapi.IJsapiService;
|
||||
import ink.wgink.module.wechat.utils.pay.PayCertificateUtil;
|
||||
import ink.wgink.module.wechat.utils.pay.PayPrivateKeyUtil;
|
||||
import ink.wgink.properties.wechat.miniapp.MiniappProperties;
|
||||
import ink.wgink.properties.wechat.pay.v3.PayProperties;
|
||||
import ink.wgink.util.BeanPropertyCheckUtil;
|
||||
import ink.wgink.util.UUIDUtil;
|
||||
import ink.wgink.util.string.WStringUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
@ -28,22 +33,59 @@ public class JsapiServiceImpl extends DefaultBaseService implements IJsapiServic
|
||||
|
||||
@Autowired
|
||||
private PayProperties payProperties;
|
||||
@Autowired
|
||||
private MiniappProperties miniappProperties;
|
||||
|
||||
@Override
|
||||
public String placeOrder(PayPlaceOrder payPlaceOrder) throws Exception {
|
||||
public PaySign placeOrder(PayPlaceOrder payPlaceOrder) throws Exception {
|
||||
payPlaceOrder.setAppid(miniappProperties.getAppKey());
|
||||
payPlaceOrder.setMchid(payProperties.getMchid());
|
||||
BeanPropertyCheckUtil.checkField(payPlaceOrder);
|
||||
String urlSuffix = "/v3/pay/transactions/jsapi";
|
||||
String url = "https://api.mch.weixin.qq.com" + urlSuffix;
|
||||
|
||||
// 获得证书
|
||||
LOG.debug("获得证书");
|
||||
X509Certificate certificate = PayCertificateUtil.getCertificate(new FileInputStream(payProperties.getCertificatePath()));
|
||||
String serialNumber = certificate.getSerialNumber().toString(16);
|
||||
|
||||
LOG.debug("调用微信支付,发起预支付");
|
||||
PlaceOrderPayRequestImpl placeOrderPayRequest = new PlaceOrderPayRequestImpl();
|
||||
String body = placeOrderPayRequest.bodyJsonString(payPlaceOrder);
|
||||
String authorization = placeOrderPayRequest.getAuthorization(RequestMethod.POST, urlSuffix, serialNumber, payProperties, body, PayAuthorizationTypeEnum.WECHATPAY2_SHA256_RSA2048);
|
||||
// 请求获得结果
|
||||
LOG.debug("请求获得结果");
|
||||
PayPrepay payPrepay = placeOrderPayRequest.post(url, authorization, serialNumber, body);
|
||||
return payPrepay.getPrepayId();
|
||||
|
||||
LOG.debug("生成返回结果");
|
||||
long timestamp = System.currentTimeMillis();
|
||||
String nonceStr = WStringUtil.randomSubStr(UUIDUtil.get32UUID(), 10).toUpperCase();
|
||||
|
||||
PaySign paySign = new PaySign();
|
||||
paySign.setAppId(miniappProperties.getAppKey());
|
||||
paySign.setPrepayId(payPrepay.getPrepayId());
|
||||
paySign.setNonceStr(nonceStr);
|
||||
paySign.setTimestamp(String.valueOf(timestamp));
|
||||
paySign.setPaySign(getPaySign(timestamp, nonceStr, payPrepay.getPrepayId()));
|
||||
return paySign;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得小程序签名
|
||||
*
|
||||
* @param timestamp
|
||||
* @param nonceStr
|
||||
* @param prepayId
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private String getPaySign(long timestamp, String nonceStr, String prepayId) throws Exception {
|
||||
StringBuilder signBS = new StringBuilder();
|
||||
signBS.append(miniappProperties.getAppKey()).append("\n")
|
||||
.append(timestamp).append("\n")
|
||||
.append(nonceStr).append("\n")
|
||||
.append("prepay_id=").append(prepayId).append("\n");
|
||||
String key = PayPrivateKeyUtil.getPrivateKey(payProperties.getKeyPath());
|
||||
// 生成签名
|
||||
return PayPrivateKeyUtil.encryptByPrivateKey(signBS.toString(), key);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package ink.wgink.module.wechat.startup;
|
||||
|
||||
import ink.wgink.module.wechat.manager.MiniappManager;
|
||||
import ink.wgink.module.wechat.manager.OfficialAccountAccessTokenManager;
|
||||
import ink.wgink.module.wechat.manager.pay.v3.PayManager;
|
||||
import ink.wgink.properties.wechat.miniapp.MiniappProperties;
|
||||
import ink.wgink.properties.wechat.official.account.OfficialAccountProperties;
|
||||
import ink.wgink.properties.wechat.pay.v3.PayProperties;
|
||||
@ -36,9 +35,6 @@ public class WechatStartUp implements ApplicationRunner {
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
if (payProperties.getActive()) {
|
||||
PayManager.getInstance().setX509Certificate(payProperties.getCertificatePath());
|
||||
}
|
||||
new Thread(() -> {
|
||||
refreshOfficialAccountAccessToken();
|
||||
}).start();
|
||||
|
@ -16,9 +16,6 @@ import java.util.*;
|
||||
*/
|
||||
public class PaySignAuthorizationUtil {
|
||||
|
||||
// 商户号:1609461201
|
||||
// APIv3秘钥:_TSKJ_0471_TSkj_0471_tsKJ_0471__
|
||||
|
||||
/**
|
||||
* @param requestMethod 请求方法
|
||||
* @param url 请求接口
|
||||
|
@ -19,11 +19,11 @@ public class PayVerifyUtil {
|
||||
/**
|
||||
* 验证签名
|
||||
*
|
||||
* @param signature
|
||||
* @param body
|
||||
* @param nonce
|
||||
* @param timestamp
|
||||
* @param certInputStream
|
||||
* @param signature 待验证的签名
|
||||
* @param body 应答主体
|
||||
* @param nonce 随机串
|
||||
* @param timestamp 时间戳
|
||||
* @param certInputStream 微信支付平台证书输入流
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@ -35,6 +35,15 @@ public class PayVerifyUtil {
|
||||
return checkByPublicKey(buildSignMessage, signature, publicKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 公钥验证签名
|
||||
*
|
||||
* @param data 需要加密的数据
|
||||
* @param sign 签名
|
||||
* @param publicKey 公钥
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static boolean checkByPublicKey(String data, String sign, PublicKey publicKey) throws Exception {
|
||||
java.security.Signature signature = java.security.Signature.getInstance("SHA256WithRSA");
|
||||
signature.initVerify(publicKey);
|
||||
|
Loading…
Reference in New Issue
Block a user