最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java對接微信支付SDK接口簡單圖文教程

 更新時間:2024年11月01日 10:28:03   作者:子木凝煙  
在微信支付接口對接過程中,開發(fā)者需準(zhǔn)備多項關(guān)鍵參數(shù),如開發(fā)者ID(appid)、商戶號等,并完成相關(guān)注冊與認(rèn)證流程,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下

1.對接準(zhǔn)備

需要的參數(shù)包括開發(fā)者ID(appid)、商戶號、商戶api私鑰、商戶證書序列號、商戶APIV3密鑰、回調(diào)地址。

在微信公眾平臺https://mp.weixin.qq.com/ 注冊應(yīng)用,類型只選擇“公眾號/小程序/企業(yè)微信”,注冊完成后需完成”微信認(rèn)證“(微信收取300元),在基礎(chǔ)配置中拿到開發(fā)者ID(APPID)。

在微信支付商戶平臺https://pay.weixin.qq.com注冊商戶,在賬戶中心-api安全中設(shè)置APIv3密鑰,微信支付 APIv3 使用由 證書授權(quán)機構(gòu)(Certificate Authority,簡稱CA)簽發(fā)的證書,商戶申請證書時,證書工具會生成商戶私鑰,并保存在本地證書文件夾的件 apiclient_key.pem 中。開發(fā)和部署,需要區(qū)分環(huán)境,加載 apiclient_key.pem 文件。

在賬戶中心-商戶信息中拿到微信支付商戶號,即商戶ID (收錢的商家ID);

在產(chǎn)品中心-appid賬號管理中,將申請的下來的APPID綁定到商戶號下。 

Certificate Downloader 是 Java 微信支付 APIv3 平臺證書的命令行下載工具。該工具可從https://api.mch.weixin.qq.com/v3/certificates 接口獲取商戶可用證書

2.maven引入jar包

<!-- 微信支付SDK -->
<dependency>
    <groupId>com.github.wechatpay-apiv3</groupId>
    <artifactId>wechatpay-java</artifactId>
    <version>0.2.9</version>
</dependency>

3.yml文件配置微信參數(shù),工具類讀取

@Component
public class WechatPayConfig {

    /**
     * 應(yīng)用ID
     */
    public static String appid;

    /**
     * 商戶號
     */
    public static String merchantId;

    /**
     * 商戶API私鑰路徑
     */
    public static String privateKeyPath;

    /**
     * 商戶證書序列號
     */
    public static String merchantSerialNumber;

    /**
     * 商戶APIV3密鑰
     */
    public static String apiV3Key;

    /**
     * 通知地址(有效性:1. HTTPS;2. 不允許攜帶查詢串。)
     */
    public static String notifyUrl;

    /**
     * 微信支付配置
     */
    public static Config config;

    /**
     * 訂單支付超時時間/分鐘
     */
    public static final Integer ORDER_PAY_TIME_OUT = 1440;


    private WechatPayConfig() {}

    @Value("${wechat.pay.appid}")
    public void setAppid(String appid) {
        WechatPayConfig.appid = appid;
    }

    @Value("${wechat.pay.merchantId}")
    public void setMerchantId(String merchantId) {
        WechatPayConfig.merchantId = merchantId;
    }

    @Value("${wechat.pay.privateKeyPath}")
    public void setPrivateKeyPath(String privateKeyPath) {
        String classPath = System.getProperty("java.class.path");
        // 是否運行在開發(fā)環(huán)境
        boolean isRunningFromIde = classPath.toLowerCase().contains("eclipse") || classPath.toLowerCase().contains("idea");
        // 開發(fā)環(huán)境與部署jar包環(huán)境 不同獲取私鑰路徑
        if (isRunningFromIde){
            WechatPayConfig.privateKeyPath = getClass().getClassLoader().getResource("apiclient_key.pem").getPath();
        }else {
            WechatPayConfig.privateKeyPath = privateKeyPath;
        }
    }

    @Value("${wechat.pay.merchantSerialNumber}")
    public void setMerchantSerialNumber(String merchantSerialNumber) {
        WechatPayConfig.merchantSerialNumber = merchantSerialNumber;
    }

    @Value("${wechat.pay.apiV3Key}")
    public void setApiV3Key(String apiV3Key) {
        WechatPayConfig.apiV3Key = apiV3Key;
    }

    @Value("${wechat.pay.notifyUrl}")
    public void setNotifyUrl(String notifyUrl) {
        WechatPayConfig.notifyUrl = notifyUrl;
    }

    @PostConstruct
    public void initializeConfig() {
        // 初始化微信配置
        config = new RSAAutoCertificateConfig.Builder()
                .merchantId(merchantId)
                .privateKeyFromPath(privateKeyPath)
                .merchantSerialNumber(merchantSerialNumber)
                .apiV3Key(apiV3Key)
                .build();
    }
}

