小程序支付Java-sdk
【摘要】 一.需求背景 1.小程序支付在当前数字化时代,小程序支付已成为连接用户与服务的关键桥梁,它不仅为用户提供了便捷的支付方式,也为商家带来了更高效的收款和用户管理途径。如何更将快捷和方便对接小程序的支付呢,可以参考本文的 java-sdk 2.支付api 3.api 列表具体的 api 4.回调回调查询 二.代码实现 1.源码下载微信支付-Java-sdk 2.configpublic cla...
一.需求背景
1.小程序支付
在当前数字化时代,小程序支付已成为连接用户与服务的关键桥梁,它不仅为用户提供了便捷的支付方式,也为商家带来了更高效的收款和用户管理途径。如何更将快捷和方便对接小程序的支付呢,可以参考本文的 java-sdk
2.支付
3.api 列表
4.回调
二.代码实现
1.源码下载
2.config
public class MyWxPayConfig extends WXPayConfig {
private byte[] certData;
public MyWxPayConfig() throws Exception {
String certPath = "/path/to/apiclient_cert.p12";
File file = new File(certPath);
InputStream certStream = Files.newInputStream(file.toPath());
this.certData = new byte[(int) file.length()];
certStream.read(this.certData);
certStream.close();
}
/**
* 小程序ID
*
* @return
*/
public String getAppID() {
return "wx12345e766d6ecf8a";
}
/**
* 商户号
*
* @return
*/
public String getMchID() {
return "1684444405";
}
public String getKey() {
return "88888888888888888888888888888888";
}
public InputStream getCertStream() {
return new ByteArrayInputStream(this.certData);
}
public int getHttpConnectTimeoutMs() {
return 8000;
}
public int getHttpReadTimeoutMs() {
return 10000;
}
@Override
protected IWXPayDomain getWXPayDomain() {
return null;
}
}
3.controller
@Api(tags = "微信支付管理", description = "微信支付管理")
@RestController
@RequestMapping("pay")
public class WxPayOrderController {
@Resource
private WxPayOrderService wxPayOrderService;
@ApiOperation(value = "统一下单", nickname = "统一下单")
@GetMapping("/unifiedOrder")
public Result unifiedOrder(@RequestParam("outTradeNo") String outTradeNo,
@RequestParam("totalFee") Integer totalFee) {
return Result.ok(wxPayOrderService.unifiedOrder(outTradeNo, totalFee));
}
@ApiOperation(value = "查询订单", nickname = "查询订单")
@GetMapping("/orderQuery")
public Result orderQuery(@RequestParam("outTradeNo") String outTradeNo) {
return Result.ok(wxPayOrderService.orderQuery(outTradeNo));
}
@ApiOperation(value = "关闭订单", nickname = "关闭订单")
@GetMapping("/closeOrder")
public Result closeOrder(@RequestParam("outTradeNo") String outTradeNo) {
return Result.ok(wxPayOrderService.closeOrder(outTradeNo));
}
@ApiOperation(value = "申请退款", nickname = "申请退款")
@GetMapping("/refund")
public Result refund(@RequestParam("outTradeNo") String outTradeNo, @RequestParam("outRefundNo") String outRefundNo,
@RequestParam("totalFee") Integer totalFee, @RequestParam("refundFee") Integer refundFee) {
return Result.ok(wxPayOrderService.refund(outTradeNo, outRefundNo, totalFee, refundFee));
}
@ApiOperation(value = "退款查询", nickname = "退款查询")
@GetMapping("/refundQuery")
public Result refundQuery(@RequestParam("outTradeNo") String outTradeNo) {
return Result.ok(wxPayOrderService.refundQuery(outTradeNo));
}
@ApiOperation(value = "支付结果通知", nickname = "支付结果通知")
@GetMapping("/notify")
public String notify(HttpServletRequest request, HttpServletResponse response) {
return wxPayOrderService.notify(request,response);
}
}
4.service
public interface WxPayOrderService {
/**
* 统一下单接口
*
* @return
*/
Map<String, String> unifiedOrder(String outTradeNo, Integer totalFee);
/**
* 订单查询
*
* @return
*/
Map<String, String> orderQuery(String outTradeNo);
/**
* 关闭订单
* <p>
* 商户订单支付失败需要生成新单号重新发起支付,要对原订单号调用关单,避免重复支付;系统下单后,用户支付超时,系统退出不再受理,避免用户继续,请调用关单接口。
* 订单生成后不能马上调用关单接口,最短调用时间间隔为5分钟。
*
* @param outTradeNo
* @return
*/
Map<String, String> closeOrder(String outTradeNo);
/**
* 申请退款
*
* @param outTradeNo 系统订单号
* @param outRefundNo 退款订单号
* @param totalFee 总金额
* @param refundFee 退款金额
* @return
*/
Map<String, String> refund(String outTradeNo, String outRefundNo, Integer totalFee, Integer refundFee);
/**
* 退款查询
*
* @param outTradeNo
* @return
*/
Map<String, String> refundQuery(String outTradeNo);
/**
* 支付回调
*
* @return
*/
String notify(HttpServletRequest request, HttpServletResponse response);
}
5.实现类
@Slf4j
@Service
public class WxPayOrderServiceImpl implements WxPayOrderService {
@Autowired
private OrderInfoService orderInfoService;
@Override
public Map<String, String> unifiedOrder(String outTradeNo, Integer totalFee) {
try {
Map<String, String> data = new HashMap<>();
WXPayConfig config = new MyWxPayConfig();
WXPay wxpay = new WXPay(config);
data.put("body", "新空间小程序代办中心");// 产品描述
data.put("out_trade_no", outTradeNo);// 商户订单号
data.put("fee_type", "CNY");
data.put("total_fee", String.valueOf(totalFee));// 订单总金额,单位为分
data.put("spbill_create_ip", "ip");// 客户端ip
data.put("notify_url", "https://xxxxxxxxxxx/notify");// 服务回调地址
data.put("trade_type", "JSAPI"); // 此处指定为小程序支付
Map<String, String> resp = wxpay.unifiedOrder(data);
log.info("统一下单接口,返回信息={}", resp.toString());
return resp;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public Map<String, String> orderQuery(String outTradeNo) {
try {
WXPayConfig config = new MyWxPayConfig();
WXPay wxpay = new WXPay(config);
Map<String, String> data = new HashMap<>();
data.put("out_trade_no", outTradeNo);
Map<String, String> resp = wxpay.orderQuery(data);
log.info("查询订单接口,返回信息={}", resp.toString());
return resp;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public Map<String, String> closeOrder(String outTradeNo) {
try {
WXPayConfig config = new MyWxPayConfig();
WXPay wxpay = new WXPay(config);
Map<String, String> data = new HashMap<>();
data.put("out_trade_no", outTradeNo);
Map<String, String> resp = wxpay.closeOrder(data);
System.out.println(resp);
log.info("关闭订单,返回信息={}", resp.toString());
return resp;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public Map<String, String> refund(String outTradeNo, String outRefundNo, Integer totalFee, Integer refundFee) {
try {
WXPayConfig config = new MyWxPayConfig();
WXPay wxpay = new WXPay(config);
Map<String, String> data = new HashMap<>();
data.put("out_trade_no", outTradeNo);
data.put("out_refund_no", outRefundNo);
data.put("total_fee", String.valueOf(totalFee));
data.put("refund_fee", String.valueOf(refundFee));
Map<String, String> resp = wxpay.refundQuery(data);
System.out.println(resp);
log.info("申请退款,返回信息={}", resp.toString());
return resp;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public Map<String, String> refundQuery(String outTradeNo) {
try {
WXPayConfig config = new MyWxPayConfig();
WXPay wxpay = new WXPay(config);
Map<String, String> data = new HashMap<>();
data.put("out_trade_no", outTradeNo);
Map<String, String> resp = wxpay.refundQuery(data);
System.out.println(resp);
log.info("退款查询,返回信息={}", resp.toString());
return resp;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public String notify(HttpServletRequest request, HttpServletResponse response) {
Map<String, String> data = new HashMap<>();
try {
WXPayConfig config = new MyWxPayConfig();
WXPay wxpay = new WXPay(config);
String notifyData = WXPayUtil.requestToMap(request);
Map<String, String> notifyMap = WXPayUtil.xmlToMap(notifyData); // 转换成map
if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {
// 签名正确
// 注意特殊情况:订单已经退款,但收到了支付结果成功的通知,不应把商户侧订单状态从退款改成支付成功
log.info("支付成功");
String transactionId = notifyMap.get("transaction_id");
String outTradeNo = notifyMap.get("out_trade_no");
final OrderInfo byId = orderInfoService.getById(Integer.valueOf(outTradeNo));
byId.setTransactionId(transactionId);
orderInfoService.updateById(byId);
} else {
// 签名错误,如果数据里没有sign字段,也认为是签名错误
throw new ApplicationException("签名错误");
}
data.put("return_code", "SUCCESS");
data.put("return_msg", "OK");
WXPayUtil.mapToXml(data);
return WXPayUtil.mapToXml(data);
} catch (Exception e) {
e.printStackTrace();
log.error("通知失败");
throw new ApplicationException("通知失败");
}
}
}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)