红孩儿演出服 发表于 2023-1-2 16:07:09

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

​ 这里有个坑

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;
    } 

来源:https://www.cnblogs.com/simpe/p/16949847.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 微信支付 “商家转账到零钱”