4.對接支付接口

    /**
     * 微信 Native 支付下單
     *
     * @param amt         金額
     * @param orderNumber 訂單號
     * @param description 描述
     * @return 二維碼鏈接
     */
    public static AjaxResult nativePay(BigDecimal amt, String orderNumber, String description) {
        // 當(dāng)前時間
        Date currentDate = new Date();
        // 將金額轉(zhuǎn)換為分
        int total = amt.multiply(new BigDecimal("100")).intValue();
        try {
            // 構(gòu)建service
            NativePayService service = new NativePayService.Builder().config(WechatPayConfig.config).build();
            // 構(gòu)建請求對象
            PrepayRequest request = new PrepayRequest();
            request.setAppid(WechatPayConfig.appid);
            request.setMchid(WechatPayConfig.merchantId);
            request.setNotifyUrl(WechatPayConfig.notifyUrl);
            // 設(shè)置金額
            Amount amount = new Amount();
            amount.setTotal(total);
            request.setAmount(amount);
            request.setDescription(description);
            request.setOutTradeNo(orderNumber);
            // 計算訂單失效時間
            Calendar calendar = DateUtils.toCalendar(currentDate);
            calendar.add(Calendar.MINUTE, WechatPayConfig.ORDER_PAY_TIME_OUT);
            request.setTimeExpire(DateUtils.parseDateToStr("yyyy-MM-dd'T'HH:mm:ss+08:00", calendar.getTime()));
            return AjaxResult.success(service.prepay(request).getCodeUrl());
        } catch (Exception e){
            log.error(e.getMessage(),e);
            return AjaxResult.error("支付訂單創(chuàng)建失敗");
        }
    }

