翼度科技»论坛 编程开发 PHP 查看内容

微信支付 “商家转账到零钱”

6

主题

6

帖子

18

积分

新手上路

Rank: 1

积分
18
这里有个坑

1:转账低于5毛会失败
2:转账金额需要自己取整一下,微信官方金额是 分 为单位,换算成 元 时可能会除不尽
  1.   {   
  2.     "code":"PARAM_ERROR",
  3.     "detail":{
  4.         "location":"body",
  5.         "value":7.000000000000001   // 微信金额除不尽出现的问题
  6.              },
  7.         "message":" 无法将 JSON 输入源“\/body\/
  8.                     total_amount”映射到目标字段“转账总金额”中,
  9.                     此字段需要一个合法的 64 位有符号整数"
  10.    }
复制代码
1.服务层

  1.    const SSLCERT_PATH = '证书路径';
  2.     const SSLKEY_PATH  = '证书key路径';
  3.     const MCHID        = '商户号';
  4.     const APPID        = 'app_id';
  5.     const KEY          = 'key值';
  6.     /**
  7.      * 付款到微信零钱
  8.      * sOpenid:收款方openid
  9.      * nMoney:转账金额
  10.      */
  11.     public function transfer_batches($sOpenid, $nMoney)
  12.     {
  13.         // 付款到零钱方法url
  14.         $url = 'https://api.mch.weixin.qq.com/v3/transfer/batches';
  15.         // 订单号
  16.         $sOrderId = '测试付款' . time();
  17.         // 转账备注 (微信用户会收到该备注)                                                   
  18.         $tRemark  = '测试付款' . $sOrderId;
  19.         // 转账金额:微信是分为单位 *100 转换                                             
  20.         $transfer_amount = $nMoney * 100;
  21.         // 转账接收列表设置
  22.         $transfer_detail_list = array(               
  23.             [
  24.                 'out_detail_no'   => $sOrderId,                  // 明细单号
  25.                 'transfer_amount' => intval($transfer_amount),   // 转账总金额
  26.                 'transfer_remark' => $tRemark,                   // 单条转账备注
  27.                 'openid'          => $sOpenid,                   // 收款方openid
  28.                 // 'user_name'       => '张三',
  29.                 // 转账金额 >= 2,000元,收款用户姓名必填                  
  30.             ],
  31.         );
  32.         // 请求参数设置
  33.         $params = [                                                // 请求参数设置
  34.             'appid'                => self::APPID,                 // 文档顶部定义
  35.             'out_batch_no'         => $sOrderId,                   // 商家批次单号
  36.             'batch_name'           => 'x年x月转账',                 // 转账的名称
  37.             'batch_remark'         => 'x年x月转账',                 // 转账的备注
  38.             'total_amount'         => intval($transfer_amount),    // 转账总金额
  39.             'total_num'            => 1,                           // 转账总笔数
  40.             'transfer_detail_list' => $transfer_detail_list,       // 转账接收列表
  41.         ];
  42.         // 获取token
  43.         $token        = $this->getToken($params);
  44.         // 发送请求                                    
  45.         $res          = $this->https_request($url, json_encode($params), $token);
  46.         // 反馈数组化  
  47.         $resArr       = json_decode($res, true);                                   
  48.         dump($resArr);
  49.         // 存储转账成功信息或别的操作
  50.         // 成功实例返回值
  51.         {
  52.           "out_batch_no": "plfk2020042013",                        // wx唯一识别号
  53.           "batch_id": "1030000071100999991182020050700019480001",  // 商家批次单号
  54.           "create_time": "2015-05-20T13:29:35.120+08:00"           // 创建时间
  55.         }
  56.     }
  57.     /**
  58.      * 构造请求
  59.      */
  60.     function https_request($url, $data = null, $token)
  61.     {
  62.         $curl = curl_init();
  63.         curl_setopt($curl, CURLOPT_URL, (string)$url);
  64.         curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
  65.         curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
  66.         if (!empty($data)) {
  67.             curl_setopt($curl, CURLOPT_POST, 1);
  68.             curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
  69.         }
  70.         curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  71.         // 添加请求头
  72.         $headers =     [
  73.             'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $token,
  74.             'Accept: application/json',
  75.             'Content-Type: application/json; charset=utf-8',
  76.             'User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
  77.         ];
  78.         if (!empty($headers)) {
  79.             curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
  80.         }
  81.         $output = curl_exec($curl);
  82.         curl_close($curl);
  83.         return $output;
  84.     }
  85.     /**
  86.      * 获取token
  87.      */
  88.     public function getToken($pars)
  89.     {
  90.         $url = 'https://api.mch.weixin.qq.com/v3/transfer/batches';
  91.         $http_method = 'POST';                                  // 请求方法(GET,POST,PUT)
  92.         $timestamp   = time();                                  // 请求时间戳
  93.         $url_parts   = parse_url($url);                         // 获取请求的绝对URL
  94.         $nonce       = $timestamp . rand('10000', '99999');     // 请求随机串
  95.         $body        = json_encode((object)$pars);              // 请求报文主体
  96.         $stream_opts = [
  97.             "ssl" => [
  98.                 "verify_peer"          => false,
  99.                 "verify_peer_name"     => false,
  100.             ]
  101.         ];
  102.         // 证书路径信息:文档顶部定义
  103.         $apiclient_cert_path = self::SSLCERT_PATH;
  104.         $apiclient_key_path  = self::SSLKEY_PATH;
  105.         $apiclient_cert_arr = openssl_x509_parse(file_get_contents($apiclient_cert_path, false, stream_context_create($stream_opts)));
  106.         // 证书序列号
  107.         $serial_no          = $apiclient_cert_arr['serialNumberHex'];
  108.         // 密钥                                                                  
  109.         $mch_private_key    = file_get_contents($apiclient_key_path, false, stream_context_create($stream_opts));
  110.         // 商户id:文档顶部定义                       
  111.         $merchant_id        = self::MCHID;                                                                                             
  112.         $canonical_url      = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
  113.         $message            = $http_method . "\n" .
  114.             $canonical_url . "\n" .
  115.             $timestamp . "\n" .
  116.             $nonce . "\n" .
  117.             $body . "\n";
  118.         openssl_sign($message, $raw_sign, $mch_private_key, 'sha256WithRSAEncryption');
  119.         // 签名
  120.         $sign   = base64_encode($raw_sign);                                                                                                               
  121.         $schema = 'WECHATPAY2-SHA256-RSA2048';
  122.         $token  = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"', $merchant_id, $nonce, $timestamp, $serial_no, $sign);
  123.         // 微信返回token
  124.         return $token;
  125.     }
复制代码
 
2.控制层

  1.     public function onTransferBatches($openid, $nMoney)
  2.     {
  3.         // 实例化服务层
  4.         $serviceTransfer = new serviceTransfer();
  5.         // 带参请求:sOpenid(收款方openid)   nMoney(转账金额)
  6.         $result          = $serviceTransfer->transfer_batches($openid, $nMoney);
  7.         return $result;
  8.     }
复制代码
 

来源:https://www.cnblogs.com/simpe/p/16949847.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具