PHP实现微信提现V3版本2022-5更新接口:商家转账到零钱

微信官方又更新了接口。。。

V3版本的微信商家转账到零钱的接口—俗称提现接口

注意事项

[scode type=“yellow”]
一:开通条件:需满足入驻满90天,连续正常交易30天,保持正常健康交易。
二:分为页面发起和api接口操作,均需要手动开启才可。
三:需要设置IP白名单,否则不能发起接口调用。
四:商家转账的户口为商户平台的运营账户,非商户基本账户,注意保证运营账户的余额充足!
五:注意提现额度的变化,超过设置的免密额度,该笔提现会自动发送给超级管理员审核,输入密码确定此笔提现操作。
[/scode]

1658818053.png
1658819455.jpg
1658820824.jpg

class Withdraw
{
    public $mchid = '你的商户id';
    public $appid = '小程序appid';
    public $serial_no = '你的证书序列号'; // 证书序列号,不知道怎么获取的看上面的图
 

    public function transfer($openid, $trade_no, $money, $desc='备注说明')
    {
        $money = (int)($money * 100);

        $post_data = [
            "appid" => $this->appid,//appid
            "out_batch_no" => $trade_no,//商家批次单号
            "batch_name" => $desc,//批次名称
            "batch_remark" => $desc,//批次备注
            "total_amount" => $money,// 转账金额单位为“分”
            "total_num" => 1, // 转账总笔数
            //此处可以多笔提现  组合二维数组放到transfer_detail_list即可   我这里单笔操作,写死了
            "transfer_detail_list" => [
                [
                    'out_detail_no' => $trade_no,
                    'transfer_amount' => $money,
                    'transfer_remark' => $desc,
                    'openid' => $openid,
                ]
            ]
        ];
        $url = 'https://api.mch.weixin.qq.com/v3/transfer/batches';
        //JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE  防止中文被转义
        $result = $this->wx_post($url, json_encode($post_data, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE));

        $result = json_decode($result, true);
        if (isset($result['prepay_id'])) {
            return $result['prepay_id'];
        }
        return $result;
    }

    /**post请求
     * @param $url
     * @param $param
     * @return bool|string
     */
    private function wx_post($url, $param)
    {
        $authorization = $this->getV3Sign($url, "POST", $param);
        $curl = curl_init();
        $headers = [
            'Authorization:' . $authorization,
            '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',
        ];
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_TIMEOUT, 500);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $param);
        curl_setopt($curl, CURLOPT_POST, true);
        $res = curl_exec($curl);
        curl_close($curl);
        return $res;
    }

    /**
     * 微信提现V3签名
     * @param $url
     * @param $http_method
     * @param $body
     * @return string
     */
    private function getV3Sign($url, $http_method, $body)
    {
        $nonce = strtoupper($this->createNonceStr(32));
        $timestamp = time();
        $url_parts = parse_url($url);
        $canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
        $cert_dir = ROOT_PATH.DS."config".DS."payment_cert".DS."wechatpay".DS;
        $sslKeyPath = $cert_dir."apiclient_key.pem";
        //拼接参数
        $message = $http_method . "\n" .
            $canonical_url . "\n" .
            $timestamp . "\n" .
            $nonce . "\n" .
            $body . "\n";
        $private_key = $this->getPrivateKey($sslKeyPath);
        openssl_sign($message, $raw_sign, $private_key, 'sha256WithRSAEncryption');
        $sign   = base64_encode($raw_sign);
        $token = sprintf('WECHATPAY2-SHA256-RSA2048 mchid="%s",nonce_str="%s",timestamp="%s",serial_no="%s",signature="%s"', $this->mchid, $nonce, $timestamp, $this->serial_no, $sign);
        return $token;
    }

    /**
     * 生成随机32位字符串
     * @param $length
     * @return string
     */
    public function createNonceStr($length = 16) { //生成随机16个字符的字符串
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }

    /**
     * 获取私钥
     * @param $filepath
     * @return false|resource
     */
    private function getPrivateKey($filepath = '')
    {
        if (empty($filepath)) {
            //私钥位置
            $cert_dir = ROOT_PATH.DS."config".DS."payment_cert".DS."wechatpay".DS;
            $filepath = $cert_dir."apiclient_key.pem";
        }
        return openssl_get_privatekey(file_get_contents($filepath));
    }
}

以上所写,如有bug还请各位大佬,批评指正!
我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=kl1ukrm72nx7

微信商家转账零钱 V3实现需要通过微信支付 API 接口实现,以下是 JAVA 版本的代码实现: 1. 导入依赖包 ```java import java.util.HashMap; import java.util.Map; import com.github.wxpay.sdk.WXPay; import com.github.wxpay.sdk.WXPayConfig; import com.github.wxpay.sdk.WXPayConstants; import com.github.wxpay.sdk.WXPayUtil; ``` 2. 构造微信支付配置对象 ```java public class WXPayConfigImpl implements WXPayConfig { private String appID; // 公众账号ID或应用ID private String mchID; // 商户号 private String key; // 商户密钥 private String certPath; // 商户证书路径 private int httpConnectTimeoutMs = 6 * 1000; // 连接超时时间 private int httpReadTimeoutMs = 8 * 1000; // 读取超时时间 public WXPayConfigImpl(String appID, String mchID, String key, String certPath) { this.appID = appID; this.mchID = mchID; this.key = key; this.certPath = certPath; } @Override public String getAppID() { return appID; } @Override public String getMchID() { return mchID; } @Override public String getKey() { return key; } @Override public InputStream getCertStream() { try { return new FileInputStream(new File(certPath)); } catch (FileNotFoundException e) { e.printStackTrace(); } return null; } @Override public int getHttpConnectTimeoutMs() { return httpConnectTimeoutMs; } @Override public int getHttpReadTimeoutMs() { return httpReadTimeoutMs; } } ``` 3. 构造微信支付对象 ```java WXPayConfig wxPayConfig = new WXPayConfigImpl(appID, mchID, key, certPath); WXPay wxPay = new WXPay(wxPayConfig, WXPayConstants.SignType.MD5, true); ``` 4. 构造参数并调用接口 ```java // 构造请求参数 Map<String, String> reqData = new HashMap<String, String>(); reqData.put("mch_appid", appID); reqData.put("mchid", mchID); reqData.put("nonce_str", WXPayUtil.generateNonceStr()); reqData.put("partner_trade_no", "xxxxxxxxxxxx"); // 商户订单号 reqData.put("openid", "xxxxxxxxxxxx"); // 用户openid reqData.put("check_name", "NO_CHECK"); // 不校验真实姓名 reqData.put("amount", "100"); // 转账金额 reqData.put("desc", "测试转账"); // 转账描述 reqData.put("spbill_create_ip", "127.0.0.1"); // 调用接口的机器IP地址 // 调用接口 Map<String, String> respData = wxPay.transfer(reqData); ``` 其中,`appID`、`mchID`、`key`、`certPath` 等参数需要根据实际情况填写。`wxPay.transfer(reqData)` 方法返回的是一个 Map 对象,包含了接口响应的所有信息,可以根据业务需求进行处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PHP小志

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值