這裡有個坑 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; }