小程序支付Java-sdk

举报
kwan的解忧杂货铺 发表于 2024/09/01 22:59:59 2024/09/01
【摘要】 一.需求背景 1.小程序支付在当前数字化时代,小程序支付已成为连接用户与服务的关键桥梁,它不仅为用户提供了便捷的支付方式,也为商家带来了更高效的收款和用户管理途径。如何更将快捷和方便对接小程序的支付呢,可以参考本文的 java-sdk 2.支付api 3.api 列表具体的 api 4.回调回调查询 二.代码实现 1.源码下载微信支付-Java-sdk 2.configpublic cla...

一.需求背景

1.小程序支付

在当前数字化时代,小程序支付已成为连接用户与服务的关键桥梁,它不仅为用户提供了便捷的支付方式,也为商家带来了更高效的收款和用户管理途径。如何更将快捷和方便对接小程序的支付呢,可以参考本文的 java-sdk

2.支付

api

image-20240901133802170

3.api 列表

具体的 api

image-20240901223423239

4.回调

回调查询

image-20240901223451632

二.代码实现

1.源码下载

微信支付-Java-sdk

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

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。