微信支付 “商家轉賬到零錢”

来源:https://www.cnblogs.com/simpe/archive/2022/12/04/16949847.html
-Advertisement-
Play Games

​ 這裡有個坑 1:轉賬低於5毛會失敗 2:轉賬金額需要自己取整一下,微信官方金額是 分 為單位,換算成 元 時可能會除不盡 { "code":"PARAM_ERROR", "detail":{ "location":"body", "value":7.000000000000001 // 微信金額 ...


這裡有個坑

1:轉賬低於5毛會失敗

2:轉賬金額需要自己取整一下,微信官方金額是 分 為單位,換算成 元 時可能會除不盡

  {   
    "code":"PARAM_ERROR",
    "detail":{
        "location":"body",
        "value":7.000000000000001   // 微信金額除不盡出現的問題
             },
        "message":" 無法將 JSON 輸入源“\/body\/
                    total_amount”映射到目標欄位“轉賬總金額”中,
                    此欄位需要一個合法的 64 位有符號整數"
   }

1.服務層

   const SSLCERT_PATH = '證書路徑';
    const SSLKEY_PATH  = '證書key路徑';
    const MCHID        = '商戶號';
    const APPID        = 'app_id';
    const KEY          = 'key值';

    /**
     * 付款到微信零錢
     * sOpenid:收款方openid
     * nMoney:轉賬金額
     */
    public function transfer_batches($sOpenid, $nMoney)
    {
        // 付款到零錢方法url
        $url = 'https://api.mch.weixin.qq.com/v3/transfer/batches';

        // 訂單號
        $sOrderId = '測試付款' . time();
        // 轉賬備註 (微信用戶會收到該備註)                                                    
        $tRemark  = '測試付款' . $sOrderId; 
        // 轉賬金額:微信是分為單位 *100 轉換                                             
        $transfer_amount = $nMoney * 100;

        // 轉賬接收列表設置
        $transfer_detail_list = array(                
            [
                'out_detail_no'   => $sOrderId,                  // 明細單號
                'transfer_amount' => intval($transfer_amount),   // 轉賬總金額 
                'transfer_remark' => $tRemark,                   // 單條轉賬備註
                'openid'          => $sOpenid,                   // 收款方openid

                // 'user_name'       => '張三',
                // 轉賬金額 >= 2,000元,收款用戶姓名必填                   
            ],
        );
        // 請求參數設置
        $params = [                                                // 請求參數設置
            'appid'                => self::APPID,                 // 文檔頂部定義
            'out_batch_no'         => $sOrderId,                   // 商家批次單號
            'batch_name'           => 'x年x月轉賬',                 // 轉賬的名稱 
            'batch_remark'         => 'x年x月轉賬',                 // 轉賬的備註
            'total_amount'         => intval($transfer_amount),    // 轉賬總金額
            'total_num'            => 1,                           // 轉賬總筆數
            'transfer_detail_list' => $transfer_detail_list,       // 轉賬接收列表
        ];
        // 獲取token
        $token        = $this->getToken($params);
        // 發送請求                                    
        $res          = $this->https_request($url, json_encode($params), $token);
        // 反饋數組化  
        $resArr       = json_decode($res, true);                                   

        dump($resArr);
        // 存儲轉賬成功信息或別的操作


        // 成功實例返回值
        {
          "out_batch_no": "plfk2020042013",                        // wx唯一識別號
          "batch_id": "1030000071100999991182020050700019480001",  // 商家批次單號
          "create_time": "2015-05-20T13:29:35.120+08:00"           // 創建時間 
        }
    }


    /**
     * 構造請求
     */
    function https_request($url, $data = null, $token)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, (string)$url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        if (!empty($data)) {
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

        // 添加請求頭
        $headers =     [
            'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $token,
            'Accept: application/json',
            'Content-Type: application/json; charset=utf-8',
            'User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
        ];
        if (!empty($headers)) {
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        }

        $output = curl_exec($curl);
        curl_close($curl);

        return $output;
    }

    /**
     * 獲取token
     */
    public function getToken($pars)
    {
        $url = 'https://api.mch.weixin.qq.com/v3/transfer/batches';
        $http_method = 'POST';                                  // 請求方法(GET,POST,PUT)
        $timestamp   = time();                                  // 請求時間戳
        $url_parts   = parse_url($url);                         // 獲取請求的絕對URL
        $nonce       = $timestamp . rand('10000', '99999');     // 請求隨機串
        $body        = json_encode((object)$pars);              // 請求報文主體
        $stream_opts = [
            "ssl" => [
                "verify_peer"          => false,
                "verify_peer_name"     => false,
            ]
        ];

        // 證書路徑信息:文檔頂部定義
        $apiclient_cert_path = self::SSLCERT_PATH;
        $apiclient_key_path  = self::SSLKEY_PATH;

        $apiclient_cert_arr = openssl_x509_parse(file_get_contents($apiclient_cert_path, false, stream_context_create($stream_opts)));
        // 證書序列號
        $serial_no          = $apiclient_cert_arr['serialNumberHex'];
        // 密鑰                                                                   
        $mch_private_key    = file_get_contents($apiclient_key_path, false, stream_context_create($stream_opts));
        // 商戶id:文檔頂部定義                       
        $merchant_id        = self::MCHID;                                                                                              
        $canonical_url      = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
        $message            = $http_method . "\n" .
            $canonical_url . "\n" .
            $timestamp . "\n" .
            $nonce . "\n" .
            $body . "\n";
        openssl_sign($message, $raw_sign, $mch_private_key, 'sha256WithRSAEncryption');
        // 簽名
        $sign   = base64_encode($raw_sign);                                                                                                                
        $schema = 'WECHATPAY2-SHA256-RSA2048';
        $token  = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"', $merchant_id, $nonce, $timestamp, $serial_no, $sign); 
        // 微信返回token
        return $token;
    }

 

2.控制層

public function onTransferBatches($openid, $nMoney)
    {
        // 實例化服務層
        $serviceTransfer = new serviceTransfer();
        // 帶參請求:sOpenid(收款方openid)   nMoney(轉賬金額)
        $result          = $serviceTransfer->transfer_batches($openid, $nMoney);
        return $result;
    }

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ###Http Http (超文本輸出協議) 是一種分散式、協作式和超媒體信息系統的應用層協議,它通常運行在TCP之上,網際網路應用最廣泛的便是Http協議,所有www都遵循這個標準。主要用於Web 瀏覽器與 Web 伺服器之間的通信而設計的,但也可以用於其他目的,是一個基於 TCP/IP 通信協議來 ...
  • 隨著跨境獨立站的流行,中英雙語的公司官網越來越受到重視。 此項目是基於開源CMS開發出的中英文雙語外貿企業網站內容管理系統,命名HanCMS HanCMS 漢CMS中英雙語多語種外貿網站系統,是一個輕量級的網站系統,訪問速度極快,使用簡單。程式代碼簡潔嚴謹,完全免費開源。可用於建設各種類型的中英文網 ...
  • 原文: JDK中內嵌JS引擎介紹及使用 - Stars-One的雜貨小窩 最近研究閱讀這個APP,其主要功能就是通過一個個書源,從而實現移動端閱讀的體驗 比如說某些線上小說閱讀網站,會加上相應的廣告,從而影響用戶閱讀體驗,於是閱讀這個APP就是做了類似凈化閱讀體驗 但是小說閱讀網站千千萬萬,如果去適 ...
  • 概述 ZYNQ分為PS和PL兩部分,PS端即ARM,PL即FPGA。在使用ZYNQ的時候不免需要PS和PL端進行通信。大多是情況下PS作為主端,PL作為從端,通過AXI匯流排實現PS-PL端的通信。本文主要介紹PL(即FPGA)如何配置的。 Block Design創建 1.點擊Create Bloc ...
  • 動態代理和責任鏈設計模式適用範圍廣,在Spring和MyBatis有著重要的應用,比如SpringAOP、Mybatis的插件技術,想要搞懂當中的技術原理必須掌握上面兩個設計模式。 代理模式可以理解為您要操作一個對象,但是要經過這個對象的“代理”對象去操作。就好似你在一家軟體公司做開發,客戶發現程式 ...
  • 說明: 1. 本文基於Spring-Framework 5.1.x版本講解 2. 建議讀者對Mybatis有基本的使用經驗 概述 這一篇我們講講org.springframework.beans.factory.FactoryBean介面,這個介面功能非常強大,可以集成不同的中間件或組件到Sprin ...
  • 本文基於 newbeemall 項目升級Spring Boot3.0踩坑總結而來,附帶更新說明: Spring-Boot-3.0-發佈說明 Spring-Boot-3.0.0-M5-發佈說明 一. 編譯報錯,import javax.servlet.*; 不存在 這個報錯主要是Spring Boot ...
  • 前言 近期在對開發框架安全策略方面進行升級優化,提供一些通用場景的解決方案,本文針對前後端數據傳輸加密進行簡單的分享,處理流程設計如下圖所示,本加密方法對原有項目相容性較好,只需要更換封裝好的加密Ajax請求方法,後端統一攔截判斷是否需要解密即可 生成DESKey 生成的DES加密密鑰一定是8的整數 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...