5.回調(diào)地址

    /**
     * 微信支付回調(diào)
     *
     * @return 回調(diào)結(jié)果
     */
    @PostMapping("/wechat")
    public ResponseEntity.BodyBuilder wechat(@RequestBody String body, HttpServletRequest request) {
        try {
            // 構(gòu)造 RequestParam
            RequestParam requestParam = new RequestParam.Builder()
                    // 序列號
                    .serialNumber(request.getHeader("Wechatpay-Serial"))
                    // 隨機數(shù)
                    .nonce(request.getHeader("Wechatpay-Nonce"))
                    // 簽名
                    .signature(request.getHeader("Wechatpay-Signature"))
                    // 時間戳
                    .timestamp(request.getHeader("Wechatpay-Timestamp"))
                    .body(body)
                    .build();
            // 初始化解析器
            NotificationParser parser = new NotificationParser((NotificationConfig) WechatPayConfig.config);
            // 驗簽、解密并轉(zhuǎn)換成 Transaction
            Transaction transaction = parser.parse(requestParam, Transaction.class);
            // 校驗交易狀態(tài)
            if (Transaction.TradeStateEnum.SUCCESS.equals(transaction.getTradeState())) {
                // 支付成功,根據(jù)訂單編號查詢訂單信息
                // 1.查詢訂單信息
                Order orderOld = orderService.selectForUpdateByOrderNumber(transaction.getOutTradeNo());
                // 校驗金額
                if (orderOld != null && orderOld.getPayAmount().equals(transaction.getAmount().getTotal())) {
                    // 金額相等 完成支付 更新訂單狀態(tài)
                    WechatPayUtil.success(orderOld,transaction);
                } else {
                    // 金額異常 執(zhí)行退款
                    WechatPayUtil.refunded(new WechatPayRedis(transaction.getOutTradeNo(), transaction.getAmount().getTotal(), null));
                }
            }
        } catch (ValidationException e) {
            // 簽名驗證失敗,返回 401 UNAUTHORIZED 狀態(tài)碼
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED);
        }

        // 處理成功,返回 200 OK 狀態(tài)碼
        return ResponseEntity.status(HttpStatus.OK);
    }

    /**
     * 支付成功
     */
    public static void success( Order orderOld,Transaction transaction) {
        try {
            // 支付完成時間
            Date payTime = DateUtils.parseDate(transaction.getSuccessTime(), "yyyy-MM-dd'T'HH:mm:ss+08:00");
            // 校驗訂單信息 & 支付結(jié)果 & 訂單有效期止日期
            if (orderOld != null && orderOld.getPayResult() == 0 && payTime.compareTo(orderOld.getExpirationDate()) < 1) {
                // 構(gòu)建修改對象
                Order updateOrder = new Order();
                updateOrder.setId(orderOld.getId());
                updateOrder.setPayMethod(PayMethodEnum.W.name());
                updateOrder.setPayChannel(PayChannelEnum.P.name());
                updateOrder.setPayDate(payTime);
                updateOrder.setPayResult(PayResultEnum.PAID.getCode());
                updateOrder.setPayType(PayTypeEnum.U.name());
                updateOrder.setSerialNumber(transaction.getTransactionId());
                if (orderService.editPayResult(updateOrder,orderOld) == 1) {
                    // 刪除Redis訂單支付信息
                    SpringUtils.getBean(RedisCache.class).deleteObject(WechatPayConfig.ORDER_PAY_REDIS_PREFIX + transaction.getOutTradeNo());
                }
            } else {
                // 訂單信息不存在 執(zhí)行退款
                WechatPayUtil.refunded(new WechatPayRedis(transaction.getOutTradeNo(), transaction.getAmount().getTotal(), null));
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    /**
     * 執(zhí)行退款
     */
    public static void refunded(WechatPayRedis wechatPay) {
        try {
            // 構(gòu)建退款Service
            RefundService service = new RefundService.Builder().config(WechatPayConfig.config).build();
            // 構(gòu)建請求對象
            CreateRequest request = new CreateRequest();
            request.setOutTradeNo(wechatPay.getOrderNumber());
            request.setOutRefundNo(wechatPay.getOrderNumber());
            // 支付總金額(分)
            long total = wechatPay.getTotal();
            // 設(shè)置退款金額
            AmountReq amount = new AmountReq();
            amount.setRefund(total);
            amount.setTotal(total);
            amount.setCurrency("CNY");
            request.setAmount(amount);
            // 請求API申請退款
            Refund refund = service.create(request);
            // 校驗退款結(jié)果
            if (refund != null && Status.SUCCESS.equals(refund.getStatus())) {
                // 退款成功
                log.info("微信退款成功:{}", wechatPay);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

總結(jié) 

到此這篇關(guān)于java對接微信支付SDK接口的文章就介紹到這了,更多相關(guān)java對接微信支付SDK接口內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringCloud Stream使用解析

    SpringCloud Stream使用解析

    這篇文章主要介紹了SpringCloud Stream介紹,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • SpringBoot集成阿里云OSS圖片上傳

    SpringBoot集成阿里云OSS圖片上傳

    這篇文章主要為大家詳細(xì)介紹了SpringBoot集成阿里云OSS圖片上傳,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • 在Eclipse IDE使用Gradle構(gòu)建應(yīng)用程序(圖文)

    在Eclipse IDE使用Gradle構(gòu)建應(yīng)用程序(圖文)

    這篇文章主要介紹了在Eclipse IDE使用Gradle構(gòu)建應(yīng)用程序(圖文),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12
  • Java縮小文件內(nèi)存占用的方法技巧分享

    Java縮小文件內(nèi)存占用的方法技巧分享

    在Java應(yīng)用程序中,處理大文件時經(jīng)常會遇到內(nèi)存占用過高的問題,為了縮小文件的內(nèi)存占用,我們可以采取一些有效的方法來優(yōu)化和管理內(nèi)存的使用,本文將介紹一些在Java中縮小文件內(nèi)存占用的技巧,需要的朋友可以參考下
    2024-10-10
  • Java中字符串中連續(xù)相同字符去重方法

    Java中字符串中連續(xù)相同字符去重方法

    今天小編就為大家分享一篇Java中字符串中連續(xù)相同字符去重方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • spring boot測試打包部署的方法

    spring boot測試打包部署的方法

    spring boot項目如何測試,如何部署,在生產(chǎn)中有什么好的部署方案嗎?這篇文章就來介紹一下spring boot 如何開發(fā)、調(diào)試、打包到最后的投產(chǎn)上線,感興趣的朋友一起看看吧
    2018-01-01
  • SpringBoot集成JWT生成token及校驗方法過程解析

    SpringBoot集成JWT生成token及校驗方法過程解析

    這篇文章主要介紹了SpringBoot集成JWT生成token及校驗方法過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-04-04
  • Java?Collections.sort()實現(xiàn)List排序的默認(rèn)方法和自定義方法

    Java?Collections.sort()實現(xiàn)List排序的默認(rèn)方法和自定義方法

    這篇文章主要介紹了Java?Collections.sort()實現(xiàn)List排序的默認(rèn)方法和自定義方法,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2017-06-06
  • IDEA java關(guān)閉某些代碼檢查提示W(wǎng)arning實現(xiàn)方式

    IDEA java關(guān)閉某些代碼檢查提示W(wǎng)arning實現(xiàn)方式

    文章內(nèi)容涉及編程中兩種常見警告:Methodisneverused(未使用方法)和Uncheckedcast(未檢查類型轉(zhuǎn)換),提示需檢查代碼邏輯及類型安全處理
    2025-09-09
  • Java利用Easyexcel導(dǎo)出excel表格的示例代碼

    Java利用Easyexcel導(dǎo)出excel表格的示例代碼

    這篇文章主要為大家詳細(xì)介紹了Java利用Easyexcel導(dǎo)出excel表格的示例代碼,文中的代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下
    2022-07-07

最新評論

枞阳县| 开封市| 浦东新区| 忻州市| 固镇县| 镇远县| 苏尼特左旗| 璧山县| 冕宁县| 巴南区| 达州市| 饶平县| 新泰市| 昌图县| 贞丰县| 娄底市| 东兴市| 无锡市| 乌海市| 错那县| 喀什市| 高台县| 屏东市| 岚皋县| 东丽区| 潼南县| 山西省| 万山特区| 宁乡县| 历史| 犍为县| 无为县| 延川县| 开鲁县| 汝州市| 东兰县| 丁青县| 阿拉善右旗| 北宁市| 绥阳县| 景泰县|