java实现jsapi⽀付,微信异步通知结果
private static String privateApiV3Key="cn5HxRmmbTDTUYgw3nGHU1YyFe72222";
/**
中国传统文化资料* 异步接收微信⽀付结果通知的回调地址,通知url必须为外⽹可访问的url
*
* @return
*/
@PostMapping("/get/result")
@ApiOperationSupport(order = 5)
@ApiOperation(value = " 异步接收微信⽀付结果通知的回调地址,通知url必须为外⽹可访问的url", notes = " 异步接收微信⽀付结果通知的回调地址,通知url必须为外 public void notifyUrl(HttpServletRequest request, HttpServletRespon respon) throws Exception{
String requestString = InputStream());
logger.info("微信结果通知加密字符串"+requestString);
NotifyResutlVo obj = JSON.parObject(requestString, NotifyResutlVo.class);
String associated_data = Resource().getAssociated_data();
String nonce = Resource().getNonce();
String ciphertext = Resource().getCiphertext();
AesUtil aesUtil = new Bytes());
try {
String s = aesUtil.decryptToString(Bytes(), Bytes(), ciphertext);
logger.info("微信结果通知解密字符串"+s);
JSONObject jsonObject = JSONObject.fromObject(s);
/
/订单号
String out_trade_no = String("out_trade_no");
//微信⽀付订单号
String transaction_id = String("transaction_id");
/**
* 交易状态
*
* 1.SUCCESS:⽀付成功
* 2.REFUND:转⼊退款
* 3.NOTPAY:未⽀付
* 4.CLOSED:已关闭
* 5.REVOKED:已撤销(付款码⽀付)
* 6.USERPAYING:⽤户⽀付中(付款码⽀付)
* 7.PAYERROR:⽀付失败(其他原因,如银⾏返回失败)
*
*
*/
QueryWrapper<BladeWechat> queryWrapperNew = new QueryWrapper<>();
queryWrapperNew.lambda().eq(BladeWechat::getOutTradeNumber, out_trade_no);
BladeWechat bw = new BladeWechat();
bw.tVehicleWechatOrder(transaction_id);
String trade_String("trade_state");
if("SUCCESS".equals(trade_state)){
bw.tStatus(Index());
}el if("PAYERROR".equals(trade_state)) {
bw.tStatus(Index());
}el{
logger.info(String.format("其它未完成⽀付原因,当前的订单号:%s,通知的⽀付状态是:%s",out_trade_no,trade_state));
快速口语
bw.Index());
}
bladeWechatService.update(bw, queryWrapperNew);
} catch (GeneralSecurityException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
e.printStackTrace();
}
}
数据模型:
package s.modules.payment.vo;
import lombok.Data;
/**
* @ProjectName: BladeX-Boot
* @Package: s.modules.payment.vo * @ClassName: NotifyResutlVo
* @Author: szk
* @Description:
* @Date: 2021/9/13 10:55
*/
@Data
public class NotifyResutlVo {
private String id;
private String create_time;
private String resource_type;
private String event_type;
private String summary;
private ResouceVo resource;
public String getId() {
return id;
}
public void tId(String id) {
this.id = id;
}
public String getCreate_time() {
return create_time;
}
public void tCreate_time(String create_time) {
}
public String getResource_type() {
return resource_type;
}
public void tResource_type(String resource_type) { source_type = resource_type;
}
public String getEvent_type() {
吨和千克的换算return event_type;
}
public void tEvent_type(String event_type) {
this.event_type = event_type;
}
public String getSummary() {
return summary;
}
public void tSummary(String summary) {
public void tSummary(String summary) {
this.summary = summary;
}
public ResouceVo getResource() {
return resource;
}
public void tResource(ResouceVo resource) {
}
@Override
public String toString() {
return "NotifyResutlVo{" +
"id='" + id + '\'' +
", create_time='" + create_time + '\'' +
", resource_type='" + resource_type + '\'' +
", event_type='" + event_type + '\'' +
", summary='" + summary + '\'' +
", resource=" + resource +
'}';
}
}
package s.modules.payment.vo;
import lombok.Data;
/**
* @ProjectName: BladeX-Boot
* @Package: s.modules.payment.vo * @ClassName: ResouceVo
* @Author: szk
* @Description:
* @Date: 2021/9/13 11:11
be动词练习题
*/
@Data
public class ResouceVo {
private String original_type;
private String algorithm;
private String ciphertext;
private String associated_data;
private String nonce;
public String getOriginal_type() {
船的图片简笔画return original_type;
}
public void tOriginal_type(String original_type) { iginal_type = original_type;销声匿迹意思
}
public String getAlgorithm() {
return algorithm;
}
public void tAlgorithm(String algorithm) {
this.algorithm = algorithm;
}
public String getCiphertext() {
public String getCiphertext() {
return ciphertext;
}
public void tCiphertext(String ciphertext) {
this.ciphertext = ciphertext;
}
public String getAssociated_data() {
return associated_data;
}
cad缩小比例public void tAssociated_data(String associated_data) { this.associated_data = associated_data;
}
public String getNonce() {
return nonce;
}普洱熟茶的泡法
public void tNonce(String nonce) {
< = nonce;
}
@Override
public String toString() {
return "ResouceVo{" +
"original_type='" + original_type + '\'' +
", algorithm='" + algorithm + '\'' +
", ciphertext='" + ciphertext + '\'' +
", associated_data='" + associated_data + '\'' +
", nonce='" + nonce + '\'' +
'}';
}
}
解密⼯具
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.ib.apache.httpclient.util;
import java.io.IOException;
import java.curity.GeneralSecurityException;
import java.curity.InvalidAlgorithmParameterException;
import java.curity.InvalidKeyException;
import java.curity.NoSuchAlgorithmException;
import java.util.Ba64;
pto.Cipher;
pto.NoSuchPaddingException;
pto.spec.GCMParameterSpec;
pto.spec.SecretKeySpec;
public class AesUtil {
static final int KEY_LENGTH_BYTE = 32;
static final int TAG_LENGTH_BIT = 128;
private final byte[] aesKey;
public AesUtil(byte[] key) {
if (key.length != 32) {
throw new IllegalArgumentException("⽆效的ApiV3Key,长度必须为32个字节");
} el {
this.aesKey = key;
}
}
public String decryptToString(byte[] associatedData, byte[] nonce, String ciphertext) throws GeneralSecurityException, IOException { try {
Cipher cipher = Instance("AES/GCM/NoPadding");
SecretKeySpec key = new SecretKeySpec(this.aesKey, "AES");
GCMParameterSpec spec = new GCMParameterSpec(128, nonce);
cipher.init(2, key, spec);
cipher.updateAAD(associatedData);
return new String(cipher.Decoder().decode(ciphertext)), "utf-8");
} catch (NoSuchPaddingException | NoSuchAlgorithmException var7) {
throw new IllegalStateException(var7);
} catch (InvalidAlgorithmParameterException | InvalidKeyException var8) {
throw new IllegalArgumentException(var8);
}
}
}
pom依赖
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-apache-httpclient</artifactId>
<version>0.2.1</version>
</dependency>