微信提现(商家转账到零钱)
准备工作
- 微信商户号
- API证书
- API证书序列号(申请api证书完成之后可以看到)
- API V3密钥
注意事项
- 基于微信官方sdk
- 微信支付平台证书需要自己手动生成,请一定注意,这是手动生成的
- 场景-现金营销(其他场景也可以,但操作步骤可能不同,请注意,以下代码均以现金营销为准)
- 需要开通运营账户,转出的钱均从运营账户里扣除,商户号得到的钱均进入基本账户
windows本地获取 微信支付平台证书
- 1、新建文件夹
- 2、composer require wechatpay/wechatpay
- 3、composer require guzzlehttp/guzzle
- 4、查看php版本,找到对应版本的php目录下,然后下载好的ca证书放到目录,并修改php.ini中的curl.cainfo,如果前面有分号(;),需要删除
- 5、新建文件夹下运行:php vendor/bin/CertificateDownloader.php -k apiv3秘钥 -m 商户号 -f 证书私钥文件路径\apiclient_key.pem -s 证书序列号 -o 生成文件路径
- 例如 : 新建文件夹下运行:php vendor/bin/CertificateDownloader.php -k ba12313p12317go123o -m 112xxx381 -f certs\apiclient_key.pem -s 证书序列号 -o cert
公共部分:
protected function getInstance(): \WeChatPay\BuilderChainable
{
//自己的商户号
$merchantId = config('site.merchant_id');
// 从本地文件中加载「商户API私钥」,「商户API私钥」会用来生成请求的签名
$merchantPrivateKeyFilePath = 'file://' . '填写你本地证书的地址,xxxx.pem';
$merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE);
// 「商户API证书」的「证书序列号」
$merchantCertificateSerial = config('site.serial_num');
// 从本地文件中加载「微信支付平台证书」,用来验证微信支付应答的签名
$platformCertificateFilePath = 'file://' . '填写你本地证书的地址,xxxx.pem';
$platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
// 从「微信支付平台证书」中获取「证书序列号」
$platformCertificateSerial = PemUtil::parseCertificateSerialNo($platformCertificateFilePath);
// 构造一个 APIv3 客户端实例
$instance = Builder::factory([
'mchid' => $merchantId,
'serial' => $merchantCertificateSerial,
'privateKey' => $merchantPrivateKeyInstance,
'certs' => [
$platformCertificateSerial => $platformPublicKeyInstance,
],
]);
// 加密敏感信息 金额超过2k才会使用加密算法 输入的真实姓名为真实的绑定微信的实名信息
$encryptor = static function (string $msg) use ($platformPublicKeyInstance): string {
return \WeChatPay\Crypto\Rsa::encrypt($msg, $platformPublicKeyInstance);
};
return $instance;
}
微信转账:
public function wxTransfer($params, $openid)
{
//传进来的是业务数据,数组类型 请自行修改
//(该接口不会返回分账成功或者失败,只会返回调用结果是否成功,若想查看是否转账成功,请使用本代码getWithdrawResult)
$instance = $this->getInstance();
// 商家转账到零钱
$response = $instance
->chain('v3/transfer/batches')
->post(['json' => [
'appid' => config('site.user_appid'),
'out_batch_no' => 'jrt' . $params['order_num'], //商户系统内部的商家批次单号,要求此参数只能由数字、大小写字母组成,在商户系统内部唯一,
'batch_name' => date('Y-m', time()) . ' - 提现', //该笔批量转账的名称
'batch_remark' => $params['name'] . "-" . $params['memo'], //转账说明,UTF8编码,最多允许32个字符
'total_amount' => (int)intval(strval($params['money'] * 100)), //转账总金额 单位为“分”
'total_num' => 1,
'transfer_detail_list' => [
[
'out_detail_no' => $params['order_num'],
'transfer_amount' => intval(strval($params['money'] * 100)),
'transfer_remark' => $params['name'] . "-" . $params['memo'],
'openid' => $openid,
//'user_name' => $encryptor($params['name']) // 金额超过`2000`才填写
]
]
]]);
return $response;
}
查询转账结果==通过商家明细查看明细单号:
public function getWithdrawResult($withdrawOrderData)
{
$instance = $this->getInstance();
//out_detail_no == 商家明细单号 == 申请转账的时候传的这个== item2--转账接口传了
//out_batch_no == 商家批次单号 == 申请转账的时候也传了==item1--转账接口传了
// 示例 https://api.mch.weixin.qq.com/v3/transfer/batches/out-batch-no/x23zy545Bd5436/details/out-detail-no/plfk2020042013
$resp = $instance->v3->transfer->batches->outBatchNo->_item1_->details->outDetailNo->_item2_->get([
// 变量名 => 变量值
'item1' => 'xrzk' . $withdrawOrderData->order_num,
'item2' => $withdrawOrderData->order_num,
]);
$result = json_decode($resp->getBody(), true);
//失败原因处理
if ($result['detail_status'] == 'FAIL') {
$result['fail_reason'] = $this->reasonList($result['fail_reason']);
}
}
失败原因:
public function reasonList($value)
{
$list = [
'ACCOUNT_FROZEN' => '账户冻结',
'REAL_NAME_CHECK_FAIL' => '用户未实名',
'NAME_NOT_CORRECT' => '用户姓名校验失败',
'OPENID_INVALID' => 'Openid校验失败',
'TRANSFER_QUOTA_EXCEED' => '超过用户单笔收款额度',
'DAY_RECEIVED_QUOTA_EXCEED' => '超过用户单日收款额度',
'MONTH_RECEIVED_QUOTA_EXCEED' => '超过用户单月收款额度',
'DAY_RECEIVED_COUNT_EXCEED' => '超过用户单日收款次数',
'PRODUCT_AUTH_CHECK_FAIL' => '产品权限校验失败',
'OVERDUE_CLOSE' => '转账关闭',
'ID_CARD_NOT_CORRECT' => '用户身份证校验失败',
'ACCOUNT_NOT_EXIST' => '用户账户不存在',
'TRANSFER_RISK' => '转账存在风险',
'REALNAME_ACCOUNT_RECEIVED_QUOTA_EXCEED' => '用户账户收款受限,请引导用户在微信支付查看详情',
'RECEIVE_ACCOUNT_NOT_PERMMIT' => '未配置该用户为转账收款人',
'PAYER_ACCOUNT_ABNORMAL' => '商户账户付款受限,可前往商户平台-违约记录获取解除功能限制指引',
'PAYEE_ACCOUNT_ABNORMAL' => '用户账户收款异常,请引导用户完善其在微信支付的身份信息以继续收款',
'TRANSFER_REMARK_SET_FAIL' => '转账备注设置失败,请调整对应文案后重新再试',
];
return isset($list[$value]) ? $list[$value] : '未知错误,请去 微信商户中心 - 交易中心 - 商家转账到零钱 - 查询具体原因';
}